]> granicus.if.org Git - postgis/commitdiff
Reduce calls to geometry::text during topology population (#2616)
authorSandro Santilli <strk@keybit.net>
Mon, 27 Jan 2014 11:32:20 +0000 (11:32 +0000)
committerSandro Santilli <strk@keybit.net>
Mon, 27 Jan 2014 11:32:20 +0000 (11:32 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@12194 b70326c6-7e19-0410-871a-916f4a2858ee

topology/sql/populate.sql.in
topology/sql/sqlmm.sql.in

index 657f60eb315713b5bd91f814b97ec7614a06a11c..34c0b2cfa5c75d67f39b2ef5503446fd8116a857 100644 (file)
@@ -116,9 +116,8 @@ BEGIN
        --
        FOR rec IN EXECUTE 'SELECT node_id FROM '
                || quote_ident(atopology) || '.node ' ||
-               'WHERE geom && ' || quote_literal(apoint::text) || '::geometry'
-               ||' AND ST_X(geom) = ST_X('||quote_literal(apoint::text)||'::geometry)'
-               ||' AND ST_Y(geom) = ST_Y('||quote_literal(apoint::text)||'::geometry)'
+               'WHERE geom && $1 AND ST_X(geom) = ST_X($1) AND ST_Y(geom) = ST_Y($1)'
+    USING apoint
        LOOP
                RETURN  rec.node_id;
        END LOOP;
@@ -129,13 +128,10 @@ BEGIN
        --
        FOR rec IN EXECUTE 'SELECT edge_id FROM '
                || quote_ident(atopology) || '.edge ' 
-               || 'WHERE ST_DWithin('
-               || quote_literal(apoint::text) 
-               || ', geom, 0) AND NOT ST_Equals('
-               || quote_literal(apoint::text)
-               || ', ST_StartPoint(geom)) AND NOT ST_Equals('
-               || quote_literal(apoint::text)
-               || ', ST_EndPoint(geom))'
+               || 'WHERE ST_DWithin($1, geom, 0) AND '
+    || 'NOT ST_Equals($1, ST_StartPoint(geom)) AND '
+    || 'NOT ST_Equals($1, ST_EndPoint(geom))'
+    USING apoint
        LOOP
     IF allowEdgeSplitting THEN
       RETURN ST_ModEdgeSplit(atopology, rec.edge_id, apoint);
@@ -169,8 +165,8 @@ BEGIN
        --
        EXECUTE 'INSERT INTO ' || quote_ident(atopology)
                || '.node(node_id, containing_face, geom) 
-               VALUES(' || nodeid || ',' || coalesce(containing_face::text, 'NULL') || ','
-    || quote_literal(apoint::text) || ')';
+               VALUES(' || nodeid || ',' || coalesce(containing_face::text, 'NULL')
+    || ',$1)' USING apoint;
 
        RETURN nodeid;
        
@@ -255,9 +251,8 @@ BEGIN
        --
        FOR rec IN EXECUTE 'SELECT node_id FROM '
                || quote_ident(atopology) || '.node '
-               || 'WHERE ST_Crosses('
-               || quote_literal(aline::text) || '::geometry, geom'
-               || ')'
+               || 'WHERE ST_Crosses($1, geom)'
+    USING aline
        LOOP
                RAISE EXCEPTION 'Edge crosses node %', rec.node_id;
        END LOOP;
@@ -281,14 +276,9 @@ BEGIN
        --    FF1 F0F 1F2
        --    FF1 F** 1*2 <-- our match
        --
-       FOR rec IN EXECUTE 'SELECT edge_id, geom, ST_Relate('
-               || quote_literal(aline::text)
-               || '::geometry, geom, 2) as im'
-               || ' FROM '
-               || quote_ident(atopology) || '.edge '
-               || 'WHERE '
-               || quote_literal(aline::text) || '::geometry && geom'
-
+       FOR rec IN EXECUTE 'SELECT edge_id, geom, ST_Relate($1, geom, 2) as im FROM '
+               || quote_ident(atopology) || '.edge WHERE $1 && geom'
+    USING aline
        LOOP
 
          IF ST_RelateMatch(rec.im, 'FF1F**1*2') THEN
@@ -343,16 +333,12 @@ BEGIN
                -- start_node
                || 'topology.addNode('
                || quote_literal(atopology)
-               || ', ST_StartPoint('
-               || quote_literal(aline::text)
-               || ')) ,'
+               || ', ST_StartPoint($1)), '
 
                -- end_node
                || 'topology.addNode('
                || quote_literal(atopology)
-               || ', ST_EndPoint('
-               || quote_literal(aline::text)
-               || ')) ,'
+               || ', ST_EndPoint($1)), '
 
                -- next_left_edge
                || -edgeid ||','
@@ -367,8 +353,8 @@ BEGIN
                || '0,'
 
                -- geom
-               ||quote_literal(aline::text)
-               || ')';
+               || '$1)'
+    USING aline;
 
        RETURN edgeid;
        
@@ -459,15 +445,12 @@ BEGIN
     --
     bounds = ST_Boundary(rrec.geom);
 
-    sql := 'SELECT e.geom, e.edge_id, '
-      || 'e.left_face, e.right_face FROM '
-      || quote_ident(atopology) || '.edge e, (SELECT '
-      || quote_literal(bounds::text)
-      || '::geometry as geom) r WHERE '
-      || 'r.geom && e.geom'
+    sql := 'SELECT e.geom, e.edge_id, e.left_face, e.right_face FROM '
+      || quote_ident(atopology)
+      || '.edge e, (SELECT $1 as geom) r WHERE r.geom && e.geom'
     ;
     -- RAISE DEBUG 'SQL: %', sql;
-    FOR rec IN EXECUTE sql
+    FOR rec IN EXECUTE sql USING bounds
     LOOP -- {
       --RAISE DEBUG 'Edge % has bounding box intersection', rec.edge_id;
 
@@ -612,8 +595,8 @@ BEGIN
     -- face_id
     || faceid || ','
     -- minimum bounding rectangle
-    || quote_literal(ST_Envelope(apoly)::text)
-    || ')';
+    || '$1)'
+    USING ST_Envelope(apoly);
 
   --
   -- Update all edges having this face on the left
@@ -651,9 +634,8 @@ BEGIN
     || quote_literal(faceid)
     || ', left_face = '
     || quote_literal(faceid)
-    || ' WHERE ST_Contains('
-    || quote_literal(apoly::text)
-    || ', geom)';
+    || ' WHERE ST_Contains($1, geom)'
+    USING apoly;
 
   -- 
   -- Set containing_face of any contained node 
@@ -662,9 +644,8 @@ BEGIN
     || quote_ident(atopology)
     || '.node SET containing_face = '
     || quote_literal(faceid)
-    || ' WHERE containing_face IS NOT NULL AND ST_Contains('
-    || quote_literal(apoly::text)
-    || ', geom)';
+    || ' WHERE containing_face IS NOT NULL AND ST_Contains($1, geom)'
+    USING apoly;
 
   RETURN faceid;
        
@@ -710,17 +691,13 @@ BEGIN
   --    and if so pick the closest
   sql := 'SELECT a.node_id FROM ' 
     || quote_ident(atopology) 
-    || '.node as a WHERE ST_DWithin(a.geom,'
-    || quote_literal(apoint::text) || '::geometry,'
-    || tol || ') AND ST_Distance('
-    || quote_literal(apoint::text)
-    || '::geometry, a.geom) < ' || tol || ' ORDER BY ST_Distance('
-    || quote_literal(apoint::text)
-    || '::geometry, a.geom) LIMIT 1;';
+    || '.node as a WHERE ST_DWithin(a.geom,$1,'
+    || tol || ') AND ST_Distance($1, a.geom) < ' || tol
+    || ' ORDER BY ST_Distance($1, a.geom) LIMIT 1';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO id;
+  EXECUTE sql INTO id USING apoint;
   IF id IS NOT NULL THEN
     RETURN id;
   END IF;
@@ -733,15 +710,12 @@ BEGIN
   --    and if so split it by a point projected on it
   sql := 'SELECT a.edge_id, a.geom FROM ' 
     || quote_ident(atopology) 
-    || '.edge as a WHERE ST_DWithin(a.geom,'
-    || quote_literal(apoint::text) || '::geometry,'
-    || tol || ') ORDER BY ST_Distance('
-    || quote_literal(apoint::text)
-    || '::geometry, a.geom) LIMIT 1;';
+    || '.edge as a WHERE ST_DWithin(a.geom,$1,'
+    || tol || ') ORDER BY ST_Distance($1, a.geom) LIMIT 1';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO rec;
+  EXECUTE sql INTO rec USING apoint;
   IF rec IS NOT NULL THEN
     -- project point to line, split edge by point
     prj := ST_ClosestPoint(rec.geom, apoint);
@@ -841,14 +815,12 @@ BEGIN
   -- 2. Node to edges falling within tol distance
   sql := 'WITH nearby AS ( SELECT e.geom FROM '
     || quote_ident(atopology) 
-    || '.edge e WHERE ST_DWithin(e.geom, '
-    || quote_literal(noded::text)
-    || '::geometry, '
-    || tol || ') ) SELECT st_collect(geom) FROM nearby;';
+    || '.edge e WHERE ST_DWithin(e.geom, $1,'
+    || tol || ') ) SELECT st_collect(geom) FROM nearby';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO iedges;
+  EXECUTE sql INTO iedges USING noded;
   IF iedges IS NOT NULL THEN
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
@@ -886,14 +858,12 @@ BEGIN
   -- TODO: check if we should be only considering _isolated_ nodes!
   sql := 'WITH nearby AS ( SELECT n.geom FROM '
     || quote_ident(atopology) 
-    || '.node n WHERE ST_DWithin(n.geom, '
-    || quote_literal(noded::text)
-    || '::geometry, '
+    || '.node n WHERE ST_DWithin(n.geom, $1, '
     || tol || ') ) SELECT st_collect(geom) FROM nearby;';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO inodes;
+  EXECUTE sql INTO inodes USING noded;
 
   IF inodes IS NOT NULL THEN -- {
 #ifdef POSTGIS_TOPOLOGY_DEBUG
@@ -986,12 +956,11 @@ BEGIN
 
     -- Check if the so-snapped edge _now_ exists
     sql := 'SELECT edge_id FROM ' || quote_ident(atopology)
-      || '.edge_data WHERE ST_Equals(geom, ' || quote_literal(snapped::text)
-      || '::geometry)';
+      || '.edge_data WHERE ST_Equals(geom, $1)';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
     RAISE DEBUG '%', sql;
 #endif
-    EXECUTE sql INTO id;
+    EXECUTE sql INTO id USING snapped;
     IF id IS NULL THEN
       id := topology.ST_AddEdgeModFace(atopology, start_node, end_node,
                                        snapped);
@@ -1057,13 +1026,11 @@ BEGIN
   -- 3. Find faces covered by input polygon
   --    NOTE: potential snapping changed polygon edges
   sql := 'SELECT DISTINCT f.face_id FROM ' || quote_ident(atopology)
-    || '.face f WHERE f.mbr && '
-    || quote_literal(apoly::text)
-    || '::geometry';
+    || '.face f WHERE f.mbr && $1';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  FOR rec IN EXECUTE sql LOOP
+  FOR rec IN EXECUTE sql USING apoly LOOP
     -- check for actual containment
     fgeom := ST_PointOnSurface(ST_GetFaceGeometry(atopology, rec.face_id));
     IF NOT ST_Covers(apoly, fgeom) THEN
index dbb0a27788768e9fbd29359c4619f98e99d4888d..9b9d92e7d42378b13badb38b2f3263fa37930e92 100644 (file)
@@ -78,18 +78,14 @@ BEGIN
     sql := 'WITH er2 AS ( ' 
       || 'WITH er AS ( SELECT ' 
       || 'min(e.edge_id) over (), count(*) over () as cnt, e.edge_id, '
-      || 'ST_LineLocatePoint('
-      || quote_literal(bounds::text)
+      || 'ST_LineLocatePoint($1'
       || ', ST_LineInterpolatePoint(e.geom, 0.2)) as pos'
-      || ', ST_LineLocatePoint('
-      || quote_literal(bounds::text)
+      || ', ST_LineLocatePoint($1'
       || ', ST_LineInterpolatePoint(e.geom, 0.8)) as pos2 FROM '
       || quote_ident(toponame)
       || '.edge e WHERE ( e.left_face = ' || face_id
       || ' OR e.right_face = ' || face_id
-      || ') AND ST_Covers('
-      || quote_literal(bounds::text)
-      || ', e.geom)';
+      || ') AND ST_Covers($1, e.geom)';
     IF face_id = 0 THEN
       sql := sql || ' ORDER BY POS ASC) ';
     ELSE
@@ -103,7 +99,7 @@ BEGIN
 
     --RAISE DEBUG 'SQL: %', sql;
 
-    FOR rec IN EXECUTE sql
+    FOR rec IN EXECUTE sql USING bounds
     LOOP
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
@@ -343,8 +339,8 @@ BEGIN
     || ',' || rec.next_right_edge
     || ',' || rec.left_face
     || ',' || rec.right_face
-    || ',' || quote_literal(rec.geom::text)
-    || ')';
+    || ', $1)'
+    USING rec.geom;
   -- End of new edge insertion }
 
   -- Update next_left_edge/next_right_edge for
@@ -623,14 +619,15 @@ BEGIN
     e2sign = 1;
   END IF;
   EXECUTE 'UPDATE ' || quote_ident(toponame)
-    || '.edge_data SET geom = ' || quote_literal(rec.geom::text)
+    || '.edge_data SET geom = $1'
     || ', start_node = ' || rec.start_node
     || ', end_node = ' || rec.end_node
     || ', next_left_edge = ' || rec.next_left_edge
     || ', abs_next_left_edge = ' || abs(rec.next_left_edge)
     || ', next_right_edge = ' || rec.next_right_edge
     || ', abs_next_right_edge = ' || abs(rec.next_right_edge)
-    || ' WHERE edge_id = ' || e1id;
+    || ' WHERE edge_id = ' || e1id
+    USING rec.geom;
   -- End of first edge update }
 
   -- Update next_left_edge/next_right_edge for
@@ -1486,8 +1483,9 @@ BEGIN
   -- We use index AND x/y equality
   --
   FOR rec IN EXECUTE 'SELECT node_id FROM '
-    || quote_ident(atopology) || '.node ' ||
-    'WHERE ST_Equals(geom, ' || quote_literal(apoint::text) || '::geometry)'
+    || quote_ident(atopology)
+    || '.node WHERE ST_Equals(geom, $1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
      'SQL/MM Spatial exception - coincident node';
@@ -1499,8 +1497,8 @@ BEGIN
   --
   FOR rec IN EXECUTE 'SELECT edge_id FROM '
     || quote_ident(atopology) || '.edge ' 
-    || 'WHERE ST_Intersects(geom, ' || quote_literal(apoint::text)
-    || '::geometry)'
+    || 'WHERE ST_Intersects(geom, $1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
     'SQL/MM Spatial exception - edge crosses node.';
@@ -1513,13 +1511,11 @@ BEGIN
   --
   sql := 'SELECT f.face_id FROM ' 
         || quote_ident(atopology) 
-        || '.face f WHERE f.face_id > 0 AND f.mbr && '
-        || quote_literal(apoint::text)
-        || '::geometry AND ST_Contains(topology.ST_GetFaceGeometry('
+        || '.face f WHERE f.face_id > 0 AND f.mbr && $1'
+        || ' AND ST_Contains(topology.ST_GetFaceGeometry('
         || quote_literal(atopology) 
-        || ', f.face_id), '
-        || quote_literal(apoint::text)
-        || '::geometry)';
+        || ', f.face_id), $1)'
+        ;
   IF aface IS NOT NULL AND aface != 0 THEN
     sql := sql || ' AND f.face_id = ' || aface;
   END IF;
@@ -1527,7 +1523,7 @@ BEGIN
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO containingface;
+  EXECUTE sql INTO containingface USING apoint;
 
   -- If aface was specified, check that it was correct
   IF aface IS NOT NULL THEN -- {
@@ -1555,15 +1551,14 @@ BEGIN
       || quote_ident(atopology)
       || '.node(node_id, geom, containing_face) SELECT nextval('
       || quote_literal( quote_ident(atopology) || '.node_node_id_seq' )
-      || '),'
-      ||quote_literal(apoint::text)
-      || '::geometry,' || containingface
+      || '), $1, '
+      || containingface
       || ' RETURNING node_id';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
 
-  EXECUTE sql INTO nodeid;
+  EXECUTE sql INTO nodeid USING apoint;
 
   RETURN nodeid;
 EXCEPTION
@@ -1623,10 +1618,10 @@ BEGIN
   -- We use index AND x/y equality
   --
   FOR rec IN EXECUTE 'SELECT node_id FROM '
-    || quote_ident(atopology) || '.node ' ||
-    'WHERE geom && ' || quote_literal(apoint::text) || '::geometry'
-    ||' AND ST_X(geom) = ST_X('||quote_literal(apoint::text)||'::geometry)'
-    ||' AND ST_Y(geom) = ST_Y('||quote_literal(apoint::text)||'::geometry)'
+    || quote_ident(atopology)
+    || '.node WHERE geom && $1 '
+    ||' AND ST_X(geom) = ST_X($1) AND ST_Y(geom) = ST_Y($1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
      'SQL/MM Spatial exception - coincident node';
@@ -1637,10 +1632,9 @@ BEGIN
   -- I used _intersects_ here to include boundaries (endpoints)
   --
   FOR rec IN EXECUTE 'SELECT edge_id FROM '
-    || quote_ident(atopology) || '.edge ' 
-    || 'WHERE geom && ' || quote_literal(apoint::text) 
-    || ' AND ST_Intersects(geom, ' || quote_literal(apoint::text)
-    || '::geometry)'
+    || quote_ident(atopology)
+    || '.edge WHERE ST_Intersects(geom, $1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
     'SQL/MM Spatial exception - edge crosses node.';
@@ -1650,8 +1644,8 @@ BEGIN
   -- Update node point
   --
   EXECUTE 'UPDATE ' || quote_ident(atopology) || '.node '
-    || ' SET geom = ' || quote_literal(apoint::text) 
-    || ' WHERE node_id = ' || anode;
+    || ' SET geom = $1 WHERE node_id = $2'
+    USING apoint, anode;
 
   RETURN 'Isolated Node ' || anode || ' moved to location '
     || ST_X(apoint) || ',' || ST_Y(apoint);
@@ -1854,13 +1848,9 @@ BEGIN
   -- Check if a coincident node already exists
   --
   FOR rec IN EXECUTE 'SELECT node_id FROM '
-    || quote_ident(atopology) || '.node '
-    || 'WHERE geom && '
-    || quote_literal(apoint::text) || '::geometry'
-    || ' AND ST_X(geom) = ST_X('
-    || quote_literal(apoint::text) || '::geometry)'
-    || ' AND ST_Y(geom) = ST_Y('
-    || quote_literal(apoint::text) || '::geometry)'
+    || quote_ident(atopology) || '.node WHERE geom && $1 '
+    || ' AND ST_X(geom) = ST_X($1) AND ST_Y(geom) = ST_Y($1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
      'SQL/MM Spatial exception - coincident node';
@@ -1881,16 +1871,15 @@ BEGIN
   -- Add the new node 
   --
   EXECUTE 'INSERT INTO ' || quote_ident(atopology)
-    || '.node(node_id, geom) 
-    VALUES(' || nodeid || ','
-    || quote_literal(apoint::text)
-    || ')';
+    || '.node(node_id, geom) VALUES($1, $2)'
+    USING nodeid, apoint;
 
   --
   -- Delete the old edge
   --
-  EXECUTE 'DELETE FROM ' || quote_ident(atopology) || '.edge_data '
-    || ' WHERE edge_id = ' || anedge;
+  EXECUTE 'DELETE FROM ' || quote_ident(atopology)
+    || '.edge_data WHERE edge_id = $1'
+    USING anedge;
 
   --
   -- Compute new edges
@@ -1942,8 +1931,8 @@ BEGIN
               END
     || ',' || oldedge.left_face               -- left_face
     || ',' || oldedge.right_face              -- right_face
-    || ',' || quote_literal(edge1::text)      -- geom
-    ||')';
+    || ',$1)' -- geom
+    USING edge1;
 
   EXECUTE 'INSERT INTO ' || quote_ident(atopology)
     || '.edge VALUES('
@@ -1964,8 +1953,8 @@ BEGIN
     || ',' || -edgeid1                        -- next_right_edge
     || ',' || oldedge.left_face               -- left_face
     || ',' || oldedge.right_face              -- right_face
-    || ',' || quote_literal(edge2::text)      -- geom
-    ||')';
+    || ',$1)' -- geom
+    USING edge2;
 
   --
   -- Update all next edge references to match new layout
@@ -2151,13 +2140,9 @@ BEGIN
   -- Check if a coincident node already exists
   --
   FOR rec IN EXECUTE 'SELECT node_id FROM '
-    || quote_ident(atopology) || '.node ' ||
-    'WHERE geom && '
-    || quote_literal(apoint::text) || '::geometry'
-    ||' AND ST_X(geom) = ST_X('
-    || quote_literal(apoint::text) || '::geometry)'
-    ||' AND ST_Y(geom) = ST_Y('
-    ||quote_literal(apoint::text)||'::geometry)'
+    || quote_ident(atopology) || '.node WHERE geom && $1'
+    ||' AND ST_X(geom) = ST_X($1) AND ST_Y(geom) = ST_Y($1)'
+    USING apoint
   LOOP
     RAISE EXCEPTION
      'SQL/MM Spatial exception - coincident node';
@@ -2178,9 +2163,8 @@ BEGIN
   -- Add the new node 
   --
   EXECUTE 'INSERT INTO ' || quote_ident(atopology)
-    || '.node(node_id, geom) 
-    VALUES('||nodeid||','||quote_literal(apoint::text)||
-    ')';
+    || '.node(node_id, geom) VALUES($1, $2)'
+    USING nodeid,apoint;
 
   --
   -- Compute new edge
@@ -2224,20 +2208,16 @@ BEGIN
     || ',' || -anedge                        -- next_right_edge
     || ',' || oldedge.left_face              -- left_face
     || ',' || oldedge.right_face             -- right_face
-    || ',' || quote_literal(newedge2::text)  -- geom
-    ||')';
+    || ',$1)' --geom
+    USING newedge2;
 
   --
   -- Update the old edge
   --
-  EXECUTE 'UPDATE ' || quote_ident(atopology) || '.edge_data '
-    || ' SET geom = ' || quote_literal(newedge1::text)
-    || ','
-    || ' next_left_edge = ' || newedgeid
-    || ', abs_next_left_edge = ' || newedgeid
-    || ','
-    || ' end_node = ' || nodeid
-    || ' WHERE edge_id = ' || anedge;
+  EXECUTE 'UPDATE ' || quote_ident(atopology)
+    || '.edge_data SET geom = $1, next_left_edge = $2, ' 
+    || 'abs_next_left_edge = $2, end_node = $3 WHERE edge_id = $4'
+    USING newedge1, newedgeid, nodeid, anedge;
 
 
   --
@@ -2444,9 +2424,8 @@ BEGIN
   -- 
   FOR rec IN EXECUTE 'SELECT node_id FROM '
     || quote_ident(atopology) || '.node '
-    || ' WHERE geom && ' || quote_literal(acurve::text) 
-    || ' AND ST_Contains(' || quote_literal(acurve::text)
-    || ',geom)'
+    || ' WHERE ST_Contains($1, geom)'
+    USING acurve 
   LOOP
     RAISE EXCEPTION
       'SQL/MM Spatial exception - geometry crosses a node';
@@ -2457,7 +2436,8 @@ BEGIN
   -- 
   FOR rec IN EXECUTE 'SELECT * FROM '
     || quote_ident(atopology) || '.edge_data
-    WHERE ST_Intersects(geom, ' || quote_literal(acurve::text) || '::geometry)'
+    WHERE ST_Intersects(geom, $1)'
+    USING acurve
   LOOP
     RAISE EXCEPTION 'SQL/MM Spatial exception - geometry intersects an edge';
   END LOOP;
@@ -2483,8 +2463,8 @@ BEGIN
     || '.edge VALUES(' || edgeid || ',' || anode
     || ',' || anothernode || ',' || (-edgeid)
     || ',' || edgeid || ','
-    || aface || ',' || aface || ','
-    || quote_literal(acurve::text) || ')';
+    || aface || ',' || aface || ',$1)'
+    USING acurve;
 
   --
   -- Update Node containing_face values
@@ -2652,14 +2632,12 @@ BEGIN
   -- g) Check if curve crosses any node
   -- 
   FOR rec IN EXECUTE
-    'SELECT node_id, ST_Relate(geom, '
-    || quote_literal(acurve::text) || '::geometry, 2) as relate FROM '
+    'SELECT node_id, ST_Relate(geom, $1, 2) as relate FROM '
     || quote_ident(atopology)
-    || '.node WHERE geom && '
-    || quote_literal(acurve::text)
-    || '::geometry AND node_id NOT IN ('
+    || '.node WHERE geom && $1 AND node_id NOT IN ('
     || oldedge.start_node || ',' || oldedge.end_node
     || ')'
+    USING acurve
   LOOP
     IF ST_RelateMatch(rec.relate, 'T********') THEN
       RAISE EXCEPTION 'SQL/MM Spatial exception - geometry crosses a node';
@@ -2669,13 +2647,10 @@ BEGIN
   --
   -- h) Check if this geometry has any interaction with any existing edge
   --
-  sql := 'SELECT edge_id, ST_Relate(geom,' 
-    || quote_literal(acurve::text)
-    || '::geometry, 2) as im FROM '
+  sql := 'SELECT edge_id, ST_Relate(geom, $1, 2) as im FROM '
     || quote_ident(atopology)
-    || '.edge_data WHERE edge_id != ' || anedge || ' AND geom && '
-    || quote_literal(acurve::text) || '::geometry';
-  FOR rec IN EXECUTE sql LOOP -- {
+    || '.edge_data WHERE edge_id != $2 AND geom && $1';
+  FOR rec IN EXECUTE sql USING acurve, anedge LOOP -- {
 
     --RAISE DEBUG 'IM=%',rec.im;
 
@@ -2712,15 +2687,14 @@ BEGIN
   sql := 'SELECT ST_Collect(geom) as nodes, '
     || 'null::geometry as r1, null::geometry as r2 FROM '
     || quote_ident(atopology)
-    || '.node WHERE geom && '
-    || quote_literal(ST_Collect(ST_Envelope(oldedge.geom),
-                                ST_Envelope(acurve))::text)
-    || '::geometry AND node_id NOT IN ( '
+    || '.node WHERE geom && $1 AND node_id NOT IN ( '
     || oldedge.start_node || ',' || oldedge.end_node || ')';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO rng_info;
+  EXECUTE sql INTO rng_info USING ST_Collect(ST_Envelope(oldedge.geom),
+                                             ST_Envelope(acurve))
+  ;
 
   -- There's no collision if there's no nodes in the combined
   -- bbox of old and new edges.
@@ -2812,8 +2786,8 @@ BEGIN
   -- Update edge geometry
   --
   EXECUTE 'UPDATE ' || quote_ident(atopology) || '.edge_data '
-    || ' SET geom = ' || quote_literal(acurve::text) 
-    || ' WHERE edge_id = ' || anedge;
+    || ' SET geom = $1 WHERE edge_id = $2'
+    USING acurve, anedge;
 
   -- 
   -- Check edge adjacency after
@@ -2852,20 +2826,20 @@ BEGIN
   --       would be larger than the old face MBR...
   --
   IF oldedge.left_face != 0 THEN
-    sql := 'UPDATE ' || quote_ident(atopology) || '.face '
-      || ' SET mbr = ' || quote_literal(
-        ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.left_face))::text
-        )
-      || '::geometry WHERE face_id = ' || oldedge.left_face;
-    EXECUTE sql;
+    sql := 'UPDATE ' || quote_ident(atopology)
+      || '.face SET mbr = $1 WHERE face_id = $2' ;
+    EXECUTE sql USING
+      ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.left_face)),
+      oldedge.left_face
+      ;
   END IF;
   IF oldedge.right_face != 0 AND oldedge.right_face != oldedge.left_face THEN
-    sql := 'UPDATE ' || quote_ident(atopology) || '.face '
-      || ' SET mbr = ' || quote_literal(
-        ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.right_face))::text
-        )
-      || '::geometry WHERE face_id = ' || oldedge.right_face;
-    EXECUTE sql;
+    sql := 'UPDATE ' || quote_ident(atopology)
+      || '.face SET mbr = $1 WHERE face_id = $2';
+    EXECUTE sql USING
+      ST_Envelope(ST_GetFaceGeometry(atopology, oldedge.right_face)),
+      oldedge.right_face
+    ;
   END IF;
   
 
@@ -2939,14 +2913,17 @@ BEGIN
   RAISE DEBUG 'Edge % splitted face %', anedge, oface;
 #endif
 
-  sql := 'WITH ids as ( select row_number() over () as seq, edge from unnest('
-    || quote_literal(fan.newring_edges::text)
-    || '::int[] ) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
-    || quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g;';
+  sql := 'WITH ids as ( select row_number() over () as seq, edge '
+    || 'from unnest($1) u(edge) ), edges AS ( select CASE WHEN i.edge < 0 '
+    || 'THEN ST_Reverse(e.geom) ELSE e.geom END as g FROM ids i left join '
+    || quote_ident(atopology) || '.edge_data e ON(e.edge_id = abs(i.edge)) '
+    || 'ORDER BY seq) SELECT ST_MakePolygon(ST_MakeLine(g.g)) FROM edges g';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG '%', sql;
 #endif
-  EXECUTE sql INTO fan.shell;
+  EXECUTE sql INTO fan.shell USING
+    fan.newring_edges
+  ;
 
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG 'got shell'; 
@@ -2971,13 +2948,15 @@ BEGIN
     -- Update old face mbr (nothing to do if we're opening an hole)
     IF isccw THEN -- {
       sql := 'UPDATE '
-        || quote_ident(atopology) || '.face SET mbr = '
-        || quote_literal(ST_Envelope(fan.shell)::text)
-        || '::geometry WHERE face_id = ' || oface;
+        || quote_ident(atopology)
+        || '.face SET mbr = $1 WHERE face_id = $2';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
        RAISE DEBUG 'Updating old face mbr'; 
 #endif
-       EXECUTE sql;
+       EXECUTE sql USING
+        ST_Envelope(fan.shell),
+        oface
+      ;
     END IF; -- }
     RETURN NULL;
   END IF;
@@ -2991,16 +2970,14 @@ BEGIN
       || ' RETURNING face_id';
   ELSE
     sql := 'INSERT INTO '
-      || quote_ident(atopology) || '.face(mbr) VALUES ('
-      || quote_literal(ST_Envelope(fan.shell)::text)
-      || '::geometry) RETURNING face_id';
+      || quote_ident(atopology) || '.face(mbr) VALUES ($1) RETURNING face_id';
   END IF; -- }
 
   -- Insert new face
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG 'Inserting new face'; 
 #endif
-  EXECUTE sql INTO STRICT newface;
+  EXECUTE sql INTO STRICT newface USING ST_Envelope(fan.shell);
 
   -- Update forward edges
   sql := 'UPDATE '
@@ -3052,14 +3029,13 @@ BEGIN
        )::text )
     || ') AND ';
   IF ishole THEN sql := sql || 'NOT '; END IF;
-  sql := sql || '( ' || quote_literal(fan.shell::text)
-    || ' && geom AND _ST_Contains(' || quote_literal(fan.shell::text)
+  sql := sql || '($1 && geom AND _ST_Contains($1'
     -- We only need to check a single point, but must not be an endpoint
-    || '::geometry, ST_LineInterpolatePoint(geom, 0.2)) )';
+    || ', ST_LineInterpolatePoint(geom, 0.2)) )';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG 'Updating edges bounding the old face: %', sql;
 #endif
-  EXECUTE sql;
+  EXECUTE sql USING fan.shell;
 
   -- Update isolated nodes in new new face 
   sql := 'UPDATE '
@@ -3067,11 +3043,11 @@ BEGIN
     || ' WHERE containing_face = ' || oface 
     || ' AND ';
   IF ishole THEN sql := sql || 'NOT '; END IF;
-  sql := sql || 'ST_Contains(' || quote_literal(fan.shell::text) || '::geometry, geom)';
+  sql := sql || 'ST_Contains($1, geom)';
 #ifdef POSTGIS_TOPOLOGY_DEBUG
   RAISE DEBUG 'Updating isolated nodes in old face';
 #endif
-  EXECUTE sql;
+  EXECUTE sql USING fan.shell;
 
   RETURN newface;
 
@@ -3244,12 +3220,10 @@ BEGIN
   -- Check if this geometry crosses any node
   --
   FOR rec IN EXECUTE
-    'SELECT node_id, ST_Relate(geom, '
-    || quote_literal(acurve::text) || '::geometry, 2) as relate FROM '
+    'SELECT node_id, ST_Relate(geom, $1, 2) as relate FROM '
     || quote_ident(atopology)
-    || '.node WHERE geom && '
-    || quote_literal(acurve::text)
-    || '::geometry'
+    || '.node WHERE geom && $1'
+    USING acurve
   LOOP
     IF ST_RelateMatch(rec.relate, 'T********') THEN
       RAISE EXCEPTION 'SQL/MM Spatial exception - geometry crosses a node';
@@ -3259,12 +3233,10 @@ BEGIN
   --
   -- Check if this geometry has any interaction with any existing edge
   --
-  FOR rec IN EXECUTE 'SELECT edge_id, ST_Relate(geom,' 
-    || quote_literal(acurve::text)
-    || '::geometry, 2) as im FROM '
+  FOR rec IN EXECUTE 'SELECT edge_id, ST_Relate(geom, $1, 2) as im FROM '
     || quote_ident(atopology)
-    || '.edge_data WHERE geom && '
-    || quote_literal(acurve::text) || '::geometry'
+    || '.edge_data WHERE geom && $1'
+    USING acurve
   LOOP
 
     --RAISE DEBUG 'IM=%',rec.im;
@@ -3320,11 +3292,10 @@ BEGIN
   IF newedge.isclosed THEN
     sql := sql || ' UNION SELECT '
       || newedge.edge_id || ',' || newedge.end_node
-      || ',-1,0,0,' -- pretend we start elsewhere
-      || quote_literal(newedge.cleangeom::text);
+      || ',-1,0,0,$1'; -- pretend we start elsewhere
   END IF;
   i := 0;
-  FOR rec IN EXECUTE sql
+  FOR rec IN EXECUTE sql USING newedge.cleangeom
   LOOP -- incident edges {
 
     i := i + 1;
@@ -3447,11 +3418,10 @@ BEGIN
   IF newedge.isclosed THEN
     sql := sql || ' UNION SELECT '
       || newedge.edge_id || ',' || -1 -- pretend we end elsewhere
-      || ',' || newedge.start_node || ',0,0,'
-      || quote_literal(newedge.cleangeom::text);
+      || ',' || newedge.start_node || ',0,0,$1';
   END IF;
   i := 0;
-  FOR rec IN EXECUTE sql
+  FOR rec IN EXECUTE sql USING newedge.cleangeom
   LOOP -- incident edges {
 
     i := i + 1;
@@ -3580,8 +3550,9 @@ BEGIN
     || ',' || newedge.next_right_edge
     || ',' || newedge.left_face
     || ',' || newedge.right_face
-    || ',' || quote_literal(newedge.geom::geometry::text)
-    || ')';
+    || ',$1)'
+    USING newedge.geom
+    ;
 
   -- Link prev_left_edge to us 
   -- (if it's not us already)
@@ -3873,12 +3844,10 @@ BEGIN
   -- Check if this geometry crosses any node
   --
   FOR rec IN EXECUTE
-    'SELECT node_id, ST_Relate(geom, '
-    || quote_literal(acurve::text) || '::geometry, 2) as relate FROM '
+    'SELECT node_id, ST_Relate(geom, $1, 2) as relate FROM '
     || quote_ident(atopology)
-    || '.node WHERE geom && '
-    || quote_literal(acurve::text)
-    || '::geometry'
+    || '.node WHERE geom && $1'
+    USING acurve
   LOOP
     IF ST_RelateMatch(rec.relate, 'T********') THEN
       RAISE EXCEPTION 'SQL/MM Spatial exception - geometry crosses a node';
@@ -3888,12 +3857,10 @@ BEGIN
   --
   -- Check if this geometry has any interaction with any existing edge
   --
-  FOR rec IN EXECUTE 'SELECT edge_id, ST_Relate(geom,' 
-    || quote_literal(acurve::text)
-    || '::geometry, 2) as im FROM '
+  FOR rec IN EXECUTE 'SELECT edge_id, ST_Relate(geom, $1, 2) as im FROM '
     || quote_ident(atopology)
-    || '.edge_data WHERE geom && '
-    || quote_literal(acurve::text) || '::geometry'
+    || '.edge_data WHERE geom && $1'
+    USING acurve
   LOOP
 
     --RAISE DEBUG 'IM=%',rec.im;
@@ -4209,8 +4176,9 @@ BEGIN
     || ',' || newedge.next_right_edge
     || ',' || newedge.left_face
     || ',' || newedge.right_face
-    || ',' || quote_literal(newedge.geom::geometry::text)
-    || ')';
+    || ',$1)'
+    USING newedge.geom
+    ;
 
   -- Link prev_left_edge to us 
   -- (if it's not us already)