From 7e00d4e2e08d999f7df8c893e731ef5b6e775fae Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Thu, 2 Feb 2023 19:56:51 +0800 Subject: [PATCH v1] Draft patch to fix postponed quals --- src/backend/optimizer/plan/initsplan.c | 65 ++++++++++++++++++-------- 1 file changed, 45 insertions(+), 20 deletions(-) diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 35b2dc1034..835319f99a 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -74,6 +74,9 @@ typedef struct JoinTreeItem /* Fields filled during deconstruct_distribute: */ SpecialJoinInfo *sjinfo; /* if outer join, its SpecialJoinInfo */ List *oj_joinclauses; /* outer join quals not yet distributed */ + + List *children; + List *postponed_qual_list; } JoinTreeItem; /* Elements of the postponed_qual_list used during deconstruct_distribute */ @@ -89,8 +92,7 @@ static void extract_lateral_references(PlannerInfo *root, RelOptInfo *brel, static List *deconstruct_recurse(PlannerInfo *root, Node *jtnode, JoinDomain *parent_domain, List **item_list); -static void deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, - List **postponed_qual_list); +static void deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem); static void process_security_barrier_quals(PlannerInfo *root, int rti, Relids qualscope, JoinDomain *jdomain); @@ -742,7 +744,6 @@ deconstruct_jointree(PlannerInfo *root) List *result; JoinDomain *top_jdomain; List *item_list = NIL; - List *postponed_qual_list = NIL; ListCell *lc; /* @@ -780,13 +781,9 @@ deconstruct_jointree(PlannerInfo *root) { JoinTreeItem *jtitem = (JoinTreeItem *) lfirst(lc); - deconstruct_distribute(root, jtitem, - &postponed_qual_list); + deconstruct_distribute(root, jtitem); } - /* Shouldn't be any leftover postponed quals */ - Assert(postponed_qual_list == NIL); - /* * However, if there were any special joins then we may have some * postponed LEFT JOIN clauses to deal with. @@ -882,6 +879,7 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, parent_domain, item_list); sub_item = (JoinTreeItem *) llast(*item_list); + jtitem->children = lappend(jtitem->children, sub_item); jtitem->qualscope = bms_add_members(jtitem->qualscope, sub_item->qualscope); jtitem->inner_join_rels = sub_item->inner_join_rels; @@ -929,6 +927,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, item_list); right_item = (JoinTreeItem *) llast(*item_list); /* Compute qualscope etc */ + jtitem->children = lappend(jtitem->children, left_item); + jtitem->children = lappend(jtitem->children, right_item); jtitem->qualscope = bms_union(left_item->qualscope, right_item->qualscope); jtitem->inner_join_rels = jtitem->qualscope; @@ -954,6 +954,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, item_list); right_item = (JoinTreeItem *) llast(*item_list); /* Compute join domain contents, qualscope etc */ + jtitem->children = lappend(jtitem->children, left_item); + jtitem->children = lappend(jtitem->children, right_item); parent_domain->jd_relids = bms_add_members(parent_domain->jd_relids, child_domain->jd_relids); @@ -991,6 +993,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, item_list); right_item = (JoinTreeItem *) llast(*item_list); /* Compute qualscope etc */ + jtitem->children = lappend(jtitem->children, left_item); + jtitem->children = lappend(jtitem->children, right_item); jtitem->qualscope = bms_union(left_item->qualscope, right_item->qualscope); /* SEMI join never has rtindex, so don't add to anything */ @@ -1024,6 +1028,8 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, item_list); right_item = (JoinTreeItem *) llast(*item_list); /* Compute qualscope etc */ + jtitem->children = lappend(jtitem->children, left_item); + jtitem->children = lappend(jtitem->children, right_item); fj_domain->jd_relids = bms_add_members(fj_domain->jd_relids, child_domain->jd_relids); parent_domain->jd_relids = bms_add_members(parent_domain->jd_relids, @@ -1120,11 +1126,12 @@ deconstruct_recurse(PlannerInfo *root, Node *jtnode, * (because their lateral references are still unsatisfied). */ static void -deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, - List **postponed_qual_list) +deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem) { Node *jtnode = jtitem->jtnode; + Assert(jtitem->postponed_qual_list == NIL); + if (IsA(jtnode, RangeTblRef)) { int varno = ((RangeTblRef *) jtnode)->rtindex; @@ -1139,14 +1146,23 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, else if (IsA(jtnode, FromExpr)) { FromExpr *f = (FromExpr *) jtnode; - List *new_postponed_quals = NIL; + List *child_postponed_qual_list = NIL; ListCell *l; + foreach(l, jtitem->children) + { + JoinTreeItem *sub_item = (JoinTreeItem *) lfirst(l); + + child_postponed_qual_list = + list_concat(child_postponed_qual_list, + sub_item->postponed_qual_list); + } + /* * Try to process any quals postponed by children. If they need * further postponement, add them to my output postponed_qual_list. */ - foreach(l, *postponed_qual_list) + foreach(l, child_postponed_qual_list) { PostponedQual *pq = (PostponedQual *) lfirst(l); @@ -1159,9 +1175,9 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, true, false, false, NULL, NULL); else - new_postponed_quals = lappend(new_postponed_quals, pq); + jtitem->postponed_qual_list = + lappend(jtitem->postponed_qual_list, pq); } - *postponed_qual_list = new_postponed_quals; /* * Now process the top-level quals. @@ -1172,18 +1188,27 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, root->qual_security_level, jtitem->qualscope, NULL, NULL, true, false, false, - postponed_qual_list, NULL); + &jtitem->postponed_qual_list, NULL); } else if (IsA(jtnode, JoinExpr)) { JoinExpr *j = (JoinExpr *) jtnode; - List *new_postponed_quals = NIL; + List *child_postponed_qual_list = NIL; Relids ojscope; List *my_quals; SpecialJoinInfo *sjinfo; List **postponed_oj_qual_list; ListCell *l; + foreach(l, jtitem->children) + { + JoinTreeItem *sub_item = (JoinTreeItem *) lfirst(l); + + child_postponed_qual_list = + list_concat(child_postponed_qual_list, + sub_item->postponed_qual_list); + } + /* * Try to process any quals postponed by children. If they need * further postponement, add them to my output postponed_qual_list. @@ -1191,7 +1216,7 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, * that they'll be handled properly in make_outerjoininfo. */ my_quals = NIL; - foreach(l, *postponed_qual_list) + foreach(l, child_postponed_qual_list) { PostponedQual *pq = (PostponedQual *) lfirst(l); @@ -1204,10 +1229,10 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, * If this Assert fires, pull_up_subqueries() messed up. */ Assert(j->jointype == JOIN_INNER); - new_postponed_quals = lappend(new_postponed_quals, pq); + jtitem->postponed_qual_list = + lappend(jtitem->postponed_qual_list, pq); } } - *postponed_qual_list = new_postponed_quals; my_quals = list_concat(my_quals, (List *) j->quals); /* @@ -1275,7 +1300,7 @@ deconstruct_distribute(PlannerInfo *root, JoinTreeItem *jtitem, ojscope, jtitem->nonnullable_rels, true, /* allow_equivalence */ false, false, /* not clones */ - postponed_qual_list, + &jtitem->postponed_qual_list, postponed_oj_qual_list); /* And add the SpecialJoinInfo to join_info_list */ -- 2.31.0