[GRASS-SVN] r58313 - grass/trunk/lib/vector/Vlib
svn_grass at osgeo.org
svn_grass at osgeo.org
Tue Nov 26 12:43:04 PST 2013
Author: martinl
Date: 2013-11-26 12:43:03 -0800 (Tue, 26 Nov 2013)
New Revision: 58313
Modified:
grass/trunk/lib/vector/Vlib/build_pg.c
grass/trunk/lib/vector/Vlib/read_pg.c
grass/trunk/lib/vector/Vlib/write_pg.c
Log:
vlib/pg: speed-up topology building - make all constraints deferrable
Modified: grass/trunk/lib/vector/Vlib/build_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_pg.c 2013-11-26 14:17:41 UTC (rev 58312)
+++ grass/trunk/lib/vector/Vlib/build_pg.c 2013-11-26 20:43:03 UTC (rev 58313)
@@ -172,6 +172,8 @@
if (Vect__execute_pg(pg_info->conn, "BEGIN"))
return 0;
+ Vect__execute_pg(pg_info->conn, "SET CONSTRAINTS ALL DEFERRED");
+
/* write full node topo info to DB if requested */
if (!pg_info->topo_geo_only) {
write_nodes(plus, pg_info);
@@ -390,7 +392,7 @@
pg_info->schema_name, pg_info->table_name,
pg_info->topogeom_column, pg_info->toposchema_id,
topo_id, topogeom_type, pg_info->topogeom_column, fid);
-
+
return 1;
}
Modified: grass/trunk/lib/vector/Vlib/read_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read_pg.c 2013-11-26 14:17:41 UTC (rev 58312)
+++ grass/trunk/lib/vector/Vlib/read_pg.c 2013-11-26 20:43:03 UTC (rev 58313)
@@ -1485,7 +1485,8 @@
if (!result || PQresultStatus(result) != PGRES_COMMAND_OK) {
PQclear(result);
- G_warning(_("Execution failed: %s"), PQerrorMessage(conn));
+ G_warning(_("Execution failed: %s\nReason: %s"), stmt,
+ PQerrorMessage(conn));
return -1;
}
@@ -1515,7 +1516,8 @@
PQntuples(result) != 1) {
PQclear(result);
- G_warning(_("Execution failed: %s"), PQerrorMessage(conn));
+ G_warning(_("Execution failed: %s\nReason: %s"), stmt,
+ PQerrorMessage(conn));
return -1;
}
Modified: grass/trunk/lib/vector/Vlib/write_pg.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_pg.c 2013-11-26 14:17:41 UTC (rev 58312)
+++ grass/trunk/lib/vector/Vlib/write_pg.c 2013-11-26 20:43:03 UTC (rev 58313)
@@ -68,6 +68,8 @@
static int update_topo_face(struct Map_info *, int);
static int add_line_to_topo_pg(struct Map_info *, off_t, int, const struct line_pnts *);
static int delete_line_from_topo_pg(struct Map_info *, int, int, const struct line_pnts *);
+static int set_constraint_to_deferrable(struct Format_info_pg *, const char *, const char *,
+ const char *, const char *, const char *);
#endif
static struct line_pnts *Points;
@@ -315,7 +317,7 @@
}
if (offset >= pg_info->offset.array_num) {
- G_warning(_("Invalid offset (%d)"), offset);
+ G_warning(_("Invalid offset (%ld)"), offset);
return -1;
}
@@ -832,16 +834,11 @@
pg_info->toposchema_name, pg_info->schema_name,
pg_info->table_name, pg_info->geom_column, tolerance,
with_z == WITH_Z ? "t" : "f");
- G_debug(2, "SQL: %s", stmt);
-
- result = PQexec(pg_info->conn, stmt);
- if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
- G_warning(_("Execution failed: %s"), PQerrorMessage(pg_info->conn));
+ pg_info->toposchema_id = Vect__execute_get_value_pg(pg_info->conn, stmt);
+ if (pg_info->toposchema_id == -1) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
}
- /* store toposchema id */
- pg_info->toposchema_id = atoi(PQgetvalue(result, 0, 0));
/* add topo column to the feature table */
G_verbose_message(_("Adding new topology column <%s>..."),
@@ -850,14 +847,32 @@
"'%s', '%s')", pg_info->toposchema_name, pg_info->schema_name,
pg_info->table_name, pg_info->topogeom_column,
get_sftype(pg_info->feature_type));
- G_debug(2, "SQL: %s", stmt);
+ if (-1 == Vect__execute_get_value_pg(pg_info->conn, stmt)) {
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
- result = PQexec(pg_info->conn, stmt);
- if (!result || PQresultStatus(result) != PGRES_TUPLES_OK) {
- G_warning(_("Execution failed: %s"), PQerrorMessage(pg_info->conn));
+ /* create index on topo column */
+ sprintf(stmt, "CREATE INDEX \"%s_%s_idx\" ON %s (((%s).id))",
+ pg_info->table_name, pg_info->topogeom_column,
+ pg_info->table_name, pg_info->topogeom_column);
+ if (-1 == Vect__execute_pg(pg_info->conn, stmt)) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
return -1;
}
+
+ /* change constraints to deferrable initially deferred */
+ if (-1 == set_constraint_to_deferrable(pg_info, "node", "face_exists",
+ "containing_face", "face", "face_id") ||
+ -1 == set_constraint_to_deferrable(pg_info, "edge_data", "end_node_exists",
+ "end_node", "node", "node_id") ||
+ -1 == set_constraint_to_deferrable(pg_info, "edge_data", "left_face_exists",
+ "left_face", "face", "face_id") ||
+ -1 == set_constraint_to_deferrable(pg_info, "edge_data", "right_face_exists",
+ "right_face", "face", "face_id") ||
+ -1 == set_constraint_to_deferrable(pg_info, "edge_data", "start_node_exists",
+ "start_node", "node", "node_id"))
+ return -1;
/* create additional tables in topological schema to store
GRASS topology in DB */
@@ -874,7 +889,8 @@
}
sprintf(stmt, "ALTER TABLE \"%s\".%s ADD CONSTRAINT node_exists "
- "FOREIGN KEY (node_id) REFERENCES \"%s\".node (node_id)",
+ "FOREIGN KEY (node_id) REFERENCES \"%s\".node (node_id) "
+ "DEFERRABLE INITIALLY DEFERRED",
pg_info->toposchema_name, TOPO_TABLE_NODE, pg_info->toposchema_name);
if (Vect__execute_pg(pg_info->conn, stmt) == -1) {
Vect__execute_pg(pg_info->conn, "ROLLBACK");
@@ -2714,4 +2730,30 @@
return 0;
}
+int set_constraint_to_deferrable(struct Format_info_pg *pg_info,
+ const char *table, const char *constraint,
+ const char *column, const char *ref_table,
+ const char *ref_column)
+{
+ char stmt[DB_SQL_MAX];
+
+ sprintf(stmt, "ALTER TABLE \"%s\".%s DROP CONSTRAINT %s",
+ pg_info->toposchema_name, table, constraint);
+ if (-1 == Vect__execute_pg(pg_info->conn, stmt)) {
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ sprintf(stmt, "ALTER TABLE \"%s\".%s ADD CONSTRAINT %s "
+ "FOREIGN KEY (%s) REFERENCES \"%s\".%s (%s) "
+ "DEFERRABLE INITIALLY DEFERRED",
+ pg_info->toposchema_name, table, constraint, column,
+ pg_info->toposchema_name, ref_table);
+ if (-1 == Vect__execute_pg(pg_info->conn, stmt)) {
+ Vect__execute_pg(pg_info->conn, "ROLLBACK");
+ return -1;
+ }
+
+ return 0;
+}
#endif
More information about the grass-commit
mailing list