#include "postgres.h" #include "utils/array.h" #include "cubedata.h" /* contrib/cube */ #include "fmgr.h" /* ** CREATE OR REPLACE FUNCTION cube_from_arrays(float[], float[]) RETURNS cube ** AS 'cube_from_arrays' ** LANGUAGE C; */ /* ** Taken from the intarray contrib header */ #define ARRPTR(x) ( (double *) ARR_DATA_PTR(x) ) #define ARRNELEMS(x) ArrayGetNItems( ARR_NDIM(x), ARR_DIMS(x)) /* ** Allows the construction of a cube from 2 float[]'s */ PG_FUNCTION_INFO_V1(cube_from_arrays); NDBOX * cube_from_arrays (PG_FUNCTION_ARGS) { int i; int dim; int size; NDBOX *result; ArrayType *ur, *ll; double *dur, *dll; if (PG_ARGISNULL(0) || PG_ARGISNULL(1)) { ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("Cannot work with NULL arrays"))); } ur = (ArrayType *) PG_GETARG_VARLENA_P(0); ll = (ArrayType *) PG_GETARG_VARLENA_P(1); dim = ARRNELEMS(ur); if (ARRNELEMS(ll) != dim) { ereport(ERROR, (errcode(ERRCODE_ARRAY_ELEMENT_ERROR), errmsg("UR and LL arrays must be of same length"))); PG_RETURN_NULL(); } dur = ARRPTR(ur); dll = ARRPTR(ll); size = offsetof(NDBOX, x[0]) + sizeof(double) * 2 * dim; result = (NDBOX *) palloc (size); memset (result, 0, size); result->size = size; result->dim = dim; for (i=0; ix[i] = dur[i]; result->x[i+dim] = dll[i]; } PG_RETURN_DATUM(result); }