Commit 575ae858 authored by Raúl Marín's avatar Raúl Marín

Change ST_AsGML(geometry) to use a C function direcly

By using a inline SQL, the cache that lives in the upper context was
deleted for each processed row (thus being ineffective)

Closes #4674
parent b5bd6836
Pipeline #144123522 passed with stage
in 27 minutes and 58 seconds
......@@ -36,7 +36,7 @@
#include "utils/array.h"
#include "utils/builtins.h" /* for pg_atoi */
#include "lib/stringinfo.h" /* For binary input */
#include "catalog/pg_type.h" /* for CSTRINGOID */
#include "catalog/pg_type.h" /* for CSTRINGOID, INT4OID */
#include "liblwgeom.h" /* For standard geometry types. */
#include "lwgeom_cache.h"
......
......@@ -31,6 +31,7 @@
#include "float.h" /* for DBL_DIG */
#include "postgres.h"
#include "catalog/pg_type.h" /* for INT4OID */
#include "executor/spi.h"
#include "utils/builtins.h"
#include "utils/jsonb.h"
......@@ -71,37 +72,55 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
char *gml_id_buf, *prefix_buf;
text *prefix_text, *gml_id_text;
/* Get the version */
version = PG_GETARG_INT32(0);
if ( version != 2 && version != 3 )
/*
* Two potential callers, one starts with GML version,
* one starts with geometry, and we check for initial
* argument type and then dynamically change what args
* we read based on presence/absence
*/
Oid first_type = get_fn_expr_argtype(fcinfo->flinfo, 0);
int argnum = 0;
if (first_type != INT4OID)
{
elog(ERROR, "Only GML 2 and GML 3 are supported");
PG_RETURN_NULL();
version = 2;
}
else
{
/* Get the version */
version = PG_GETARG_INT32(argnum++);
if (version != 2 && version != 3)
{
elog(ERROR, "Only GML 2 and GML 3 are supported");
PG_RETURN_NULL();
}
}
/* Get the geometry */
if ( PG_ARGISNULL(1) ) PG_RETURN_NULL();
geom = PG_GETARG_GSERIALIZED_P(1);
if (PG_ARGISNULL(argnum))
PG_RETURN_NULL();
geom = PG_GETARG_GSERIALIZED_P(argnum++);
/* Retrieve precision if any (default is max) */
if (PG_NARGS() > 2 && !PG_ARGISNULL(2))
if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
{
precision = PG_GETARG_INT32(2);
precision = PG_GETARG_INT32(argnum);
/* TODO: leave this to liblwgeom ? */
if (precision > DBL_DIG)
precision = DBL_DIG;
else if (precision < 0)
precision = 0;
}
argnum++;
/* retrieve option */
if (PG_NARGS() > 3 && !PG_ARGISNULL(3)) option = PG_GETARG_INT32(3);
if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
option = PG_GETARG_INT32(argnum);
argnum++;
/* retrieve prefix */
if (PG_NARGS() >4 && !PG_ARGISNULL(4))
if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
{
prefix_text = PG_GETARG_TEXT_P(4);
prefix_text = PG_GETARG_TEXT_P(argnum);
if ( VARSIZE(prefix_text) == VARHDRSZ )
{
prefix = "";
......@@ -117,10 +136,11 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
prefix = prefix_buf;
}
}
argnum++;
if (PG_NARGS() >5 && !PG_ARGISNULL(5))
if (PG_NARGS() > argnum && !PG_ARGISNULL(argnum))
{
gml_id_text = PG_GETARG_TEXT_P(5);
gml_id_text = PG_GETARG_TEXT_P(argnum);
if ( VARSIZE(gml_id_text) == VARHDRSZ )
{
gml_id = "";
......@@ -134,6 +154,7 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
gml_id = gml_id_buf;
}
}
argnum++;
srid = gserialized_get_srid(geom);
if (srid == SRID_UNKNOWN) srs = NULL;
......@@ -147,7 +168,7 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
if (option & 8)
{
elog(ERROR,
"Options %d passed to ST_AsGML(geography) sets "
"Options %d passed to ST_AsGML(geometry) sets "
"unsupported value 8",
option);
PG_RETURN_NULL();
......
......@@ -4659,8 +4659,8 @@ CREATE OR REPLACE FUNCTION _ST_AsGML(int4, geometry, int4, int4, text, text)
-- Changed: 2.0.0 to have default args
CREATE OR REPLACE FUNCTION ST_AsGML(geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT 0)
RETURNS TEXT
AS $$ SELECT @[email protected]_ST_AsGML(2, $1, $2, $3, null, null); $$
LANGUAGE 'sql' IMMUTABLE STRICT PARALLEL SAFE
AS 'MODULE_PATHNAME','LWGEOM_asGML'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE
_COST_MEDIUM;
-- ST_AsGML(version, geom, precision, option)
......@@ -4672,8 +4672,8 @@ CREATE OR REPLACE FUNCTION ST_AsGML(geom geometry, maxdecimaldigits int4 DEFAULT
-- Availability: 2.1.0
CREATE OR REPLACE FUNCTION ST_AsGML(version int4, geom geometry, maxdecimaldigits int4 DEFAULT 15, options int4 DEFAULT 0, nprefix text DEFAULT null, id text DEFAULT null)
RETURNS TEXT
AS $$ SELECT @[email protected]_ST_AsGML($1, $2, $3, $4, $5, $6); $$
LANGUAGE 'sql' IMMUTABLE PARALLEL SAFE
AS 'MODULE_PATHNAME','LWGEOM_asGML'
LANGUAGE 'c' IMMUTABLE PARALLEL SAFE
_COST_MEDIUM;
-----------------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment