[postgis-tickets] r15113 - Early release memory used by SPI executed topology callback queries

Sandro Santilli strk at kbt.io
Fri Sep 16 02:16:48 PDT 2016


Author: strk
Date: 2016-09-16 02:16:48 -0700 (Fri, 16 Sep 2016)
New Revision: 15113

Modified:
   trunk/topology/postgis_topology.c
Log:
Early release memory used by SPI executed topology callback queries

Modified: trunk/topology/postgis_topology.c
===================================================================
--- trunk/topology/postgis_topology.c	2016-09-15 02:57:21 UTC (rev 15112)
+++ trunk/topology/postgis_topology.c	2016-09-16 09:16:48 UTC (rev 15113)
@@ -203,6 +203,7 @@
   dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
   if ( isnull ) {
 		cberror(be, "Topology '%s' has null identifier", name);
+    SPI_freetuptable(SPI_tuptable);
     return NULL;
   }
   topo->id = DatumGetInt32(dat);
@@ -210,6 +211,7 @@
   dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 2, &isnull);
   if ( isnull ) {
 		cberror(be, "Topology '%s' has null SRID", name);
+    SPI_freetuptable(SPI_tuptable);
     return NULL;
   }
   topo->srid = DatumGetInt32(dat);
@@ -235,6 +237,8 @@
                     "id %d, srid %d, precision %g",
              name, topo->id, topo->srid, topo->precision);
 
+  SPI_freetuptable(SPI_tuptable);
+
   return topo;
 }
 
@@ -594,6 +598,7 @@
   Datum dat;
   int val;
   GSERIALIZED *geom;
+  LWGEOM *lwg;
   int colno = 0;
 
   POSTGIS_DEBUGF(2, "fillEdgeFields: got %d atts and fields %x",
@@ -687,10 +692,16 @@
   }
   if ( fields & LWT_COL_EDGE_GEOM ) {
     dat = SPI_getbinval(row, rowdesc, ++colno, &isnull);
-    if ( ! isnull ) {
-      geom = (GSERIALIZED *)PG_DETOAST_DATUM_COPY(dat);
-      edge->geom = lwgeom_as_lwline(lwgeom_from_gserialized(geom));
-    } else {
+    if ( ! isnull ) {{
+      MemoryContext oldcontext = CurrentMemoryContext;
+      geom = (GSERIALIZED *)PG_DETOAST_DATUM(dat);
+      lwg = lwgeom_from_gserialized(geom);
+      MemoryContextSwitchTo( TopMemoryContext );
+      edge->geom = lwgeom_as_lwline(lwgeom_clone_deep(lwg));
+      MemoryContextSwitchTo( oldcontext ); /* switch back */
+      lwgeom_free(lwg);
+      if ( DatumGetPointer(dat) != (Pointer)geom ) pfree(geom); /* IF_COPY */
+    }} else {
       lwpgwarning("Found edge with NULL geometry !");
       edge->geom = NULL;
     }
@@ -703,6 +714,7 @@
   bool isnull;
   Datum dat;
   GSERIALIZED *geom;
+  LWGEOM *lwg;
   int colno = 0;
 
   if ( fields & LWT_COL_NODE_NODE_ID ) {
@@ -717,8 +729,11 @@
   if ( fields & LWT_COL_NODE_GEOM ) {
     dat = SPI_getbinval(row, rowdesc, ++colno, &isnull);
     if ( ! isnull ) {
-      geom = (GSERIALIZED *)PG_DETOAST_DATUM_COPY(dat);
-      node->geom = lwgeom_as_lwpoint(lwgeom_from_gserialized(geom));
+      geom = (GSERIALIZED *)PG_DETOAST_DATUM(dat);
+      lwg = lwgeom_from_gserialized(geom);
+      node->geom = lwgeom_as_lwpoint(lwgeom_clone_deep(lwg));
+      lwgeom_free(lwg);
+      if ( DatumGetPointer(dat) != (Pointer)geom ) pfree(geom); /* IF_COPY */
     } else {
       lwpgnotice("Found node with NULL geometry !");
       node->geom = NULL;
@@ -744,7 +759,7 @@
     dat = SPI_getbinval(row, rowdesc, ++colno, &isnull);
     if ( ! isnull ) {
       /* NOTE: this is a geometry of which we want to take (and clone) the BBOX */
-      geom = (GSERIALIZED *)PG_DETOAST_DATUM_COPY(dat);
+      geom = (GSERIALIZED *)PG_DETOAST_DATUM(dat);
       g = lwgeom_from_gserialized(geom);
       box = lwgeom_get_bbox(g);
       if ( box ) {
@@ -753,6 +768,8 @@
         lwpgnotice("Found face with EMPTY MBR !");
         face->mbr = NULL;
       }
+      lwgeom_free(g);
+      if ( DatumGetPointer(dat) != (Pointer)geom ) pfree(geom);
     } else {
       /* NOTE: perfectly fine for universe face */
       POSTGIS_DEBUG(1, "Found face with NULL MBR");
@@ -819,6 +836,8 @@
     fillEdgeFields(&edges[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -875,6 +894,8 @@
     fillEdgeFields(&edges[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -951,6 +972,8 @@
     fillEdgeFields(&edges[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -1001,6 +1024,8 @@
     fillFaceFields(&faces[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return faces;
 }
 
@@ -1075,6 +1100,8 @@
                       " is edge %d", i, edge, val);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -1123,6 +1150,8 @@
     fillNodeFields(&nodes[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return nodes;
 }
 
@@ -1179,6 +1208,8 @@
     fillNodeFields(&nodes[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return nodes;
 }
 
@@ -1247,6 +1278,9 @@
       *numelems = exists ? 1 : 0;
       POSTGIS_DEBUGF(1, "cb_getEdgeWithinDistance2D: exists ? %d", *numelems);
     }
+
+    SPI_freetuptable(SPI_tuptable);
+
     return NULL;
   }
 
@@ -1257,6 +1291,8 @@
     fillEdgeFields(&edges[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -1330,6 +1366,9 @@
       exists = DatumGetBool(dat);
       *numelems = exists ? 1 : 0;
     }
+
+    SPI_freetuptable(SPI_tuptable);
+
     return NULL;
   }
   else
@@ -1341,6 +1380,9 @@
       fillNodeFields(&nodes[i], row, SPI_tuptable->tupdesc, fields);
     }
     *numelems = SPI_processed;
+
+    SPI_freetuptable(SPI_tuptable);
+
     return nodes;
   }
 }
@@ -1395,6 +1437,8 @@
       SPI_tuptable->tupdesc, LWT_COL_NODE_NODE_ID);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return 1;
 }
 
@@ -1452,6 +1496,8 @@
     }
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return SPI_processed;
 }
 
@@ -1508,6 +1554,8 @@
     }
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return SPI_processed;
 }
 
@@ -1867,6 +1915,9 @@
 	  return -1;
   }
   edge_id = DatumGetInt64(dat); /* sequences return 64bit integers */
+
+  SPI_freetuptable(SPI_tuptable);
+
   return edge_id;
 }
 
@@ -1966,6 +2017,9 @@
           topogeo_id, layer_id, negate ? -new_edge2 : new_edge2, element_type);
       }
     }
+
+    SPI_freetuptable(SPI_tuptable);
+
     POSTGIS_DEBUGF(1, "cb_updateTopoGeomEdgeSplit query: %s", sql->data);
     spi_result = SPI_execute(sql->data, false, 0);
     MemoryContextSwitchTo( oldcontext ); /* switch back */
@@ -2086,6 +2140,8 @@
       }
     }
 
+    SPI_freetuptable(SPI_tuptable);
+
     POSTGIS_DEBUGF(1, "cb_updateTopoGeomFaceSplit query: %s", sql->data);
     spi_result = SPI_execute(sql->data, false, 0);
     MemoryContextSwitchTo( oldcontext ); /* switch back */
@@ -2095,6 +2151,7 @@
       pfree(sqldata.data);
       return 0;
     }
+
     if ( SPI_processed ) topo->be_data->data_changed = true;
   }
 
@@ -2150,6 +2207,8 @@
     table_name = SPI_getvalue(row, tdesc, 4);
     col_name = SPI_getvalue(row, tdesc, 5);
 
+    SPI_freetuptable(SPI_tuptable);
+
     cberror(topo->be_data, "TopoGeom %s in layer %s "
                            "(%s.%s.%s) cannot be represented "
                            "dropping edge %" LWTFMT_ELEMID,
@@ -2206,6 +2265,8 @@
       table_name = SPI_getvalue(row, tdesc, 4);
       col_name = SPI_getvalue(row, tdesc, 5);
 
+      SPI_freetuptable(SPI_tuptable);
+
       cberror(topo->be_data, "TopoGeom %s in layer %s "
                              "(%s.%s.%s) cannot be represented "
                              "healing faces %" LWTFMT_ELEMID
@@ -2268,6 +2329,8 @@
     table_name = SPI_getvalue(row, tdesc, 4);
     col_name = SPI_getvalue(row, tdesc, 5);
 
+    SPI_freetuptable(SPI_tuptable);
+
     cberror(topo->be_data, "TopoGeom %s in layer %s "
                            "(%s.%s.%s) cannot be represented "
                            "healing edges %" LWTFMT_ELEMID
@@ -2493,10 +2556,12 @@
   dat = SPI_getbinval( SPI_tuptable->vals[0],
                        SPI_tuptable->tupdesc, 1, &isnull );
   if ( isnull ) {
+    SPI_freetuptable(SPI_tuptable);
 		cberror(topo->be_data, "corrupted topology: face with NULL face_id");
 	  return -2;
   }
   face_id = DatumGetInt32(dat);
+  SPI_freetuptable(SPI_tuptable);
   return face_id;
 }
 
@@ -2631,6 +2696,7 @@
       bool isnull, exists;
       dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
       exists = DatumGetBool(dat);
+      SPI_freetuptable(SPI_tuptable);
       *numelems = exists ? 1 : 0;
       POSTGIS_DEBUGF(1, "cb_getNodeWithinBox2D: exists ? %d", *numelems);
     }
@@ -2644,6 +2710,8 @@
     fillNodeFields(&nodes[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return nodes;
 }
 
@@ -2704,6 +2772,7 @@
       dat = SPI_getbinval(SPI_tuptable->vals[0], SPI_tuptable->tupdesc, 1, &isnull);
       exists = DatumGetBool(dat);
       *numelems = exists ? 1 : 0;
+      SPI_freetuptable(SPI_tuptable);
       POSTGIS_DEBUGF(1, "cb_getEdgeWithinBox2D: exists ? %d", *numelems);
     }
     return NULL;
@@ -2716,6 +2785,8 @@
     fillEdgeFields(&edges[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return edges;
 }
 
@@ -2778,6 +2849,9 @@
       *numelems = exists ? 1 : 0;
       POSTGIS_DEBUGF(1, "cb_getFaceWithinBox2D: exists ? %d", *numelems);
     }
+
+    SPI_freetuptable(SPI_tuptable);
+
     return NULL;
   }
 
@@ -2788,6 +2862,8 @@
     fillFaceFields(&faces[i], row, SPI_tuptable->tupdesc, fields);
   }
 
+  SPI_freetuptable(SPI_tuptable);
+
   return faces;
 }
 



More information about the postgis-tickets mailing list