[postgis-tickets] r16262 - When looking up SRID numbers, assume that spatial_ref_sys will

Paul Ramsey pramsey at cleverelephant.ca
Thu Jan 11 02:09:36 PST 2018


Author: pramsey
Date: 2018-01-11 14:09:35 -0800 (Thu, 11 Jan 2018)
New Revision: 16262

Modified:
   trunk/libpgcommon/lwgeom_pg.h
   trunk/libpgcommon/lwgeom_transform.c
   trunk/libpgcommon/lwgeom_transform.h
Log:
When looking up SRID numbers, assume that spatial_ref_sys will
share a schema will the calling function (st_transform, usually)
and look for spatial_ref_sys there. (References #3975)


Modified: trunk/libpgcommon/lwgeom_pg.h
===================================================================
--- trunk/libpgcommon/lwgeom_pg.h	2018-01-11 21:36:35 UTC (rev 16261)
+++ trunk/libpgcommon/lwgeom_pg.h	2018-01-11 22:09:35 UTC (rev 16262)
@@ -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: trunk/libpgcommon/lwgeom_transform.c
===================================================================
--- trunk/libpgcommon/lwgeom_transform.c	2018-01-11 21:36:35 UTC (rev 16261)
+++ trunk/libpgcommon/lwgeom_transform.c	2018-01-11 22:09:35 UTC (rev 16262)
@@ -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 );
 
@@ -336,10 +345,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_execute(proj4_spi_buffer, true, 1);
-	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)
@@ -655,6 +679,30 @@
 }
 
 
+/*
+* 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)
 {
@@ -663,6 +711,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 )

Modified: trunk/libpgcommon/lwgeom_transform.h
===================================================================
--- trunk/libpgcommon/lwgeom_transform.h	2018-01-11 21:36:35 UTC (rev 16261)
+++ trunk/libpgcommon/lwgeom_transform.h	2018-01-11 22:09:35 UTC (rev 16262)
@@ -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