diff options
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 8243802199d..7a81010e4cf 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -27,6 +27,7 @@ #include "optimizer/clauses.h" #include "optimizer/cost.h" #include "optimizer/paths.h" +#include "optimizer/placeholder.h" #include "optimizer/plancat.h" #include "optimizer/planmain.h" #include "optimizer/predtest.h" @@ -1886,7 +1887,20 @@ create_nestloop_plan(PlannerInfo *root, NestLoopParam *nlp = (NestLoopParam *) lfirst(cell); next = lnext(cell); - if (bms_is_member(nlp->paramval->varno, outerrelids)) + if (IsA(nlp->paramval, Var) && + bms_is_member(nlp->paramval->varno, outerrelids)) + { + root->curOuterParams = list_delete_cell(root->curOuterParams, + cell, prev); + nestParams = lappend(nestParams, nlp); + } + else if (IsA(nlp->paramval, PlaceHolderVar) && + bms_overlap(((PlaceHolderVar *) nlp->paramval)->phrels, + outerrelids) && + bms_is_subset(find_placeholder_info(root, + (PlaceHolderVar *) nlp->paramval, + false)->ph_eval_at, + outerrelids)) { root->curOuterParams = list_delete_cell(root->curOuterParams, cell, prev); @@ -2314,11 +2328,12 @@ create_hashjoin_plan(PlannerInfo *root, /* * replace_nestloop_params - * Replace outer-relation Vars in the given expression with nestloop Params + * Replace outer-relation Vars and PlaceHolderVars in the given expression + * with nestloop Params * - * All Vars belonging to the relation(s) identified by root->curOuterRels - * are replaced by Params, and entries are added to root->curOuterParams if - * not already present. + * All Vars and PlaceHolderVars belonging to the relation(s) identified by + * root->curOuterRels are replaced by Params, and entries are added to + * root->curOuterParams if not already present. */ static Node * replace_nestloop_params(PlannerInfo *root, Node *expr) @@ -2345,7 +2360,7 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) if (!bms_is_member(var->varno, root->curOuterRels)) return node; /* Create a Param representing the Var */ - param = assign_nestloop_param(root, var); + param = assign_nestloop_param_var(root, var); /* Is this param already listed in root->curOuterParams? */ foreach(lc, root->curOuterParams) { @@ -2365,6 +2380,48 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) /* And return the replacement Param */ return (Node *) param; } + if (IsA(node, PlaceHolderVar)) + { + PlaceHolderVar *phv = (PlaceHolderVar *) node; + Param *param; + NestLoopParam *nlp; + ListCell *lc; + + /* Upper-level PlaceHolderVars should be long gone at this point */ + Assert(phv->phlevelsup == 0); + + /* + * If not to be replaced, just return the PlaceHolderVar unmodified. + * We use bms_overlap as a cheap/quick test to see if the PHV might + * be evaluated in the outer rels, and then grab its PlaceHolderInfo + * to tell for sure. + */ + if (!bms_overlap(phv->phrels, root->curOuterRels)) + return node; + if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at, + root->curOuterRels)) + return node; + /* Create a Param representing the PlaceHolderVar */ + param = assign_nestloop_param_placeholdervar(root, phv); + /* Is this param already listed in root->curOuterParams? */ + foreach(lc, root->curOuterParams) + { + nlp = (NestLoopParam *) lfirst(lc); + if (nlp->paramno == param->paramid) + { + Assert(equal(phv, nlp->paramval)); + /* Present, so we can just return the Param */ + return (Node *) param; + } + } + /* No, so add it */ + nlp = makeNode(NestLoopParam); + nlp->paramno = param->paramid; + nlp->paramval = (Var *) phv; + root->curOuterParams = lappend(root->curOuterParams, nlp); + /* And return the replacement Param */ + return (Node *) param; + } return expression_tree_mutator(node, replace_nestloop_params_mutator, (void *) root); @@ -2377,7 +2434,7 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root) * * We have four tasks here: * * Remove RestrictInfo nodes from the input clauses. - * * Replace any outer-relation Var nodes with nestloop Params. + * * Replace any outer-relation Var or PHV nodes with nestloop Params. * (XXX eventually, that responsibility should go elsewhere?) * * Index keys must be represented by Var nodes with varattno set to the * index's attribute number, not the attribute number in the original rel. |