Expose PC_Get(pcpoint) returning an array of float8 at the SQL level

Initial code by Remi-C, refactored to reduce code extent and equipped
with regress test.
This commit is contained in:
Sandro Santilli 2015-02-12 12:08:23 +01:00
parent 225327468d
commit 2ecca0b602
5 changed files with 57 additions and 0 deletions

View File

@ -225,6 +225,14 @@ Now that you have created two tables, you'll see entries for them in the `pointc
>
> 4
**PC_Get(pt pcpoint)** returns **float8[]** (from 2.0)
> Return values of all dimensions in an array.
>
> SELECT PC_Get('010100000064CEFFFF94110000703000000400'::pcpoint);
>
> {-127,45,124,4}
**PC_Patch(pts pcpoint[])** returns **pcpatch**
> Aggregate function that collects a result set of `pcpoint` values into a `pcpatch`.

View File

@ -126,6 +126,14 @@ SELECT Sum(PC_Get(pt, 'y')) FROM pt_test;
0.09
(1 row)
SELECT PC_Get(pt) FROM pt_test;
pc_get
--------------------
{0.01,0.02,0.03,4}
{0.02,0.03,0.03,5}
{0.03,0.04,0.03,6}
(3 rows)
SELECT PC_AsText(pt) FROM pt_test;
pc_astext
------------------------------------

View File

@ -15,6 +15,7 @@
/* General SQL functions */
Datum pcpoint_get_value(PG_FUNCTION_ARGS);
Datum pcpoint_get_values(PG_FUNCTION_ARGS);
Datum pcpatch_from_pcpoint_array(PG_FUNCTION_ARGS);
Datum pcpatch_from_pcpatch_array(PG_FUNCTION_ARGS);
Datum pcpatch_uncompress(PG_FUNCTION_ARGS);
@ -71,6 +72,39 @@ Datum pcpoint_get_value(PG_FUNCTION_ARGS)
PG_RETURN_DATUM(DirectFunctionCall1(float8_numeric, Float8GetDatum(double_result)));
}
/**
* Returns all the values of a point as a double precision array
* PC_Get(point pcpoint) returns Float8[]
*/
PG_FUNCTION_INFO_V1(pcpoint_get_values);
Datum pcpoint_get_values(PG_FUNCTION_ARGS)
{
SERIALIZED_POINT *serpt;
ArrayType *result;
PCSCHEMA *schema;
PCPOINT *pt;
Datum *elems;
int i;
double *vals;
serpt = PG_GETARG_SERPOINT_P(0);
schema = pc_schema_from_pcid(serpt->pcid, fcinfo);
pt = pc_point_deserialize(serpt, schema);
if ( ! pt ) PG_RETURN_NULL();
elems = (Datum * )palloc(schema->ndims * sizeof(Datum) );
vals = pc_point_to_double_array(pt);
i = schema->ndims;
while (i--) elems[i] = Float8GetDatum(vals[i]);
pcfree(vals);
result = construct_array(elems, schema->ndims, FLOAT8OID,
sizeof(float8), FLOAT8PASSBYVAL, 'd');
pc_point_free(pt);
PG_RETURN_ARRAYTYPE_P(result);
}
static inline bool
array_get_isnull(const bits8 *nullbitmap, int offset)
{

View File

@ -81,6 +81,11 @@ CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint, dimname text)
RETURNS numeric AS 'MODULE_PATHNAME', 'pcpoint_get_value'
LANGUAGE 'c' IMMUTABLE STRICT;
-- Availability: 2.0
CREATE OR REPLACE FUNCTION PC_Get(pt pcpoint)
RETURNS float8[] AS 'MODULE_PATHNAME', 'pcpoint_get_values'
LANGUAGE 'c' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION PC_MakePoint(pcid integer, vals float8[])
RETURNS pcpoint AS 'MODULE_PATHNAME', 'pcpoint_from_double_array'
LANGUAGE 'c' IMMUTABLE STRICT;

View File

@ -109,6 +109,8 @@ INSERT INTO pt_test (pt) VALUES ('00000000010000000300000004000000030006');
SELECT PC_Get(pt, 'Intensity') FROM pt_test;
SELECT Sum(PC_Get(pt, 'y')) FROM pt_test;
SELECT PC_Get(pt) FROM pt_test;
SELECT PC_AsText(pt) FROM pt_test;
SELECT PC_AsText(PC_Patch(pt)) FROM pt_test;