From: Sandro Santilli Date: Tue, 28 Oct 2003 15:16:17 +0000 (+0000) Subject: unite_sfunc() from postgis_geos.c renamed to geom_accum() and moved in postgis_fn.c X-Git-Tag: pgis_0_8_0~46 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=560d10c8a212b155e6a68cacb20bbd78cdb1f7a3;p=postgis unite_sfunc() from postgis_geos.c renamed to geom_accum() and moved in postgis_fn.c git-svn-id: http://svn.osgeo.org/postgis/trunk@336 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis.h b/postgis.h index 2f9a5c44d..4e3e06a60 100644 --- a/postgis.h +++ b/postgis.h @@ -11,6 +11,9 @@ * ********************************************************************** * $Log$ + * Revision 1.36 2003/10/28 15:16:17 strk + * unite_sfunc() from postgis_geos.c renamed to geom_accum() and moved in postgis_fn.c + * * Revision 1.35 2003/10/28 11:16:46 strk * Added postgis_algo.c prototypes * @@ -576,6 +579,7 @@ Datum box3dtobox(PG_FUNCTION_ARGS); Datum transform_geom(PG_FUNCTION_ARGS); Datum max_distance(PG_FUNCTION_ARGS); +Datum geom_accum(PG_FUNCTION_ARGS); Datum collector(PG_FUNCTION_ARGS); Datum WKBtoBYTEA(PG_FUNCTION_ARGS); diff --git a/postgis_fn.c b/postgis_fn.c index 067bcabca..758010f18 100644 --- a/postgis_fn.c +++ b/postgis_fn.c @@ -11,6 +11,9 @@ * ********************************************************************** * $Log$ + * Revision 1.28 2003/10/28 15:16:17 strk + * unite_sfunc() from postgis_geos.c renamed to geom_accum() and moved in postgis_fn.c + * * Revision 1.27 2003/10/17 16:12:23 dblasby * Made Envelope() CW instead of CCW. * @@ -56,6 +59,7 @@ #include "postgis.h" #include "utils/elog.h" +#include "utils/array.h" #define NfunctionFirstPoint 1 @@ -2591,6 +2595,86 @@ Datum segmentize(PG_FUNCTION_ARGS) PG_RETURN_POINTER(result); } +/* + * This is a geometry array constructor + * for use as aggregates sfunc. + * Will have * as input an array of Geometry pointers and a Geometry. + * Will DETOAST given geometry and put a pointer to it + * in the given array. DETOASTED value is first copied + * to a safe memory context to avoid premature deletion. + */ +PG_FUNCTION_INFO_V1(geom_accum); +Datum geom_accum(PG_FUNCTION_ARGS) +{ + ArrayType *array; + int nelems, nbytes; + Datum datum; + GEOMETRY *geom; + ArrayType *result; + Pointer **pointers; + MemoryContext oldcontext; + + datum = PG_GETARG_DATUM(0); + if ( (Pointer *)datum == NULL ) { + array = NULL; + nelems = 0; + //elog(NOTICE, "geom_accum: NULL array, nelems=%d", nelems); + } else { + array = (ArrayType *) PG_DETOAST_DATUM_COPY(datum); + nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array)); + } + + datum = PG_GETARG_DATUM(1); + // Do nothing, return state array + if ( (Pointer *)datum == NULL ) + { + //elog(NOTICE, "geom_accum: NULL geom, nelems=%d", nelems); + PG_RETURN_ARRAYTYPE_P(array); + } + + /* + * Switch to * flinfo->fcinfo->fn_mcxt + * memory context to be sure both detoasted + * geometry AND array of pointers to it + * last till the call to unite_finalfunc. + */ + oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); + + /* Make a DETOASTED copy of input geometry */ + geom = (GEOMETRY *)PG_DETOAST_DATUM_COPY(datum); + + //elog(NOTICE, "geom_accum: adding %p (nelems=%d)", geom, nelems); + + /* + * Might use a more optimized version instead of repalloc'ing + * at every iteration. This is not the bottleneck anyway. + * --strk(TODO); + */ + ++nelems; + nbytes = ARR_OVERHEAD(1) + sizeof(Pointer *) * nelems; + if ( ! array ) { + result = (ArrayType *) palloc(nbytes); + result->size = nbytes; + result->ndim = 1; + *((int *) ARR_DIMS(result)) = nelems; + } else { + result = (ArrayType *) repalloc(array, nbytes); + result->size = nbytes; + result->ndim = 1; + *((int *) ARR_DIMS(result)) = nelems; + } + + pointers = (Pointer **)ARR_DATA_PTR(result); + pointers[nelems-1] = (Pointer *)geom; + + /* Go back to previous memory context */ + MemoryContextSwitchTo(oldcontext); + + + PG_RETURN_ARRAYTYPE_P(result); + +} + // collector( geom, geom ) returns a geometry which contains // all the sub_objects from both of the argument geometries diff --git a/postgis_geos.c b/postgis_geos.c index e4c9767a1..239d3cb53 100644 --- a/postgis_geos.c +++ b/postgis_geos.c @@ -10,6 +10,9 @@ * ********************************************************************** * $Log$ + * Revision 1.18 2003/10/28 15:16:17 strk + * unite_sfunc() from postgis_geos.c renamed to geom_accum() and moved in postgis_fn.c + * * Revision 1.17 2003/10/28 10:59:55 strk * handled NULL state array in unite_finalfunc, cleaned up some spurios code * @@ -187,7 +190,6 @@ Datum difference(PG_FUNCTION_ARGS); Datum boundary(PG_FUNCTION_ARGS); Datum symdifference(PG_FUNCTION_ARGS); Datum geomunion(PG_FUNCTION_ARGS); -Datum unite_sfunc(PG_FUNCTION_ARGS); Datum unite_finalfunc(PG_FUNCTION_ARGS); @@ -241,93 +243,6 @@ resize_ptrArrayType(ArrayType *a, int num) } -/* - * This is the state function for union/fastunite/geomunion - * aggregate (still discussing the name). Will have - * as input an array of Geometry pointers and a Geometry. - * Will DETOAST given geometry and put a pointer to it - * in the given array. DETOASTED value is first copied - * to a safe memory context to avoid premature deletion. - */ -#define DEBUG -PG_FUNCTION_INFO_V1(unite_sfunc); -Datum unite_sfunc(PG_FUNCTION_ARGS) -{ - ArrayType *array; - int nelems, nbytes; - Datum datum; - GEOMETRY *geom; - ArrayType *result; - Pointer **pointers; - MemoryContext oldcontext; - - datum = PG_GETARG_DATUM(0); - if ( (Pointer *)datum == NULL ) { - array = NULL; - nelems = 0; -#ifdef DEBUG - elog(NOTICE, "unite_sfunc: NULL array, nelems=%d", nelems); -#endif - } else { - array = (ArrayType *) PG_DETOAST_DATUM_COPY(datum); - nelems = ArrayGetNItems(ARR_NDIM(array), ARR_DIMS(array)); - } - - datum = PG_GETARG_DATUM(1); - // Do nothing, return state array - if ( (Pointer *)datum == NULL ) - { -#ifdef DEBUG - elog(NOTICE, "unite_sfunc: NULL geom, nelems=%d", nelems); -#endif - PG_RETURN_ARRAYTYPE_P(array); - } - - /* - * Switch to * flinfo->fcinfo->fn_mcxt - * memory context to be sure both detoasted - * geometry AND array of pointers to it - * last till the call to unite_finalfunc. - */ - oldcontext = MemoryContextSwitchTo(fcinfo->flinfo->fn_mcxt); - - /* Make a DETOASTED copy of input geometry */ - geom = (GEOMETRY *)PG_DETOAST_DATUM_COPY(datum); - -#ifdef DEBUG - elog(NOTICE, "unite_sfunc: adding %p (nelems=%d)", geom, nelems); -#endif - - /* - * Might use a more optimized version instead of repalloc'ing - * at every iteration. This is not the bottleneck anyway. - * --strk(TODO); - */ - ++nelems; - nbytes = ARR_OVERHEAD(1) + sizeof(Pointer *) * nelems; - if ( ! array ) { - result = (ArrayType *) palloc(nbytes); - result->size = nbytes; - result->ndim = 1; - *((int *) ARR_DIMS(result)) = nelems; - } else { - result = (ArrayType *) repalloc(array, nbytes); - result->size = nbytes; - result->ndim = 1; - *((int *) ARR_DIMS(result)) = nelems; - } - - pointers = (Pointer **)ARR_DATA_PTR(result); - pointers[nelems-1] = (Pointer *)geom; - - /* Go back to previous memory context */ - MemoryContextSwitchTo(oldcontext); - - - PG_RETURN_ARRAYTYPE_P(result); - -} - /* * This is the final function for union/fastunite/geomunion * aggregate (still discussing the name). Will have