summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/createplan.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r--src/backend/optimizer/plan/createplan.c178
1 files changed, 8 insertions, 170 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 9c16065c154..452cf0dfae4 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -19,7 +19,6 @@
#include <limits.h>
#include <math.h>
-#include "access/stratnum.h"
#include "access/sysattr.h"
#include "catalog/pg_class.h"
#include "foreign/fdwapi.h"
@@ -29,11 +28,11 @@
#include "nodes/nodeFuncs.h"
#include "optimizer/clauses.h"
#include "optimizer/cost.h"
+#include "optimizer/paramassign.h"
#include "optimizer/paths.h"
#include "optimizer/placeholder.h"
#include "optimizer/plancat.h"
#include "optimizer/planmain.h"
-#include "optimizer/planner.h"
#include "optimizer/predtest.h"
#include "optimizer/restrictinfo.h"
#include "optimizer/subselect.h"
@@ -147,8 +146,6 @@ static MergeJoin *create_mergejoin_plan(PlannerInfo *root, MergePath *best_path)
static HashJoin *create_hashjoin_plan(PlannerInfo *root, HashPath *best_path);
static Node *replace_nestloop_params(PlannerInfo *root, Node *expr);
static Node *replace_nestloop_params_mutator(Node *node, PlannerInfo *root);
-static void process_subquery_nestloop_params(PlannerInfo *root,
- List *subplan_params);
static List *fix_indexqual_references(PlannerInfo *root, IndexPath *index_path);
static List *fix_indexorderby_references(PlannerInfo *root, IndexPath *index_path);
static Node *fix_indexqual_operand(Node *node, IndexOptInfo *index, int indexcol);
@@ -295,7 +292,7 @@ create_plan(PlannerInfo *root, Path *best_path)
/* plan_params should not be in use in current query level */
Assert(root->plan_params == NIL);
- /* Initialize this module's private workspace in PlannerInfo */
+ /* Initialize this module's workspace in PlannerInfo */
root->curOuterRels = NULL;
root->curOuterParams = NIL;
@@ -3444,9 +3441,6 @@ create_nestloop_plan(PlannerInfo *root,
Relids outerrelids;
List *nestParams;
Relids saveOuterRels = root->curOuterRels;
- ListCell *cell;
- ListCell *prev;
- ListCell *next;
/* NestLoop can project, so no need to be picky about child tlists */
outer_plan = create_plan_recurse(root, best_path->outerjoinpath, 0);
@@ -3490,38 +3484,10 @@ create_nestloop_plan(PlannerInfo *root,
/*
* Identify any nestloop parameters that should be supplied by this join
- * node, and move them from root->curOuterParams to the nestParams list.
+ * node, and remove them from root->curOuterParams.
*/
outerrelids = best_path->outerjoinpath->parent->relids;
- nestParams = NIL;
- prev = NULL;
- for (cell = list_head(root->curOuterParams); cell; cell = next)
- {
- NestLoopParam *nlp = (NestLoopParam *) lfirst(cell);
-
- next = lnext(cell);
- 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);
- nestParams = lappend(nestParams, nlp);
- }
- else
- prev = cell;
- }
+ nestParams = identify_current_nestloop_params(root, outerrelids);
join_plan = make_nestloop(tlist,
joinclauses,
@@ -4007,42 +3973,18 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
if (IsA(node, Var))
{
Var *var = (Var *) node;
- Param *param;
- NestLoopParam *nlp;
- ListCell *lc;
/* Upper-level Vars should be long gone at this point */
Assert(var->varlevelsup == 0);
/* If not to be replaced, we can just return the Var unmodified */
if (!bms_is_member(var->varno, root->curOuterRels))
return node;
- /* Create a Param representing the Var */
- param = assign_nestloop_param_var(root, var);
- /* Is this param already listed in root->curOuterParams? */
- foreach(lc, root->curOuterParams)
- {
- nlp = (NestLoopParam *) lfirst(lc);
- if (nlp->paramno == param->paramid)
- {
- Assert(equal(var, 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;
- root->curOuterParams = lappend(root->curOuterParams, nlp);
- /* And return the replacement Param */
- return (Node *) param;
+ /* Replace the Var with a nestloop Param */
+ return (Node *) replace_nestloop_param_var(root, var);
}
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);
@@ -4079,26 +4021,8 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
root);
return (Node *) newphv;
}
- /* 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;
+ /* Replace the PlaceHolderVar with a nestloop Param */
+ return (Node *) replace_nestloop_param_placeholdervar(root, phv);
}
return expression_tree_mutator(node,
replace_nestloop_params_mutator,
@@ -4106,92 +4030,6 @@ replace_nestloop_params_mutator(Node *node, PlannerInfo *root)
}
/*
- * process_subquery_nestloop_params
- * Handle params of a parameterized subquery that need to be fed
- * from an outer nestloop.
- *
- * Currently, that would be *all* params that a subquery in FROM has demanded
- * from the current query level, since they must be LATERAL references.
- *
- * The subplan's references to the outer variables are already represented
- * as PARAM_EXEC Params, so we need not modify the subplan here. What we
- * do need to do is add entries to root->curOuterParams to signal the parent
- * nestloop plan node that it must provide these values.
- */
-static void
-process_subquery_nestloop_params(PlannerInfo *root, List *subplan_params)
-{
- ListCell *ppl;
-
- foreach(ppl, subplan_params)
- {
- PlannerParamItem *pitem = (PlannerParamItem *) lfirst(ppl);
-
- if (IsA(pitem->item, Var))
- {
- Var *var = (Var *) pitem->item;
- NestLoopParam *nlp;
- ListCell *lc;
-
- /* If not from a nestloop outer rel, complain */
- if (!bms_is_member(var->varno, root->curOuterRels))
- elog(ERROR, "non-LATERAL parameter required by subquery");
- /* Is this param already listed in root->curOuterParams? */
- foreach(lc, root->curOuterParams)
- {
- nlp = (NestLoopParam *) lfirst(lc);
- if (nlp->paramno == pitem->paramId)
- {
- Assert(equal(var, nlp->paramval));
- /* Present, so nothing to do */
- break;
- }
- }
- if (lc == NULL)
- {
- /* No, so add it */
- nlp = makeNode(NestLoopParam);
- nlp->paramno = pitem->paramId;
- nlp->paramval = copyObject(var);
- root->curOuterParams = lappend(root->curOuterParams, nlp);
- }
- }
- else if (IsA(pitem->item, PlaceHolderVar))
- {
- PlaceHolderVar *phv = (PlaceHolderVar *) pitem->item;
- NestLoopParam *nlp;
- ListCell *lc;
-
- /* If not from a nestloop outer rel, complain */
- if (!bms_is_subset(find_placeholder_info(root, phv, false)->ph_eval_at,
- root->curOuterRels))
- elog(ERROR, "non-LATERAL parameter required by subquery");
- /* Is this param already listed in root->curOuterParams? */
- foreach(lc, root->curOuterParams)
- {
- nlp = (NestLoopParam *) lfirst(lc);
- if (nlp->paramno == pitem->paramId)
- {
- Assert(equal(phv, nlp->paramval));
- /* Present, so nothing to do */
- break;
- }
- }
- if (lc == NULL)
- {
- /* No, so add it */
- nlp = makeNode(NestLoopParam);
- nlp->paramno = pitem->paramId;
- nlp->paramval = copyObject(phv);
- root->curOuterParams = lappend(root->curOuterParams, nlp);
- }
- }
- else
- elog(ERROR, "unexpected type of subquery parameter");
- }
-}
-
-/*
* fix_indexqual_references
* Adjust indexqual clauses to the form the executor's indexqual
* machinery needs.