Datum
alpine_miner_kmeans_distance_result(PG_FUNCTION_ARGS)
{


	 ArrayType  *sample_arg, *data_arg;
	 Datum     *sample_data, *data_data;
	 Oid         sample_eltype,data_eltype;
	 int16       sample_typlen, data_typlen;
	 bool        sample_typbyval, data_typbyval;
	 char        sample_typalign, data_typalign;
	 bool       *sample_nulls, *data_nulls;
	 int         sample_count, data_count,k,distanceMode;
	 float       len;
	 
	if (PG_ARGISNULL(0) || PG_ARGISNULL(1) || PG_ARGISNULL(2)||PG_ARGISNULL(3) )
	{
		PG_RETURN_NULL();
	}

	 /* get sample_arg args */
	 sample_arg=PG_GETARG_ARRAYTYPE_P(0);
	  /* get sample_arg array element type */
	   sample_eltype = ARR_ELEMTYPE(sample_arg);

	  get_typlenbyvalalign(sample_eltype, &sample_typlen, &sample_typbyval, &sample_typalign);

	  deconstruct_array(sample_arg, sample_eltype, 
		sample_typlen, sample_typbyval, sample_typalign,
		&sample_data, &sample_nulls, &sample_count);

	    /* get data_arg args */
        data_arg = PG_GETARG_ARRAYTYPE_P(1);
	/* get data_arg array element type */	
	data_eltype = ARR_ELEMTYPE(data_arg);

	get_typlenbyvalalign(data_eltype, &data_typlen, &data_typbyval, &data_typalign);

	 deconstruct_array(data_arg, data_eltype, 
		data_typlen, data_typbyval, data_typalign,
		&data_data, &data_nulls, &data_count);

	 k=PG_GETARG_INT32(2);
	 distanceMode=PG_GETARG_INT32(3);

	 len=alpine_miner_resultEuclideanDistance(sample_data,sample_count,data_data,data_count,k,distanceMode);

	 pfree(sample_data);
        pfree(sample_nulls);
        pfree(data_data);
        pfree(data_nulls);

	PG_RETURN_FLOAT8(len);
}
Ejemplo n.º 2
0
/*
 * Types are always allocated in global context.
 */
Type TypeClass_allocInstance2(TypeClass cls, Oid typeId, Form_pg_type pgType)
{
	Type t = (Type)PgObjectClass_allocInstance((PgObjectClass)(cls), TopMemoryContext);
	t->typeId       = typeId;
	t->arrayType    = 0;
	t->elementType  = 0;
	t->objectType   = 0;
	t->inCoercions  = 0;
	t->outCoercions = 0;
	if(pgType != 0)
	{
		t->length  = pgType->typlen;
		t->byValue = pgType->typbyval;
		t->align   = pgType->typalign;
	}
	else if(typeId != InvalidOid)
	{
		get_typlenbyvalalign(typeId,
						 &t->length,
						 &t->byValue,
						 &t->align);
	}
	else
	{
		t->length = 0;
		t->byValue = true;
		t->align = 'i';
	}
	return t;
}
Ejemplo n.º 3
0
void dump_bvf1_inputs(ArrayType *broker_list_p, text *sector_name_p) {
	int ndim, nitems;
	int *dim;

	int16 typlen;
	bool typbyval;
	char typalign;

	int i;

	char *broker_list;

	ndim = ARR_NDIM(broker_list_p);
	dim = ARR_DIMS(broker_list_p);
	nitems = ArrayGetNItems(ndim, dim);
	get_typlenbyvalalign(ARR_ELEMTYPE(broker_list_p), &typlen, &typbyval,
			&typalign);

	broker_list = ARR_DATA_PTR(broker_list_p);
	elog(NOTICE, "BVF1: INPUTS START");
	for (i = 0; i < nitems; i++) {
		elog(NOTICE, "BVF1: broker_list[%d] %s", i,
				DatumGetCString(DirectFunctionCall1(textout,
				PointerGetDatum(broker_list))));
		broker_list = att_addlength_pointer(broker_list, typlen,
				broker_list);
		broker_list = (char *) att_align_nominal(broker_list, typalign);
	}
	elog(NOTICE, "BVF1: sector_name %s",
			DatumGetCString(DirectFunctionCall1(textout,
			PointerGetDatum(sector_name_p))));
	elog(NOTICE, "BVF1: INPUTS END");
}
Ejemplo n.º 4
0
/* 
 * pivot_find() - Searchs an array of labels for a matching value.
 *
 * Returns: index of found value, or -1 if not found
 *
 * It may eventually do something smarter than a linear scan, but
 * for now this is sufficient given that we don't know anything about the
 * order of 'labels'.
 *
 */
static int pivot_find(ArrayType *labels, text *attr) 
{
	char    *labelsp;
	int      i, nelem, asize;
	int16    typlen;
	bool     typbyval;
	char     typalign;
	
	if (ARR_ELEMTYPE(labels) != TEXTOID)
		ereport(ERROR, 
				(errcode(ERRCODE_DATATYPE_MISMATCH),
				 errmsg("pivot_accum: labels are not type text")));

	/* Text alignment properties */
	get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
	
	/* Get the size of the input attribute, we'll use this for fast compares */
	asize = VARSIZE(attr);
	
	/* The labels array is an array of varying length text, scan it adding
	   the length of the previous entry until we are done or we have found
	   a match. */
	labelsp = (char *) ARR_DATA_PTR(labels);
	nelem = ARR_DIMS(labels)[0];
	for (i = 0; i < nelem; i++)
	{
		int lsize = VARSIZE(labelsp);
		if (asize == lsize && !memcmp(attr, labelsp, lsize))
			return i;  /* Found */
		labelsp  = labelsp + lsize;
		labelsp  = (char*) att_align(labelsp, typalign); 
	}
	return -1;  /* Not found */
}
Ejemplo n.º 5
0
void array_loop(ArrayType *array, int32 start, array_iter *iter)
{
	iter->array = array;
	iter->ptr   = ARR_DATA_PTR(array);
	iter->max   = ARR_DIMS(array)[0];
	get_typlenbyvalalign(ARR_ELEMTYPE(array), 
						 &iter->typlen,
						 &iter->typbyval,
						 &iter->typalign);

	/* If we are starting in the middle of the array, then scan forward */
	start = start - ARR_LBOUND(array)[0];
	if (start <= 0)
		iter->index = start;
	else
	{
		/* 
		 * could probably be more efficient for fixed length arrays, but
		 * they would still require adjustments for nulls.
		 */
		iter->index = 0;
		while (start--)
		{
			Datum d;
			bool  isna;
			array_next(iter, &d, &isna);
		}
	}
}
Ejemplo n.º 6
0
/*
 * extractValue support function
 */
Datum
ginarrayextract(PG_FUNCTION_ARGS)
{
	/* Make copy of array input to ensure it doesn't disappear while in use */
	ArrayType  *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
	int32	   *nkeys = (int32 *) PG_GETARG_POINTER(1);
	bool	  **nullFlags = (bool **) PG_GETARG_POINTER(2);
	int16		elmlen;
	bool		elmbyval;
	char		elmalign;
	Datum	   *elems;
	bool	   *nulls;
	int			nelems;

	get_typlenbyvalalign(ARR_ELEMTYPE(array),
						 &elmlen, &elmbyval, &elmalign);

	deconstruct_array(array,
					  ARR_ELEMTYPE(array),
					  elmlen, elmbyval, elmalign,
					  &elems, &nulls, &nelems);

	*nkeys = nelems;
	*nullFlags = nulls;

	/* we should not free array, elems[i] points into it */
	PG_RETURN_POINTER(elems);
}
Ejemplo n.º 7
0
static Datum
build_array(element_set_t * eset, Oid element_type)
{
    Datum * array_of_datums;
    int i;

    int16       typlen;
    bool        typbyval;
    char        typalign;

    /* do the compaction */
    compact_set(eset, false);

#if DEBUG_PROFILE
    print_set_stats(eset);
#endif
    
    /* get detailed type information on the element type */
    get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

    /* Copy data from compact array to array of Datums
     * A bit suboptimal way, spends excessive memory
     */
    array_of_datums = palloc0(eset->nsorted * sizeof(Datum));
    for (i = 0; i < eset->nsorted; i++)
        memcpy(array_of_datums + i, eset->data + (eset->item_size * i), eset->item_size);

    /* build and return the array */
    PG_RETURN_DATUM(PointerGetDatum(construct_array(
        array_of_datums, eset->nsorted, element_type, typlen, typbyval, typalign
    )));
}
Ejemplo n.º 8
0
Datum postal_normalize(PG_FUNCTION_ARGS)
{
	text *address = PG_GETARG_TEXT_P(0);
	size_t arr_nelems, i;
	libpostal_normalize_options_t options = libpostal_get_default_options();
	char **expansions = libpostal_expand_address(text_to_cstring(address), options, &arr_nelems);
	ArrayType *arr;
	Datum *arr_elems = palloc(sizeof(Datum) * arr_nelems);
	
	Oid elem_type = TEXTOID;
	int16 elem_len;
	char elem_byval;
	char elem_align;
	
	get_typlenbyvalalign(elem_type, &elem_len, &elem_byval, &elem_align);
	
	for (i = 0; i < arr_nelems; i++)
	{
		arr_elems[i] = PointerGetDatum(cstring_to_text(expansions[i]));
	}
	
	/* Array construction takes a full copy of the input */
	arr = construct_array(arr_elems, arr_nelems, elem_type, elem_len, elem_byval, elem_align);
	
	/* Clean up unmanaged memory */
	libpostal_expansion_array_destroy(expansions, arr_nelems);
	
	PG_RETURN_ARRAYTYPE_P(arr); 
}
Ejemplo n.º 9
0
/*
 * actually does the work for array(), and array_accum() if it is given a null
 * input array.
 *
 * numelems and elem_start allow the function to be shared given the differing
 * arguments accepted by array() and array_accum(). With array(), all function
 * arguments are used for array construction -- therefore elem_start is 0 and
 * numelems is the number of function arguments. With array_accum(), we are
 * always initializing the array with a single element given to us as argument
 * number 1 (i.e. the second argument).
 *
 */
static ArrayType *
plr_array_create(FunctionCallInfo fcinfo, int numelems, int elem_start)
{
	Oid			funcid = fcinfo->flinfo->fn_oid;
	Datum	   *dvalues = (Datum *) palloc(numelems * sizeof(Datum));
	int16		typlen;
	bool		typbyval;
	Oid			typinput;
	Oid			element_type;
	char		typalign;
	int			i;
	HeapTuple	tp;
	Oid			functypeid;
	Oid		   *funcargtypes;
	ArrayType  *result;

	if (numelems == 0)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("at least one value required to construct an array")));

	/*
	 * Get the type metadata for the array return type and its elements
	 */
	tp = SearchSysCache(PROCOID,
						ObjectIdGetDatum(funcid),
						0, 0, 0);
	if (!HeapTupleIsValid(tp))
		/* internal error */
		elog(ERROR, "function OID %u does not exist", funcid);

	functypeid = ((Form_pg_proc) GETSTRUCT(tp))->prorettype;
	getTypeInputInfo(functypeid, &typinput, &element_type);

	get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

	funcargtypes = FUNCARGTYPES(tp);

	/*
	 * the first function argument(s) may not be one of our array elements,
	 * but the caller is responsible to ensure we get nothing but array
	 * elements once they start coming
	 */
	for (i = elem_start; i < elem_start + numelems; i++)
		if (funcargtypes[i] != element_type)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("argument %d datatype not " \
							"compatible with return data type", i + 1)));

	ReleaseSysCache(tp);

	for (i = 0; i < numelems; i++)
		dvalues[i] = PG_GETARG_DATUM(elem_start + i);

	result = construct_array(dvalues, numelems, element_type,
							 typlen, typbyval, typalign);

	return result;
}
Ejemplo n.º 10
0
/*
 * extractQuery support function
 */
Datum
ginqueryarrayextract(PG_FUNCTION_ARGS)
{
	/* Make copy of array input to ensure it doesn't disappear while in use */
	ArrayType  *array = PG_GETARG_ARRAYTYPE_P_COPY(0);
	int32	   *nkeys = (int32 *) PG_GETARG_POINTER(1);
	StrategyNumber strategy = PG_GETARG_UINT16(2);

	/* bool   **pmatch = (bool **) PG_GETARG_POINTER(3); */
	/* Pointer	   *extra_data = (Pointer *) PG_GETARG_POINTER(4); */
	bool	  **nullFlags = (bool **) PG_GETARG_POINTER(5);
	int32	   *searchMode = (int32 *) PG_GETARG_POINTER(6);
	int16		elmlen;
	bool		elmbyval;
	char		elmalign;
	Datum	   *elems;
	bool	   *nulls;
	int			nelems;

	get_typlenbyvalalign(ARR_ELEMTYPE(array),
						 &elmlen, &elmbyval, &elmalign);

	deconstruct_array(array,
					  ARR_ELEMTYPE(array),
					  elmlen, elmbyval, elmalign,
					  &elems, &nulls, &nelems);

	*nkeys = nelems;
	*nullFlags = nulls;

	switch (strategy)
	{
		case GinOverlapStrategy:
			*searchMode = GIN_SEARCH_MODE_DEFAULT;
			break;
		case GinContainsStrategy:
			if (nelems > 0)
				*searchMode = GIN_SEARCH_MODE_DEFAULT;
			else	/* everything contains the empty set */
				*searchMode = GIN_SEARCH_MODE_ALL;
			break;
		case GinContainedStrategy:
			/* empty set is contained in everything */
			*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
			break;
		case GinEqualStrategy:
			if (nelems > 0)
				*searchMode = GIN_SEARCH_MODE_DEFAULT;
			else
				*searchMode = GIN_SEARCH_MODE_INCLUDE_EMPTY;
			break;
		default:
			elog(ERROR, "ginqueryarrayextract: unknown strategy number: %d",
				 strategy);
	}

	/* we should not free array, elems[i] points into it */
	PG_RETURN_POINTER(elems);
}
Ejemplo n.º 11
0
Datum array_quantile(PG_FUNCTION_ARGS) {
	// The formal PostgreSQL array object
	ArrayType *array;

	// The array element type
	Oid arrayElementType;

	// The array element type width
	int16 arrayElementTypeWidth;

	// The array element type "is passed by value" flags (not used, should always be true)
	bool arrayElementTypeByValue;

	// The array element type alignment codes (not used)
	char arrayElementTypeAlignmentCode;

	// The array contents, as PostgreSQL "datum" objects
	Datum *arrayContent;

	// List of "is null" flags for the array contents
	bool *arrayNullFlags;

	// The size of each array
	int arrayLength;

	int i,j, nelem;
	double median, mad, f, quantile;
	double *inarray;

	if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) 
		ereport(ERROR, (errmsg("Null arrays not accepted")));

	// Get array and quantile from input
	array = PG_GETARG_ARRAYTYPE_P(0);
	f = PG_GETARG_FLOAT8(1);

	if (ARR_NDIM(array) != 1) 
		ereport(ERROR, (errmsg("One-dimesional arrays are required")));

	if (array_contains_nulls(array)) 
		ereport(ERROR, (errmsg("Array contains null elements")));

	arrayLength = (ARR_DIMS(array))[0];
	arrayElementType = ARR_ELEMTYPE(array);
	get_typlenbyvalalign(arrayElementType, &arrayElementTypeWidth, &arrayElementTypeByValue, &arrayElementTypeAlignmentCode);
	deconstruct_array(array, arrayElementType, arrayElementTypeWidth, arrayElementTypeByValue, arrayElementTypeAlignmentCode, &arrayContent, &arrayNullFlags, &arrayLength);
	
	inarray = (double*)malloc(arrayLength*sizeof(double));  
	for (i=0; i<arrayLength; i++) {
		inarray[i] = DatumGetFloat4(arrayContent[i]);
	}

	gsl_sort (inarray, 1, arrayLength);

	quantile = gsl_stats_quantile_from_sorted_data(inarray, 1, arrayLength, f);

	PG_RETURN_FLOAT8(quantile);
}
Ejemplo n.º 12
0
/*
 * used by text_to_array() in varlena.c
 */
array_s *create_singleton_array(struct fc_info* fcinfo, oid_t element_type,
	datum_t element, bool isNull, int ndims)
{
	datum_t dvalues[1];
	bool nulls[1];
	int16 typlen;
	bool typbyval;
	char typalign;
	int dims[MAXDIM];
	int lbs[MAXDIM];
	int i;
	array_meta_s *my_extra;

	if (ndims < 1)
		ereport(ERROR, (
		errcode(E_INVALID_PARAMETER_VALUE),
		errmsg("invalid number of dimensions: %d", ndims)));

	if (ndims > MAXDIM)
		ereport(ERROR, (
		errcode(E_PROGRAM_LIMIT_EXCEEDED),
		errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
			ndims, MAXDIM)));

	dvalues[0] = element;
	nulls[0] = isNull;
	for (i = 0; i < ndims; i++) {
		dims[i] = 1;
		lbs[i] = 1;
	}

	/*
	 * We arrange to look up info about element type only once per series of
	 * calls, assuming the element type doesn't change underneath us.
	 */
	my_extra = (array_meta_s *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL) {
		fcinfo->flinfo->fn_extra = mctx_alloc(fcinfo->flinfo->fn_mcxt, 
		 	sizeof(array_meta_s));
		my_extra = (array_meta_s *) fcinfo->flinfo->fn_extra;
		my_extra->element_type = ~element_type;
	}

	if (my_extra->element_type != element_type) {
		/* Get info about element type */
		get_typlenbyvalalign(element_type, &my_extra->typlen, &my_extra->typbyval, 
			&my_extra->typalign);
		my_extra->element_type = element_type;
	}

	typlen = my_extra->typlen;
	typbyval = my_extra->typbyval;
	typalign = my_extra->typalign;

	return construct_md_array(dvalues, nulls, ndims, dims, lbs, element_type, typlen,
		typbyval, typalign);
}
Ejemplo n.º 13
0
/*
 * Find 'findelem' within array 'v'. Returns -1 if not found in an array
 * without any NULL elements, NULL if not found but one or more NULLs appeared
 * in the array.
 *
 * Declared STRICT, must not be called with NULL input(s).
 */
Datum
array_idx(PG_FUNCTION_ARGS)
{
    Datum        findelem = PG_GETARG_DATUM(0);
    ArrayType    *v = PG_GETARG_ARRAYTYPE_P(1);

    Oid          arg0_typeid = get_fn_expr_argtype(fcinfo->flinfo, 0);
    Oid          arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1);
    Oid          arg0_elemid;
    Oid          arg1_elemid;
    Oid          element_type;

    int16        typlen;
    bool         typbyval;
    char         typalign;

    Datum        *elems;
    bool         *nulls;
    int          nelems;

    Datum        cur_elem;
    bool         has_nulls;

    int i;
    

    if (ARR_NDIM(v) == 0)
        PG_RETURN_NULL();
    else if (ARR_NDIM(v) != 1)
        ereport(ERROR,
            (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
             errmsg("idx(...) only makes sense for one-dimensional arrays, not %i", ARR_NDIM(v))));

    element_type = ARR_ELEMTYPE(v);
    /* For optimal performance we'd get this from a syscache or cache it in the function
     * call context; see array_push in src/backend/utils/adt/array_userfuncs.c */
    get_typlenbyvalalign(element_type,
                         &typlen,
                         &typbyval,
                         &typalign);
    
    deconstruct_array(v, element_type, typlen, typbyval, typalign, &elems, &nulls, &nelems);

    has_nulls = false;
    for (i = 0; i < nelems; i++)
    {
        has_nulls |= nulls[i];
        cur_elem = elems[i];
        /* Compare find_elem for equality against cur_elem */
        PG_RETURN_INT(i+1);
    }
   
    if (has_nulls)
        PG_RETURN_NULL();
    else
        PG_RETURN_INT(-1);
}
Ejemplo n.º 14
0
Datum
count_distinct_append(PG_FUNCTION_ARGS)
{
    element_set_t  *eset;

    /* info for anyelement */
    Oid         element_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
    Datum       element = PG_GETARG_DATUM(1);

    /* memory contexts */
    MemoryContext oldcontext;
    MemoryContext aggcontext;

    /*
     * If the new value is NULL, we simply return the current aggregate state
     * (it might be NULL, so check it).
     */
    if (PG_ARGISNULL(1) && PG_ARGISNULL(0))
        PG_RETURN_NULL();
    else if (PG_ARGISNULL(1))
        PG_RETURN_DATUM(PG_GETARG_DATUM(0));

    /* from now on we know the new value is not NULL */

    /* switch to the per-group hash-table memory context */
    GET_AGG_CONTEXT("count_distinct_append", fcinfo, aggcontext);

    oldcontext = MemoryContextSwitchTo(aggcontext);

    /* init the hash table, if needed */
    if (PG_ARGISNULL(0))
    {
        int16       typlen;
        bool        typbyval;
        char        typalign;

        /* get type information for the second parameter (anyelement item) */
        get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

        /* we can't handle varlena types yet or values passed by reference */
        if ((typlen < 0) || (! typbyval))
            elog(ERROR, "count_distinct handles only fixed-length types passed by value");

        eset = init_set(typlen, typalign, aggcontext);
    } else
        eset = (element_set_t *)PG_GETARG_POINTER(0);

    /* add the value into the set */
    add_element(eset, (char*)&element);

    MemoryContextSwitchTo(oldcontext);

    PG_RETURN_POINTER(eset);
}
Datum
get_power_in_range(PG_FUNCTION_ARGS)
{
    //the size of the array we are trying to transform
    int arraySize;
    int power;
    int32 duration;
    float startRange;
    float endRange;
    // a Datum for the constructred and deconstructed input arrays
    Datum *input_data;
    // the final result to return and the input to the function
    ArrayType *input;
    Oid input_type;
    //next 6 variables are inputted into get_typlenbyvalalign() and      int fftw_export_wisdom_to_filename(const char *filename);are used for construct and deconstruct array
    //small int in postgreSQL is int16
    int16 input_typelen;
    bool input_typbyval;
    char input_typalign;


    // get input row
    input = PG_GETARG_ARRAYTYPE_P(0);
    // get duration
    duration = PG_GETARG_INT32(1);
    // get ranges
    startRange = PG_GETARG_FLOAT8(2);
    endRange = PG_GETARG_FLOAT8(3);

    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);

    
    // 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
    power = 0;
    for (int i = 0; i < arraySize; i++) {
        if(startRange < i/duration && i/duration <= endRange)
        {
            Complex *temp = (Complex*) DatumGetPointer(input_data[i]);
            power += temp->x*temp->x + temp->y*temp->y;
        }
    }

    // free memory
    pfree(input_data);

    // return result
    PG_RETURN_INT32(power);
}
Ejemplo n.º 16
0
Datum welle_count( PG_FUNCTION_ARGS )
{

    if( PG_ARGISNULL( 0 ) )
    {
        PG_RETURN_NULL();
    }

    ArrayType * input;
    input = PG_GETARG_ARRAYTYPE_P( 0 );

    Datum * i_data;

    Oid i_eltype;
    i_eltype = ARR_ELEMTYPE( input );

    int16 i_typlen;
    bool  i_typbyval;
    char  i_typalign;

    get_typlenbyvalalign(
            i_eltype,
            &i_typlen,
            &i_typbyval,
            &i_typalign
    );

    bool * nulls;
    int n;

    deconstruct_array(
            input,
            i_eltype,
            i_typlen,
            i_typbyval,
            i_typalign,
            &i_data,
            &nulls,
            &n
    );

    switch( i_eltype )
    {
        case INT4OID:
            PG_RETURN_POINTER( adeven_count_int_array( i_data, n, nulls ) );
            break;
        case TEXTOID:
            PG_RETURN_POINTER( adeven_count_text_array( i_data, n, nulls ) );
            break;
        default:
            elog( ERROR, "INVALID input data type" );
            break;
    }
}
Ejemplo n.º 17
0
/*
 * fetch_array_arg_replace_nulls
 *
 * Fetch an array-valued argument; if it's null, construct an empty array
 * value of the proper data type.  Also cache basic element type information
 * in fn_extra.
 */
static ArrayType *
fetch_array_arg_replace_nulls(FunctionCallInfo fcinfo, int argno)
{
	ArrayType  *v;
	Oid			element_type;
	ArrayMetaState *my_extra;

	/* First collect the array value */
	if (!PG_ARGISNULL(argno))
	{
		v = PG_GETARG_ARRAYTYPE_P(argno);
		element_type = ARR_ELEMTYPE(v);
	}
	else
	{
		/* We have to look up the array type and element type */
		Oid			arr_typeid = get_fn_expr_argtype(fcinfo->flinfo, argno);

		if (!OidIsValid(arr_typeid))
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not determine input data type")));
		element_type = get_element_type(arr_typeid);
		if (!OidIsValid(element_type))
			ereport(ERROR,
					(errcode(ERRCODE_DATATYPE_MISMATCH),
					 errmsg("input data type is not an array")));

		v = construct_empty_array(element_type);
	}

	/* Now cache required info, which might change from call to call */
	my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL)
	{
		my_extra = (ArrayMetaState *)
			MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
							   sizeof(ArrayMetaState));
		my_extra->element_type = InvalidOid;
		fcinfo->flinfo->fn_extra = my_extra;
	}

	if (my_extra->element_type != element_type)
	{
		get_typlenbyvalalign(element_type,
							 &my_extra->typlen,
							 &my_extra->typbyval,
							 &my_extra->typalign);
		my_extra->element_type = element_type;
	}

	return v;
}
Ejemplo n.º 18
0
Archivo: putline.c Proyecto: 50wu/gpdb
Datum
dbms_output_get_lines(PG_FUNCTION_ARGS)
{
	TupleDesc	tupdesc;
	Datum		result;
	HeapTuple	tuple;
	Datum		values[2];
	bool		nulls[2] = { false, false };
	text	   *line;

	int32		max_lines = PG_GETARG_INT32(0);
	int32		n;
    ArrayBuildState *astate = NULL;

	/* Build a tuple descriptor for our result type */
	if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
		elog(ERROR, "return type must be a row type");

	for (n = 0; n < max_lines && (line = dbms_output_next()) != NULL; n++)
	{
		astate = accumArrayResult(astate, PointerGetDatum(line), false,
					TEXTOID, CurrentMemoryContext);
	}

	/* 0: lines as text array */
	if (n > 0)
		values[0] = makeArrayResult(astate, CurrentMemoryContext);
	else
	{
		int16		typlen;
		bool		typbyval;
		char		typalign;
		ArrayType  *arr;

		get_typlenbyvalalign(TEXTOID, &typlen, &typbyval, &typalign);
		arr = construct_md_array(
			NULL,
#if PG_VERSION_NUM >= 80200
			NULL,
#endif
			0, NULL, NULL, TEXTOID, typlen, typbyval, typalign);
		values[0] = PointerGetDatum(arr);
	}

	/* 1: # of lines as integer */
	values[1] = Int32GetDatum(n);

	tuple = heap_form_tuple(tupdesc, values, nulls);
	result = HeapTupleGetDatum(tuple);

	PG_RETURN_DATUM(result);
}
Datum find_peak_power(PG_FUNCTION_ARGS)
{

    //the size of the array we are trying to transform
    int arraySize;
    int peak;
    // a Datum for the constructred and deconstructed input arrays
    Datum *input_data;
    // the final result to return and the input to the function
    ArrayType *input;
    Oid 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 input_typelen;
    bool input_typbyval;
    char 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);

    
    // 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
    peak = 0;
    for (int i = 0; i < arraySize; i++) {
        Complex *temp = (Complex*) DatumGetPointer(input_data[i]);
        int tempValue = temp->x*temp->x + temp->y*temp->y;
        if(i == 0)
        {
            peak = tempValue;
        } else {
            if(tempValue > peak){
                peak = tempValue;
            }
        }
    
    }

    // free memory
    pfree(input_data);

    // return result
    PG_RETURN_INT32(peak);
}
Ejemplo n.º 20
0
static void
initXNodeTypeInfo(Oid fnOid, int argNr, TypeInfo *ti)
{
	HeapTuple	tup;
	Form_pg_proc procStruct;

	tup = SearchSysCache1(PROCOID, ObjectIdGetDatum(fnOid));
	Assert(HeapTupleIsValid(tup));
	procStruct = (Form_pg_proc) GETSTRUCT(tup);
	ti->oid = procStruct->proargtypes.values[argNr];
	ReleaseSysCache(tup);
	get_typlenbyvalalign(ti->oid, &ti->elmlen, &ti->elmbyval, &ti->elmalign);
}
Ejemplo n.º 21
0
Datum
adaptive_add_item_agg2(PG_FUNCTION_ARGS)
{

    AdaptiveCounter acounter;

    /* info for anyelement */
    Oid         element_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
    Datum       element = PG_GETARG_DATUM(1);
    int16       typlen;
    bool        typbyval;
    char        typalign;

    /* is the counter created (if not, create it with default parameters) */
    if (PG_ARGISNULL(0)) {
      acounter = ac_init(DEFAULT_ERROR, DEFAULT_NDISTINCT);
    } else {
      acounter = (AdaptiveCounter)PG_GETARG_BYTEA_P(0);
    }

    /* add the item to the estimator */
    if (! PG_ARGISNULL(1)) {

        /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache),
        * but if it turns out to have a noticeable impact it's possible to cache that
        * between the calls (in the estimator). */

        /* get type information for the second parameter (anyelement item) */
        get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

        /* it this a varlena type, passed by reference or by value ? */
        if (typlen == -1) {
            /* varlena */
            ac_add_item(acounter, VARDATA(element), VARSIZE(element) - VARHDRSZ);
        } else if (typbyval) {
            /* fixed-length, passed by value */
            ac_add_item(acounter, (char*)&element, typlen);
        } else {
            /* fixed-length, passed by reference */
            ac_add_item(acounter, (char*)element, typlen);
        }

    }

    /* return the updated bytea */
    PG_RETURN_BYTEA_P(acounter);

}
Ejemplo n.º 22
0
Datum anyold_transfn(PG_FUNCTION_ARGS)
{
	Oid           type;
	Datum         state;
	MemoryContext aggcontext,
	              oldcontext;
	int16         typlen;
	bool          typbyval;
	char          typalign;
	
	if (!AggCheckCallContext(fcinfo, &aggcontext))
	{
		/* cannot be called directly because of internal-type argument */
		elog(ERROR, "anyold_transfn called in non-aggregate context");
	}
	
	if (PG_ARGISNULL(0))
	{
		if (PG_ARGISNULL(1))
			PG_RETURN_NULL();
		/* First non-null value --- initialize */
		oldcontext = MemoryContextSwitchTo(aggcontext);
		
		type = get_fn_expr_argtype(fcinfo->flinfo, 1);
		if (type == InvalidOid)
			ereport(ERROR,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("could not determine input data type")));
		get_typlenbyvalalign(type,
							&typlen,
							&typbyval,
							&typalign);

		/* Copy initial value */
		if (typlen == -1)
			state = PointerGetDatum(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
		else
			state = datumCopy(PG_GETARG_DATUM(1), typbyval, typlen);

		MemoryContextSwitchTo(oldcontext);
	}
	else
	{
		state = PG_GETARG_DATUM(0);
	}
	
	PG_RETURN_DATUM(state);
}
Datum
probabilistic_add_item_agg2(PG_FUNCTION_ARGS)
{

    ProbabilisticCounter pcounter;

    /* info for anyelement */
    Oid         element_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
    Datum       element = PG_GETARG_DATUM(1);
    int16       typlen;
    bool        typbyval;
    char        typalign;

    /* create a new estimator (with requested error rate) or reuse the existing one */
    if (PG_ARGISNULL(0)) {
        pcounter = pc_create(DEFAULT_NBYTES, DEFAULT_NSALTS);
    } else { /* existing estimator */
        pcounter = (ProbabilisticCounter)PG_GETARG_BYTEA_P(0);
    }

    /* add the item to the estimator (skip NULLs) */
    if (! PG_ARGISNULL(1)) {

        /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache),
         * but if it turns out to have a noticeable impact it's possible to cache that
         * between the calls (in the estimator). */
        
        /* get type information for the second parameter (anyelement item) */
        get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

        /* it this a varlena type, passed by reference or by value ? */
        if (typlen == -1) {
            /* varlena */
            pc_add_element(pcounter, VARDATA(element), VARSIZE(element) - VARHDRSZ);
        } else if (typbyval) {
            /* fixed-length, passed by value */
            pc_add_element(pcounter, (char*)&element, typlen);
        } else {
            /* fixed-length, passed by reference */
            pc_add_element(pcounter, (char*)element, typlen);
        }
    }

    /* return the updated bytea */
    PG_RETURN_BYTEA_P(pcounter);
    
}
Datum
probabilistic_add_item(PG_FUNCTION_ARGS)
{

    ProbabilisticCounter pcounter;

    /* requires the estimator to be already created */
    if (PG_ARGISNULL(0))
        elog(ERROR, "probabilistic counter must not be NULL");

    /* if the element is not NULL, add it to the estimator (i.e. skip NULLs) */
    if (! PG_ARGISNULL(1)) {

        Oid         element_type = get_fn_expr_argtype(fcinfo->flinfo, 1);
        Datum       element = PG_GETARG_DATUM(1);
        int16       typlen;
        bool        typbyval;
        char        typalign;

        /* estimator (we know it's not a NULL value) */
        pcounter = (ProbabilisticCounter)PG_GETARG_BYTEA_P(0);

        /* TODO The requests for type info shouldn't be a problem (thanks to lsyscache),
         * but if it turns out to have a noticeable impact it's possible to cache that
         * between the calls (in the estimator). */

        /* get type information for the second parameter (anyelement item) */
        get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

        /* it this a varlena type, passed by reference or by value ? */
        if (typlen == -1) {
            /* varlena */
            pc_add_element(pcounter, VARDATA(element), VARSIZE(element) - VARHDRSZ);
        } else if (typbyval) {
            /* fixed-length, passed by value */
            pc_add_element(pcounter, (char*)&element, typlen);
        } else {
            /* fixed-length, passed by reference */
            pc_add_element(pcounter, (char*)element, typlen);
        }

    }

    PG_RETURN_VOID();
    
}
Ejemplo n.º 25
0
/*
 * Function used as extractValue and extractQuery both
 */
Datum
ginarrayextract(PG_FUNCTION_ARGS)
{
	ArrayType  *array;
	int32	   *nentries = (int32 *) PG_GETARG_POINTER(1);
	Datum	   *entries = NULL;
	int16		elmlen;
	bool		elmbyval;
	char		elmalign;

	/*
	 * we should guarantee that array will not be destroyed during all
	 * operation
	 */
	array = PG_GETARG_ARRAYTYPE_P_COPY(0);

	ARRAYCHECK(array);

	get_typlenbyvalalign(ARR_ELEMTYPE(array),
						 &elmlen, &elmbyval, &elmalign);

	deconstruct_array(array,
					  ARR_ELEMTYPE(array),
					  elmlen, elmbyval, elmalign,
					  &entries, NULL, (int *) nentries);

	if (*nentries == 0 && PG_NARGS() == 3)
	{
		switch (PG_GETARG_UINT16(2))	/* StrategyNumber */
		{
			case GinOverlapStrategy:
				*nentries = -1; /* nobody can be found */
				break;
			case GinContainsStrategy:
			case GinContainedStrategy:
			case GinEqualStrategy:
			default:			/* require fullscan: GIN can't find void
								 * arrays */
				break;
		}
	}

	/* we should not free array, entries[i] points into it */
	PG_RETURN_POINTER(entries);
}
Ejemplo n.º 26
0
/*
 * Turn an array into JSON.
 */
static void
array_to_jsonb_internal(Datum array, JsonbInState *result)
{
	ArrayType  *v = DatumGetArrayTypeP(array);
	Oid			element_type = ARR_ELEMTYPE(v);
	int		   *dim;
	int			ndim;
	int			nitems;
	int			count = 0;
	Datum	   *elements;
	bool	   *nulls;
	int16		typlen;
	bool		typbyval;
	char		typalign;
	JsonbTypeCategory tcategory;
	Oid			outfuncoid;

	ndim = ARR_NDIM(v);
	dim = ARR_DIMS(v);
	nitems = ArrayGetNItems(ndim, dim);

	if (nitems <= 0)
	{
		result->res = pushJsonbValue(&result->parseState, WJB_BEGIN_ARRAY, NULL);
		result->res = pushJsonbValue(&result->parseState, WJB_END_ARRAY, NULL);
		return;
	}

	get_typlenbyvalalign(element_type,
						 &typlen, &typbyval, &typalign);

	jsonb_categorize_type(element_type,
						  &tcategory, &outfuncoid);

	deconstruct_array(v, element_type, typlen, typbyval,
					  typalign, &elements, &nulls,
					  &nitems);

	array_dim_to_jsonb(result, 0, ndim, dim, elements, nulls, &count, tcategory,
					   outfuncoid);

	pfree(elements);
	pfree(nulls);
}
Ejemplo n.º 27
0
Datum
plr_array_push(PG_FUNCTION_ARGS)
{
	ArrayType  *v;
	Datum		newelem;
	int		   *dimv,
			   *lb, ub;
	ArrayType  *result;
	int			indx;
	Oid			element_type;
	int16		typlen;
	bool		typbyval;
	char		typalign;

	v = PG_GETARG_ARRAYTYPE_P(0);
	newelem = PG_GETARG_DATUM(1);

	/* Sanity check: do we have a one-dimensional array */
	if (ARR_NDIM(v) != 1)
		ereport(ERROR,
				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
				 errmsg("input must be one-dimensional array")));

	lb = ARR_LBOUND(v);
	dimv = ARR_DIMS(v);
	ub = dimv[0] + lb[0] - 1;
	indx = ub + 1;

	element_type = ARR_ELEMTYPE(v);
	/* Sanity check: do we have a non-zero element type */
	if (element_type == 0)
		/* internal error */
		elog(ERROR, "invalid array element type");

	get_typlenbyvalalign(element_type, &typlen, &typbyval, &typalign);

	result = array_set(v, 1, &indx, newelem, FALSE, -1,
						typlen, typbyval, typalign);

	PG_RETURN_ARRAYTYPE_P(result);
}
Ejemplo n.º 28
0
ArrayType *build_array(q3c_coord_t ra, q3c_coord_t dec)
{
	Datum       *data;
	int16       typlen;
	bool        typbyval;
	char        typalign;
	int         nelems;
	ArrayType  *result;

    nelems = 2;
	data = ( Datum *) palloc(sizeof(Datum) * nelems);

	data[0] = Float8GetDatum (ra);
	data[1] = Float8GetDatum (dec);

	/* get required info about the element type */
    get_typlenbyvalalign(FLOAT8OID, &typlen, &typbyval, &typalign);

    /* now build the array */
    result = construct_array(data, nelems, FLOAT8OID, typlen, typbyval, typalign);
    return result;
}
Ejemplo n.º 29
0
/*
 * ExecIndexEvalArrayKeys
 *		Evaluate any array key values, and set up to iterate through arrays.
 *
 * Returns TRUE if there are array elements to consider; FALSE means there
 * is at least one null or empty array, so no match is possible.  On TRUE
 * result, the scankeys are initialized with the first elements of the arrays.
 */
bool
ExecIndexEvalArrayKeys(ExprContext *econtext,
					   IndexArrayKeyInfo *arrayKeys, int numArrayKeys)
{
	bool		result = true;
	int			j;
	MemoryContext oldContext;

	/* We want to keep the arrays in per-tuple memory */
	oldContext = MemoryContextSwitchTo(econtext->ecxt_per_tuple_memory);

	for (j = 0; j < numArrayKeys; j++)
	{
		ScanKey		scan_key = arrayKeys[j].scan_key;
		ExprState  *array_expr = arrayKeys[j].array_expr;
		Datum		arraydatum;
		bool		isNull;
		ArrayType  *arrayval;
		int16		elmlen;
		bool		elmbyval;
		char		elmalign;
		int			num_elems;
		Datum	   *elem_values;
		bool	   *elem_nulls;

		/*
		 * Compute and deconstruct the array expression. (Notes in
		 * ExecIndexEvalRuntimeKeys() apply here too.)
		 */
		arraydatum = ExecEvalExpr(array_expr,
								  econtext,
								  &isNull,
								  NULL);
		if (isNull)
		{
			result = false;
			break;				/* no point in evaluating more */
		}
		arrayval = DatumGetArrayTypeP(arraydatum);
		/* We could cache this data, but not clear it's worth it */
		get_typlenbyvalalign(ARR_ELEMTYPE(arrayval),
							 &elmlen, &elmbyval, &elmalign);
		deconstruct_array(arrayval,
						  ARR_ELEMTYPE(arrayval),
						  elmlen, elmbyval, elmalign,
						  &elem_values, &elem_nulls, &num_elems);
		if (num_elems <= 0)
		{
			result = false;
			break;				/* no point in evaluating more */
		}

		/*
		 * Note: we expect the previous array data, if any, to be
		 * automatically freed by resetting the per-tuple context; hence no
		 * pfree's here.
		 */
		arrayKeys[j].elem_values = elem_values;
		arrayKeys[j].elem_nulls = elem_nulls;
		arrayKeys[j].num_elems = num_elems;
		scan_key->sk_argument = elem_values[0];
		if (elem_nulls[0])
			scan_key->sk_flags |= SK_ISNULL;
		else
			scan_key->sk_flags &= ~SK_ISNULL;
		arrayKeys[j].next_elem = 1;
	}

	MemoryContextSwitchTo(oldContext);

	return result;
}
Ejemplo n.º 30
0
/*
 * used by text_to_array() in varlena.c
 */
ArrayType *
create_singleton_array(FunctionCallInfo fcinfo,
					   Oid element_type,
					   Datum element,
					   int ndims)
{
	Datum		dvalues[1];
	int16		typlen;
	bool		typbyval;
	char		typalign;
	int			dims[MAXDIM];
	int			lbs[MAXDIM];
	int			i;
	ArrayMetaState *my_extra;

	if (ndims < 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("invalid number of dimensions: %d", ndims)));
	if (ndims > MAXDIM)
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
				 errmsg("number of array dimensions (%d) exceeds the maximum allowed (%d)",
						ndims, MAXDIM)));

	dvalues[0] = element;

	for (i = 0; i < ndims; i++)
	{
		dims[i] = 1;
		lbs[i] = 1;
	}

	/*
	 * We arrange to look up info about element type only once per series of
	 * calls, assuming the element type doesn't change underneath us.
	 */
	my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL)
	{
		fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
													  sizeof(ArrayMetaState));
		my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
		my_extra->element_type = ~element_type;
	}

	if (my_extra->element_type != element_type)
	{
		/* Get info about element type */
		get_typlenbyvalalign(element_type,
							 &my_extra->typlen,
							 &my_extra->typbyval,
							 &my_extra->typalign);
		my_extra->element_type = element_type;
	}
	typlen = my_extra->typlen;
	typbyval = my_extra->typbyval;
	typalign = my_extra->typalign;

	return construct_md_array(dvalues, NULL, ndims, dims, lbs, element_type,
							  typlen, typbyval, typalign);
}