]> granicus.if.org Git - postgis/commitdiff
Make PostgreSQL 11 compile against PostGIS 2.5 (trunk) and change PostgreSQL 9.6...
authorRegina Obe <lr@pcorp.us>
Wed, 20 Dec 2017 15:20:22 +0000 (15:20 +0000)
committerRegina Obe <lr@pcorp.us>
Wed, 20 Dec 2017 15:20:22 +0000 (15:20 +0000)
(still need to patch address standardizer)
References #3946

git-svn-id: http://svn.osgeo.org/postgis/trunk@16167 b70326c6-7e19-0410-871a-916f4a2858ee

libpgcommon/lwgeom_transform.c
postgis/lwgeom_geos_prepared.c

index 726200b5484ecdf36dee9e9126cd7a3530d56398..894e104d8ebebb56b984697a9954017be1ebac95 100644 (file)
@@ -64,6 +64,9 @@ typedef struct struct_PJHashEntry
 {
        MemoryContext ProjectionContext;
        projPJ projection;
+#if POSTGIS_PGSQL_VERSION >= 96
+       MemoryContextCallback callback; /* for releasing hashentry when done */
+#endif
 }
 PJHashEntry;
 
@@ -87,24 +90,24 @@ static void DeleteFromPROJ4SRSCache(PROJ4PortalCache *PROJ4Cache, int srid);
 static bool IsPROJ4LibPathSet = false;
 void SetPROJ4LibPath(void);
 
-/* Memory context cache functions */
-static void PROJ4SRSCacheInit(MemoryContext context);
+#if POSTGIS_PGSQL_VERSION < 96
 static void PROJ4SRSCacheDelete(MemoryContext context);
+#else
+static void PROJ4SRSCacheDelete(void *arg);
+#endif
+/* Memory context cache function prototypes
+Only need for PostgreSQL where we will not be using a built-in memory context*/
+#if POSTGIS_PGSQL_VERSION < 96
+static void PROJ4SRSCacheInit(MemoryContext context);
 static void PROJ4SRSCacheReset(MemoryContext context);
 static bool PROJ4SRSCacheIsEmpty(MemoryContext context);
 
-#if POSTGIS_PGSQL_VERSION >= 96
-static void PROJ4SRSCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals);
-#else
 static void PROJ4SRSCacheStats(MemoryContext context, int level);
-#endif
 
 #ifdef MEMORY_CONTEXT_CHECKING
 static void PROJ4SRSCacheCheck(MemoryContext context);
 #endif
 
-
-/* Memory context definition must match the current version of PostgreSQL */
 static MemoryContextMethods PROJ4SRSCacheContextMethods =
 {
        NULL,
@@ -121,7 +124,6 @@ static MemoryContextMethods PROJ4SRSCacheContextMethods =
 #endif
 };
 
-
 static void
 PROJ4SRSCacheInit(MemoryContext context)
 {
@@ -131,26 +133,6 @@ PROJ4SRSCacheInit(MemoryContext context)
         */
 }
 
-static void
-PROJ4SRSCacheDelete(MemoryContext context)
-{
-       projPJ projection;
-
-       /* Lookup the projPJ pointer in the global hash table so we can free it */
-       projection = GetPJHashEntry(context);
-
-       if (!projection)
-               elog(ERROR, "PROJ4SRSCacheDelete: Trying to delete non-existant projection object with MemoryContext key (%p)", (void *)context);
-
-       POSTGIS_DEBUGF(3, "deleting projection object (%p) with MemoryContext key (%p)", projection, context);
-
-       /* Free it */
-       pj_free(projection);
-
-       /* Remove the hash entry as it is no longer needed */
-       DeletePJHashEntry(context);
-}
-
 static void
 PROJ4SRSCacheReset(MemoryContext context)
 {
@@ -196,6 +178,38 @@ PROJ4SRSCacheCheck(MemoryContext context)
 }
 #endif
 
+#endif
+
+
+static void
+#if POSTGIS_PGSQL_VERSION < 96
+PROJ4SRSCacheDelete(MemoryContext context)
+{
+       projPJ projection;
+       /* Lookup the projPJ pointer in the global hash table so we can free it */
+       projection = GetPJHashEntry(context);
+#else  /** to use built-in memory context we need to provide our delete hook in a form suitable for callback **/
+PROJ4SRSCacheDelete(void *arg)
+{
+       PJHashEntry *he = (PJHashEntry *) arg;
+       projPJ projection = he->projection;
+       MemoryContext context;
+       if (projection)
+               context = he->ProjectionContext;
+
+#endif
+       if (!projection)
+               elog(ERROR, "PROJ4SRSCacheDelete: Trying to delete non-existant projection object with MemoryContext key (%p)", (void *)context);
+
+       POSTGIS_DEBUGF(3, "deleting projection object (%p) with MemoryContext key (%p)", projection, context);
+
+       /* Free it */
+       pj_free(projection);
+
+       /* Remove the hash entry as it is no longer needed */
+       DeletePJHashEntry(context);
+}
+
 
 /*
  * PROJ4 projPJ Hash Table functions
@@ -546,11 +560,20 @@ AddToPROJ4SRSCache(PROJ4PortalCache *PROJ4Cache, int srid, int other_srid)
         * store it in the backend hash
         */
        POSTGIS_DEBUGF(3, "adding SRID %d with proj4text \"%s\" to query cache at index %d", srid, proj_str, PROJ4Cache->PROJ4SRSCacheCount);
-
+#if POSTGIS_PGSQL_VERSION < 96
        PJMemoryContext = MemoryContextCreate(T_AllocSetContext, 8192,
-                                             &PROJ4SRSCacheContextMethods,
-                                             PROJ4Cache->PROJ4SRSCacheContext,
-                                             "PostGIS PROJ4 PJ Memory Context");
+                                                                                       &PROJ4SRSCacheContextMethods,
+                                                                                       PROJ4Cache->PROJ4SRSCacheContext,
+                                                                                       "PostGIS PROJ4 PJ Memory Context");
+#else
+/** TODO: Verify that CacheMemoryContext is best.  I originally tried PortalMemoryContext
+ * as suggested on pg-hackers, but that caused failures in delete of hash entries,
+ * I presume because PortalMemory was sometimes cleaned before delete happened.  **/
+       PJMemoryContext = AllocSetContextCreate(CacheMemoryContext,
+                                                                                        "PostGIS PROJ4 PJ Memory Context",
+                                                                                        ALLOCSET_SMALL_SIZES);
+
+#endif
 
        /* Create the backend hash if it doesn't already exist */
        if (!PJHash)
@@ -564,6 +587,25 @@ AddToPROJ4SRSCache(PROJ4PortalCache *PROJ4Cache, int srid, int other_srid)
 
        AddPJHashEntry(PJMemoryContext, projection);
 
+       /* Register cleanup callback only for PostgreSQL where
+        * we are using built-in context instead of our own
+        */
+       #if POSTGIS_PGSQL_VERSION >= 96
+       /* The hash key is the MemoryContext pointer */
+       void **key;
+       key = (void *)&PJMemoryContext;
+       /** We need to do this because GetPJHashEntry returns the projection
+        * and NOT the entry as the name would lead you to believe **/
+       PJHashEntry *he;
+
+       /* Return the projection object from the hash */
+       he = (PJHashEntry *) hash_search(PJHash, key, HASH_FIND, NULL);
+       he->callback.func = PROJ4SRSCacheDelete;
+       he->callback.arg = (void *) he;
+       MemoryContextRegisterResetCallback(he->ProjectionContext,
+                                                                               &he->callback);
+       #endif
+
        PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].srid = srid;
        PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection = projection;
        PROJ4Cache->PROJ4SRSCache[PROJ4Cache->PROJ4SRSCacheCount].projection_mcxt = PJMemoryContext;
index 3f0b9ccf1d6f07e59f28f5aaa5ca3fcff1829e8e..a5f260e191a5ca6e720115229fb156008224d71d 100644 (file)
@@ -79,11 +79,14 @@ static HTAB* PrepGeomHash = NULL;
 
 #define PREPARED_BACKEND_HASH_SIZE     32
 
-typedef struct
+typedef struct PrepGeomHashEntry
 {
        MemoryContext context;
        const GEOSPreparedGeometry* prepared_geom;
        const GEOSGeometry* geom;
+#if POSTGIS_PGSQL_VERSION >= 96
+       MemoryContextCallback callback; /* for releasing hashentry when done */
+#endif
 }
 PrepGeomHashEntry;
 
@@ -94,22 +97,25 @@ static void AddPrepGeomHashEntry(PrepGeomHashEntry pghe);
 static PrepGeomHashEntry *GetPrepGeomHashEntry(MemoryContext mcxt);
 static void DeletePrepGeomHashEntry(MemoryContext mcxt);
 
-/* Memory context cache function prototypes */
+#if POSTGIS_PGSQL_VERSION < 96
+static void PreparedCacheDelete(MemoryContext context);
+#else
+static void  PreparedCacheDelete(void *arg);
+#endif
+/* Memory context cache function prototypes
+Only need for PostgreSQL where we will not be using a built-in memory context*/
+#if POSTGIS_PGSQL_VERSION < 96
 static void PreparedCacheInit(MemoryContext context);
 static void PreparedCacheReset(MemoryContext context);
-static void PreparedCacheDelete(MemoryContext context);
+
 static bool PreparedCacheIsEmpty(MemoryContext context);
-#if POSTGIS_PGSQL_VERSION >= 96
-static void PreparedCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals);
-#else
+
 static void PreparedCacheStats(MemoryContext context, int level);
-#endif
 
 #ifdef MEMORY_CONTEXT_CHECKING
 static void PreparedCacheCheck(MemoryContext context);
 #endif
 
-/* Memory context definition must match the current version of PostgreSQL */
 static MemoryContextMethods PreparedCacheContextMethods =
 {
        NULL,
@@ -135,28 +141,6 @@ PreparedCacheInit(MemoryContext context)
         */
 }
 
-static void
-PreparedCacheDelete(MemoryContext context)
-{
-       PrepGeomHashEntry* pghe;
-
-       /* Lookup the hash entry pointer in the global hash table so we can free it */
-       pghe = GetPrepGeomHashEntry(context);
-
-       if (!pghe)
-               elog(ERROR, "PreparedCacheDelete: Trying to delete non-existant hash entry object with MemoryContext key (%p)", (void *)context);
-
-       POSTGIS_DEBUGF(3, "deleting geom object (%p) and prepared geom object (%p) with MemoryContext key (%p)", pghe->geom, pghe->prepared_geom, context);
-
-       /* Free them */
-       if ( pghe->prepared_geom )
-               GEOSPreparedGeom_destroy( pghe->prepared_geom );
-       if ( pghe->geom )
-               GEOSGeom_destroy( (GEOSGeometry *)pghe->geom );
-
-       /* Remove the hash entry as it is no longer needed */
-       DeletePrepGeomHashEntry(context);
-}
 
 static void
 PreparedCacheReset(MemoryContext context)
@@ -178,11 +162,7 @@ PreparedCacheIsEmpty(MemoryContext context)
 }
 
 static void
-#if POSTGIS_PGSQL_VERSION >= 96
-PreparedCacheStats(MemoryContext context, int level, bool print, MemoryContextCounters *totals)
-#else
 PreparedCacheStats(MemoryContext context, int level)
-#endif
 {
        /*
         * Simple stats display function - we must supply a function since this call is mandatory according to tgl
@@ -202,6 +182,40 @@ PreparedCacheCheck(MemoryContext context)
         */
 }
 #endif
+#endif
+
+
+
+static void
+#if POSTGIS_PGSQL_VERSION < 96
+PreparedCacheDelete(MemoryContext context)
+{
+       PrepGeomHashEntry* pghe;
+       /* Lookup the hash entry pointer in the global hash table so we can free it */
+       pghe = GetPrepGeomHashEntry(context);
+#else  /** to use built-in memory context we need to provide our delete hook in a form suitable for callback **/
+PreparedCacheDelete(void *arg)
+{
+       PrepGeomHashEntry *pghe =  (PrepGeomHashEntry *) arg;
+       MemoryContext context;
+       if (pghe)
+               context = pghe->context;
+#endif
+       if (!pghe)
+               elog(ERROR, "PreparedCacheDelete: Trying to delete non-existant hash entry object with MemoryContext key (%p)", (void *)context);
+
+       POSTGIS_DEBUGF(3, "deleting geom object (%p) and prepared geom object (%p) with MemoryContext key (%p)", pghe->geom, pghe->prepared_geom, context);
+
+       /* Free them */
+       if ( pghe->prepared_geom )
+               GEOSPreparedGeom_destroy( pghe->prepared_geom );
+       if ( pghe->geom )
+               GEOSGeom_destroy( (GEOSGeometry *)pghe->geom );
+
+       /* Remove the hash entry as it is no longer needed */
+       DeletePrepGeomHashEntry(context);
+}
+
 
 /* TODO: put this in common are for both transform and prepared
 ** mcxt_ptr_hash
@@ -307,7 +321,6 @@ PrepGeomCacheBuilder(const LWGEOM *lwgeom, GeomCache *cache)
 {
        PrepGeomCache* prepcache = (PrepGeomCache*)cache;
        PrepGeomHashEntry* pghe;
-
        /*
        * First time through? allocate the global hash.
        */
@@ -319,11 +332,26 @@ PrepGeomCacheBuilder(const LWGEOM *lwgeom, GeomCache *cache)
        */
        if ( ! prepcache->context_callback )
        {
+               /** TODO: This is yucky that we are reusing the same variable name
+                * we used as a global pointer above, as a local variable.  We should reconsider this.
+                * Took me a while to realize they weren't the same. **/
                PrepGeomHashEntry pghe;
-               prepcache->context_callback = MemoryContextCreate(T_AllocSetContext, 8192,
-                                            &PreparedCacheContextMethods,
-                                            prepcache->context_statement,
-                                            "PostGIS Prepared Geometry Context");
+               #if POSTGIS_PGSQL_VERSION < 96
+                       prepcache->context_callback = MemoryContextCreate(T_AllocSetContext, 8192,
+                                                                                       &PreparedCacheContextMethods,
+                                                                                       prepcache->context_statement,
+                                                                                       "PostGIS Prepared Geometry Context");
+               #else
+/**For 9.5+ we can use a PostgreSQL context instead of creating our own and add a delete callback to it.
+ * TODO: change so not just PostgreSQL 11 goes thru this loop **/
+/** TODO: Verify that CacheMemoryContext is best.  I originally tried PortalMemoryContext
+ * as suggested on pg-hackers, but that caused failures in delete of hash entries,
+ * I presume because PortalMemory was sometimes cleaned before delete happened.  **/
+                       prepcache->context_callback = AllocSetContextCreate(CacheMemoryContext,
+                                                                                        "PostGIS PROJ4 PJ Memory Context",
+                                                                                       ALLOCSET_SMALL_SIZES
+                       );
+               #endif
                pghe.context = prepcache->context_callback;
                pghe.geom = 0;
                pghe.prepared_geom = 0;
@@ -361,6 +389,15 @@ PrepGeomCacheBuilder(const LWGEOM *lwgeom, GeomCache *cache)
        * extra references in a global hash object.
        */
        pghe = GetPrepGeomHashEntry(prepcache->context_callback);
+
+       #if POSTGIS_PGSQL_VERSION >= 96
+       /* Immediately register cleanup callback only for PostgreSQL where
+        we are using built in context instead of our own  */
+       pghe->callback.func = PreparedCacheDelete;
+       pghe->callback.arg = (void *) pghe;
+       MemoryContextRegisterResetCallback(pghe->context,
+                                                                               &pghe->callback);
+       #endif
        if ( ! pghe )
        {
                lwpgerror("PrepGeomCacheBuilder failed to find hash entry for context %p", prepcache->context_callback);
@@ -370,6 +407,8 @@ PrepGeomCacheBuilder(const LWGEOM *lwgeom, GeomCache *cache)
        pghe->geom = prepcache->geom;
        pghe->prepared_geom = prepcache->prepared_geom;
 
+
+
        return LW_SUCCESS;
 }