mirror of
https://github.com/pgpointcloud/pointcloud.git
synced 2025-12-08 20:36:04 +00:00
Add pcpoint>patch aggregates
This commit is contained in:
parent
23829781d1
commit
17e0134305
21
libpc/pc_dimensional.c
Normal file
21
libpc/pc_dimensional.c
Normal file
@ -0,0 +1,21 @@
|
||||
/***********************************************************************
|
||||
* pc_dimensional.c
|
||||
*
|
||||
* Support for "dimensional compression", which is a catch-all
|
||||
* term for applying compression separately on each dimension
|
||||
* of a PCPATCH collection of PCPOINTS.
|
||||
*
|
||||
* Depending on the character of the data, one of these schemes
|
||||
* will be used:
|
||||
*
|
||||
* - run-length encoding
|
||||
* - significant-bit removal
|
||||
* - deflate
|
||||
*
|
||||
* Portions Copyright (c) 2012, OpenGeo
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "pc_api_internal.h"
|
||||
|
||||
@ -223,7 +223,7 @@ pc_patch_from_points(const PCPOINTLIST *pl)
|
||||
{
|
||||
if ( pl->points[i] )
|
||||
{
|
||||
if ( pl->points[i]->schema != s )
|
||||
if ( pl->points[i]->schema->pcid != s->pcid )
|
||||
{
|
||||
pcerror("pc_patch_from_points: points do not share a schema");
|
||||
return NULL;
|
||||
|
||||
@ -9,18 +9,25 @@
|
||||
|
||||
#include "pc_pgsql.h" /* Common PgSQL support for our type */
|
||||
#include "utils/numeric.h"
|
||||
#include "funcapi.h"
|
||||
|
||||
/* Other SQL functions */
|
||||
Datum PC_Get(PG_FUNCTION_ARGS);
|
||||
|
||||
Datum pcpoint_get_value(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS);
|
||||
|
||||
/* Aggregation functions */
|
||||
Datum pcpoint_agg_final_pcpatch(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_agg_final_array(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_agg_transfn(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_abs_in(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_abs_out(PG_FUNCTION_ARGS);
|
||||
|
||||
/**
|
||||
* Read a named dimension from a PCPOINT
|
||||
* PC_Get(point pcpoint, dimname text) returns Numeric
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(PC_Get);
|
||||
Datum PC_Get(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpoint_get_value);
|
||||
Datum pcpoint_get_value(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
|
||||
text *dim_name = PG_GETARG_TEXT_P(1);
|
||||
@ -42,3 +49,209 @@ Datum PC_Get(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_DATUM(DirectFunctionCall1(float8_numeric, Float8GetDatum(double_result)));
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpatch_from_pcpoint_array);
|
||||
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ArrayType *array;
|
||||
Datum datum = PG_GETARG_DATUM(0);
|
||||
int nelems;
|
||||
bits8 *bitmap;
|
||||
int bitmask;
|
||||
size_t offset = 0;
|
||||
int i;
|
||||
PCPOINTLIST *pl;
|
||||
PCPATCH *pa;
|
||||
SERIALIZED_PATCH *serpa;
|
||||
uint32_t pcid = 0;
|
||||
|
||||
/* Null array, null geometry (should be empty?) */
|
||||
if ( (Pointer *)datum == NULL ) PG_RETURN_NULL();
|
||||
|
||||
array = DatumGetArrayTypeP(datum);
|
||||
|
||||
/* How many things in our array? */
|
||||
nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array));
|
||||
|
||||
/* PgSQL supplies a bitmap of which array entries are null */
|
||||
bitmap = ARR_NULLBITMAP(array);
|
||||
|
||||
/* Empty array? Null return */
|
||||
if ( nelems == 0 )
|
||||
PG_RETURN_NULL();
|
||||
|
||||
/* Make our holder */
|
||||
pl = pc_pointlist_make(nelems);
|
||||
|
||||
offset = 0;
|
||||
bitmap = ARR_NULLBITMAP(array);
|
||||
bitmask = 1;
|
||||
for ( i = 0; i < nelems; i++ )
|
||||
{
|
||||
/* Only work on non-NULL entries in the array */
|
||||
if ( (bitmap && (*bitmap & bitmask)) || !bitmap )
|
||||
{
|
||||
SERIALIZED_POINT *serpt = (SERIALIZED_POINT *)(ARR_DATA_PTR(array)+offset);
|
||||
PCPOINT *pt;
|
||||
|
||||
if ( ! pcid )
|
||||
{
|
||||
pcid = serpt->pcid;
|
||||
}
|
||||
else if ( pcid != serpt->pcid )
|
||||
{
|
||||
elog(ERROR, "pcpatch_from_pcpoint_array: pcid mismatch (%d != %d)", serpt->pcid, pcid);
|
||||
}
|
||||
|
||||
pt = pc_point_deserialize(serpt);
|
||||
if ( ! pt )
|
||||
{
|
||||
elog(ERROR, "pcpatch_from_pcpoint_array: point deserialization failed");
|
||||
}
|
||||
|
||||
pc_pointlist_add_point(pl, pt);
|
||||
|
||||
offset += INTALIGN(VARSIZE(serpt));
|
||||
}
|
||||
|
||||
/* Advance NULL bitmap */
|
||||
if (bitmap)
|
||||
{
|
||||
bitmask <<= 1;
|
||||
if (bitmask == 0x100)
|
||||
{
|
||||
bitmap++;
|
||||
bitmask = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( pl->npoints == 0 )
|
||||
PG_RETURN_NULL();
|
||||
|
||||
pa = pc_patch_from_points(pl);
|
||||
pc_pointlist_free(pl);
|
||||
serpa = pc_patch_serialize(pa);
|
||||
pc_patch_free(pa);
|
||||
PG_RETURN_POINTER(serpa);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
ArrayBuildState *s;
|
||||
} abs_trans;
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_abs_in);
|
||||
Datum pcpoint_abs_in(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("function pcpoint_abs_in not implemented")));
|
||||
PG_RETURN_POINTER(NULL);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_abs_out);
|
||||
Datum pcpoint_abs_out(PG_FUNCTION_ARGS)
|
||||
{
|
||||
ereport(ERROR,(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
|
||||
errmsg("function pcpoint_abs_out not implemented")));
|
||||
PG_RETURN_POINTER(NULL);
|
||||
}
|
||||
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_agg_transfn);
|
||||
Datum pcpoint_agg_transfn(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid arg1_typeid = get_fn_expr_argtype(fcinfo->flinfo, 1);
|
||||
MemoryContext aggcontext;
|
||||
abs_trans *a;
|
||||
ArrayBuildState *state;
|
||||
Datum elem;
|
||||
|
||||
if (arg1_typeid == InvalidOid)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
|
||||
errmsg("could not determine input data type")));
|
||||
|
||||
if (fcinfo->context && IsA(fcinfo->context, AggState))
|
||||
{
|
||||
aggcontext = ((AggState *) fcinfo->context)->aggcontext;
|
||||
}
|
||||
else if (fcinfo->context && IsA(fcinfo->context, WindowAggState))
|
||||
{
|
||||
aggcontext = ((WindowAggState *) fcinfo->context)->aggcontext;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* cannot be called directly because of dummy-type argument */
|
||||
elog(ERROR, "pcpoint_agg_transfn called in non-aggregate context");
|
||||
aggcontext = NULL; /* keep compiler quiet */
|
||||
}
|
||||
|
||||
if ( PG_ARGISNULL(0) )
|
||||
{
|
||||
a = (abs_trans*) palloc(sizeof(abs_trans));
|
||||
a->s = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (abs_trans*) PG_GETARG_POINTER(0);
|
||||
}
|
||||
state = a->s;
|
||||
elem = PG_ARGISNULL(1) ? (Datum) 0 : PG_GETARG_DATUM(1);
|
||||
state = accumArrayResult(state,
|
||||
elem,
|
||||
PG_ARGISNULL(1),
|
||||
arg1_typeid,
|
||||
aggcontext);
|
||||
a->s = state;
|
||||
|
||||
PG_RETURN_POINTER(a);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
static Datum
|
||||
pcpoint_agg_final(abs_trans *a, MemoryContext mctx, FunctionCallInfo fcinfo)
|
||||
{
|
||||
ArrayBuildState *state;
|
||||
int dims[1];
|
||||
int lbs[1];
|
||||
state = a->s;
|
||||
dims[0] = state->nelems;
|
||||
lbs[0] = 1;
|
||||
return makeMdArrayResult(state, 1, dims, lbs, mctx, false);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_agg_final_array);
|
||||
Datum pcpoint_agg_final_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
abs_trans *a;
|
||||
Datum result = 0;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL(); /* returns null iff no input values */
|
||||
|
||||
a = (abs_trans*) PG_GETARG_POINTER(0);
|
||||
|
||||
result = pcpoint_agg_final(a, CurrentMemoryContext, fcinfo);
|
||||
PG_RETURN_DATUM(result);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_agg_final_pcpatch);
|
||||
Datum pcpoint_agg_final_pcpatch(PG_FUNCTION_ARGS)
|
||||
{
|
||||
abs_trans *a;
|
||||
Datum result = 0;
|
||||
Datum result_final = 0;
|
||||
|
||||
if (PG_ARGISNULL(0))
|
||||
PG_RETURN_NULL(); /* returns null iff no input values */
|
||||
|
||||
a = (abs_trans*) PG_GETARG_POINTER(0);
|
||||
|
||||
result = pcpoint_agg_final(a, CurrentMemoryContext, fcinfo);
|
||||
result_final = DirectFunctionCall1(pcpatch_from_pcpoint_array, result);
|
||||
PG_RETURN_DATUM(result_final);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -16,13 +16,13 @@ Datum pcpatch_in(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_out(PG_FUNCTION_ARGS);
|
||||
|
||||
/* Other SQL functions */
|
||||
Datum PC_SchemaIsValid(PG_FUNCTION_ARGS);
|
||||
Datum PC_SchemaGetNDims(PG_FUNCTION_ARGS);
|
||||
Datum PC_MakePointFromArray(PG_FUNCTION_ARGS);
|
||||
Datum PC_PointAsText(PG_FUNCTION_ARGS);
|
||||
Datum PC_PatchAsText(PG_FUNCTION_ARGS);
|
||||
Datum PC_PointAsByteA(PG_FUNCTION_ARGS);
|
||||
Datum PC_PatchEnvelopeAsByteA(PG_FUNCTION_ARGS);
|
||||
Datum pcschema_is_valid(PG_FUNCTION_ARGS);
|
||||
Datum pcschema_get_ndims(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_from_double_array(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_as_text(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_as_text(PG_FUNCTION_ARGS);
|
||||
Datum pcpoint_as_bytea(PG_FUNCTION_ARGS);
|
||||
Datum pcpatch_bytea_envelope(PG_FUNCTION_ARGS);
|
||||
|
||||
PG_FUNCTION_INFO_V1(pcpoint_in);
|
||||
Datum pcpoint_in(PG_FUNCTION_ARGS)
|
||||
@ -125,8 +125,8 @@ Datum pcpatch_out(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_CSTRING(hexwkb);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_SchemaIsValid);
|
||||
Datum PC_SchemaIsValid(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcschema_is_valid);
|
||||
Datum pcschema_is_valid(PG_FUNCTION_ARGS)
|
||||
{
|
||||
bool valid;
|
||||
text *xml = PG_GETARG_TEXT_P(0);
|
||||
@ -145,8 +145,8 @@ Datum PC_SchemaIsValid(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_BOOL(valid);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_SchemaGetNDims);
|
||||
Datum PC_SchemaGetNDims(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcschema_get_ndims);
|
||||
Datum pcschema_get_ndims(PG_FUNCTION_ARGS)
|
||||
{
|
||||
int ndims;
|
||||
uint32 pcid = PG_GETARG_INT32(0);
|
||||
@ -161,10 +161,10 @@ Datum PC_SchemaGetNDims(PG_FUNCTION_ARGS)
|
||||
}
|
||||
|
||||
/**
|
||||
* PC_MakePointFromArray(integer pcid, float8[] returns PcPoint
|
||||
* pcpoint_from_double_array(integer pcid, float8[] returns PcPoint
|
||||
*/
|
||||
PG_FUNCTION_INFO_V1(PC_MakePointFromArray);
|
||||
Datum PC_MakePointFromArray(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpoint_from_double_array);
|
||||
Datum pcpoint_from_double_array(PG_FUNCTION_ARGS)
|
||||
{
|
||||
uint32 pcid = PG_GETARG_INT32(0);
|
||||
ArrayType *arrptr = PG_GETARG_ARRAYTYPE_P(1);
|
||||
@ -208,8 +208,8 @@ Datum PC_MakePointFromArray(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_POINTER(serpt);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_PointAsText);
|
||||
Datum PC_PointAsText(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpoint_as_text);
|
||||
Datum pcpoint_as_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
|
||||
text *txt;
|
||||
@ -225,8 +225,8 @@ Datum PC_PointAsText(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(txt);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_PatchAsText);
|
||||
Datum PC_PatchAsText(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpatch_as_text);
|
||||
Datum pcpatch_as_text(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
text *txt;
|
||||
@ -242,8 +242,8 @@ Datum PC_PatchAsText(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_TEXT_P(txt);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_PointAsByteA);
|
||||
Datum PC_PointAsByteA(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpoint_as_bytea);
|
||||
Datum pcpoint_as_bytea(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_POINT *serpt = PG_GETARG_SERPOINT_P(0);
|
||||
uint8_t *bytes;
|
||||
@ -267,8 +267,8 @@ Datum PC_PointAsByteA(PG_FUNCTION_ARGS)
|
||||
PG_RETURN_BYTEA_P(wkb);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(PC_PatchEnvelopeAsByteA);
|
||||
Datum PC_PatchEnvelopeAsByteA(PG_FUNCTION_ARGS)
|
||||
PG_FUNCTION_INFO_V1(pcpatch_bytea_envelope);
|
||||
Datum pcpatch_bytea_envelope(PG_FUNCTION_ARGS)
|
||||
{
|
||||
SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
|
||||
uint8_t *bytes;
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
-- Confirm the XML representation of a schema has everything we need
|
||||
CREATE OR REPLACE FUNCTION PC_SchemaIsValid(xml text)
|
||||
RETURNS boolean AS 'MODULE_PATHNAME','PC_SchemaIsValid'
|
||||
RETURNS boolean AS 'MODULE_PATHNAME','pcschema_is_valid'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-- Metadata table describing contents of pcpoints
|
||||
@ -24,7 +24,7 @@ CREATE TABLE pointcloud_formats (
|
||||
SELECT pg_catalog.pg_extension_config_dump('pointcloud_formats', '');
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_SchemaGetNDims(pcid integer)
|
||||
RETURNS integer AS 'MODULE_PATHNAME','PC_SchemaGetNDims'
|
||||
RETURNS integer AS 'MODULE_PATHNAME','pcschema_get_ndims'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
|
||||
@ -56,19 +56,19 @@ CREATE TYPE pcpoint (
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint, dimname text)
|
||||
RETURNS numeric AS 'MODULE_PATHNAME', 'PC_Get'
|
||||
RETURNS numeric AS 'MODULE_PATHNAME', 'pcpoint_get_value'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_MakePoint(pcid integer, vals float8[])
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'PC_MakePointFromArray'
|
||||
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpoint_from_double_array'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_AsText(p pcpoint)
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'PC_PointAsText'
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pcpoint_as_text'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_AsBinary(p pcpoint)
|
||||
RETURNS bytea AS 'MODULE_PATHNAME', 'PC_PointAsByteA'
|
||||
RETURNS bytea AS 'MODULE_PATHNAME', 'pcpoint_as_bytea'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
@ -98,11 +98,74 @@ CREATE TYPE pcpatch (
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_AsText(p pcpatch)
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'PC_PatchAsText'
|
||||
RETURNS text AS 'MODULE_PATHNAME', 'pcpatch_as_text'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
CREATE OR REPLACE FUNCTION PC_Envelope(p pcpatch)
|
||||
RETURNS bytea AS 'MODULE_PATHNAME', 'PC_PatchEnvelopeAsByteA'
|
||||
RETURNS bytea AS 'MODULE_PATHNAME', 'pcpatch_bytea_envelope'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
|
||||
|
||||
-------------------------------------------------------------------
|
||||
-- AGGREGATE / EXPLODE
|
||||
-------------------------------------------------------------------
|
||||
|
||||
CREATE OR REPLACE FUNCTION pcpoint_abs_in(cstring)
|
||||
RETURNS pcpoint_abs AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE OR REPLACE FUNCTION pcpoint_abs_out(pcpoint_abs)
|
||||
RETURNS cstring AS 'MODULE_PATHNAME'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE TYPE pcpoint_abs (
|
||||
internallength = 8,
|
||||
input = pcpoint_abs_in,
|
||||
output = pcpoint_abs_out,
|
||||
alignment = double
|
||||
);
|
||||
|
||||
CREATE FUNCTION PC_Patch(pcpoint[])
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpatch_from_pcpoint_array'
|
||||
LANGUAGE 'c' IMMUTABLE STRICT;
|
||||
|
||||
|
||||
CREATE FUNCTION pcpoint_agg_transfn (pcpoint_abs, pcpoint)
|
||||
RETURNS pcpoint_abs AS'MODULE_PATHNAME', 'pcpoint_agg_transfn'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE FUNCTION pcpoint_agg_final_array (pcpoint_abs)
|
||||
RETURNS pcpoint[] AS 'MODULE_PATHNAME', 'pcpoint_agg_final_array'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE FUNCTION pcpoint_agg_final_pcpatch (pcpoint_abs)
|
||||
RETURNS pcpatch AS 'MODULE_PATHNAME', 'pcpoint_agg_final_pcpatch'
|
||||
LANGUAGE 'c';
|
||||
|
||||
CREATE AGGREGATE PC_Patch (
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pcpoint_abs,
|
||||
FINALFUNC = pcpoint_agg_final_pcpatch
|
||||
);
|
||||
|
||||
CREATE AGGREGATE PC_Point_Agg (
|
||||
BASETYPE = pcpoint,
|
||||
SFUNC = pcpoint_agg_transfn,
|
||||
STYPE = pcpoint_abs,
|
||||
FINALFUNC = pcpoint_agg_final_array
|
||||
);
|
||||
|
||||
|
||||
-- CREATE FUNCTION pcpoint_array_from_pcpatch(pcpatch)
|
||||
-- RETURNS pcpoint[] AS 'MODULE_PATHNAME', 'pcpoint_array_from_pcpatch'
|
||||
-- LANGUAGE 'sql' IMMUTABLE STRICT;
|
||||
|
||||
-- The enumeration function
|
||||
-- returns each element in a one dimensional integer array
|
||||
-- as a row.
|
||||
-- CREATE FUNCTION int_array_enum(int4[])
|
||||
-- RETURNS setof integer
|
||||
-- AS 'array_unnest'
|
||||
-- LANGUAGE INTERNAL IMMUTABLE STRICT;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user