[postgis-tickets] r14524 - Fix crash on splitting edge defining multiple TopoGeometries
Sandro Santilli
strk at keybit.net
Sat Dec 26 05:54:55 PST 2015
Author: strk
Date: 2015-12-26 05:54:55 -0800 (Sat, 26 Dec 2015)
New Revision: 14524
Modified:
branches/2.2/NEWS
branches/2.2/topology/postgis_topology.c
branches/2.2/topology/test/regress/st_modedgesplit.sql
branches/2.2/topology/test/regress/st_modedgesplit_expected
branches/2.2/topology/test/regress/st_newedgessplit.sql
branches/2.2/topology/test/regress/st_newedgessplit_expected
Log:
Fix crash on splitting edge defining multiple TopoGeometries
Closes #3407
Modified: branches/2.2/NEWS
===================================================================
--- branches/2.2/NEWS 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/NEWS 2015-12-26 13:54:55 UTC (rev 14524)
@@ -20,6 +20,8 @@
- #3388, Fix missing end-points in ST_Removepoints
- #3393, ST_Area NaN for some polygons
- #3404, ST_ClusterWithin crashes backend
+ - #3407, Fix crash on splitting a face or an edge
+ defining multiple TopoGeometry objects
- Fix memory leak in lwt_ChangeEdgeGeom [liblwgeom]
Modified: branches/2.2/topology/postgis_topology.c
===================================================================
--- branches/2.2/topology/postgis_topology.c 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/topology/postgis_topology.c 2015-12-26 13:54:55 UTC (rev 14524)
@@ -1903,50 +1903,60 @@
}
ntopogeoms = SPI_processed;
- for ( i=0; i<ntopogeoms; ++i )
+ if ( ntopogeoms )
{
- HeapTuple row = SPI_tuptable->vals[i];
- TupleDesc tdesc = SPI_tuptable->tupdesc;
- int negate;
- int element_id;
- int topogeo_id;
- int layer_id;
- int element_type;
+ resetStringInfo(sql);
+ appendStringInfo(sql, "INSERT INTO \"%s\".relation VALUES ", topo->name);
+ for ( i=0; i<ntopogeoms; ++i )
+ {
+ HeapTuple row = SPI_tuptable->vals[i];
+ TupleDesc tdesc = SPI_tuptable->tupdesc;
+ int negate;
+ int element_id;
+ int topogeo_id;
+ int layer_id;
+ int element_type;
- if ( ! getNotNullInt32( row, tdesc, 1, &element_id ) ) {
- cberror(topo->be_data,
- "unexpected null element_id in \"%s\".relation",
- topo->name);
- return 0;
- }
- negate = ( element_id < 0 );
+ if ( ! getNotNullInt32( row, tdesc, 1, &element_id ) ) {
+ cberror(topo->be_data,
+ "unexpected null element_id in \"%s\".relation",
+ topo->name);
+ return 0;
+ }
+ negate = ( element_id < 0 );
- if ( ! getNotNullInt32( row, tdesc, 2, &topogeo_id ) ) {
- cberror(topo->be_data,
- "unexpected null topogeo_id in \"%s\".relation",
- topo->name);
- return 0;
- }
+ if ( ! getNotNullInt32( row, tdesc, 2, &topogeo_id ) ) {
+ cberror(topo->be_data,
+ "unexpected null topogeo_id in \"%s\".relation",
+ topo->name);
+ return 0;
+ }
- if ( ! getNotNullInt32( row, tdesc, 3, &layer_id ) ) {
- cberror(topo->be_data,
- "unexpected null layer_id in \"%s\".relation",
- topo->name);
- return 0;
- }
+ if ( ! getNotNullInt32( row, tdesc, 3, &layer_id ) ) {
+ cberror(topo->be_data,
+ "unexpected null layer_id in \"%s\".relation",
+ topo->name);
+ return 0;
+ }
- if ( ! getNotNullInt32( row, tdesc, 4, &element_type ) ) {
- cberror(topo->be_data,
- "unexpected null element_type in \"%s\".relation",
- topo->name);
- return 0;
- }
+ if ( ! getNotNullInt32( row, tdesc, 4, &element_type ) ) {
+ cberror(topo->be_data,
+ "unexpected null element_type in \"%s\".relation",
+ topo->name);
+ return 0;
+ }
- resetStringInfo(sql);
- appendStringInfo(sql,
- "INSERT INTO \"%s\".relation VALUES ("
- "%d,%d,%" LWTFMT_ELEMID ",%d)", topo->name,
- topogeo_id, layer_id, negate ? -new_edge1 : new_edge1, element_type);
+ if ( i ) appendStringInfoChar(sql, ',');
+ appendStringInfo(sql, "(%d,%d,%" LWTFMT_ELEMID ",%d)",
+ topogeo_id, layer_id, negate ? -new_edge1 : new_edge1, element_type);
+ if ( new_edge2 != -1 ) {
+ resetStringInfo(sql);
+ appendStringInfo(sql,
+ ",VALUES (%d,%d,%" LWTFMT_ELEMID ",%d",
+ topogeo_id, layer_id, negate ? -new_edge2 : new_edge2, element_type);
+ }
+ }
+ POSTGIS_DEBUGF(1, "cb_updateTopoGeomEdgeSplit query: %s", sql->data);
spi_result = SPI_execute(sql->data, false, 0);
MemoryContextSwitchTo( oldcontext ); /* switch back */
if ( spi_result != SPI_OK_INSERT ) {
@@ -1956,28 +1966,11 @@
return 0;
}
if ( SPI_processed ) topo->be_data->data_changed = true;
- if ( new_edge2 != -1 ) {
- resetStringInfo(sql);
- appendStringInfo(sql,
- "INSERT INTO FROM \"%s\".relation VALUES ("
- "%d,%d,%" LWTFMT_ELEMID ",%d", topo->name,
- topogeo_id, layer_id, negate ? -new_edge2 : new_edge2, element_type);
- spi_result = SPI_execute(sql->data, false, 0);
- MemoryContextSwitchTo( oldcontext ); /* switch back */
- if ( spi_result != SPI_OK_INSERT ) {
- cberror(topo->be_data, "unexpected return (%d) from query execution: %s",
- spi_result, sql->data);
- pfree(sqldata.data);
- return 0;
- }
- if ( SPI_processed ) topo->be_data->data_changed = true;
- }
}
- /* TODO: release string info ! */
-
POSTGIS_DEBUGF(1, "cb_updateTopoGeomEdgeSplit: updated %d topogeoms", ntopogeoms);
+ pfree(sqldata.data);
return 1;
}
Modified: branches/2.2/topology/test/regress/st_modedgesplit.sql
===================================================================
--- branches/2.2/topology/test/regress/st_modedgesplit.sql 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/topology/test/regress/st_modedgesplit.sql 2015-12-26 13:54:55 UTC (rev 14524)
@@ -92,12 +92,30 @@
SELECT 'closed', ST_ModEdgeSplit('city_data', 1, 'SRID=4326;POINT(3 38)');
SELECT check_changes();
+--
+-- Split an edge referenced by multiple TopoGeometries
+--
+-- See https://trac.osgeo.org/postgis/ticket/3407
+--
+CREATE TABLE city_data.fl(id varchar);
+SELECT 'L' || topology.AddTopoGeometryColumn('city_data',
+ 'city_data', 'fl', 'g', 'LINESTRING');
+INSERT INTO city_data.fl VALUES
+ ('E7.1', topology.CreateTopoGeom('city_data', 2, 1, '{{7,2}}')),
+ ('E7.2', topology.CreateTopoGeom('city_data', 2, 1, '{{7,2}}'));
+SELECT '#3407', ST_ModEdgeSplit('city_data', 7, 'SRID=4326;POINT(28 22)');
+SELECT check_changes();
+
-- Robustness of edge splitting (#1711)
-- clean all up first
DELETE FROM city_data.edge_data;
DELETE FROM city_data.node;
DELETE FROM city_data.face where face_id > 0;
+SELECT 'seq_reset',
+ setval('city_data.edge_data_edge_id_seq', 1, false),
+ setval('city_data.face_face_id_seq', 1, false),
+ setval('city_data.node_node_id_seq', 1, false);
CREATE TEMP TABLE t AS
SELECT
Modified: branches/2.2/topology/test/regress/st_modedgesplit_expected
===================================================================
--- branches/2.2/topology/test/regress/st_modedgesplit_expected 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/topology/test/regress/st_modedgesplit_expected 2015-12-26 13:54:55 UTC (rev 14524)
@@ -33,11 +33,12 @@
N|27||POINT(3 38)
E|1|sn1|en27|nl31|nr-31|lf1|rf0
E|31|sn27|en1|nl1|nr-1|lf1|rf0
-robust.1|E32|N30
-N|28||POINT(20 10)
-N|29||POINT(10 20)
-N|30||POINT(9 12)
-E|32|sn28|en30|nl33|nr32|lf0|rf0
-E|33|sn30|en29|nl-33|nr-32|lf0|rf0
+L1
+#3407|28
+N|28||POINT(28 22)
+E|7|sn17|en28|nl32|nr-19|lf0|rf4
+E|32|sn28|en18|nl8|nr-7|lf0|rf4
+seq_reset|1|1|1
+robust.1|E1|N3
robust.2|t|t
Topology 'city_data' dropped
Modified: branches/2.2/topology/test/regress/st_newedgessplit.sql
===================================================================
--- branches/2.2/topology/test/regress/st_newedgessplit.sql 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/topology/test/regress/st_newedgessplit.sql 2015-12-26 13:54:55 UTC (rev 14524)
@@ -92,12 +92,30 @@
SELECT 'closed', ST_NewEdgesSplit('city_data', 1, 'SRID=4326;POINT(3 38)');
SELECT check_changes();
+--
+-- Split an edge referenced by multiple TopoGeometries
+--
+-- See https://trac.osgeo.org/postgis/ticket/3407
+--
+CREATE TABLE city_data.fl(id varchar);
+SELECT 'L' || topology.AddTopoGeometryColumn('city_data',
+ 'city_data', 'fl', 'g', 'LINESTRING');
+INSERT INTO city_data.fl VALUES
+ ('E7.1', topology.CreateTopoGeom('city_data', 2, 1, '{{7,2}}')),
+ ('E7.2', topology.CreateTopoGeom('city_data', 2, 1, '{{7,2}}'));
+SELECT '#3407', ST_ModEdgeSplit('city_data', 7, 'SRID=4326;POINT(28 22)');
+SELECT check_changes();
+
-- Robustness of edge splitting (#1711)
-- clean all up first
DELETE FROM city_data.edge_data;
DELETE FROM city_data.node;
DELETE FROM city_data.face where face_id > 0;
+SELECT 'seq_reset',
+ setval('city_data.edge_data_edge_id_seq', 1, false),
+ setval('city_data.face_face_id_seq', 1, false),
+ setval('city_data.node_node_id_seq', 1, false);
CREATE TEMP TABLE t AS
SELECT
Modified: branches/2.2/topology/test/regress/st_newedgessplit_expected
===================================================================
--- branches/2.2/topology/test/regress/st_newedgessplit_expected 2015-12-26 12:49:41 UTC (rev 14523)
+++ branches/2.2/topology/test/regress/st_newedgessplit_expected 2015-12-26 13:54:55 UTC (rev 14524)
@@ -33,11 +33,12 @@
N|27||POINT(3 38)
E|35|sn1|en27|nl36|nr-36|lf1|rf0
E|36|sn27|en1|nl35|nr-35|lf1|rf0
-robust.1|E37|N30
-N|28||POINT(20 10)
-N|29||POINT(10 20)
-N|30||POINT(9 12)
-E|38|sn28|en30|nl39|nr38|lf0|rf0
-E|39|sn30|en29|nl-39|nr-38|lf0|rf0
+L1
+#3407|28
+N|28||POINT(28 22)
+E|7|sn17|en28|nl37|nr-19|lf0|rf4
+E|37|sn28|en18|nl8|nr-7|lf0|rf4
+seq_reset|1|1|1
+robust.1|E1|N3
robust.2|t|t
Topology 'city_data' dropped
More information about the postgis-tickets
mailing list