diff --git a/NEWS.md b/NEWS.md index 07445be9e4b..75a8bd8d6b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,7 +8,19 @@ ### pgRouting 3.8.0 Release Notes -No Changes Yet +**Changes on proposed functions** + +* pgr_extractVertices + + * Error messages adjustment. + +* pgr_findCloseEdges + + * Error messages adjustment. + +* pgr_degree + + * Error messages adjustment. ## pgRouting 3.7 diff --git a/doc/src/release_notes.rst b/doc/src/release_notes.rst index f621169b4f6..3870e08f775 100644 --- a/doc/src/release_notes.rst +++ b/doc/src/release_notes.rst @@ -39,7 +39,25 @@ pgRouting 3.8 pgRouting 3.8.0 Release Notes ------------------------------------------------------------------------------- -No Changes Yet +.. rubric:: Changes on proposed functions + +* pgr_extractVertices + + .. include:: pgr_extractVertices.rst + :start-after: Version 3.8.0 + :end-before: .. rubric + +* pgr_findCloseEdges + + .. include:: pgr_findCloseEdges.rst + :start-after: Version 3.8.0 + :end-before: .. rubric + +* pgr_degree + + .. include:: pgr_degree.rst + :start-after: Version 3.8.0 + :end-before: .. rubric pgRouting 3.7 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ diff --git a/doc/topology/pgr_degree.rst b/doc/topology/pgr_degree.rst index 8eea85a7df0..6e6a4a33922 100644 --- a/doc/topology/pgr_degree.rst +++ b/doc/topology/pgr_degree.rst @@ -25,9 +25,13 @@ .. rubric:: Availability -* Version 3.4.0 +.. rubric:: Version 3.8.0 - * New proposed function. +* Error messages adjustment. + +.. rubric:: Version 3.4.0 + +* New proposed function. Description diff --git a/doc/topology/pgr_extractVertices.rst b/doc/topology/pgr_extractVertices.rst index 2787f5c7192..32fb2d9f727 100644 --- a/doc/topology/pgr_extractVertices.rst +++ b/doc/topology/pgr_extractVertices.rst @@ -25,13 +25,17 @@ .. rubric:: Availability -* Version 3.3.0 +.. rubric:: Version 3.8.0 - * Classified as **proposed** function +* Error messages adjustment. -* Version 3.0.0 +.. rubric:: Version 3.3.0 - * New experimental function. +* Function promoted to proposed. + +.. rubric:: Version 3.0.0 + +* New experimental function. Description diff --git a/doc/utilities/pgr_findCloseEdges.rst b/doc/utilities/pgr_findCloseEdges.rst index f52c3634de1..0cf77aa0fe0 100644 --- a/doc/utilities/pgr_findCloseEdges.rst +++ b/doc/utilities/pgr_findCloseEdges.rst @@ -20,9 +20,13 @@ .. rubric:: Availability -* Version 3.4.0 +.. rubric:: Version 3.8.0 - * New proposed function. +* Error messages adjustment. + +.. rubric:: Version 3.4.0 + +* New proposed function. Description ------------------------------------------------------------------------------- diff --git a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po index 3933bf91a47..039a42f9274 100644 --- a/locale/en/LC_MESSAGES/pgrouting_doc_strings.po +++ b/locale/en/LC_MESSAGES/pgrouting_doc_strings.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v3.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-27 18:35+0000\n" +"POT-Creation-Date: 2025-02-27 23:12+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -4404,7 +4404,19 @@ msgstr "" msgid "pgRouting 3.8.0 Release Notes" msgstr "" -msgid "No Changes Yet" +msgid "Changes on proposed functions" +msgstr "" + +msgid "pgr_extractVertices" +msgstr "" + +msgid "Error messages adjustment." +msgstr "" + +msgid "pgr_findCloseEdges" +msgstr "" + +msgid "pgr_degree" msgstr "" msgid "All releases" @@ -10200,6 +10212,9 @@ msgid "" " of edges incident to the vertex." msgstr "" +msgid "Version 3.8.0" +msgstr "" + msgid "Calculates the degree of the vertices of an **undirected** graph" msgstr "" @@ -11451,9 +11466,6 @@ msgstr "" msgid "``pgr_extractVertices`` — Extracts the vertices information" msgstr "" -msgid "Classified as **proposed** function" -msgstr "" - msgid "" "This is an auxiliary function for extracting the vertex information of " "the set of edges of a graph." @@ -15761,9 +15773,6 @@ msgstr "" msgid "Changes on the documentation to the following:" msgstr "" -msgid "pgr_degree" -msgstr "" - msgid "pgr_dijkstra" msgstr "" @@ -16155,9 +16164,6 @@ msgstr "" msgid "pgr_sequentialVertexColoring" msgstr "" -msgid "pgr_extractVertices" -msgstr "" - msgid "Traversal" msgstr "" diff --git a/locale/pot/pgrouting_doc_strings.pot b/locale/pot/pgrouting_doc_strings.pot index bb2040b4f04..aa73c611d52 100644 --- a/locale/pot/pgrouting_doc_strings.pot +++ b/locale/pot/pgrouting_doc_strings.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: pgRouting v3.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-02-27 18:35+0000\n" +"POT-Creation-Date: 2025-02-27 23:12+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -3928,7 +3928,19 @@ msgstr "" msgid "pgRouting 3.8.0 Release Notes" msgstr "" -msgid "No Changes Yet" +msgid "Changes on proposed functions" +msgstr "" + +msgid "pgr_extractVertices" +msgstr "" + +msgid "Error messages adjustment." +msgstr "" + +msgid "pgr_findCloseEdges" +msgstr "" + +msgid "pgr_degree" msgstr "" msgid "All releases" @@ -8713,6 +8725,9 @@ msgstr "" msgid "``pgr_degree`` — For each vertex in an undirected graph, return the count of edges incident to the vertex." msgstr "" +msgid "Version 3.8.0" +msgstr "" + msgid "Calculates the degree of the vertices of an **undirected** graph" msgstr "" @@ -9745,9 +9760,6 @@ msgstr "" msgid "``pgr_extractVertices`` — Extracts the vertices information" msgstr "" -msgid "Classified as **proposed** function" -msgstr "" - msgid "This is an auxiliary function for extracting the vertex information of the set of edges of a graph." msgstr "" @@ -13201,9 +13213,6 @@ msgstr "" msgid "Changes on the documentation to the following:" msgstr "" -msgid "pgr_degree" -msgstr "" - msgid "pgr_dijkstra" msgstr "" @@ -13516,9 +13525,6 @@ msgstr "" msgid "pgr_sequentialVertexColoring" msgstr "" -msgid "pgr_extractVertices" -msgstr "" - msgid "Traversal" msgstr "" diff --git a/pgtap/topology/degree/edge_cases.pg b/pgtap/topology/degree/edge_cases.pg index a762c248286..39fe52c0d5c 100644 --- a/pgtap/topology/degree/edge_cases.pg +++ b/pgtap/topology/degree/edge_cases.pg @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. BEGIN; UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); -SELECT CASE WHEN min_version('3.4.0') THEN plan(12) ELSE plan(1) END; +SELECT CASE WHEN min_version('3.4.0') THEN plan(16) ELSE plan(1) END; CREATE OR REPLACE FUNCTION edge_cases() @@ -59,11 +59,13 @@ BEGIN SELECT * FROM pgr_degree('edges','SELECT id, out_edges FROM vertices'); RETURN QUERY SELECT lives_ok('query_1', 'Good execution'); - RETURN QUERY SELECT throws_ok('query_2', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('query_3', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('query_4', 'P0001', 'Missing column', 'Incomlete data -> throws'); + RETURN QUERY SELECT column_missing('query_2', 'id'); + RETURN QUERY SELECT column_missing('query_3', 'in_edges'); + RETURN QUERY SELECT column_missing('query_4', 'id'); RETURN QUERY SELECT lives_ok('query_5', 'Missing column out_edges but usable'); RETURN QUERY SELECT lives_ok('query_5', 'Missing column in_edges but usable'); + RETURN QUERY SELECT wrong_relation($$SELECT * FROM pgr_degree('SELECT id FROM foo', 'SELECT * FROM vertices')$$, 'foo'); + RETURN QUERY SELECT wrong_relation($$SELECT * FROM pgr_degree('SELECT id FROM edges', 'SELECT * FROM bar')$$, 'bar'); PREPARE subedges AS SELECT id FROM edges WHERE id < 17; @@ -90,12 +92,29 @@ BEGIN SELECT * FROM pgr_degree('subedges','SELECT id, out_edges FROM vertices'); RETURN QUERY SELECT lives_ok('query_7', 'Good execution'); - RETURN QUERY SELECT throws_ok('query_8', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('query_9', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('query_10', 'P0001', 'Missing column', 'Incomlete data -> throws'); + RETURN QUERY SELECT column_missing('query_8', 'id'); + RETURN QUERY SELECT column_missing('query_9', 'in_edges'); + RETURN QUERY SELECT column_missing('query_10', 'id'); RETURN QUERY SELECT lives_ok('query_11', 'Missing column out_edges but usable'); RETURN QUERY SELECT lives_ok('query_12', 'Missing column in_edges but usable'); + PREPARE empty_vertices AS + SELECT * FROM pgr_degree('SELECT id FROM edges', 'SELECT * FROM vertices WHERE id > 20'); + RETURN QUERY SELECT is_empty('empty_vertices', 'Empty vertices give empty result'); + + PREPARE empty_graph AS + SELECT * FROM pgr_degree('SELECT id FROM edges WHERE id > 20', 'SELECT * FROM vertices') ORDER BY node; + RETURN QUERY + SELECT CASE WHEN min_version('3.8.0') THEN + collect_tap( + is_empty('empty_graph', 'is empty: Empty edges give 0 count on all vertices so none is in result') + ) + ELSE + collect_tap( + results_eq('empty_graph', 'SELECT generate_series (1,17)::BIGINT, 0::BIGINT', 'Empty edges give 0 count') + ) + END; + END; $BODY$ LANGUAGE plpgsql; diff --git a/pgtap/topology/extractVertices/edge_cases.pg b/pgtap/topology/extractVertices/edge_cases.pg index 430727e708d..4e3756f7f3c 100644 --- a/pgtap/topology/extractVertices/edge_cases.pg +++ b/pgtap/topology/extractVertices/edge_cases.pg @@ -25,103 +25,43 @@ SELECT plan(30); UPDATE edges SET cost = sign(cost) + 0.001 * id * id, reverse_cost = sign(reverse_cost) + 0.001 * id * id; -- -PREPARE query_1 AS -SELECT * FROM pgr_extractVertices( - 'SELECT source - FROM edges' -); - -PREPARE query_2 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT target - FROM edges' -); - -SELECT throws_ok('query_1', 'P0001', 'Missing column', 'Incomlete data -> throws'); -SELECT throws_ok('query_2', 'P0001', 'Missing column', 'Incomlete data -> throws'); --- -PREPARE query_3 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT ST_StartPoint(geom) AS startpoint - FROM edges' -); - -PREPARE query_4 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT ST_EndPoint(geom) AS endpoint - FROM edges' -); - -SELECT throws_ok('query_3', 'P0001', 'Missing column', 'Incomlete data -> throws'); -SELECT throws_ok('query_4', 'P0001', 'Missing column', 'Incomlete data -> throws'); +PREPARE test_1(TEXT) AS +SELECT * FROM pgr_extractVertices('SELECT ' || $1 || ' FROM edges'); + +SELECT column_missing($$test_1('source')$$, 'target'); +SELECT column_missing($$test_1('target')$$, 'source'); -- -PREPARE query_5 AS -SELECT * FROM pgr_extractVertices( - 'SELECT source, geom - FROM edges' -); +SELECT column_missing($$"test_1"('ST_StartPoint(geom) AS startpoint')$$, 'endpoint'); +SELECT column_missing($$"test_1"('ST_EndPoint(geom) AS endpoint')$$, 'startpoint'); -PREPARE query_6 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT target, geom - FROM edges' -); +-- -SELECT lives_ok('query_5', 'geom column makes data complete'); -SELECT lives_ok('query_6', 'geom column makes data complete'); +SELECT lives_ok($$"test_1"('source, geom')$$, 'geom column makes data complete'); +SELECT lives_ok($$"test_1"('target, geom')$$, 'geom column makes data complete'); -- -PREPARE query_7 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT ST_StartPoint(geom) AS startpoint, geom - FROM edges' -); - -PREPARE query_8 AS -SELECT * -FROM pgr_extractVertices( - 'SELECT ST_EndPoint(geom) AS endpoint, geom - FROM edges' -); - -SELECT lives_ok('query_7', 'geom column makes data complete'); -SELECT lives_ok('query_8', 'geom column makes data complete'); --- +SELECT lives_ok($$"test_1"('ST_StartPoint(geom) AS startpoint, geom')$$, 'geom column makes data complete'); +SELECT lives_ok($$"test_1"('ST_EndPoint(geom) AS endpoint, geom')$$, 'geom column makes data complete'); -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT geom FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT ST_StartPoint(geom) AS startpoint, ST_EndPoint(geom) AS endpoint FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT source, target FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); +-- -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT id, geom FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT id, ST_StartPoint(geom) AS startpoint, ST_EndPoint(geom) AS endpoint FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); -SELECT set_eq( - $$SELECT count(*) FROM pgr_extractVertices( 'SELECT id, source, target FROM edges')$$, - $$VALUES (17)$$, - '17: Number of vertices extracted'); +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT geom FROM edges')), + 17::BIGINT, '17 vertices with geom'); +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT ST_StartPoint(geom) AS startpoint, ST_EndPoint(geom) AS endpoint FROM edges')), + 17::BIGINT, '17 vertices with points'); +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT source, target FROM edges')), + 17::BIGINT, '17 vertices with source, target'); + +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT id, geom FROM edges')), + 17::BIGINT, '17 vertices with id, geom'); +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT id, ST_StartPoint(geom) AS startpoint, ST_EndPoint(geom) AS endpoint FROM edges')), + 17::BIGINT, '17 vertices with id, points'); +SELECT is((SELECT count(*) FROM pgr_extractVertices('SELECT id, source, target FROM edges')), + 17::BIGINT, '17 vertices with id, source, target'); -- SELECT set_eq( diff --git a/pgtap/utilities/findCloseEdges/edge_cases.pg b/pgtap/utilities/findCloseEdges/edge_cases.pg index 90c58046a2b..0c634c2f5ca 100644 --- a/pgtap/utilities/findCloseEdges/edge_cases.pg +++ b/pgtap/utilities/findCloseEdges/edge_cases.pg @@ -20,7 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. BEGIN; UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); -SELECT CASE WHEN min_version('3.4.0') THEN plan(12) ELSE plan(1) END; +SELECT CASE WHEN min_version('3.4.0') THEN plan(16) ELSE plan(1) END; SET client_min_messages TO 'WARNING'; @@ -60,9 +60,14 @@ BEGIN RETURN QUERY SELECT lives_ok('query_3', 'dryrun'); RETURN QUERY SELECT is_empty('query_3', 'dryrun'); - RETURN QUERY SELECT throws_ok('err1', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('err2', 'P0001', 'Missing column', 'Incomlete data -> throws'); + RETURN QUERY SELECT column_missing('err1', 'geom'); + RETURN QUERY SELECT column_missing('err2', 'id'); + RETURN QUERY SELECT wrong_relation($$SELECT * FROM pgr_findCloseEdges( + 'SELECT id, geom FROM foo', (SELECT geom FROM pointsOfInterest WHERE pid = 5), 0.5)$$, 'foo'); + RETURN QUERY SELECT throws_ok($$SELECT * FROM pgr_findCloseEdges( + 'SELECT id, geom FROM edges', (SELECT geom FROM bar WHERE pid = 5), 0.5)$$, + '42P01', 'relation "bar" does not exist'); -- Many points PREPARE query_4 AS @@ -82,10 +87,15 @@ BEGIN RETURN QUERY SELECT lives_ok('query_6', 'dryrun'); RETURN QUERY SELECT is_empty('query_6', 'dryrun'); - RETURN QUERY SELECT throws_ok('err3', 'P0001', 'Missing column', 'Incomlete data -> throws'); - RETURN QUERY SELECT throws_ok('err4', 'P0001', 'Missing column', 'Incomlete data -> throws'); + RETURN QUERY SELECT column_missing('err3', 'geom'); + RETURN QUERY SELECT column_missing('err4', 'id'); + RETURN QUERY SELECT wrong_relation($$SELECT * FROM pgr_findCloseEdges( + 'SELECT id, geom FROM foo', (SELECT array_agg(geom) FROM pointsOfInterest), 0.5)$$, 'foo'); + RETURN QUERY SELECT throws_ok($$SELECT * FROM pgr_findCloseEdges( + 'SELECT id, geom FROM edges', (SELECT array_agg(geom) FROM bar), 0.5)$$, + '42P01', 'relation "bar" does not exist'); END; $BODY$ diff --git a/sql/common/_checkcolumn.sql b/sql/common/_checkcolumn.sql index eb0a59108c1..36edfe3b876 100644 --- a/sql/common/_checkcolumn.sql +++ b/sql/common/_checkcolumn.sql @@ -36,12 +36,23 @@ $BODY$ DECLARE has_column BOOLEAN := TRUE; rec RECORD; + sqlhint TEXT; BEGIN BEGIN EXECUTE format('SELECT %1$s FROM ( %2$s ) AS __a__ limit 1', $2, $1); + EXCEPTION WHEN OTHERS THEN + BEGIN + IF NOT is_optional THEN + RAISE EXCEPTION '%', SQLERRM USING HINT = $1, ERRCODE = SQLSTATE; + ELSE + has_column := FALSE; + END IF; + END; + END; + BEGIN EXECUTE format('SELECT pg_typeof(%1$s) FROM ( %2$s ) AS __a__ limit 1', $2, $1) INTO rec; @@ -89,7 +100,5 @@ END; $BODY$ LANGUAGE plpgsql VOLATILE STRICT; - --- COMMENTS COMMENT ON FUNCTION _pgr_checkColumn(TEXT, TEXT, TEXT, BOOLEAN, BOOLEAN) IS 'pgRouting internal function'; diff --git a/sql/common/_checkquery.sql b/sql/common/_checkquery.sql index ef6550e8d65..d649b775ee1 100644 --- a/sql/common/_checkquery.sql +++ b/sql/common/_checkquery.sql @@ -33,18 +33,19 @@ DECLARE BEGIN - BEGIN + IF $1 !~ '[[:space:]]' THEN + -- prepared statements no arguments EXECUTE format($$ SELECT regexp_replace(regexp_replace(statement, %1$L,'','i'),';$','') FROM pg_prepared_statements WHERE name = %2$L$$, '.*' || $1 || '\s*as', $1) INTO main_sql; - EXCEPTION WHEN OTHERS - THEN main_sql := $1; - END; - - IF main_sql IS NULL THEN + IF main_sql IS NULL THEN + RAISE EXCEPTION 'prepared statement "%" does not exist', $1; + END IF; + ELSE + -- normal query main_sql := $1; END IF; @@ -52,8 +53,7 @@ BEGIN EXECUTE format('SELECT * FROM ( %1$s ) AS __a__ limit 1', main_sql); EXCEPTION WHEN OTHERS THEN - RAISE EXCEPTION '%', SQLERRM - USING HINT = 'Please check query: '|| $1; + RAISE EXCEPTION '%', SQLERRM USING HINT = $1, ERRCODE = SQLSTATE; END; RETURN main_sql; @@ -62,7 +62,5 @@ END; $BODY$ LANGUAGE plpgsql VOLATILE STRICT; - --- COMMENTS COMMENT ON FUNCTION _pgr_checkquery(TEXT) IS 'pgrouting internal function'; diff --git a/sql/topology/degree.sql b/sql/topology/degree.sql index 033a63ee20c..980095aad4a 100644 --- a/sql/topology/degree.sql +++ b/sql/topology/degree.sql @@ -42,17 +42,29 @@ DECLARE has_out_edges BOOLEAN := TRUE; eids TEXT; query TEXT; + sqlhint TEXT; BEGIN - edges_sql := _pgr_checkQuery($1); - PERFORM _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', dryrun => $3); + BEGIN + edges_sql := _pgr_checkQuery($1); + PERFORM _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', dryrun => $3); + + vertices_sql := _pgr_checkQuery($2); + PERFORM _pgr_checkColumn(vertices_sql, 'id', 'ANY-INTEGER', dryrun => $3); + + EXCEPTION WHEN OTHERS THEN + GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT; + RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE; + END; - vertices_sql := _pgr_checkQuery($2); - PERFORM _pgr_checkColumn(vertices_sql, 'id', 'ANY-INTEGER', dryrun => $3); has_in_edges := _pgr_checkColumn(vertices_sql, 'in_edges', 'ANY-INTEGER[]', true, dryrun => $3); has_out_edges := _pgr_checkColumn(vertices_sql, 'out_edges', 'ANY-INTEGER[]', true, dryrun => $3); + IF NOT has_in_edges AND NOT has_out_edges THEN + RAISE EXCEPTION 'column "in_edges" does not exist' USING HINT = vertices_sql, ERRCODE = 42703; + END IF; + IF has_in_edges THEN eids = $$coalesce(in_edges::BIGINT[], '{}'::BIGINT[])$$; END IF; @@ -106,16 +118,10 @@ BEGIN RETURN QUERY EXECUTE query; END IF; - EXCEPTION WHEN OTHERS THEN - RAISE EXCEPTION '%', SQLERRM - USING HINT = 'Please check query: '|| $1; - END; $BODY$ LANGUAGE plpgsql VOLATILE STRICT; - --- COMMENTS COMMENT ON FUNCTION pgr_degree(TEXT, TEXT, BOOLEAN) IS 'pgr_degree - PROPOSED diff --git a/sql/topology/extractVertices.sql b/sql/topology/extractVertices.sql index 1dc5180e1ea..26cb099f933 100644 --- a/sql/topology/extractVertices.sql +++ b/sql/topology/extractVertices.sql @@ -44,20 +44,49 @@ DECLARE quoted TEXT; query TEXT; has_geom BOOLEAN := TRUE; + has_st BOOLEAN := TRUE; has_source BOOLEAN := TRUE; + has_target BOOLEAN := TRUE; has_points BOOLEAN := TRUE; + has_start BOOLEAN := TRUE; + has_end BOOLEAN := TRUE; has_id BOOLEAN := TRUE; rec RECORD; + sqlhint TEXT; + BEGIN - edges_sql := _pgr_checkQuery($1); + BEGIN + edges_sql := _pgr_checkQuery($1); + EXCEPTION WHEN OTHERS THEN + GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT; + RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE; + END; + has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', true, dryrun => $2); - has_source := _pgr_checkColumn(edges_sql, 'source', 'ANY-INTEGER', true, dryrun => $2) - AND _pgr_checkColumn(edges_sql, 'target', 'ANY-INTEGER', true, dryrun => $2); + has_source := _pgr_checkColumn(edges_sql, 'source', 'ANY-INTEGER', true, dryrun => $2); + has_target := _pgr_checkColumn(edges_sql, 'target', 'ANY-INTEGER', true, dryrun => $2); has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', true, dryrun => $2); - has_points := _pgr_checkColumn(edges_sql, 'startpoint', 'geometry', true, dryrun => $2) - AND _pgr_checkColumn(edges_sql, 'endpoint', 'geometry', true, dryrun => $2); + has_start := _pgr_checkColumn(edges_sql, 'startpoint', 'geometry', true, dryrun => $2); + has_end := _pgr_checkColumn(edges_sql, 'endpoint', 'geometry', true, dryrun => $2); + has_points := has_start AND has_end; + has_st := has_source AND has_target; + + IF (NOT has_geom) THEN + IF (has_target AND NOT has_source) THEN + RAISE EXCEPTION 'column "source" does not exist' USING HINT = $1, ERRCODE = 42703; + ELSIF (NOT has_target AND has_source) THEN + RAISE EXCEPTION 'column "target" does not exist' USING HINT = $1, ERRCODE = 42703; + ELSIF (has_start AND NOT has_end) THEN + RAISE EXCEPTION 'column "endpoint" does not exist' USING HINT = $1, ERRCODE = 42703; + ELSIF (NOT has_start AND has_end) THEN + RAISE EXCEPTION 'column "startpoint" does not exist' USING HINT = $1, ERRCODE = 42703; + ELSIF (NOT has_st AND NOT has_points AND NOT has_geom) THEN + RAISE EXCEPTION 'column "geom" does not exist' USING HINT = $1, ERRCODE = 42703; + END IF; + END IF; + IF has_geom AND has_id THEN -- SELECT id, geom @@ -202,7 +231,7 @@ BEGIN SELECT row_number() over(ORDER BY ST_X(geom), ST_Y(geom)) AS id, NULL::BIGINT[], NULL::BIGINT[], x, y, geom FROM the_points$q$; - ELSIF has_source AND has_id THEN + ELSIF has_st AND has_id THEN -- SELECT id, source, target query := $q$ WITH @@ -232,7 +261,7 @@ BEGIN FROM the_points$q$; - ELSIF has_source AND NOT has_id THEN + ELSIF has_st AND NOT has_id THEN -- SELECT source, target query := $q$ WITH @@ -251,10 +280,6 @@ BEGIN SELECT DISTINCT vid::BIGINT AS id, NULL::BIGINT[], NULL::BIGINT[], NULL::FLOAT, NULL::FLOAT, NULL::geometry FROM the_points$q$; - ELSE - RAISE EXCEPTION 'Missing column' - USING HINT = 'Please check query: '|| $1; - END IF; IF dryrun THEN @@ -263,10 +288,6 @@ BEGIN RETURN QUERY EXECUTE query; END IF; - EXCEPTION WHEN OTHERS THEN - RAISE EXCEPTION '%', SQLERRM - USING HINT = 'Please check query: '|| $1; - END; $BODY$ LANGUAGE plpgsql VOLATILE STRICT; diff --git a/sql/utilities/findCloseEdges.sql b/sql/utilities/findCloseEdges.sql index 5b207f9a526..87869712abe 100644 --- a/sql/utilities/findCloseEdges.sql +++ b/sql/utilities/findCloseEdges.sql @@ -44,6 +44,9 @@ DECLARE has_geom BOOLEAN; ret_query TEXT; ret_query_end TEXT; + + sqlhint TEXT; + BEGIN IF ($3 < 0) THEN @@ -54,10 +57,14 @@ BEGIN RAISE EXCEPTION 'Invalid value for cap'; END IF; - edges_sql := _pgr_checkQuery($1); - has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun => dryrun); - has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun => dryrun); - + BEGIN + edges_sql := _pgr_checkQuery($1); + has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun => dryrun); + has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun => dryrun); + EXCEPTION WHEN OTHERS THEN + GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT; + RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE; + END; ret_query = format( $q$ @@ -155,15 +162,23 @@ DECLARE has_geom BOOLEAN; ret_query TEXT; ret_query_end TEXT; + + sqlhint TEXT; + BEGIN IF ($3 < 0) THEN RAISE EXCEPTION 'Invalid value for tolerance'; END IF; - edges_sql := _pgr_checkQuery($1); - has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun => dryrun); - has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun => dryrun); + BEGIN + edges_sql := _pgr_checkQuery($1); + has_id := _pgr_checkColumn(edges_sql, 'id', 'ANY-INTEGER', false, dryrun => dryrun); + has_geom := _pgr_checkColumn(edges_sql, 'geom', 'geometry', false, dryrun => dryrun); + EXCEPTION WHEN OTHERS THEN + GET STACKED DIAGNOSTICS sqlhint = PG_EXCEPTION_HINT; + RAISE EXCEPTION '%', SQLERRM USING HINT = sqlhint, ERRCODE = SQLSTATE; + END; ret_query = format( $q$ diff --git a/tools/testers/general_pgtap_tests.sql b/tools/testers/general_pgtap_tests.sql index 4a066f5b51c..465c1b4015c 100644 --- a/tools/testers/general_pgtap_tests.sql +++ b/tools/testers/general_pgtap_tests.sql @@ -29,3 +29,23 @@ END; $BODY$ LANGUAGE plpgsql; + +CREATE OR REPLACE FUNCTION column_missing(TEXT, TEXT) +RETURNS TEXT AS +$BODY$ + SELECT CASE WHEN min_version('3.8.0') THEN + collect_tap(throws_ok($1, '42703','column "' || $2 || '" does not exist')) + ELSE + collect_tap(throws_ok($1, 'P0001', 'Missing column')) + END; +$BODY$ LANGUAGE SQL; + +CREATE OR REPLACE FUNCTION wrong_relation(TEXT, TEXT) +RETURNS TEXT AS +$BODY$ + SELECT CASE WHEN min_version('3.8.0') THEN + collect_tap(throws_ok($1, '42P01', 'relation "' || $2 || '" does not exist')) + ELSE + collect_tap(throws_ok($1, 'P0001', 'relation "' || $2 || '" does not exist')) + END; +$BODY$ LANGUAGE SQL;