예제 #1
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);
}
예제 #2
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);
}
예제 #3
0
파일: plda.c 프로젝트: dcking/madlib
Datum cword_count(PG_FUNCTION_ARGS)
{
	ArrayType * count_arr, * doc_arr, * topics_arr;
	int32 * count, * doc, * topics;
	int32 doclen, num_topics, dsize, i;
	Datum * array;
	int32 idx;

	if (!(fcinfo->context && IsA(fcinfo->context, AggState)))
		elog(ERROR, "cword_count not used as part of an aggregate");

	doclen = PG_GETARG_INT32(3);
	num_topics = PG_GETARG_INT32(4);
	dsize = PG_GETARG_INT32(5);

	/* Construct a zero'd array at the first call of this function */
	if (PG_ARGISNULL(0)) {
		array = palloc0(dsize*num_topics*sizeof(Datum));
		count_arr =
		    construct_array(array,dsize*num_topics,INT4OID,4,true,'i');
	} else {
		count_arr = PG_GETARG_ARRAYTYPE_P(0);
	}
	doc_arr = PG_GETARG_ARRAYTYPE_P(1);
	topics_arr = PG_GETARG_ARRAYTYPE_P(2);

	/* Check that the input arrays are of the right dimension and type */
	if (ARR_NDIM(count_arr) != 1 || ARR_ELEMTYPE(count_arr) != INT4OID ||
	    ARR_NDIM(doc_arr) != 1 || ARR_ELEMTYPE(doc_arr) != INT4OID ||
	    ARR_NDIM(topics_arr) != 1 || ARR_ELEMTYPE(topics_arr) != INT4OID)
		ereport
		 (ERROR,
		  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
		   errmsg("transition function \"%s\" called with invalid parameters",
			  format_procedure(fcinfo->flinfo->fn_oid))));

	count = (int32 *)ARR_DATA_PTR(count_arr);
	doc = (int32 *)ARR_DATA_PTR(doc_arr);
	topics = (int32 *)ARR_DATA_PTR(topics_arr);

	/* Update the word-topic count */
	for (i=0; i!=doclen; i++) {
		idx = (doc[i]-1) * num_topics + (topics[i]-1);

		if (idx < 0 || idx >= dsize*num_topics)
			ereport
			 (ERROR,
			  (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
		           errmsg("function \"%s\" called with invalid parameters",
				  format_procedure(fcinfo->flinfo->fn_oid))));
		
		count[idx]++;
	}
	PG_RETURN_BYTEA_P(count_arr);
}
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);
}
예제 #5
0
Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
{
	uint32 pcid = PG_GETARG_INT32(0);
	ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
	int nelems;
	float8 *vals;
	PCPOINT *pt;
	PCSCHEMA *schema = pc_schema_from_pcid(pcid, fcinfo);
	SERIALIZED_POINT *serpt;

	if ( ! schema )
		elog(ERROR, "unable to load schema for pcid = %d", pcid);

	if ( ARR_ELEMTYPE(arrptr) != FLOAT8OID )
		elog(ERROR, "array must be of float8[]");

	if ( ARR_NDIM(arrptr) != 1 )
		elog(ERROR, "float8[] must have only one dimension");

	if ( ARR_HASNULL(arrptr) )
		elog(ERROR, "float8[] must not have null elements");

	nelems = ARR_DIMS(arrptr)[0];
	if ( nelems != schema->ndims || ARR_LBOUND(arrptr)[0] > 1 )
		elog(ERROR, "array dimensions do not match schema dimensions of pcid = %d", pcid);

	vals = (float8*) ARR_DATA_PTR(arrptr);
	pt = pc_point_from_double_array(schema, vals, nelems);

	serpt = pc_point_serialize(pt);
	pc_point_free(pt);
	PG_RETURN_POINTER(serpt);
}
예제 #6
0
/*
 *		int2vectorrecv			- converts external binary format to int2vector
 */
Datum
int2vectorrecv(PG_FUNCTION_ARGS)
{
	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);
	FunctionCallInfoData locfcinfo;
	int2vector *result;

	/*
	 * Normally one would call array_recv() using DirectFunctionCall3, but
	 * that does not work since array_recv wants to cache some data using
	 * fcinfo->flinfo->fn_extra.  So we need to pass it our own flinfo
	 * parameter.
	 */
	InitFunctionCallInfoData(locfcinfo, fcinfo->flinfo, 3, NULL, NULL);

	locfcinfo.arg[0] = PointerGetDatum(buf);
	locfcinfo.arg[1] = ObjectIdGetDatum(INT2OID);
	locfcinfo.arg[2] = Int32GetDatum(-1);
	locfcinfo.argnull[0] = false;
	locfcinfo.argnull[1] = false;
	locfcinfo.argnull[2] = false;

	result = (int2vector *) DatumGetPointer(array_recv(&locfcinfo));

	Assert(!locfcinfo.isnull);

	/* sanity checks: int2vector must be 1-D, no nulls */
	if (ARR_NDIM(result) != 1 ||
		ARR_HASNULL(result) ||
		ARR_ELEMTYPE(result) != INT2OID)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
				 errmsg("invalid int2vector data")));
	PG_RETURN_POINTER(result);
}
예제 #7
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);
		}
	}
}
예제 #8
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");
}
예제 #9
0
파일: _int_tool.c 프로젝트: Brar/postgres
/* Create a new int array with room for "num" elements */
ArrayType *
new_intArrayType(int num)
{
	ArrayType  *r;
	int			nbytes;

	/* if no elements, return a zero-dimensional array */
	if (num <= 0)
	{
		r = construct_empty_array(INT4OID);
		return r;
	}

	nbytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int) * num;

	r = (ArrayType *) palloc0(nbytes);

	SET_VARSIZE(r, nbytes);
	ARR_NDIM(r) = 1;
	r->dataoffset = 0;			/* marker for no null bitmap */
	ARR_ELEMTYPE(r) = INT4OID;
	ARR_DIMS(r)[0] = num;
	ARR_LBOUND(r)[0] = 1;

	return r;
}
예제 #10
0
파일: Array.c 프로젝트: greenplum-db/pljava
ArrayType* createArrayType(jsize nElems, size_t elemSize, Oid elemType, bool withNulls)
{
	ArrayType* v;
	Size nBytes = elemSize * nElems;
	MemoryContext currCtx = Invocation_switchToUpperContext();

	Size dataoffset;
	if(withNulls)
	{
		dataoffset = ARR_OVERHEAD_WITHNULLS(1, nElems);
		nBytes += dataoffset;
	}
	else
	{
		dataoffset = 0;			/* marker for no null bitmap */
		nBytes += ARR_OVERHEAD_NONULLS(1);
	}
	v = (ArrayType*)palloc0(nBytes);
	AssertVariableIsOfType(v->dataoffset, int32);
	v->dataoffset = (int32)dataoffset;
	MemoryContextSwitchTo(currCtx);

	SET_VARSIZE(v, nBytes);
	ARR_NDIM(v) = 1;
	ARR_ELEMTYPE(v) = elemType;
	*((int*)ARR_DIMS(v)) = nElems;
	*((int*)ARR_LBOUND(v)) = 1;
	return v;
}
예제 #11
0
파일: operators.c 프로젝트: 50wu/gpdb
Datum
svec_cast_float8arr(PG_FUNCTION_ARGS) {
	ArrayType *A_PG = PG_GETARG_ARRAYTYPE_P(0);
	SvecType *output_svec;

	if (ARR_ELEMTYPE(A_PG) != FLOAT8OID)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("svec_cast_float8arr only defined over float8[]")));
	if (ARR_NDIM(A_PG) != 1)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("svec_cast_float8arr only defined over 1 dimensional arrays"))
		       );

	if (ARR_NULLBITMAP(A_PG))
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("svec_cast_float8arr does not allow null bitmaps on arrays"))
		       );


	/* Extract array */
	{
		int dimension = ARR_DIMS(A_PG)[0];
		float8 *array = (float8 *)ARR_DATA_PTR(A_PG);

		/* Create the output SVEC */
		SparseData sdata = float8arr_to_sdata(array,dimension);
		output_svec = svec_from_sparsedata(sdata,true);
	}

	PG_RETURN_SVECTYPE_P(output_svec);
}
예제 #12
0
/*
 * cms_topn_frequency is a user-facing UDF which returns the estimated frequency
 * of an item. The first parameter is for CmsTopn and second is for the item to
 * return the frequency.
 */
Datum
cms_topn_frequency(PG_FUNCTION_ARGS)
{
	CmsTopn *cmsTopn = (CmsTopn *) PG_GETARG_VARLENA_P(0);
	ArrayType *topnArray = TopnArray(cmsTopn);
	Datum item = PG_GETARG_DATUM(1);
	Oid itemType = get_fn_expr_argtype(fcinfo->flinfo, 1);
	TypeCacheEntry *itemTypeCacheEntry = NULL;
	Frequency frequency = 0;

	if (itemType == InvalidOid)
	{
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
		                errmsg("could not determine input data types")));
	}

	if (topnArray != NULL && itemType != ARR_ELEMTYPE(topnArray))
	{
		ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
		                errmsg("Not proper type for this cms_topn")));
	}

	itemTypeCacheEntry = lookup_type_cache(itemType, 0);
	frequency = CmsTopnEstimateItemFrequency(cmsTopn, item, itemTypeCacheEntry);

	PG_RETURN_INT32(frequency);
}
예제 #13
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 */
}
예제 #14
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);
}
예제 #15
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);
}
예제 #16
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);
}
예제 #17
0
/**
 * Convert postgres Datum into a ConcreteValue object.
 */
AbstractValueSPtr AbstractPGValue::DatumToValue(bool inMemoryIsWritable,
    Oid inTypeID, Datum inDatum) const {
        
    // First check if datum is rowtype
    if (type_is_rowtype(inTypeID)) {
        HeapTupleHeader pgTuple = DatumGetHeapTupleHeader(inDatum);
        return AbstractValueSPtr(new PGValue<HeapTupleHeader>(pgTuple));
    } else if (type_is_array(inTypeID)) {
        ArrayType *pgArray = DatumGetArrayTypeP(inDatum);
        
        if (ARR_NDIM(pgArray) != 1)
            throw std::invalid_argument("Multidimensional arrays not yet supported");
        
        if (ARR_HASNULL(pgArray))
            throw std::invalid_argument("Arrays with NULLs not yet supported");
        
        switch (ARR_ELEMTYPE(pgArray)) {
            case FLOAT8OID: {
                MemHandleSPtr memoryHandle(new PGArrayHandle(pgArray));
                
                if (inMemoryIsWritable) {
                    return AbstractValueSPtr(
                        new ConcreteValue<Array<double> >(
                            Array<double>(memoryHandle,
                                boost::extents[ ARR_DIMS(pgArray)[0] ])
                            )
                        );
                } else {
                    return AbstractValueSPtr(
                        new ConcreteValue<Array_const<double> >(
                            Array_const<double>(memoryHandle,
                                boost::extents[ ARR_DIMS(pgArray)[0] ])
                            )
                        );
                }
            }
        }
    }

    switch (inTypeID) {
        case BOOLOID: return AbstractValueSPtr(
            new ConcreteValue<bool>( DatumGetBool(inDatum) ));
        case INT2OID: return AbstractValueSPtr(
            new ConcreteValue<int16_t>( DatumGetInt16(inDatum) ));
        case INT4OID: return AbstractValueSPtr(
            new ConcreteValue<int32_t>( DatumGetInt32(inDatum) ));
        case INT8OID: return AbstractValueSPtr(
            new ConcreteValue<int64_t>( DatumGetInt64(inDatum) ));
        case FLOAT4OID: return AbstractValueSPtr(
            new ConcreteValue<float>( DatumGetFloat4(inDatum) ));
        case FLOAT8OID: return AbstractValueSPtr(
            new ConcreteValue<double>( DatumGetFloat8(inDatum) ));
    }
    
    return AbstractValueSPtr();
}
예제 #18
0
/*
 * ex_avg() - an enhanced average calculation that takes two arguments;
 * number of rows in this group and partial sum of the value.
 * Then, it eventually generate mathmatically compatible average value.
 */
static int64 *
check_int64_array(ArrayType *transarray, int n)
{
	if (ARR_NDIM(transarray) != 1 ||
		ARR_DIMS(transarray)[0] != n ||
		ARR_HASNULL(transarray) ||
		ARR_ELEMTYPE(transarray) != INT8OID)
		elog(ERROR, "Two elements int8 array is expected");
	return (int64 *) ARR_DATA_PTR(transarray);
}
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);
}
예제 #20
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;
    }
}
예제 #21
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;
}
예제 #22
0
/*
 * anyarray_out		- output routine for pseudo-type ANYARRAY.
 *
 * We may as well allow this, since array_out will in fact work.
 * XCP needs to send from data nodes to coordinator values of that type.
 * To be able to restore values at the destination node we need to know
 * actual element type.
 */
Datum
anyarray_out(PG_FUNCTION_ARGS)
{
#ifdef XCP
	/*
	 * Output prefix: (type_namespace_name.typename) to look up actual element
	 * type at the destination node then output in usual format for array
	 */
	ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
	Oid			element_type = ARR_ELEMTYPE(v);
	Form_pg_type typeForm;
	HeapTuple	typeTuple;
	char	   *typname,
			   *typnspname;
	/* two identifiers, parenthesis, dot and trailing \0 */
	char		prefix[2*NAMEDATALEN+4],
			   *retval,
			   *newval;
	int 		prefixlen, retvallen;
	Datum		array_out_result;
	MemoryContext save_context;

	save_context = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt);
	/* Figure out type name and type namespace */
	typeTuple = SearchSysCache(TYPEOID,
							   ObjectIdGetDatum(element_type),
							   0, 0, 0);
	if (!HeapTupleIsValid(typeTuple))
		elog(ERROR, "cache lookup failed for type %u", element_type);
	typeForm = (Form_pg_type) GETSTRUCT(typeTuple);
	typname = NameStr(typeForm->typname);
	typnspname = get_namespace_name(typeForm->typnamespace);

	sprintf(prefix, "(%s.%s)", typnspname, typname);
	ReleaseSysCache(typeTuple);
	MemoryContextSwitchTo(save_context);

	/* Get standard output and make up prefixed result */
	array_out_result = array_out(fcinfo);
	retval = DatumGetCString(array_out_result);
	prefixlen = strlen(prefix);
	retvallen = strlen(retval);
	newval = (char *) palloc(prefixlen + retvallen + 1);
	strcpy(newval, prefix);
	strcpy(newval + prefixlen, retval);

	pfree(retval);

	PG_RETURN_CSTRING(newval);
#else
	return array_out(fcinfo);
#endif
}
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);
}
예제 #24
0
/*
 * Transform a relation options list (list of DefElem) into the text array
 * format that is kept in pg_class.reloptions.
 *
 * This is used for three cases: CREATE TABLE/INDEX, ALTER TABLE SET, and
 * ALTER TABLE RESET.  In the ALTER cases, oldOptions is the existing
 * reloptions value (possibly NULL), and we replace or remove entries
 * as needed.
 *
 * If ignoreOids is true, then we should ignore any occurrence of "oids"
 * in the list (it will be or has been handled by interpretOidsOption()).
 *
 * Note that this is not responsible for determining whether the options
 * are valid.
 *
 * Both oldOptions and the result are text arrays (or NULL for "default"),
 * but we declare them as Datums to avoid including array.h in reloptions.h.
 */
Datum
transformRelOptions(Datum oldOptions, List *defList,
					bool ignoreOids, bool isReset)
{
	Datum		result;
	ArrayBuildState *astate;
	ListCell   *cell;

	/* no change if empty list */
	if (defList == NIL)
		return oldOptions;

	/* We build new array using accumArrayResult */
	astate = NULL;

	/* Copy any oldOptions that aren't to be replaced */
	if (DatumGetPointer(oldOptions) != 0)
	{
		ArrayType  *array = DatumGetArrayTypeP(oldOptions);
		Datum	   *oldoptions;
		int			noldoptions;
		int			i;

		Assert(ARR_ELEMTYPE(array) == TEXTOID);

		deconstruct_array(array, TEXTOID, -1, false, 'i',
						  &oldoptions, NULL, &noldoptions);

		for (i = 0; i < noldoptions; i++)
		{
			text	   *oldoption = DatumGetTextP(oldoptions[i]);
			char	   *text_str = VARDATA(oldoption);
			int			text_len = VARSIZE(oldoption) - VARHDRSZ;

			/* Search for a match in defList */
			foreach(cell, defList)
			{
				DefElem    *def = lfirst(cell);
				int			kw_len = strlen(def->defname);

				if (text_len > kw_len && text_str[kw_len] == '=' &&
					pg_strncasecmp(text_str, def->defname, kw_len) == 0)
					break;
			}
			if (!cell)
			{
				/* No match, so keep old option */
				astate = accumArrayResult(astate, oldoptions[i],
										  false, TEXTOID,
										  CurrentMemoryContext);
			}
		}
예제 #25
0
/*
 * UpdateCmsTopn is a helper function to add new item to CmsTopn structure. It
 * adds the item to the sketch, calculates its frequency, and updates the top-n
 * array. Finally it forms new CmsTopn from updated sketch and updated top-n array.
 */
static CmsTopn *
UpdateCmsTopn(CmsTopn *currentCmsTopn, Datum newItem,
              TypeCacheEntry *newItemTypeCacheEntry)
{
	CmsTopn *updatedCmsTopn = NULL;
	ArrayType *currentTopnArray = NULL;
	ArrayType *updatedTopnArray = NULL;
	Datum detoastedItem = 0;
	Oid newItemType = newItemTypeCacheEntry->type_id;
	Oid currentItemType = InvalidOid;
	Frequency newItemFrequency = 0;
	bool topnArrayUpdated = false;
	Size currentTopnArrayLength = 0;

	currentTopnArray = TopnArray(currentCmsTopn);
	currentTopnArrayLength = ARR_DIMS(currentTopnArray)[0];
	currentItemType = ARR_ELEMTYPE(currentTopnArray);

	if (currentTopnArrayLength != 0 && currentItemType != newItemType)
	{
		ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE),
		                errmsg("not proper type for this cms_topn")));
	}

	/* if datum is toasted, detoast it */
	if (newItemTypeCacheEntry->typlen == -1)
	{
		detoastedItem = PointerGetDatum(PG_DETOAST_DATUM(newItem));
	}
	else
	{
		detoastedItem = newItem;
	}

	newItemFrequency = UpdateSketchInPlace(currentCmsTopn, detoastedItem,
	                                       newItemTypeCacheEntry);
	updatedTopnArray = UpdateTopnArray(currentCmsTopn, detoastedItem,
	                                   newItemTypeCacheEntry, newItemFrequency,
	                                   &topnArrayUpdated);

	/* we only form a new CmsTopn only if top-n array is updated */
	if (topnArrayUpdated)
	{
		updatedCmsTopn = FormCmsTopn(currentCmsTopn, updatedTopnArray);
	}
	else
	{
		updatedCmsTopn = currentCmsTopn;
	}

	return updatedCmsTopn;
}
예제 #26
0
파일: json.c 프로젝트: avontd2868/postgres
/*
 * Turn an array into JSON.
 */
static void
array_to_json_internal(Datum array, StringInfo result, bool use_line_feeds)
{
	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,
				typdelim;
	Oid			typioparam;
	Oid			typoutputfunc;
	TYPCATEGORY tcategory;

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

	if (nitems <= 0)
	{
		appendStringInfoString(result,"[]");
		return;
	}

	get_type_io_data(element_type, IOFunc_output,
					 &typlen, &typbyval, &typalign,
					 &typdelim, &typioparam, &typoutputfunc);

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

	if (element_type == RECORDOID)
		tcategory = TYPCATEGORY_COMPOSITE;
	else if (element_type == JSONOID)
		tcategory = TYPCATEGORY_JSON;
	else
		tcategory = TypeCategory(element_type);

	array_dim_to_json(result, 0, ndim, dim, elements, &count, tcategory,
					  typoutputfunc, use_line_feeds);

	pfree(elements);
	pfree(nulls);
}
예제 #27
0
파일: float.c 프로젝트: sunyangkobe/cscd43
static float8 *
check_float8_array(ArrayType *transarray, const char *caller)
{
	/*
	 * We expect the input to be a 3-element float array; verify that. We
	 * don't need to use deconstruct_array() since the array data is just
	 * going to look like a C array of 3 float8 values.
	 */
	if (ARR_NDIM(transarray) != 1 ||
		ARR_DIMS(transarray)[0] != 3 ||
		ARR_ELEMTYPE(transarray) != FLOAT8OID)
		elog(ERROR, "%s: expected 3-element float8 array", caller);
	return (float8 *) ARR_DATA_PTR(transarray);
}
예제 #28
0
파일: kmeans.c 프로젝트: 0x0all/madlib
Datum
internal_get_array_of_close_canopies(PG_FUNCTION_ARGS)
{
    SvecType       *svec;
    Datum          *all_canopies;
    int             num_all_canopies;
    float8          threshold;
    PGFunction      metric_fn;
    
    ArrayType      *close_canopies_arr;
    int4           *close_canopies;
    int             num_close_canopies;
    size_t          bytes;
    MemoryContext   mem_context_for_function_calls;
    
    svec = PG_GETARG_SVECTYPE_P(verify_arg_nonnull(fcinfo, 0));
    get_svec_array_elms(PG_GETARG_ARRAYTYPE_P(verify_arg_nonnull(fcinfo, 1)),
        &all_canopies, &num_all_canopies);
    threshold = PG_GETARG_FLOAT8(verify_arg_nonnull(fcinfo, 2));
    metric_fn = get_metric_fn(PG_GETARG_INT32(verify_arg_nonnull(fcinfo, 3)));
    
    mem_context_for_function_calls = setup_mem_context_for_functional_calls();
    close_canopies = (int4 *) palloc(sizeof(int4) * num_all_canopies);
    num_close_canopies = 0;
    for (int i = 0; i < num_all_canopies; i++) {
        if (compute_metric(metric_fn, mem_context_for_function_calls,
                PointerGetDatum(svec), all_canopies[i]) < threshold)
            close_canopies[num_close_canopies++] = i + 1 /* lower bound */;
    }
    MemoryContextDelete(mem_context_for_function_calls);

    /* If we cannot find any close canopy, return NULL. Note that the result
     * we return will be passed to internal_kmeans_closest_centroid() and if the
     * array of close canopies is NULL, then internal_kmeans_closest_centroid()
     * will consider and compute the distance to all centroids. */
    if (num_close_canopies == 0)
        PG_RETURN_NULL();

    bytes = ARR_OVERHEAD_NONULLS(1) + sizeof(int4) * num_close_canopies;
    close_canopies_arr = (ArrayType *) palloc0(bytes);
    SET_VARSIZE(close_canopies_arr, bytes);
    ARR_ELEMTYPE(close_canopies_arr) = INT4OID;
    ARR_NDIM(close_canopies_arr) = 1;
    ARR_DIMS(close_canopies_arr)[0] = num_close_canopies;
    ARR_LBOUND(close_canopies_arr)[0] = 1;
    memcpy(ARR_DATA_PTR(close_canopies_arr), close_canopies,
        sizeof(int4) * num_close_canopies);

    PG_RETURN_ARRAYTYPE_P(close_canopies_arr);
}
예제 #29
0
/* logic copied from utils/adt/float.c */
static inline float8 *
check_float8_array(ArrayType *transarray, int nitems)
{
	/*
	 * We expect the input to be an N-element float array; verify that. We
	 * don't need to use deconstruct_array() since the array data is just
	 * going to look like a C array of N float8 values.
	 */
	if (ARR_NDIM(transarray) != 1 ||
		ARR_DIMS(transarray)[0] != nitems ||
		ARR_HASNULL(transarray) ||
		ARR_ELEMTYPE(transarray) != FLOAT8OID)
		elog(ERROR, "%d-elements float8 array is expected", nitems);
	return (float8 *) ARR_DATA_PTR(transarray);
}
예제 #30
0
파일: kmeans.c 프로젝트: 0x0all/madlib
static
inline
void
get_svec_array_elms(ArrayType *inArrayType, Datum **outSvecArr, int *outLen)
{
    deconstruct_array(inArrayType,           /* array */
                  ARR_ELEMTYPE(inArrayType), /* elmtype */
                  -1,                        /* elmlen */
                  false,                     /* elmbyval */
                  'd',                       /* elmalign */
                  outSvecArr,                /* elemsp */
                  NULL,                      /* nullsp -- pass NULL, because we 
                                                don't support NULLs */
                  outLen);                   /* nelemsp */
}