aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/allpaths.c20
-rw-r--r--src/test/regress/expected/subselect.out53
-rw-r--r--src/test/regress/sql/subselect.sql26
3 files changed, 96 insertions, 3 deletions
diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c
index 8e8f43735e0..27bec72d452 100644
--- a/src/backend/optimizer/path/allpaths.c
+++ b/src/backend/optimizer/path/allpaths.c
@@ -3295,8 +3295,10 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
Assert(!contain_window_function(qual));
/*
- * Examine all Vars used in clause; since it's a restriction clause, all
- * such Vars must refer to subselect output columns.
+ * Examine all Vars used in clause. Since it's a restriction clause, all
+ * such Vars must refer to subselect output columns ... unless this is
+ * part of a LATERAL subquery, in which case there could be lateral
+ * references.
*/
vars = pull_var_clause(qual, PVC_INCLUDE_PLACEHOLDERS);
foreach(vl, vars)
@@ -3316,7 +3318,19 @@ qual_is_pushdown_safe(Query *subquery, Index rti, Node *qual,
break;
}
- Assert(var->varno == rti);
+ /*
+ * Punt if we find any lateral references. It would be safe to push
+ * these down, but we'd have to convert them into outer references,
+ * which subquery_push_qual lacks the infrastructure to do. The case
+ * arises so seldom that it doesn't seem worth working hard on.
+ */
+ if (var->varno != rti)
+ {
+ safe = false;
+ break;
+ }
+
+ /* Subqueries have no system columns */
Assert(var->varattno >= 0);
/* Check point 4 */
diff --git a/src/test/regress/expected/subselect.out b/src/test/regress/expected/subselect.out
index 5ec067ee200..f0958091844 100644
--- a/src/test/regress/expected/subselect.out
+++ b/src/test/regress/expected/subselect.out
@@ -1160,6 +1160,59 @@ from int4_tbl;
(5 rows)
--
+-- Check for sane handling of a lateral reference in a subquery's quals
+-- (most of the complication here is to prevent the test case from being
+-- flattened too much)
+--
+explain (verbose, costs off)
+select * from
+ int4_tbl i4,
+ lateral (
+ select i4.f1 > 1 as b, 1 as id
+ from (select random() order by 1) as t1
+ union all
+ select true as b, 2 as id
+ ) as t2
+where b and f1 >= 0;
+ QUERY PLAN
+--------------------------------------------
+ Nested Loop
+ Output: i4.f1, ((i4.f1 > 1)), (1)
+ -> Seq Scan on public.int4_tbl i4
+ Output: i4.f1
+ Filter: (i4.f1 >= 0)
+ -> Append
+ -> Subquery Scan on t1
+ Output: (i4.f1 > 1), 1
+ Filter: (i4.f1 > 1)
+ -> Sort
+ Output: (random())
+ Sort Key: (random())
+ -> Result
+ Output: random()
+ -> Result
+ Output: true, 2
+(16 rows)
+
+select * from
+ int4_tbl i4,
+ lateral (
+ select i4.f1 > 1 as b, 1 as id
+ from (select random() order by 1) as t1
+ union all
+ select true as b, 2 as id
+ ) as t2
+where b and f1 >= 0;
+ f1 | b | id
+------------+---+----
+ 0 | t | 2
+ 123456 | t | 1
+ 123456 | t | 2
+ 2147483647 | t | 1
+ 2147483647 | t | 2
+(5 rows)
+
+--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--
diff --git a/src/test/regress/sql/subselect.sql b/src/test/regress/sql/subselect.sql
index 352ff6daa40..74ae1fefbe6 100644
--- a/src/test/regress/sql/subselect.sql
+++ b/src/test/regress/sql/subselect.sql
@@ -628,6 +628,32 @@ select (select q from
from int4_tbl;
--
+-- Check for sane handling of a lateral reference in a subquery's quals
+-- (most of the complication here is to prevent the test case from being
+-- flattened too much)
+--
+explain (verbose, costs off)
+select * from
+ int4_tbl i4,
+ lateral (
+ select i4.f1 > 1 as b, 1 as id
+ from (select random() order by 1) as t1
+ union all
+ select true as b, 2 as id
+ ) as t2
+where b and f1 >= 0;
+
+select * from
+ int4_tbl i4,
+ lateral (
+ select i4.f1 > 1 as b, 1 as id
+ from (select random() order by 1) as t1
+ union all
+ select true as b, 2 as id
+ ) as t2
+where b and f1 >= 0;
+
+--
-- Check that volatile quals aren't pushed down past a DISTINCT:
-- nextval() should not be called more than the nominal number of times
--