[postgis-tickets] r16272 - 2.3 fix, st_transform does not qualify query to spatial_ref_sys (references #3975)

Paul Ramsey pramsey at cleverelephant.ca
Fri Jan 12 05:55:02 PST 2018


Author: pramsey
Date: 2018-01-12 05:55:02 -0800 (Fri, 12 Jan 2018)
New Revision: 16272

Modified:
   branches/2.3/NEWS
   branches/2.3/libpgcommon/lwgeom_pg.h
   branches/2.3/libpgcommon/lwgeom_transform.c
   branches/2.3/libpgcommon/lwgeom_transform.h
Log:
2.3 fix, st_transform does not qualify query to spatial_ref_sys (references #3975)


Modified: branches/2.3/NEWS
===================================================================
--- branches/2.3/NEWS	2018-01-12 13:47:51 UTC (rev 16271)
+++ branches/2.3/NEWS	2018-01-12 13:55:02 UTC (rev 16272)
@@ -11,6 +11,8 @@
   - #3956, Brin opclass object does not upgrade properly (Sandro Santilli)
   - #3982, ST_AsEncodedPolyline supports LINESTRING EMPTY and MULTIPOINT EMPTY
            (Darafei Praliaskouski)
+  - #3975, ST_Transform runs query on spatial_ref_sys without schema 
+           qualification. May cause restore issues. (Paul Ramsey)
 
 PostGIS 2.3.5
 2017/11/15

Modified: branches/2.3/libpgcommon/lwgeom_pg.h
===================================================================
--- branches/2.3/libpgcommon/lwgeom_pg.h	2018-01-12 13:47:51 UTC (rev 16271)
+++ branches/2.3/libpgcommon/lwgeom_pg.h	2018-01-12 13:55:02 UTC (rev 16272)
@@ -18,6 +18,7 @@
 #include "postgres.h"
 #include "utils/geo_decls.h"
 #include "fmgr.h"
+#include "utils/lsyscache.h"
 
 #include "liblwgeom.h"
 #include "pgsql_compat.h"

Modified: branches/2.3/libpgcommon/lwgeom_transform.c
===================================================================
--- branches/2.3/libpgcommon/lwgeom_transform.c	2018-01-12 13:47:51 UTC (rev 16271)
+++ branches/2.3/libpgcommon/lwgeom_transform.c	2018-01-12 13:55:02 UTC (rev 16272)
@@ -34,6 +34,15 @@
 #include <errno.h>
 
 
+/**
+* Global variable to hold cached information about what
+* schema functions are installed in. Currently used by
+* SetSpatialRefSysSchema and GetProj4StringSPI
+*/
+static char *spatialRefSysSchema = NULL;
+
+
+
 /* Expose an internal Proj function */
 int pj_transform_nodatum(projPJ srcdefn, projPJ dstdefn, long point_count, int point_offset, double *x, double *y, double *z );
 
@@ -349,9 +358,25 @@
 		elog(ERROR, "GetProj4StringSPI: Could not connect to database using SPI");
 	}
 
-	/* Execute the lookup query */
-	snprintf(proj4_spi_buffer, 255, "SELECT proj4text FROM spatial_ref_sys WHERE srid = %d LIMIT 1", srid);
-	spi_result = SPI_exec(proj4_spi_buffer, 1);
+	/*
+	* This global is allocated in CacheMemoryContext (lifespan of this backend)
+	* and is set by SetSpatialRefSysSchema the first time
+	* that GetProjectionsUsingFCInfo is called.
+	*/
+	if (spatialRefSysSchema)
+	{
+		/* Format the lookup query */
+		static char *proj_str_tmpl = "SELECT proj4text FROM %s.spatial_ref_sys WHERE srid = %d LIMIT 1";
+		snprintf(proj4_spi_buffer, 255, proj_str_tmpl, spatialRefSysSchema, srid);
+	}
+	else
+	{
+		/* Format the lookup query */
+		static char *proj_str_tmpl = "SELECT proj4text FROM spatial_ref_sys WHERE srid = %d LIMIT 1";
+		snprintf(proj4_spi_buffer, 255, proj_str_tmpl, srid);
+	}
+	/* Execute the query, noting the readonly status of this SQL */
+	spi_result = SPI_execute(proj4_spi_buffer, true, 1);
 
 	/* Read back the PROJ4 text */
 	if (spi_result == SPI_OK_SELECT && SPI_processed > 0)
@@ -429,7 +454,7 @@
 			int yzone = zone / 20;
 			double lat_0 = 30.0 * (yzone - 3) + 15.0;
 			double lon_0 = 0.0;
-			
+
 			/* The number of xzones is variable depending on yzone */
 			if  ( yzone == 2 || yzone == 3 )
 				lon_0 = 30.0 * (xzone - 6) + 15.0;
@@ -439,7 +464,7 @@
 				lon_0 = 90.0 * (xzone - 2) + 45.0;
 			else
 				lwerror("Unknown yzone encountered!");
-			
+
 			snprintf(proj_str, maxproj4len, "+proj=laea +ellps=WGS84 +datum=WGS84 +lat_0=%g +lon_0=%g +units=m +no_defs", lat_0, lon_0);
 		}
 		/* Lambert Azimuthal Equal Area South Pole */
@@ -511,7 +536,7 @@
 		char *pj_errstr = pj_strerrno(*pj_get_errno_ref());
 		if ( ! pj_errstr )
 			pj_errstr = "";
-		
+
 		elog(ERROR,
 		    "AddToPROJ4SRSCache: could not parse proj4 string '%s' %s",
 		    proj_str, pj_errstr);
@@ -698,6 +723,30 @@
 }
 #endif
 
+/*
+* Given a function call context, figure out what namespace the
+* function is being called from, and copy that into a global
+* for use by GetProj4StringSPI
+*/
+static void
+SetSpatialRefSysSchema(FunctionCallInfo fcinfo)
+{
+	char *nsp_name;
+
+	/* 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_name = get_namespace_name(get_func_namespace(fcinfo->flinfo->fn_oid));
+	elog(DEBUG4, "%s located %s in namespace %s", __func__, get_func_name(fcinfo->flinfo->fn_oid), nsp_name);
+
+	spatialRefSysSchema = MemoryContextAlloc(CacheMemoryContext, strlen(nsp_name)+1);
+	strcpy(spatialRefSysSchema, nsp_name);
+	return;
+}
+
 int
 GetProjectionsUsingFCInfo(FunctionCallInfo fcinfo, int srid1, int srid2, projPJ *pj1, projPJ *pj2)
 {
@@ -706,6 +755,9 @@
 	/* Set the search path if we haven't already */
 	SetPROJ4LibPath();
 
+	/* Look up the spatial_ref_sys schema if we haven't already */
+	SetSpatialRefSysSchema(fcinfo);
+
 	/* get or initialize the cache for this round */
 	proj_cache = GetPROJ4Cache(fcinfo);
 	if ( !proj_cache )
@@ -781,11 +833,11 @@
 	projPJ pj2;
 
 	srs_precision sp;
-	
+
 	sp.precision_xy = precision;
 	sp.precision_z = precision;
 	sp.precision_m = precision;
-	
+
 	if ( srid == SRID_UNKNOWN )
 		return sp;
 
@@ -797,6 +849,6 @@
 		sp.precision_xy += 5;
 		return sp;
 	}
-	
+
 	return sp;
 }

Modified: branches/2.3/libpgcommon/lwgeom_transform.h
===================================================================
--- branches/2.3/libpgcommon/lwgeom_transform.h	2018-01-12 13:47:51 UTC (rev 16271)
+++ branches/2.3/libpgcommon/lwgeom_transform.h	2018-01-12 13:55:02 UTC (rev 16272)
@@ -23,7 +23,6 @@
 char* GetProj4StringSPI(int srid);
 void SetPROJ4LibPath(void) ;
 
-
 /**
  * Opaque type to use in the projection cache API.
  */



More information about the postgis-tickets mailing list