/* Generate a subroot and Paths for the subquery */
plan_name = choose_plan_name(root->glob, rte->eref->aliasname, false);
rel->subroot = subquery_planner(root->glob, subquery, plan_name,
- root, false, tuple_fraction, NULL);
+ root, NULL, false, tuple_fraction, NULL);
/* Isolate the params needed by this specific subplan */
rel->subplan_params = root->plan_params;
subroot->query_level++;
subroot->parent_root = root;
subroot->plan_name = choose_plan_name(root->glob, "minmax", true);
+ subroot->alternative_plan_name = root->plan_name;
/* reset subplan-related stuff */
subroot->plan_params = NIL;
&tuple_fraction, es);
/* primary planning entry point (may recurse for subqueries) */
- root = subquery_planner(glob, parse, NULL, NULL, false, tuple_fraction,
- NULL);
+ root = subquery_planner(glob, parse, NULL, NULL, NULL, false,
+ tuple_fraction, NULL);
/* Select best Path and turn it into a Plan */
final_rel = fetch_upper_rel(root, UPPERREL_FINAL, NULL);
* parse is the querytree produced by the parser & rewriter.
* plan_name is the name to assign to this subplan (NULL at the top level).
* parent_root is the immediate parent Query's info (NULL at the top level).
+ * alternative_root is a previously created PlannerInfo for which this query
+ * level is an alternative implementation, or else NULL.
* hasRecursion is true if this is a recursive WITH query.
* tuple_fraction is the fraction of tuples we expect will be retrieved.
* tuple_fraction is interpreted as explained for grouping_planner, below.
*/
PlannerInfo *
subquery_planner(PlannerGlobal *glob, Query *parse, char *plan_name,
- PlannerInfo *parent_root, bool hasRecursion,
- double tuple_fraction, SetOperationStmt *setops)
+ PlannerInfo *parent_root, PlannerInfo *alternative_root,
+ bool hasRecursion, double tuple_fraction,
+ SetOperationStmt *setops)
{
PlannerInfo *root;
List *newWithCheckOptions;
root->glob = glob;
root->query_level = parent_root ? parent_root->query_level + 1 : 1;
root->plan_name = plan_name;
+ if (alternative_root != NULL)
+ root->alternative_plan_name = alternative_root->plan_name;
+ else
+ root->alternative_plan_name = plan_name;
root->parent_root = parent_root;
root->plan_params = NIL;
root->outer_params = NULL;
/* Generate Paths for the subquery */
subroot = subquery_planner(root->glob, subquery,
choose_plan_name(root->glob, sublinkstr, true),
- root, false, tuple_fraction, NULL);
+ root, NULL, false, tuple_fraction, NULL);
/* Isolate the params needed by this specific subplan */
plan_params = root->plan_params;
/* Generate Paths for the ANY subquery; we'll need all rows */
plan_name = choose_plan_name(root->glob, sublinkstr, true);
subroot = subquery_planner(root->glob, subquery, plan_name,
- root, false, 0.0, NULL);
+ root, subroot, false, 0.0, NULL);
/* Isolate the params needed by this specific subplan */
plan_params = root->plan_params;
*/
subroot = subquery_planner(root->glob, subquery,
choose_plan_name(root->glob, cte->ctename, false),
- root, cte->cterecursive, 0.0, NULL);
+ root, NULL, cte->cterecursive, 0.0, NULL);
/*
* Since the current query level doesn't yet contain any RTEs, it
subroot->glob = root->glob;
subroot->query_level = root->query_level;
subroot->plan_name = root->plan_name;
+ subroot->alternative_plan_name = root->alternative_plan_name;
subroot->parent_root = root->parent_root;
subroot->plan_params = NIL;
subroot->outer_params = NULL;
*/
plan_name = choose_plan_name(root->glob, "setop", true);
subroot = rel->subroot = subquery_planner(root->glob, subquery,
- plan_name, root,
+ plan_name, root, NULL,
false, root->tuple_fraction,
parentOp);
/* Subplan name for EXPLAIN and debugging purposes (NULL at top level) */
char *plan_name;
+ /*
+ * If this PlannerInfo exists to consider an alternative implementation
+ * strategy for a portion of the query that could also be implemented by
+ * some other PlannerInfo, this is the plan_name for that other
+ * PlannerInfo. When we are considering the first or only alternative,
+ * it is the same as plan_name.
+ *
+ * Currently, we set this to a value other than plan_name only when
+ * considering a MinMaxAggPath or a hashed SubPlan.
+ */
+ char *alternative_plan_name;
+
/*
* plan_params contains the expressions that this query level needs to
* make available to a lower query level that is currently being planned.
extern PlannerInfo *subquery_planner(PlannerGlobal *glob, Query *parse,
char *plan_name,
PlannerInfo *parent_root,
+ PlannerInfo *alternative_root,
bool hasRecursion, double tuple_fraction,
SetOperationStmt *setops);