summaryrefslogtreecommitdiff
path: root/src/test
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2024-07-14 13:49:46 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2024-07-14 13:49:46 -0400
commitcf588e10f664be37a0804e9a8662facd0e163800 (patch)
tree427bdb1d463f7da94b358b47fb08a31a386902ab /src/test
parent5ea9f66616801d0b4be6ce49c74e45bb4f325359 (diff)
Avoid unhelpful internal error for incorrect recursive-WITH queries.
checkWellFormedRecursion would issue "missing recursive reference" if a WITH RECURSIVE query contained a single self-reference but that self-reference was inside a top-level WITH, ORDER BY, LIMIT, etc, rather than inside the second arm of the UNION as expected. We already intended to throw more-on-point errors for such cases, but those error checks must be done before examining the UNION arm in order to have the desired results. So this patch need only move some code (and improve the comments). Per bug #18536 from Alexander Lakhin. Back-patch to all supported branches. Discussion: https://postgr.es/m/18536-0a342ec07901203e@postgresql.org
Diffstat (limited to 'src/test')
-rw-r--r--src/test/regress/expected/with.out40
-rw-r--r--src/test/regress/sql/with.sql29
2 files changed, 69 insertions, 0 deletions
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index b4f3121751c..08cfa5463fb 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -2029,6 +2029,46 @@ WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
ERROR: recursive reference to query "x" must not appear within its non-recursive term
LINE 1: WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
^
+-- allow this, because we historically have
+WITH RECURSIVE x(n) AS (
+ WITH x1 AS (SELECT 1 AS n)
+ SELECT 0
+ UNION
+ SELECT * FROM x1)
+ SELECT * FROM x;
+ n
+---
+ 0
+ 1
+(2 rows)
+
+-- but this should be rejected
+WITH RECURSIVE x(n) AS (
+ WITH x1 AS (SELECT 1 FROM x)
+ SELECT 0
+ UNION
+ SELECT * FROM x1)
+ SELECT * FROM x;
+ERROR: recursive reference to query "x" must not appear within a subquery
+LINE 2: WITH x1 AS (SELECT 1 FROM x)
+ ^
+-- and this too
+WITH RECURSIVE x(n) AS (
+ (WITH x1 AS (SELECT 1 FROM x) SELECT * FROM x1)
+ UNION
+ SELECT 0)
+ SELECT * FROM x;
+ERROR: recursive reference to query "x" must not appear within its non-recursive term
+LINE 2: (WITH x1 AS (SELECT 1 FROM x) SELECT * FROM x1)
+ ^
+-- and this
+WITH RECURSIVE x(n) AS (
+ SELECT 0 UNION SELECT 1
+ ORDER BY (SELECT n FROM x))
+ SELECT * FROM x;
+ERROR: ORDER BY in a recursive query is not implemented
+LINE 3: ORDER BY (SELECT n FROM x))
+ ^
CREATE TEMPORARY TABLE y (a INTEGER);
INSERT INTO y SELECT generate_series(1, 10);
-- LEFT JOIN
diff --git a/src/test/regress/sql/with.sql b/src/test/regress/sql/with.sql
index 3fb0b33fce9..8f6e6c0b405 100644
--- a/src/test/regress/sql/with.sql
+++ b/src/test/regress/sql/with.sql
@@ -908,6 +908,35 @@ WITH RECURSIVE x(n) AS (SELECT n FROM x)
WITH RECURSIVE x(n) AS (SELECT n FROM x UNION ALL SELECT 1)
SELECT * FROM x;
+-- allow this, because we historically have
+WITH RECURSIVE x(n) AS (
+ WITH x1 AS (SELECT 1 AS n)
+ SELECT 0
+ UNION
+ SELECT * FROM x1)
+ SELECT * FROM x;
+
+-- but this should be rejected
+WITH RECURSIVE x(n) AS (
+ WITH x1 AS (SELECT 1 FROM x)
+ SELECT 0
+ UNION
+ SELECT * FROM x1)
+ SELECT * FROM x;
+
+-- and this too
+WITH RECURSIVE x(n) AS (
+ (WITH x1 AS (SELECT 1 FROM x) SELECT * FROM x1)
+ UNION
+ SELECT 0)
+ SELECT * FROM x;
+
+-- and this
+WITH RECURSIVE x(n) AS (
+ SELECT 0 UNION SELECT 1
+ ORDER BY (SELECT n FROM x))
+ SELECT * FROM x;
+
CREATE TEMPORARY TABLE y (a INTEGER);
INSERT INTO y SELECT generate_series(1, 10);