ojscope;
List *leftjoinlist,
*rightjoinlist;
+ List *my_quals;
SpecialJoinInfo *sjinfo;
ListCell *l;
root->nullable_baserels = bms_add_members(root->nullable_baserels,
nullable_rels);
+ /*
+ * Try to process any quals postponed by children. If they need
+ * further postponement, add them to my output postponed_qual_list.
+ * Quals that can be processed now must be included in my_quals, so
+ * that they'll be handled properly in make_outerjoininfo.
+ */
+ my_quals = NIL;
+ foreach(l, child_postponed_quals)
+ {
+ PostponedQual *pq = (PostponedQual *) lfirst(l);
+
+ if (bms_is_subset(pq->relids, *qualscope))
+ my_quals = lappend(my_quals, pq->qual);
+ else
+ {
+ /*
+ * We should not be postponing any quals past an outer join.
+ * If this Assert fires, pull_up_subqueries() messed up.
+ */
+ Assert(j->jointype == JOIN_INNER);
+ *postponed_qual_list = lappend(*postponed_qual_list, pq);
+ }
+ }
+ /* list_concat is nondestructive of its second argument */
+ my_quals = list_concat(my_quals, (List *) j->quals);
+
/*
* For an OJ, form the SpecialJoinInfo now, because we need the OJ's
* semantic scope (ojscope) to pass to distribute_qual_to_rels. But
leftids, rightids,
*inner_join_rels,
j->jointype,
- (List *) j->quals);
+ my_quals);
if (j->jointype == JOIN_SEMI)
ojscope = NULL;
else
ojscope = NULL;
}
- /*
- * Try to process any quals postponed by children. If they need
- * further postponement, add them to my output postponed_qual_list.
- */
- foreach(l, child_postponed_quals)
- {
- PostponedQual *pq = (PostponedQual *) lfirst(l);
-
- if (bms_is_subset(pq->relids, *qualscope))
- distribute_qual_to_rels(root, pq->qual,
- false, below_outer_join, j->jointype,
- *qualscope,
- ojscope, nonnullable_rels, NULL,
- NULL);
- else
- {
- /*
- * We should not be postponing any quals past an outer join.
- * If this Assert fires, pull_up_subqueries() messed up.
- */
- Assert(j->jointype == JOIN_INNER);
- *postponed_qual_list = lappend(*postponed_qual_list, pq);
- }
- }
-
/* Process the JOIN's qual clauses */
- foreach(l, (List *) j->quals)
+ foreach(l, my_quals)
{
Node *qual = (Node *) lfirst(l);
Output: i.f1
(34 rows)
+-- check processing of postponed quals (bug #9041)
+explain (verbose, costs off)
+select * from
+ (select 1 as x) x cross join (select 2 as y) y
+ left join lateral (
+ select * from (select 3 as z) z where z.z = x.x
+ ) zz on zz.z = y.y;
+ QUERY PLAN
+----------------------------------------------
+ Nested Loop Left Join
+ Output: (1), (2), (3)
+ Join Filter: (((3) = (1)) AND ((3) = (2)))
+ -> Nested Loop
+ Output: (1), (2)
+ -> Result
+ Output: 1
+ -> Result
+ Output: 2
+ -> Result
+ Output: 3
+(11 rows)
+
-- test some error cases where LATERAL should have been used but wasn't
select f1,g from int4_tbl a, (select f1 as g) ss;
ERROR: column "f1" does not exist
) on c.q2 = ss2.q1,
lateral (select * from int4_tbl i where ss2.y > f1) ss3;
+-- check processing of postponed quals (bug #9041)
+explain (verbose, costs off)
+select * from
+ (select 1 as x) x cross join (select 2 as y) y
+ left join lateral (
+ select * from (select 3 as z) z where z.z = x.x
+ ) zz on zz.z = y.y;
+
-- test some error cases where LATERAL should have been used but wasn't
select f1,g from int4_tbl a, (select f1 as g) ss;
select f1,g from int4_tbl a, (select a.f1 as g) ss;