29 #include "access/tupmacs.h"
30 #include "utils/datum.h"
31 #include "utils/array.h"
32 #include "utils/lsyscache.h"
34 #include "../postgis_config.h"
38 #include "lwgeom_pg.h"
39 #include "lwgeom_transform.h"
70 MemoryContext aggcontext, old;
74 Datum argType = get_fn_expr_argtype(fcinfo->flinfo, 1);
76 if (argType == InvalidOid)
78 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
79 errmsg(
"could not determine input data type")));
81 if ( ! AggCheckCallContext(fcinfo, &aggcontext) )
84 elog(ERROR,
"%s called in non-aggregate context", __func__);
88 if ( PG_ARGISNULL(0) )
96 for (
int i = 0; i < n; i++)
98 Datum argument = PG_GETARG_DATUM(i+2);
99 Oid dataOid = get_fn_expr_argtype(fcinfo->flinfo, i+2);
100 old = MemoryContextSwitchTo(aggcontext);
101 state->
data[i] = datumCopy(argument, get_typbyval(dataOid), get_typlen(dataOid));
102 MemoryContextSwitchTo(old);
110 if (!PG_ARGISNULL(1))
111 gser = PG_GETARG_GSERIALIZED_P(1);
114 old = MemoryContextSwitchTo(aggcontext);
122 state->
geoms = list_make1(geom);
124 MemoryContextSwitchTo(old);
126 PG_RETURN_POINTER(state);
152 Assert(fcinfo->context &&
153 (IsA(fcinfo->context, AggState) ||
154 IsA(fcinfo->context, WindowAggState))
158 get_typlenbyvalalign(state->
geomOid, &elmlen, &elmbyval, &elmalign);
159 nelems = list_length(state->
geoms);
163 elems = palloc(nelems *
sizeof(Datum));
164 nulls = palloc(nelems *
sizeof(
bool));
166 foreach (l, state->
geoms)
169 Datum elem = (Datum)0;
174 elem = PointerGetDatum(gser);
187 arr = construct_md_array(elems, nulls, 1, dims, lbs, state->
geomOid,
188 elmlen, elmbyval, elmalign);
190 return PointerGetDatum(arr);
203 Datum geometry_array = 0;
215 PG_RETURN_DATUM(result);
229 Datum geometry_array = 0;
241 PG_RETURN_DATUM(result);
254 Datum geometry_array = 0;
266 PG_RETURN_DATUM(result);
279 Datum geometry_array = 0;
290 PG_RETURN_DATUM(result);
303 Datum geometry_array = 0;
312 elog(ERROR,
"Tolerance not defined");
321 PG_RETURN_DATUM(result);
331 #if POSTGIS_PGSQL_VERSION < 120
332 FunctionCallInfoData fcinfo;
336 InitFunctionCallInfoData(fcinfo, NULL, 1, InvalidOid, NULL, NULL);
339 fcinfo.arg[0] = arg1;
340 fcinfo.argnull[0] =
false;
342 result = (*func) (&fcinfo);
350 LOCAL_FCINFO(fcinfo, 1);
353 InitFunctionCallInfoData(*fcinfo, NULL, 1, InvalidOid, NULL, NULL);
355 fcinfo->args[0].value = arg1;
356 fcinfo->args[0].isnull =
false;
358 result = (*func)(fcinfo);
375 #if POSTGIS_PGSQL_VERSION < 120
376 FunctionCallInfoData fcinfo;
379 InitFunctionCallInfoData(fcinfo, NULL, 2, InvalidOid, NULL, NULL);
381 fcinfo.arg[0] = arg1;
382 fcinfo.arg[1] = arg2;
383 fcinfo.argnull[0] =
false;
384 fcinfo.argnull[1] =
false;
386 result = (*func) (&fcinfo);
394 LOCAL_FCINFO(fcinfo, 2);
397 InitFunctionCallInfoData(*fcinfo, NULL, 2, InvalidOid, NULL, NULL);
399 fcinfo->args[0].value = arg1;
400 fcinfo->args[1].value = arg2;
401 fcinfo->args[0].isnull =
false;
402 fcinfo->args[1].isnull =
false;
404 result = (*func)(fcinfo);
LWGEOM * lwgeom_from_gserialized(const GSERIALIZED *g)
Allocate a new LWGEOM from a GSERIALIZED.
LWGEOM * lwgeom_clone_deep(const LWGEOM *lwgeom)
Deep clone an LWGEOM, everything is copied.
This library is the generic geometry handling section of PostGIS.
Datum polygonize_garray(PG_FUNCTION_ARGS)
Datum pgis_geometry_makeline_finalfn(PG_FUNCTION_ARGS)
Datum pgis_geometry_polygonize_finalfn(PG_FUNCTION_ARGS)
Datum cluster_within_distance_garray(PG_FUNCTION_ARGS)
Datum pgis_accum_finalfn(CollectionBuildState *state, MemoryContext mctx, FunctionCallInfo fcinfo)
Datum pgis_geometry_collect_finalfn(PG_FUNCTION_ARGS)
PG_FUNCTION_INFO_V1(pgis_geometry_accum_transfn)
The transfer function builds a List of LWGEOM* allocated in the aggregate memory context.
Datum PGISDirectFunctionCall1(PGFunction func, Datum arg1)
A modified version of PostgreSQL's DirectFunctionCall1 which allows NULL results; this is required fo...
Datum pgis_geometry_clusterintersecting_finalfn(PG_FUNCTION_ARGS)
Datum PGISDirectFunctionCall2(PGFunction func, Datum arg1, Datum arg2)
A modified version of PostgreSQL's DirectFunctionCall2 which allows NULL results; this is required fo...
Datum LWGEOM_collect_garray(PG_FUNCTION_ARGS)
Datum pgis_geometry_clusterwithin_finalfn(PG_FUNCTION_ARGS)
Datum clusterintersecting_garray(PG_FUNCTION_ARGS)
Datum LWGEOM_makeline_garray(PG_FUNCTION_ARGS)
Datum pgis_geometry_accum_transfn(PG_FUNCTION_ARGS)
Datum pgis_union_geometry_array(PG_FUNCTION_ARGS)
#define CollectionBuildStateDataSize
To pass the internal state of our collection between the transfn and finalfn we need to wrap it into ...
GSERIALIZED * geometry_serialize(LWGEOM *lwgeom)
Datum data[CollectionBuildStateDataSize]