示例#1
0
Datum Function_invoke(Function self, PG_FUNCTION_ARGS)
{
	Datum retVal;
	int32 top;
	jvalue* args;
	Type  invokerType;

	fcinfo->isnull = false;
	currentInvocation->function = self;

	if(self->isUDT)
		return self->func.udt.udtFunction(self->func.udt.udt, fcinfo);

	if(self->func.nonudt.isMultiCall && SRF_IS_FIRSTCALL())
		Invocation_assertDisconnect();

	top = self->func.nonudt.numParams;
	
	/* Leave room for one extra parameter. Functions that returns unmapped
	 * composite types must have a single row ResultSet as an OUT parameter.
	 */
	args  = (jvalue*)palloc((top + 1) * sizeof(jvalue));
	invokerType = self->func.nonudt.returnType;

	if(top > 0)
	{
		int32 idx;
		Type* types = self->func.nonudt.paramTypes;

		/* a class loader or other mechanism might have connected already. This
		 * connection must be dropped since its parent context is wrong.
		 */
		if(Type_isDynamic(invokerType))
			invokerType = Type_getRealType(invokerType, get_fn_expr_rettype(fcinfo->flinfo), self->func.nonudt.typeMap);

		for(idx = 0; idx < top; ++idx)
		{
			if(PG_ARGISNULL(idx))
				/*
				 * Set this argument to zero (or null in case of object)
				 */
				args[idx].j = 0L;
			else
			{
				Type paramType = types[idx];
				if(Type_isDynamic(paramType))
					paramType = Type_getRealType(paramType, get_fn_expr_argtype(fcinfo->flinfo, idx), self->func.nonudt.typeMap);
				args[idx] = Type_coerceDatum(paramType, PG_GETARG_DATUM(idx));
			}
		}
	}

	retVal = self->func.nonudt.isMultiCall
		? Type_invokeSRF(invokerType, self->clazz, self->func.nonudt.method, args, fcinfo)
		: Type_invoke(invokerType, self->clazz, self->func.nonudt.method, args, fcinfo);

	pfree(args);
	return retVal;
}
示例#2
0
文件: variant.c 项目: decibel/variant
Datum
variant_cast_out(PG_FUNCTION_ARGS)
{
    Oid							targettypid = get_fn_expr_rettype(fcinfo->flinfo);
    VariantInt			vi;
    Datum						out;

    if( PG_ARGISNULL(0) )
        PG_RETURN_NULL();

    /* No reason to format type name, so use IOFunc_input instead of IOFunc_output */
    vi = make_variant_int(PG_GETARG_VARIANT(0), fcinfo, IOFunc_input);

    /* If original was NULL then we MUST return NULL */
    if( vi->isnull )
        PG_RETURN_NULL();

    /* If our types match exactly we don't need to cast */
    if( vi->typid == targettypid )
        PG_RETURN_DATUM(vi->data);

    /* Keep cruft localized to just here */
    {
        bool						do_pop;
        int							ret;
        bool						isnull;
        MemoryContext		cctx = CurrentMemoryContext;
        HeapTuple				tup;
        StringInfoData	cmdd;
        StringInfo			cmd = &cmdd;
        char						*nulls = " ";

        do_pop = _SPI_conn();

        initStringInfo(cmd);
        appendStringInfo( cmd, "SELECT $1::%s", format_type_be(targettypid) );
        /* command, nargs, Oid *argument_types, *values, *nulls, read_only, count */
        if( (ret = SPI_execute_with_args( cmd->data, 1, &vi->typid, &vi->data, nulls, true, 0 )) != SPI_OK_SELECT )
            elog( ERROR, "SPI_execute_with_args returned %s", SPI_result_code_string(ret));

        /*
         * Make a copy of result tuple in previous memory context. Copying the
         * entire tuple is wasteful; it would be better to only copy the actual
         * attribute; but in this case the difference isn't very large.
         */
        MemoryContextSwitchTo(cctx);
        tup = heap_copytuple(SPI_tuptable->vals[0]);

        out = heap_getattr(tup, 1, SPI_tuptable->tupdesc, &isnull);
        // getTypeOutputInfo(typoid, &foutoid, &typisvarlena);

        /* Remember this frees everything palloc'd since our connect/push call */
        _SPI_disc(do_pop);
    }
    /* End cruft */

    PG_RETURN_DATUM(out);
}
示例#3
0
Datum
int8_add(PG_FUNCTION_ARGS)
{
	int64   state1;
	int64   state2;

	/*
	 * GUARD against an incorrectly defined SQL function by verifying
	 * that the parameters are the types we are expecting:
	 *    int8_add(int64, int64) => int64
	 */
	if (PG_NARGS() != 2)
	{
		elog(ERROR, "%s defined with %d arguments, expected 2",
			 add_str, PG_NARGS() );
	}
	if (get_fn_expr_argtype(fcinfo->flinfo, 0) != INT8OID ||
		get_fn_expr_argtype(fcinfo->flinfo, 1) != INT8OID)
	{
		elog(ERROR, "%s defined with invalid types, expected (int8, int8)",
			 add_str );
	}
	if (get_fn_expr_rettype(fcinfo->flinfo) != INT8OID)
	{
		elog(ERROR, "%s defined with invalid return type, expected int8",
			 add_str );
	}

	/*
	 * GUARD against NULL input:
	 *  - IF both are null return NULL
	 *  - otherwise treat NULL as a zero value
	 */
	if (PG_ARGISNULL(0) && PG_ARGISNULL(1))
		PG_RETURN_NULL();
	state1 = PG_ARGISNULL(0) ? 0 : PG_GETARG_INT64(0);
	state2 = PG_ARGISNULL(1) ? 0 : PG_GETARG_INT64(1);

	/* Do the math and return the result */
	PG_RETURN_INT64(state1 + state2);
}
Datum transform_eeg(PG_FUNCTION_ARGS)
{
    //the size of the array we are trying to transform
    int arraySize;
    // a Datum for the constructred and deconstructed input arrays
    Datum *intermResult;
    Datum *input_data;
    // the final result to return and the input to the function
    ArrayType *result, *input;
    Oid element_type, return_type, input_type;
    //next 6 variables are inputted into get_typlenbyvalalign() and are used for construct and deconstruct array
    //small int in postgreSQL is int16
    int16 return_typelen, input_typelen;
    bool return_typbyval, input_typbyval;
    char return_typalign, input_typalign;

    //the arrays we are transforming. Transforming array in[] into array out[]
    //fftw_complex, a data structure with real (in[i].re) and imaginary (in[i].im) floating-point components. 
    fftw_complex *in, *out;
    fftw_plan my_plan;


    // get input row
    input = PG_GETARG_ARRAYTYPE_P(0);
    // get input array element type
    input_type = ARR_ELEMTYPE(input);
    //get needed variabels
    get_typlenbyvalalign(input_type, &input_typelen, &input_typbyval, &input_typalign);
    // deconstruct inupt array and save the array as Datum input_data
    deconstruct_array(input, input_type, input_typelen, input_typbyval, input_typalign, &input_data, NULL, &arraySize);

    // get element type of return vale (Complex[])
    element_type = get_fn_expr_rettype(fcinfo->flinfo);
    // get element type of an element in the return value (Complex)
    return_type = get_element_type(element_type);
    //get needed variabels
    get_typlenbyvalalign(return_type, &return_typelen, &return_typbyval, &return_typalign);

    // in and out array and plan declarations
    in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*arraySize);
    out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex)*arraySize);
    my_plan = fftw_plan_dft_1d(arraySize, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
    
    // set the in variable to the array we got as input.
    // the real parts are from the input_data array
    // the imaginary part is set to 0
    for (int i = 0; i < arraySize; i++) {
        in[i][0] = (double) DatumGetInt16(input_data[i]);
        in[i][1] = 0;
    }

    // run the plan
    fftw_execute(my_plan);

    // array to store the out array (the transformed in array)
    intermResult = palloc(sizeof(Datum)*arraySize);
    
    // for each variable in the out array. 
    // Create a complex variable then set its real and imaginary party from the processed array
    // get the datum from the pointer and save it in the result array
    for(int32 i = 0; i < arraySize; i++)
    {
        Complex *temp = palloc(sizeof(Complex));
        temp->x = out[i][0];
        temp->y = out[i][1];
        intermResult[i] = PointerGetDatum(temp);
    }

    // construct a result array
    result = construct_array(intermResult, arraySize, return_type, return_typelen, return_typbyval, return_typalign);
    
    // free memory
    fftw_destroy_plan(my_plan);
    fftw_free(in);
    fftw_free(out);
    pfree(input_data);
    pfree(intermResult);

    // return result
    PG_RETURN_POINTER(result);

}
Datum get_power_spectrum(PG_FUNCTION_ARGS)
{

    //the size of the array we are trying to transform
    int arraySize;
    int *signals;
    // a Datum for the constructred and deconstructed input arrays
    Datum *intermResult;
    Datum *input_data;
    // the final result to return and the input to the function
    ArrayType *result, *input;
    Oid element_type, return_type, input_type;
    //next 6 variables are inputted into get_typlenbyvalalign() and are used for construct and deconstruct array
    //small int in postgreSQL is int16
    int16 return_typelen, input_typelen;
    bool return_typbyval, input_typbyval;
    char return_typalign, input_typalign;


    // get input row
    input = PG_GETARG_ARRAYTYPE_P(0);
    // get input array element type
    input_type = ARR_ELEMTYPE(input);
    //get needed variabels
    get_typlenbyvalalign(input_type, &input_typelen, &input_typbyval, &input_typalign);
    // deconstruct inupt array and save the array as Datum input_data
    deconstruct_array(input, input_type, input_typelen, input_typbyval, input_typalign, &input_data, NULL, &arraySize);

    // get element type of return vale (Complex[])
    element_type = get_fn_expr_rettype(fcinfo->flinfo);
    // get element type of an element in the return value (Complex)
    return_type = get_element_type(element_type);
    //get needed variabels
    get_typlenbyvalalign(return_type, &return_typelen, &return_typbyval, &return_typalign);
    

    signals = palloc(sizeof(int)*arraySize);
    // set the in variable to the array we got as input.
    // the real parts are from the input_data array
    // the imaginary part is set to 0
    for (int i = 0; i < arraySize; i++) {
        Complex *temp = (Complex*) DatumGetPointer(input_data[i]);
        signals[i] = temp->x*temp->x + temp->y*temp->y;
    }

    intermResult = palloc(sizeof(Datum)*arraySize);
    // for each variable in the out array. 
    // Create a complex variable then set its real and imaginary party from the processed array
    // get the datum from the pointer and save it in the result array
    for(int i = 0; i < arraySize; i++)
    {
        intermResult[i] = PointerGetDatum(signals[i]);
    }


    // construct a result array
    result = construct_array(intermResult, arraySize, return_type, return_typelen, return_typbyval, return_typalign);
    
    // free memory
    pfree(input_data);
    pfree(intermResult);

    // return result
    PG_RETURN_POINTER(result);
}