[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