-
-
Notifications
You must be signed in to change notification settings - Fork 393
fix: validate negative distance in pgr_drivingDistance #3079
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| /* :file: This file is part of the pgRouting project. | ||
| :copyright: Copyright (c) 2025-2026 pgRouting developers | ||
| :license: Creative Commons Attribution-Share Alike 3.0 https://creativecommons.org/licenses/by-sa/3.0 */ | ||
|
|
||
| BEGIN; | ||
|
|
||
| UPDATE edges SET cost = sign(cost), reverse_cost = sign(reverse_cost); | ||
| SELECT CASE WHEN min_version('3.6.0') AND min_lib_version('5.0.0') THEN plan(3) ELSE plan(1) END; | ||
|
|
||
| CREATE OR REPLACE FUNCTION test_function() | ||
| RETURNS SETOF TEXT AS | ||
| $BODY$ | ||
| BEGIN | ||
| IF min_version('3.6.0') AND min_lib_version('5.0.0') THEN | ||
| -- Test negative distance throws error | ||
| SELECT throws_ok( | ||
| $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, -1.0)$$, | ||
| 'XX000', | ||
| 'Invalid value of ''distance''', | ||
| 'SHOULD THROW because distance is negative' | ||
| ); | ||
|
|
||
| -- Test zero distance throws error | ||
| SELECT throws_ok( | ||
| $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, 0.0)$$, | ||
| 'XX000', | ||
| 'Invalid value of ''distance''', | ||
| 'SHOULD THROW because distance is zero' | ||
| ); | ||
|
|
||
| -- Test positive distance works (regression test) | ||
| SELECT lives_ok( | ||
| $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, 1.0)$$, | ||
| 'SHOULD NOT THROW because distance is positive' | ||
| ); | ||
| ELSE | ||
| SELECT skip(1, 'Distance validation standardized on pgRouting 5.0.0'); | ||
| END IF; | ||
| END; | ||
| $BODY$ | ||
| LANGUAGE plpgsql; | ||
|
|
||
| SELECT * FROM test_function(); | ||
| SELECT * FROM finish(); | ||
| ROLLBACK; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -79,8 +79,8 @@ void pgr_process_spanningTree( | |
|
|
||
| switch (val) { | ||
| case 1: | ||
| if (distance < 0) { | ||
| pgr_throw_error("Negative value found on 'distance'", "Must be non negative"); | ||
| if (distance <= 0) { | ||
| pgr_throw_error("Invalid value of 'distance'", "Valid values are greater than 0"); | ||
| } | ||
|
Comment on lines
+82
to
84
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: # Search for pgtap tests related to spanningTree
find . -path "*/pgtap/*" -name "*spanningTree*" -type fRepository: pgRouting/pgrouting Length of output: 45 🏁 Script executed: # Search for any references to the distance error messages
rg -n "Negative value found on 'distance'|Invalid value of 'distance'" --type-listRepository: pgRouting/pgrouting Length of output: 452 🏁 Script executed: # Search for spanningTree test files more broadly
find . -path "*/pgtap/*" -type f | grep -i "span"Repository: pgRouting/pgrouting Length of output: 1942 🏁 Script executed: # Search for the old and new distance error messages in the entire repo
rg "Negative value found on 'distance'|Invalid value of 'distance'" -nRepository: pgRouting/pgrouting Length of output: 496 🏁 Script executed: # Also check the source file itself to see context
cat -n src/spanningTree/spanningTree_process.cpp | sed -n '75,95p'Repository: pgRouting/pgrouting Length of output: 896 🏁 Script executed: # Search for any distance validation error messages
rg "distance" pgtap/spanningTree/ -n | grep -i "error\|throw\|exception" | head -20Repository: pgRouting/pgrouting Length of output: 412 🏁 Script executed: # Read the actual test assertions for the negative distance tests
cat -n pgtap/spanningTree/prim/primDD/edge_cases.pg | sed -n '110,140p'Repository: pgRouting/pgrouting Length of output: 1004 🏁 Script executed: # Also check kruskalDD for comparison
cat -n pgtap/spanningTree/kruskal/kruskalDD/edge_cases.pg | sed -n '110,140p'Repository: pgRouting/pgrouting Length of output: 1022 🏁 Script executed: # Check the full source file around line 106 to understand both distance checks
cat -n src/spanningTree/spanningTree_process.cpp | sed -n '100,115p'Repository: pgRouting/pgrouting Length of output: 553 Update pgtap tests to expect the new distance error message. Tests in 🧰 Tools🪛 Cppcheck (2.19.0)[style] 83-83: The function 'pgr_free' is never used. (unusedFunction) 🤖 Prompt for AI Agents✅ Addressed in commit 8f1b951 |
||
| break; | ||
| case 2: | ||
|
|
@@ -102,8 +102,8 @@ void pgr_process_spanningTree( | |
| break; | ||
|
|
||
| case DIJKSTRADD: | ||
| if (distance < 0) { | ||
| pgr_throw_error("Negative value found on 'distance'", "Must be positive"); | ||
| if (distance <= 0) { | ||
| pgr_throw_error("Invalid value of 'distance'", "Valid values are greater than 0"); | ||
| } | ||
| break; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🏁 Script executed:
Repository: pgRouting/pgrouting
Length of output: 7135
🏁 Script executed:
Repository: pgRouting/pgrouting
Length of output: 396
🏁 Script executed:
Repository: pgRouting/pgrouting
Length of output: 1950
Add
RETURN QUERYbefore each assertion — test function returns zero rows without it.In a plpgsql function returning
SETOF TEXT, bareSELECTstatements execute the query but discard the results. Thethrows_ok,lives_ok, andskipreturn values are never passed to the caller, soSELECT * FROM test_function()returns zero rows instead of three. Theplan(3)call will fail with a mismatch between expected and actual assertion count.Fix: add RETURN QUERY before each assertion
IF min_version('3.6.0') THEN -- Test negative distance throws error - SELECT throws_ok( + RETURN QUERY SELECT throws_ok( $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, -1.0)$$, 'XX000', 'Invalid value of ''distance''', 'SHOULD THROW because distance is negative' ); -- Test zero distance throws error - SELECT throws_ok( + RETURN QUERY SELECT throws_ok( $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, 0.0)$$, 'XX000', 'Invalid value of ''distance''', 'SHOULD THROW because distance is zero' ); -- Test positive distance works (regression test) - SELECT lives_ok( + RETURN QUERY SELECT lives_ok( $$SELECT * FROM pgr_drivingDistance('SELECT id, source, target, cost FROM edges', 1, 1.0)$$, 'SHOULD NOT THROW because distance is positive' ); ELSE - SELECT skip(1, 'Function standardized on 3.6.0'); + RETURN QUERY SELECT skip(1, 'Function standardized on 3.6.0'); END IF;🤖 Prompt for AI Agents