[postgis-tickets] r17569 - Internal type lookups fail over FDW
Paul Ramsey
pramsey at cleverelephant.ca
Fri Jun 28 11:03:24 PDT 2019
Author: pramsey
Date: 2019-06-28 11:03:24 -0700 (Fri, 28 Jun 2019)
New Revision: 17569
Modified:
branches/2.4/NEWS
branches/2.4/libpgcommon/lwgeom_pg.c
branches/2.4/libpgcommon/lwgeom_pg.h
branches/2.4/libpgcommon/lwgeom_transform.c
branches/2.4/postgis/geobuf.c
branches/2.4/postgis/mvt.c
Log:
Internal type lookups fail over FDW
Closes #4440
Modified: branches/2.4/NEWS
===================================================================
--- branches/2.4/NEWS 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/NEWS 2019-06-28 18:03:24 UTC (rev 17569)
@@ -8,6 +8,7 @@
- #4388, AddRasterConstraints: Ignore NULLs when generating constraints (Raúl Marín)
- #4327, Avoid pfree'ing the result of getenv (Raúl Marín)
- #4406, Throw on invalid characters when decoding geohash (Raúl Marín)
+ - #4440, Internal type lookups fail over FDW (Paul Ramsey)
PostGIS 2.4.7
Modified: branches/2.4/libpgcommon/lwgeom_pg.c
===================================================================
--- branches/2.4/libpgcommon/lwgeom_pg.c 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/libpgcommon/lwgeom_pg.c 2019-06-28 18:03:24 UTC (rev 17569)
@@ -65,6 +65,125 @@
}
+
+/****************************************************************************************/
+/* Global to hold all the run-time constants */
+
+postgisConstants *POSTGIS_CONSTANTS = NULL;
+
+/* Utility call to lookup type oid given name and nspoid */
+static Oid TypenameNspGetTypid(const char *typname, Oid nsp_oid)
+ {
+ return GetSysCacheOid2(TYPENAMENSP,
+#if POSTGIS_PGSQL_VERSION >= 120
+ Anum_pg_type_oid,
+#endif
+ PointerGetDatum(typname),
+ ObjectIdGetDatum(nsp_oid));
+ }
+
+/* Cache type lookups in per-session location */
+static postgisConstants *
+getPostgisConstants(FunctionCallInfo fcinfo)
+ {
+ char *nsp_name;
+ Oid nsp_oid;
+ postgisConstants *constants;
+
+ /* For some reason we have a hobbled fcinfo/flinfo */
+ if (!fcinfo || !fcinfo->flinfo) return NULL;
+
+ /* Allocate in the CacheContext so we don't lose this at the end of the statement */
+ constants = MemoryContextAlloc(CacheMemoryContext, sizeof(postgisConstants));
+
+ /* early exit if we cannot lookup nsp_name, cf #4067 */
+ nsp_oid = get_func_namespace(fcinfo->flinfo->fn_oid);
+ if (!nsp_oid) return NULL;
+ nsp_name = get_namespace_name(nsp_oid);
+ constants->install_nsp_oid = nsp_oid;
+ 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);
+
+ /* 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);
+ constants->box2df_oid = TypenameNspGetTypid("box2df", nsp_oid);
+ constants->box3d_oid = TypenameNspGetTypid("box3d", nsp_oid);
+ constants->gidx_oid = TypenameNspGetTypid("gidx", nsp_oid);
+ constants->raster_oid = TypenameNspGetTypid("raster", nsp_oid);
+
+ /* Done */
+ return constants;
+}
+
+Oid
+postgis_oid(postgisType typ)
+{
+ /* Use a schema qualified, cached lookup if we can */
+ postgisConstants *cnsts = POSTGIS_CONSTANTS;
+ if (cnsts)
+ {
+ switch (typ)
+ {
+ case GEOMETRYOID:
+ return cnsts->geometry_oid;
+ case GEOGRAPHYOID:
+ return cnsts->geography_oid;
+ case BOX3DOID:
+ return cnsts->box3d_oid;
+ case BOX2DFOID:
+ return cnsts->box2df_oid;
+ case GIDXOID:
+ return cnsts->gidx_oid;
+ case RASTEROID:
+ return cnsts->raster_oid;
+ case POSTGISNSPOID:
+ return cnsts->install_nsp_oid;
+ default:
+ return InvalidOid;
+ }
+ }
+ /* Fall back to a bare lookup and hope the type in is */
+ /* the search_path */
+ else
+ {
+ switch (typ)
+ {
+ case GEOMETRYOID:
+ return TypenameGetTypid("geometry");
+ case GEOGRAPHYOID:
+ return TypenameGetTypid("geography");
+ case BOX3DOID:
+ return TypenameGetTypid("box3d");
+ case BOX2DFOID:
+ return TypenameGetTypid("box2df");
+ case GIDXOID:
+ return TypenameGetTypid("gidx");
+ case RASTEROID:
+ return TypenameGetTypid("raster");
+ default:
+ return InvalidOid;
+ }
+ }
+ }
+
+Oid
+postgis_oid_fcinfo(FunctionCallInfo fcinfo, postgisType oid)
+{
+ /* Cache the info if we don't already have it */
+ if (!POSTGIS_CONSTANTS)
+ POSTGIS_CONSTANTS = getPostgisConstants(fcinfo);;
+
+ if (!POSTGIS_CONSTANTS) return InvalidOid;
+ return postgis_oid(oid);
+}
+
+/****************************************************************************************/
+
+
+
+
+
/*
* Error message parsing functions
*
Modified: branches/2.4/libpgcommon/lwgeom_pg.h
===================================================================
--- branches/2.4/libpgcommon/lwgeom_pg.h 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/libpgcommon/lwgeom_pg.h 2019-06-28 18:03:24 UTC (rev 17569)
@@ -16,9 +16,15 @@
#define _LWGEOM_PG_H 1
#include "postgres.h"
+#include "fmgr.h"
+#include "catalog/namespace.h" /* For TypenameGetTypid */
+#if POSTGIS_PGSQL_VERSION > 100
+#include "catalog/pg_type_d.h" /* For TypenameGetTypid */
+#endif
#include "utils/geo_decls.h"
-#include "fmgr.h"
+#include "utils/memutils.h"
#include "utils/lsyscache.h"
+#include "utils/syscache.h"
#include "liblwgeom.h"
#include "pgsql_compat.h"
@@ -31,6 +37,47 @@
#define PG_GETARG_GSERIALIZED_P_COPY(varno) ((GSERIALIZED *)PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(varno)))
#define PG_GETARG_GSERIALIZED_P_SLICE(varno, start, size) ((GSERIALIZED *)PG_DETOAST_DATUM_SLICE(PG_GETARG_DATUM(varno), start, size))
+/****************************************************************************************
+* Caching machinery to hold information about Oid numbers for PostGIS
+* types.
+*/
+typedef enum
+{
+ GEOMETRYOID = 1,
+ GEOGRAPHYOID,
+ BOX3DOID,
+ BOX2DFOID,
+ GIDXOID,
+ RASTEROID,
+ POSTGISNSPOID
+} postgisType;
+
+typedef struct
+{
+ Oid geometry_oid;
+ Oid geography_oid;
+ Oid box2df_oid;
+ Oid box3d_oid;
+ Oid gidx_oid;
+ Oid raster_oid;
+ Oid install_nsp_oid;
+ char *install_nsp;
+} 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);
+
+/* only useful if postgis_oid_fcinfo() has been called first and */
+/* populated first, otherwise returns InvalidOid */
+Oid postgis_oid(postgisType typ);
+
+/****************************************************************************************/
+
/* Debugging macros */
#if POSTGIS_DEBUG_LEVEL > 0
Modified: branches/2.4/libpgcommon/lwgeom_transform.c
===================================================================
--- branches/2.4/libpgcommon/lwgeom_transform.c 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/libpgcommon/lwgeom_transform.c 2019-06-28 18:03:24 UTC (rev 17569)
@@ -688,6 +688,7 @@
SetSpatialRefSysSchema(FunctionCallInfo fcinfo)
{
char *nsp_name;
+ Oid nsp_oid;
/* Schema info is already cached, we're done here */
if (spatialRefSysSchema) return;
@@ -695,7 +696,9 @@
/* 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));
+ 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;
Modified: branches/2.4/postgis/geobuf.c
===================================================================
--- branches/2.4/postgis/geobuf.c 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/postgis/geobuf.c 2019-06-28 18:03:24 UTC (rev 17569)
@@ -67,7 +67,7 @@
char *key = palloc(strlen(tkey) + 1);
strcpy(key, tkey);
if (ctx->geom_name == NULL) {
- if (!geom_found && typoid == TypenameGetTypid("geometry")) {
+ if (!geom_found && typoid == postgis_oid(GEOMETRYOID)) {
ctx->geom_index = i;
geom_found = 1;
continue;
Modified: branches/2.4/postgis/mvt.c
===================================================================
--- branches/2.4/postgis/mvt.c 2019-06-28 17:29:22 UTC (rev 17568)
+++ branches/2.4/postgis/mvt.c 2019-06-28 18:03:24 UTC (rev 17569)
@@ -324,7 +324,7 @@
#endif
key = pstrdup(tkey);
if (ctx->geom_name == NULL) {
- if (!geom_found && typoid == TypenameGetTypid("geometry")) {
+ if (!geom_found && typoid == postgis_oid(GEOMETRYOID)) {
ctx->geom_index = i;
geom_found = true;
continue;
More information about the postgis-tickets
mailing list