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
commitf96c2c72788cab3005c8bc6b4934b4928b34a529 (patch)
tree6cd60539ca678ab88c840a3a4e796ddf90572b17 /src/test
parentd5e6891502ca9e359aa5f5a381d904fe9d606338 (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);