diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 0344c5b10d917c186274afb3a66cb7b22d308d36..350b99ef178fd348fb8a222cb06be5ce08405ba5 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -110,9 +110,21 @@ add_paths_to_joinrel(PlannerInfo *root, Assert(innerrel->pathlist && innerrel->cheapest_total_path); - /* Don't consider paths that have WorkTableScan as inner rel */ + /* + * Don't consider paths that have WorkTableScan as inner rel. If the outer + * rel has a WorkTableScan as well, we won't be able to produce a usable + * join so we need to error out. This case can happen when to RECURSIVE + * clauses are joined. RECURSIVE_CTE_FIXME: Revisit this when we gain + * rescannable motions. + */ if (innerrel->cheapest_startup_path && cdbpath_contains_wts(innerrel->cheapest_startup_path)) + { + if (outerrel->cheapest_startup_path && cdbpath_contains_wts(outerrel->cheapest_startup_path)) + ereport(ERROR, + (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), + errmsg("joining nested RECURSIVE clauses is not supported"))); return; + } if (cdbpath_contains_wts(innerrel->cheapest_total_path)) return; diff --git a/src/test/regress/expected/with_clause.out b/src/test/regress/expected/with_clause.out index 1493c3914034596782bef33cad6b1679aedb1eaa..3f7c8a9c17fbc9d41d360b9597a410653ea92b30 100644 --- a/src/test/regress/expected/with_clause.out +++ b/src/test/regress/expected/with_clause.out @@ -2163,3 +2163,21 @@ SELECT * FROM y; 1100 | (15 rows) +-- Nested RECURSIVE queries with double self-referential joins are planned by +-- joining two WorkTableScans, which GPDB cannot do yet. Ensure that we error +-- out with a descriptive message. +SET gp_recursive_cte TO ON; +WITH RECURSIVE r1 AS ( + SELECT 1 AS a + UNION ALL + ( + WITH RECURSIVE r2 AS ( + SELECT 2 AS b + UNION ALL + SELECT b FROM r1, r2 + ) + SELECT b FROM r2 + ) +) +SELECT * FROM r1 LIMIT 1; +ERROR: joining nested RECURSIVE clauses is not supported diff --git a/src/test/regress/expected/with_clause_optimizer.out b/src/test/regress/expected/with_clause_optimizer.out index c4ec3345c4a96d7002b46e0923846c9a31e9355a..56c3ed909c2dda53f49cc62f8220a14024399519 100644 --- a/src/test/regress/expected/with_clause_optimizer.out +++ b/src/test/regress/expected/with_clause_optimizer.out @@ -2162,3 +2162,21 @@ SELECT * FROM y; 1100 | (15 rows) +-- Nested RECURSIVE queries with double self-referential joins are planned by +-- joining two WorkTableScans, which GPDB cannot do yet. Ensure that we error +-- out with a descriptive message. +SET gp_recursive_cte TO ON; +WITH RECURSIVE r1 AS ( + SELECT 1 AS a + UNION ALL + ( + WITH RECURSIVE r2 AS ( + SELECT 2 AS b + UNION ALL + SELECT b FROM r1, r2 + ) + SELECT b FROM r2 + ) +) +SELECT * FROM r1 LIMIT 1; +ERROR: joining nested RECURSIVE clauses is not supported diff --git a/src/test/regress/sql/with_clause.sql b/src/test/regress/sql/with_clause.sql index 03176e270b8ee6f966e829ca22067fe7f46567bd..78b007a9bce86099c9ba4bd1c0a3666e8d554de1 100644 --- a/src/test/regress/sql/with_clause.sql +++ b/src/test/regress/sql/with_clause.sql @@ -341,3 +341,21 @@ WITH t AS ( SELECT m BETWEEN 100 AND 1500 FROM t LIMIT 1; SELECT * FROM y; + +-- Nested RECURSIVE queries with double self-referential joins are planned by +-- joining two WorkTableScans, which GPDB cannot do yet. Ensure that we error +-- out with a descriptive message. +SET gp_recursive_cte TO ON; +WITH RECURSIVE r1 AS ( + SELECT 1 AS a + UNION ALL + ( + WITH RECURSIVE r2 AS ( + SELECT 2 AS b + UNION ALL + SELECT b FROM r1, r2 + ) + SELECT b FROM r2 + ) +) +SELECT * FROM r1 LIMIT 1;