[postgis-tickets] [SCM] PostGIS branch stable-3.0 updated. 3.0.1-10-gefafa58

git at osgeo.org git at osgeo.org
Fri Apr 10 04:25:28 PDT 2020


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "PostGIS".

The branch, stable-3.0 has been updated
       via  efafa58a6878f34055c616a3aa16566c2e598127 (commit)
      from  b5cba66de3148fd115a92666d890b97a7ddbde41 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit efafa58a6878f34055c616a3aa16566c2e598127
Author: Raúl Marín <git at rmr.ninja>
Date:   Fri Apr 10 11:47:39 2020 +0200

    Fix access to spatial_ref_sys with a non default schema
    
    References #4661

diff --git a/NEWS b/NEWS
index 5afd631..39ecad0 100644
--- a/NEWS
+++ b/NEWS
@@ -2,7 +2,8 @@ PostGIS 3.0.2
 2020/XX/XX
 
 * Bug Fixes and Enhancements *
-  - #4652, Fix several memory related bugs in ST_GeomFromGML
+  - #4652, Fix several memory related bugs in ST_GeomFromGML (Raúl Marín)
+  - #4661, Fix access to spatial_ref_sys with a non default schema (Raúl Marín)
 
 
 
diff --git a/libpgcommon/lwgeom_pg.c b/libpgcommon/lwgeom_pg.c
index e2ee6b8..aecc38a 100644
--- a/libpgcommon/lwgeom_pg.c
+++ b/libpgcommon/lwgeom_pg.c
@@ -18,6 +18,7 @@
 #include <fmgr.h>
 #include <miscadmin.h>
 #include <executor/spi.h>
+#include "utils/builtins.h"
 #include <utils/guc.h>
 #include <utils/guc_tables.h>
 #include <catalog/namespace.h>
@@ -70,6 +71,12 @@ getPostgisConstants(FunctionCallInfo fcinfo)
 	constants->install_nsp = MemoryContextStrdup(CacheMemoryContext, nsp_name);
 	elog(DEBUG4, "%s located %s in namespace %s", __func__, get_func_name(fcinfo->flinfo->fn_oid), nsp_name);
 
+	char *spatial_ref_sys_fullpath = quote_qualified_identifier(nsp_name, "spatial_ref_sys");
+	constants->spatial_ref_sys = MemoryContextStrdup(CacheMemoryContext, spatial_ref_sys_fullpath);
+	elog(DEBUG4, "%s: Spatial ref sys qualified as %s", __func__, spatial_ref_sys_fullpath);
+	pfree(nsp_name);
+	pfree(spatial_ref_sys_fullpath);
+
 	/* Lookup all the type names in the context of the install schema */
 	constants->geometry_oid = TypenameNspGetTypid("geometry", nsp_oid);
 	constants->geography_oid = TypenameNspGetTypid("geography", nsp_oid);
@@ -133,15 +140,20 @@ postgis_oid(postgisType typ)
 	}
 }
 
-Oid
-postgis_oid_fcinfo(FunctionCallInfo fcinfo, postgisType oid)
+void
+postgis_initialize_cache(FunctionCallInfo fcinfo)
 {
 	/* Cache the info if we don't already have it */
 	if (!POSTGIS_CONSTANTS)
-		POSTGIS_CONSTANTS = getPostgisConstants(fcinfo);;
+		POSTGIS_CONSTANTS = getPostgisConstants(fcinfo);
+}
 
-	if (!POSTGIS_CONSTANTS) return InvalidOid;
-	return postgis_oid(oid);
+const char *
+postgis_spatial_ref_sys()
+{
+	if (!POSTGIS_CONSTANTS)
+		return NULL;
+	return POSTGIS_CONSTANTS->spatial_ref_sys;
 }
 
 /****************************************************************************************/
diff --git a/libpgcommon/lwgeom_pg.h b/libpgcommon/lwgeom_pg.h
index 93a52b9..546ea10 100644
--- a/libpgcommon/lwgeom_pg.h
+++ b/libpgcommon/lwgeom_pg.h
@@ -53,20 +53,26 @@ typedef struct
 	Oid raster_oid;
 	Oid install_nsp_oid;
 	char *install_nsp;
+	char *spatial_ref_sys;
 } postgisConstants;
 
 /* Global to hold all the run-time constants */
 extern postgisConstants *POSTGIS_CONSTANTS;
 
-/* uses the nsp information of the calling function to infer the */
-/* install location of postgis, and thus the namespace to use */
-/* when looking up the type name */
-Oid postgis_oid_fcinfo(FunctionCallInfo fcinfo, postgisType typ);
+/* Infer the install location of postgis, and thus the namespace to use
+ * when looking up the type name, and cache oids */
+void postgis_initialize_cache(FunctionCallInfo fcinfo);
 
-/* only useful if postgis_oid_fcinfo() has been called first and */
-/* populated first, otherwise returns InvalidOid */
+/* Useful if postgis_initialize_cache() has been called before.
+ * Otherwise it tries to do a bare lookup */
 Oid postgis_oid(postgisType typ);
 
+/* Returns the fully qualified, and properly quoted, identifier of spatial_ref_sys
+ * Note that it's length can be up to strlen(schema) + "." + strlen("spatial_ref_sys") + NULL, i.e: 80 bytes
+ * Only useful if postgis_initialize_cache has been called before. Otherwise returns "spatial_ref_sys"
+ */
+const char *postgis_spatial_ref_sys(void);
+
 /****************************************************************************************/
 
 /* Globals to hold GEOMETRYOID, GEOGRAPHYOID */
diff --git a/libpgcommon/lwgeom_transform.c b/libpgcommon/lwgeom_transform.c
index d8a172e..ab07c63 100644
--- a/libpgcommon/lwgeom_transform.c
+++ b/libpgcommon/lwgeom_transform.c
@@ -33,12 +33,6 @@
 #include <stdio.h>
 
 
-/**
-* Global variable to hold cached information about what
-* schema functions are installed in. Currently used by
-* SetSpatialRefSysSchema and GetProjStringsSPI
-*/
-static char *spatialRefSysSchema = NULL;
 
 /*
  * PROJ 4 backend hash table initial hash size
@@ -63,34 +57,6 @@ typedef struct {
 static LWPROJ *AddToPROJSRSCache(PROJPortalCache *PROJCache, int32_t srid_from, int32_t srid_to);
 static void DeleteFromPROJSRSCache(PROJPortalCache *PROJCache, uint32_t position);
 
-/*
-* Given a function call context, figure out what namespace the
-* function is being called from, and copy that into a global
-* for use by GetProjStringsSPI
-*/
-static void
-SetSpatialRefSysSchema(FunctionCallInfo fcinfo)
-{
-	char *nsp_name;
-	Oid nsp_oid;
-
-	/* Schema info is already cached, we're done here */
-	if (spatialRefSysSchema) return;
-
-	/* For some reason we have a hobbled fcinfo/flinfo */
-	if (!fcinfo || !fcinfo->flinfo) return;
-
-	nsp_oid = postgis_oid_fcinfo(fcinfo, POSTGISNSPOID);
-	if (!nsp_oid) return;
-	nsp_name = get_namespace_name(nsp_oid);
-	/* early exit if we cannot lookup nsp_name, cf #4067 */
-	if (!nsp_name) return;
-
-	elog(DEBUG4, "%s located %s in namespace %s", __func__, get_func_name(fcinfo->flinfo->fn_oid), nsp_name);
-	spatialRefSysSchema = MemoryContextStrdup(CacheMemoryContext, nsp_name);
-	return;
-}
-
 static void
 PROJSRSDestroyPJ(void *projection)
 {
@@ -369,23 +335,12 @@ GetProjStringsSPI(int32_t srid)
 		elog(ERROR, "Could not connect to database using SPI");
 	}
 
-	/*
-	* This global is allocated in CacheMemoryContext (lifespan of this backend)
-	* and is set by SetSpatialRefSysSchema the first time
-	* that GetPJUsingFCInfo is called.
-	*/
-	static char *proj_str_tmpl = "SELECT proj4text, auth_name, auth_srid, srtext "
-	                             "FROM %s%sspatial_ref_sys "
-	                             "WHERE srid = %d "
-	                             "LIMIT 1";
-	if (spatialRefSysSchema)
-	{
-		snprintf(proj_spi_buffer, spibufferlen, proj_str_tmpl, spatialRefSysSchema, ".", srid);
-	}
-	else
-	{
-		snprintf(proj_spi_buffer, spibufferlen, proj_str_tmpl, "", "", srid);
-	}
+	static char *proj_str_tmpl =
+	    "SELECT proj4text, auth_name, auth_srid, srtext "
+	    "FROM %s "
+	    "WHERE srid = %d "
+	    "LIMIT 1";
+	snprintf(proj_spi_buffer, spibufferlen, proj_str_tmpl, postgis_spatial_ref_sys(), srid);
 
 	/* Execute the query, noting the readonly status of this SQL */
 	spi_result = SPI_execute(proj_spi_buffer, true, 1);
@@ -569,6 +524,7 @@ pgstrs_get_entry(const PjStrs *strs, int n)
 }
 #endif
 
+#if POSTGIS_PROJ_VERSION < 60
 /*
 * Utility function for GML reader that still
 * needs proj4text access
@@ -584,6 +540,7 @@ GetProj4String(int32_t srid)
 	pjstrs_pfree(&strs);
 	return proj4str;
 }
+#endif
 
 /**
  * Add an entry to the local PROJ SRS cache. If we need to wrap around then
@@ -766,7 +723,7 @@ GetPJUsingFCInfo(FunctionCallInfo fcinfo, int32_t srid_from, int32_t srid_to, LW
 	PROJPortalCache *proj_cache = NULL;
 
 	/* Look up the spatial_ref_sys schema if we haven't already */
-	SetSpatialRefSysSchema(fcinfo);
+	postgis_initialize_cache(fcinfo);
 
 	/* get or initialize the cache for this round */
 	proj_cache = GetPROJSRSCache(fcinfo);
diff --git a/libpgcommon/lwgeom_transform.h b/libpgcommon/lwgeom_transform.h
index 951aa80..2d2cd2d 100644
--- a/libpgcommon/lwgeom_transform.h
+++ b/libpgcommon/lwgeom_transform.h
@@ -22,7 +22,10 @@ typedef struct srs_precision
 	int precision_m;
 } srs_precision;
 
+#if POSTGIS_PROJ_VERSION < 60
+/* Needs to call postgis_initialize_cache first */
 char *GetProj4String(int32_t srid);
+#endif
 
 /**
  * Opaque type to use in the projection cache API.
diff --git a/postgis/geography_inout.c b/postgis/geography_inout.c
index 9fc77f6..55cb152 100644
--- a/postgis/geography_inout.c
+++ b/postgis/geography_inout.c
@@ -291,8 +291,10 @@ Datum geography_as_gml(PG_FUNCTION_ARGS)
 		id = id_buf;
 	}
 
-	if (option & 1) srs = getSRSbySRID(srid, false);
-	else srs = getSRSbySRID(srid, true);
+	if (option & 1)
+		srs = getSRSbySRID(fcinfo, srid, false);
+	else
+		srs = getSRSbySRID(fcinfo, srid, true);
 	if (!srs)
 	{
 		elog(ERROR, "SRID %d unknown in spatial_ref_sys table", SRID_DEFAULT);
@@ -453,8 +455,10 @@ Datum geography_as_geojson(PG_FUNCTION_ARGS)
 	if (option & 2 || option & 4)
 	{
 		/* Geography only handle srid SRID_DEFAULT */
-		if (option & 2) srs = getSRSbySRID(SRID_DEFAULT, true);
-		if (option & 4) srs = getSRSbySRID(SRID_DEFAULT, false);
+		if (option & 2)
+			srs = getSRSbySRID(fcinfo, SRID_DEFAULT, true);
+		if (option & 4)
+			srs = getSRSbySRID(fcinfo, SRID_DEFAULT, false);
 
 		if (!srs)
 		{
diff --git a/postgis/gserialized_spgist_2d.c b/postgis/gserialized_spgist_2d.c
index 38e9bd1..fc60e18 100644
--- a/postgis/gserialized_spgist_2d.c
+++ b/postgis/gserialized_spgist_2d.c
@@ -290,8 +290,10 @@ PG_FUNCTION_INFO_V1(gserialized_spgist_config_2d);
 PGDLLEXPORT Datum gserialized_spgist_config_2d(PG_FUNCTION_ARGS)
 {
 	spgConfigOut *cfg = (spgConfigOut *)PG_GETARG_POINTER(1);
+	Oid boxoid = InvalidOid;
+	postgis_initialize_cache(fcinfo);
+	boxoid = postgis_oid(BOX2DFOID);
 
-	Oid boxoid = postgis_oid_fcinfo(fcinfo, BOX2DFOID);
 	cfg->prefixType = boxoid;
 	cfg->labelType = VOIDOID; /* We don't need node labels. */
 	cfg->leafType = boxoid;
diff --git a/postgis/gserialized_spgist_3d.c b/postgis/gserialized_spgist_3d.c
index d11c291..b417baa 100644
--- a/postgis/gserialized_spgist_3d.c
+++ b/postgis/gserialized_spgist_3d.c
@@ -373,7 +373,10 @@ PGDLLEXPORT Datum gserialized_spgist_config_3d(PG_FUNCTION_ARGS)
 {
 	spgConfigOut *cfg = (spgConfigOut *)PG_GETARG_POINTER(1);
 
-	Oid boxoid = postgis_oid_fcinfo(fcinfo, BOX3DOID);
+	Oid boxoid = InvalidOid;
+	postgis_initialize_cache(fcinfo);
+	boxoid = postgis_oid(BOX3DOID);
+
 	cfg->prefixType = boxoid;
 	cfg->labelType = VOIDOID; /* We don't need node labels. */
 	cfg->leafType = boxoid;
diff --git a/postgis/gserialized_spgist_nd.c b/postgis/gserialized_spgist_nd.c
index 5d624df..1576048 100644
--- a/postgis/gserialized_spgist_nd.c
+++ b/postgis/gserialized_spgist_nd.c
@@ -267,7 +267,9 @@ PG_FUNCTION_INFO_V1(gserialized_spgist_config_nd);
 PGDLLEXPORT Datum gserialized_spgist_config_nd(PG_FUNCTION_ARGS)
 {
 	spgConfigOut *cfg = (spgConfigOut *)PG_GETARG_POINTER(1);
-	Oid boxoid = postgis_oid_fcinfo(fcinfo, GIDXOID);
+	Oid boxoid = InvalidOid;
+	postgis_initialize_cache(fcinfo);
+	boxoid = postgis_oid(GIDXOID);
 
 	cfg->prefixType = boxoid;
 	cfg->labelType = VOIDOID; /* We don't need node labels. */
diff --git a/postgis/lwgeom_export.c b/postgis/lwgeom_export.c
index b8f83ae..9d08b82 100644
--- a/postgis/lwgeom_export.c
+++ b/postgis/lwgeom_export.c
@@ -63,11 +63,13 @@ Datum geometry_to_jsonb(PG_FUNCTION_ARGS);
  * or as long one: (i.e urn:ogc:def:crs:EPSG::4326)
  */
 char *
-getSRSbySRID(int32_t srid, bool short_crs)
+getSRSbySRID(FunctionCallInfo fcinfo, int32_t srid, bool short_crs)
 {
-	char query[256];
+	static const uint16_t max_query_size = 512;
+	char query[512];
 	char *srs, *srscopy;
 	int size, err;
+	postgis_initialize_cache(fcinfo);
 
 	if (SPI_OK_CONNECT != SPI_connect ())
 	{
@@ -77,11 +79,19 @@ getSRSbySRID(int32_t srid, bool short_crs)
 	}
 
 	if (short_crs)
-		snprintf(query, 256, "SELECT auth_name||':'||auth_srid \
-		        FROM spatial_ref_sys WHERE srid='%d'", srid);
+		snprintf(query,
+			 max_query_size,
+			 "SELECT auth_name||':'||auth_srid \
+		        FROM %s WHERE srid='%d'",
+			 postgis_spatial_ref_sys(),
+			 srid);
 	else
-		snprintf(query, 256, "SELECT 'urn:ogc:def:crs:'||auth_name||'::'||auth_srid \
-		        FROM spatial_ref_sys WHERE srid='%d'", srid);
+		snprintf(query,
+			 max_query_size,
+			 "SELECT 'urn:ogc:def:crs:'||auth_name||'::'||auth_srid \
+		        FROM %s WHERE srid='%d'",
+			 postgis_spatial_ref_sys(),
+			 srid);
 
 	err = SPI_exec(query, 1);
 	if ( err < 0 )
@@ -125,17 +135,24 @@ getSRSbySRID(int32_t srid, bool short_crs)
 * Require valid spatial_ref_sys table entry
 *
 */
-int getSRIDbySRS(const char* srs)
+int
+getSRIDbySRS(FunctionCallInfo fcinfo, const char *srs)
 {
-	char *query =
-	    "SELECT srid "
-	    "FROM spatial_ref_sys, "
-	    "regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
-	    "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid";
+	static const int16_t max_query_size = 512;
+	char query[512];
 	Oid argtypes[] = {CSTRINGOID};
 	Datum values[] = {CStringGetDatum(srs)};
 	int32_t srid, err;
 
+	postgis_initialize_cache(fcinfo);
+	snprintf(query,
+		 max_query_size,
+		 "SELECT srid "
+		 "FROM %s, "
+		 "regexp_matches($1::text, E'([a-z]+):([0-9]+)', 'gi') AS re "
+		 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
+		 postgis_spatial_ref_sys());
+
 	if (!srs) return 0;
 
 	if (SPI_OK_CONNECT != SPI_connect())
@@ -155,11 +172,13 @@ int getSRIDbySRS(const char* srs)
 	/* no entry in spatial_ref_sys */
 	if (SPI_processed <= 0)
 	{
-		query =
-		    "SELECT srid "
-		    "FROM spatial_ref_sys, "
-		    "regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
-		    "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid";
+		snprintf(query,
+			 max_query_size,
+			 "SELECT srid "
+			 "FROM %s, "
+			 "regexp_matches($1::text, E'urn:ogc:def:crs:([a-z]+):.*:([0-9]+)', 'gi') AS re "
+			 "WHERE re[1] ILIKE auth_name AND int4(re[2]) = auth_srid",
+			 postgis_spatial_ref_sys());
 
 		err = SPI_execute_with_args(query, 1, argtypes, values, NULL, true, 1);
 		if (err < 0)
@@ -272,8 +291,10 @@ Datum LWGEOM_asGML(PG_FUNCTION_ARGS)
 
 	srid = gserialized_get_srid(geom);
 	if (srid == SRID_UNKNOWN)      srs = NULL;
-	else if (option & 1) srs = getSRSbySRID(srid, false);
-	else                 srs = getSRSbySRID(srid, true);
+	else if (option & 1)
+		srs = getSRSbySRID(fcinfo, srid, false);
+	else
+		srs = getSRSbySRID(fcinfo, srid, true);
 
 	if (option & 2) lwopts &= ~LW_GML_IS_DIMS;
 	if (option & 4) lwopts |= LW_GML_SHORTLINE;
@@ -404,7 +425,7 @@ Datum LWGEOM_asGeoJson(PG_FUNCTION_ARGS)
 
 	if (srid != SRID_UNKNOWN && (output_short_crs || output_long_crs))
 	{
-		srs = getSRSbySRID(srid, !output_long_crs);
+		srs = getSRSbySRID(fcinfo, srid, !output_long_crs);
 
 		if (!srs)
 		{
@@ -566,8 +587,10 @@ Datum LWGEOM_asX3D(PG_FUNCTION_ARGS)
 	lwgeom = lwgeom_from_gserialized(geom);
 	srid = gserialized_get_srid(geom);
 	if (srid == SRID_UNKNOWN)      srs = NULL;
-	else if (option & 1) srs = getSRSbySRID(srid, false);
-	else                 srs = getSRSbySRID(srid, true);
+	else if (option & 1)
+		srs = getSRSbySRID(fcinfo, srid, false);
+	else
+		srs = getSRSbySRID(fcinfo, srid, true);
 
 	if (option & LW_X3D_USE_GEOCOORDS) {
 		if (srid != 4326) {
diff --git a/postgis/lwgeom_export.h b/postgis/lwgeom_export.h
index e01a6ee..b5de2ba 100644
--- a/postgis/lwgeom_export.h
+++ b/postgis/lwgeom_export.h
@@ -22,5 +22,5 @@
  *
  **********************************************************************/
 
-char *getSRSbySRID(int32_t SRID, bool short_crs);
-int getSRIDbySRS(const char* SRS);
+char *getSRSbySRID(FunctionCallInfo fcinfo, int32_t SRID, bool short_crs);
+int getSRIDbySRS(FunctionCallInfo fcinfo, const char *SRS);
diff --git a/postgis/lwgeom_in_geojson.c b/postgis/lwgeom_in_geojson.c
index 08b52a7..58cef93 100644
--- a/postgis/lwgeom_in_geojson.c
+++ b/postgis/lwgeom_in_geojson.c
@@ -110,7 +110,7 @@ Datum geom_from_geojson(PG_FUNCTION_ARGS)
 
 	if (srs)
 	{
-		srid = getSRIDbySRS(srs);
+		srid = getSRIDbySRS(fcinfo, srs);
 		lwfree(srs);
 	}
 
diff --git a/postgis/lwgeom_in_gml.c b/postgis/lwgeom_in_gml.c
index ef1840e..1a5eecf 100644
--- a/postgis/lwgeom_in_gml.c
+++ b/postgis/lwgeom_in_gml.c
@@ -113,6 +113,13 @@ Datum geom_from_gml(PG_FUNCTION_ARGS)
 	/* Zero for undefined */
 	root_srid = PG_GETARG_INT32(1);
 
+#if POSTGIS_PROJ_VERSION < 60
+	/* Internally lwgeom_from_gml calls gml_reproject_pa which, for PROJ before 6, called GetProj4String.
+	 * That function requires access to spatial_ref_sys, so in order to have it ready we need to ensure
+	 * the internal cache is initialized
+	 */
+	postgis_initialize_cache(fcinfo);
+#endif
 	lwgeom = lwgeom_from_gml(xml, xml_size);
 	if ( root_srid != SRID_UNKNOWN )
 		lwgeom->srid = root_srid;
diff --git a/postgis/lwgeom_out_geojson.c b/postgis/lwgeom_out_geojson.c
index 138ddc7..4d82148 100644
--- a/postgis/lwgeom_out_geojson.c
+++ b/postgis/lwgeom_out_geojson.c
@@ -86,8 +86,12 @@ ST_AsGeoJsonRow(PG_FUNCTION_ARGS)
 	bool		do_pretty = PG_GETARG_BOOL(3);
 	StringInfo	result;
 	char        *geom_column = text_to_cstring(geom_column_text);
-	Oid         geom_oid = postgis_oid_fcinfo(fcinfo, GEOMETRYOID);
-	Oid         geog_oid = postgis_oid_fcinfo(fcinfo, GEOGRAPHYOID);
+	Oid geom_oid = InvalidOid;
+	Oid geog_oid = InvalidOid;
+
+	postgis_initialize_cache(fcinfo);
+	geom_oid = postgis_oid(GEOMETRYOID);
+	geog_oid = postgis_oid(GEOGRAPHYOID);
 
 	if (strlen(geom_column) == 0)
 		geom_column = NULL;

-----------------------------------------------------------------------

Summary of changes:
 NEWS                            |  3 +-
 libpgcommon/lwgeom_pg.c         | 22 +++++++++++---
 libpgcommon/lwgeom_pg.h         | 18 +++++++----
 libpgcommon/lwgeom_transform.c  | 61 ++++++-------------------------------
 libpgcommon/lwgeom_transform.h  |  3 ++
 postgis/geography_inout.c       | 12 +++++---
 postgis/gserialized_spgist_2d.c |  4 ++-
 postgis/gserialized_spgist_3d.c |  5 ++-
 postgis/gserialized_spgist_nd.c |  4 ++-
 postgis/lwgeom_export.c         | 67 +++++++++++++++++++++++++++--------------
 postgis/lwgeom_export.h         |  4 +--
 postgis/lwgeom_in_geojson.c     |  2 +-
 postgis/lwgeom_in_gml.c         |  7 +++++
 postgis/lwgeom_out_geojson.c    |  8 +++--
 14 files changed, 122 insertions(+), 98 deletions(-)


hooks/post-receive
-- 
PostGIS


More information about the postgis-tickets mailing list