aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
Diffstat (limited to 'src/include')
-rw-r--r--src/include/nodes/relation.h71
1 files changed, 40 insertions, 31 deletions
diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h
index af9425ad9b3..2b2742d7ef5 100644
--- a/src/include/nodes/relation.h
+++ b/src/include/nodes/relation.h
@@ -75,8 +75,6 @@ typedef struct PlannerGlobal
ParamListInfo boundParams; /* Param values provided to planner() */
- List *paramlist; /* to keep track of cross-level Params */
-
List *subplans; /* Plans for SubPlan nodes */
List *subroots; /* PlannerInfos for SubPlan nodes */
@@ -93,6 +91,8 @@ typedef struct PlannerGlobal
List *invalItems; /* other dependencies, as PlanInvalItems */
+ int nParamExec; /* number of PARAM_EXEC Params used */
+
Index lastPHId; /* highest PlaceHolderVar ID assigned */
Index lastRowMarkId; /* highest PlanRowMark ID assigned */
@@ -127,6 +127,8 @@ typedef struct PlannerInfo
struct PlannerInfo *parent_root; /* NULL at outermost Query */
+ List *plan_params; /* list of PlannerParamItems, see below */
+
/*
* simple_rel_array holds pointers to "base rels" and "other rels" (see
* comments for RelOptInfo for more info). It is indexed by rangetable
@@ -344,6 +346,7 @@ typedef struct PlannerInfo
* allvisfrac - fraction of disk pages that are marked all-visible
* subplan - plan for subquery (NULL if it's not a subquery)
* subroot - PlannerInfo for subquery (NULL if it's not a subquery)
+ * subplan_params - list of PlannerParamItems to be passed to subquery
* fdwroutine - function hooks for FDW, if foreign table (else NULL)
* fdw_private - private state for FDW, if foreign table (else NULL)
*
@@ -436,6 +439,7 @@ typedef struct RelOptInfo
/* use "struct Plan" to avoid including plannodes.h here */
struct Plan *subplan; /* if subquery */
PlannerInfo *subroot; /* if subquery */
+ List *subplan_params; /* if subquery */
/* use "struct FdwRoutine" to avoid including fdwapi.h here */
struct FdwRoutine *fdwroutine; /* if foreign table */
void *fdw_private; /* if foreign table */
@@ -1507,23 +1511,26 @@ typedef struct MinMaxAggInfo
} MinMaxAggInfo;
/*
- * glob->paramlist keeps track of the PARAM_EXEC slots that we have decided
- * we need for the query. At runtime these slots are used to pass values
- * around from one plan node to another. They can be used to pass values
- * down into subqueries (for outer references in subqueries), or up out of
- * subqueries (for the results of a subplan), or from a NestLoop plan node
- * into its inner relation (when the inner scan is parameterized with values
- * from the outer relation). The n'th entry in the list (n counts from 0)
- * corresponds to Param->paramid = n.
- *
- * Each paramlist item shows the absolute query level it is associated with,
- * where the outermost query is level 1 and nested subqueries have higher
- * numbers. The item the parameter slot represents can be one of four kinds:
- *
- * A Var: the slot represents a variable of that level that must be passed
+ * At runtime, PARAM_EXEC slots are used to pass values around from one plan
+ * node to another. They can be used to pass values down into subqueries (for
+ * outer references in subqueries), or up out of subqueries (for the results
+ * of a subplan), or from a NestLoop plan node into its inner relation (when
+ * the inner scan is parameterized with values from the outer relation).
+ * The planner is responsible for assigning nonconflicting PARAM_EXEC IDs to
+ * the PARAM_EXEC Params it generates.
+ *
+ * Outer references are managed via root->plan_params, which is a list of
+ * PlannerParamItems. While planning a subquery, each parent query level's
+ * plan_params contains the values required from it by the current subquery.
+ * During create_plan(), we use plan_params to track values that must be
+ * passed from outer to inner sides of NestLoop plan nodes.
+ *
+ * The item a PlannerParamItem represents can be one of three kinds:
+ *
+ * A Var: the slot represents a variable of this level that must be passed
* down because subqueries have outer references to it, or must be passed
- * from a NestLoop node of that level to its inner scan. The varlevelsup
- * value in the Var will always be zero.
+ * from a NestLoop node to its inner scan. The varlevelsup value in the Var
+ * will always be zero.
*
* A PlaceHolderVar: this works much like the Var case, except that the
* entry is a PlaceHolderVar node with a contained expression. The PHV
@@ -1535,25 +1542,27 @@ typedef struct MinMaxAggInfo
* subquery. The Aggref itself has agglevelsup = 0, and its argument tree
* is adjusted to match in level.
*
- * A Param: the slot holds the result of a subplan (it is a setParam item
- * for that subplan). The absolute level shown for such items corresponds
- * to the parent query of the subplan.
- *
* Note: we detect duplicate Var and PlaceHolderVar parameters and coalesce
- * them into one slot, but we do not bother to do this for Aggrefs, and it
- * would be incorrect to do so for Param slots. Duplicate detection is
- * actually *necessary* for NestLoop parameters since it serves to match up
- * the usage of a Param (in the inner scan) with the assignment of the value
- * (in the NestLoop node). This might result in the same PARAM_EXEC slot being
- * used by multiple NestLoop nodes or SubPlan nodes, but no harm is done since
- * the same value would be assigned anyway.
+ * them into one slot, but we do not bother to do that for Aggrefs.
+ * The scope of duplicate-elimination only extends across the set of
+ * parameters passed from one query level into a single subquery, or for
+ * nestloop parameters across the set of nestloop parameters used in a single
+ * query level. So there is no possibility of a PARAM_EXEC slot being used
+ * for conflicting purposes.
+ *
+ * In addition, PARAM_EXEC slots are assigned for Params representing outputs
+ * from subplans (values that are setParam items for those subplans). These
+ * IDs need not be tracked via PlannerParamItems, since we do not need any
+ * duplicate-elimination nor later processing of the represented expressions.
+ * Instead, we just record the assignment of the slot number by incrementing
+ * root->glob->nParamExec.
*/
typedef struct PlannerParamItem
{
NodeTag type;
- Node *item; /* the Var, PlaceHolderVar, Aggref, or Param */
- Index abslevel; /* its absolute query level */
+ Node *item; /* the Var, PlaceHolderVar, or Aggref */
+ int paramId; /* its assigned PARAM_EXEC slot number */
} PlannerParamItem;
/*