aboutsummaryrefslogtreecommitdiff
path: root/src/include
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2020-09-27 12:51:28 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2020-09-27 12:51:28 -0400
commit41efb8340877e8ffd0023bb6b2ef22ffd1ca014d (patch)
tree74e248b1beb50cdbf1094684cbf4c00d146af5f2 /src/include
parent3c8819955023694feeaa456ee60853d0d6d0e60a (diff)
downloadpostgresql-41efb8340877e8ffd0023bb6b2ef22ffd1ca014d.tar.gz
postgresql-41efb8340877e8ffd0023bb6b2ef22ffd1ca014d.zip
Move resolution of AlternativeSubPlan choices to the planner.
When commit bd3daddaf introduced AlternativeSubPlans, I had some ambitions towards allowing the choice of subplan to change during execution. That has not happened, or even been thought about, in the ensuing twelve years; so it seems like a failed experiment. So let's rip that out and resolve the choice of subplan at the end of planning (in setrefs.c) rather than during executor startup. This has a number of positive benefits: * Removal of a few hundred lines of executor code, since AlternativeSubPlans need no longer be supported there. * Removal of executor-startup overhead (particularly, initialization of subplans that won't be used). * Removal of incidental costs of having a larger plan tree, such as tree-scanning and copying costs in the plancache; not to mention setrefs.c's own costs of processing the discarded subplans. * EXPLAIN no longer has to print a weird (and undocumented) representation of an AlternativeSubPlan choice; it sees only the subplan actually used. This should mean less confusion for users. * Since setrefs.c knows which subexpression of a plan node it's working on at any instant, it's possible to adjust the estimated number of executions of the subplan based on that. For example, we should usually estimate more executions of a qual expression than a targetlist expression. The implementation used here is pretty simplistic, because we don't want to expend a lot of cycles on the issue; but it's better than ignoring the point entirely, as the executor had to. That last point might possibly result in shifting the choice between hashed and non-hashed EXISTS subplans in a few cases, but in general this patch isn't meant to change planner choices. Since we're doing the resolution so late, it's really impossible to change any plan choices outside the AlternativeSubPlan itself. Patch by me; thanks to David Rowley for review. Discussion: https://postgr.es/m/1992952.1592785225@sss.pgh.pa.us
Diffstat (limited to 'src/include')
-rw-r--r--src/include/executor/execExpr.h10
-rw-r--r--src/include/executor/nodeSubplan.h4
-rw-r--r--src/include/nodes/execnodes.h12
-rw-r--r--src/include/nodes/nodes.h1
-rw-r--r--src/include/nodes/pathnodes.h1
-rw-r--r--src/include/nodes/primnodes.h3
6 files changed, 4 insertions, 27 deletions
diff --git a/src/include/executor/execExpr.h b/src/include/executor/execExpr.h
index dbe8649a576..b792de1bc95 100644
--- a/src/include/executor/execExpr.h
+++ b/src/include/executor/execExpr.h
@@ -218,7 +218,6 @@ typedef enum ExprEvalOp
EEOP_GROUPING_FUNC,
EEOP_WINDOW_FUNC,
EEOP_SUBPLAN,
- EEOP_ALTERNATIVE_SUBPLAN,
/* aggregation related nodes */
EEOP_AGG_STRICT_DESERIALIZE,
@@ -589,13 +588,6 @@ typedef struct ExprEvalStep
SubPlanState *sstate;
} subplan;
- /* for EEOP_ALTERNATIVE_SUBPLAN */
- struct
- {
- /* out-of-line state, created by nodeSubplan.c */
- AlternativeSubPlanState *asstate;
- } alternative_subplan;
-
/* for EEOP_AGG_*DESERIALIZE */
struct
{
@@ -734,8 +726,6 @@ extern void ExecEvalXmlExpr(ExprState *state, ExprEvalStep *op);
extern void ExecEvalGroupingFunc(ExprState *state, ExprEvalStep *op);
extern void ExecEvalSubPlan(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
-extern void ExecEvalAlternativeSubPlan(ExprState *state, ExprEvalStep *op,
- ExprContext *econtext);
extern void ExecEvalWholeRowVar(ExprState *state, ExprEvalStep *op,
ExprContext *econtext);
extern void ExecEvalSysVar(ExprState *state, ExprEvalStep *op,
diff --git a/src/include/executor/nodeSubplan.h b/src/include/executor/nodeSubplan.h
index 83e90b3d07b..b629af1f5fb 100644
--- a/src/include/executor/nodeSubplan.h
+++ b/src/include/executor/nodeSubplan.h
@@ -18,12 +18,8 @@
extern SubPlanState *ExecInitSubPlan(SubPlan *subplan, PlanState *parent);
-extern AlternativeSubPlanState *ExecInitAlternativeSubPlan(AlternativeSubPlan *asplan, PlanState *parent);
-
extern Datum ExecSubPlan(SubPlanState *node, ExprContext *econtext, bool *isNull);
-extern Datum ExecAlternativeSubPlan(AlternativeSubPlanState *node, ExprContext *econtext, bool *isNull);
-
extern void ExecReScanSetParamPlan(SubPlanState *node, PlanState *parent);
extern void ExecSetParamPlan(SubPlanState *node, ExprContext *econtext);
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index a5ab1aed14d..ef448d67c77 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -877,18 +877,6 @@ typedef struct SubPlanState
ExprState *cur_eq_comp; /* equality comparator for LHS vs. table */
} SubPlanState;
-/* ----------------
- * AlternativeSubPlanState node
- * ----------------
- */
-typedef struct AlternativeSubPlanState
-{
- NodeTag type;
- AlternativeSubPlan *subplan; /* expression plan node */
- List *subplans; /* SubPlanStates of alternative subplans */
- int active; /* list index of the one we're using */
-} AlternativeSubPlanState;
-
/*
* DomainConstraintState - one item to check during CoerceToDomain
*
diff --git a/src/include/nodes/nodes.h b/src/include/nodes/nodes.h
index 381d84b4e4f..7ddd8c011bf 100644
--- a/src/include/nodes/nodes.h
+++ b/src/include/nodes/nodes.h
@@ -213,7 +213,6 @@ typedef enum NodeTag
T_WindowFuncExprState,
T_SetExprState,
T_SubPlanState,
- T_AlternativeSubPlanState,
T_DomainConstraintState,
/*
diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h
index 485d1b06c91..dbe86e7af65 100644
--- a/src/include/nodes/pathnodes.h
+++ b/src/include/nodes/pathnodes.h
@@ -347,6 +347,7 @@ struct PlannerInfo
bool hasHavingQual; /* true if havingQual was non-null */
bool hasPseudoConstantQuals; /* true if any RestrictInfo has
* pseudoconstant = true */
+ bool hasAlternativeSubPlans; /* true if we've made any of those */
bool hasRecursion; /* true if planning a recursive WITH item */
/* These fields are used only when hasRecursion is true: */
diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h
index d73be2ad46c..fd65ee8f9c5 100644
--- a/src/include/nodes/primnodes.h
+++ b/src/include/nodes/primnodes.h
@@ -736,6 +736,9 @@ typedef struct SubPlan
/*
* AlternativeSubPlan - expression node for a choice among SubPlans
*
+ * This is used only transiently during planning: by the time the plan
+ * reaches the executor, all AlternativeSubPlan nodes have been removed.
+ *
* The subplans are given as a List so that the node definition need not
* change if there's ever more than two alternatives. For the moment,
* though, there are always exactly two; and the first one is the fast-start