[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