diff options
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 39 |
1 files changed, 21 insertions, 18 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0e34873d6a8..dd13852fbdf 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -127,7 +127,8 @@ typedef struct /* Local functions */ static Node *preprocess_expression(PlannerInfo *root, Node *expr, int kind); static void preprocess_qual_conditions(PlannerInfo *root, Node *jtnode); -static void grouping_planner(PlannerInfo *root, double tuple_fraction); +static void grouping_planner(PlannerInfo *root, double tuple_fraction, + SetOperationStmt *setops); static grouping_sets_data *preprocess_grouping_sets(PlannerInfo *root); static List *remap_to_groupclause_idx(List *groupClause, List *gsets, int *tleref_to_colnum_map); @@ -411,8 +412,7 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, } /* primary planning entry point (may recurse for subqueries) */ - root = subquery_planner(glob, parse, NULL, - false, tuple_fraction); + root = subquery_planner(glob, parse, NULL, false, tuple_fraction, NULL); /* Select best Path and turn it into a Plan */ final_rel = fetch_upper_rel(root, UPPERREL_FINAL, NULL); @@ -603,6 +603,10 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, * 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. + * setops is used for set operation subqueries to provide the subquery with + * the context in which it's being used so that Paths correctly sorted for the + * set operation can be generated. NULL when not planning a set operation + * child. * * Basically, this routine does the stuff that should only be done once * per Query object. It then calls grouping_planner. At one time, @@ -621,9 +625,9 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, *-------------------- */ PlannerInfo * -subquery_planner(PlannerGlobal *glob, Query *parse, - PlannerInfo *parent_root, - bool hasRecursion, double tuple_fraction) +subquery_planner(PlannerGlobal *glob, Query *parse, PlannerInfo *parent_root, + bool hasRecursion, double tuple_fraction, + SetOperationStmt *setops) { PlannerInfo *root; List *newWithCheckOptions; @@ -1085,7 +1089,7 @@ subquery_planner(PlannerGlobal *glob, Query *parse, /* * Do the main planning. */ - grouping_planner(root, tuple_fraction); + grouping_planner(root, tuple_fraction, setops); /* * Capture the set of outer-level param IDs we have access to, for use in @@ -1283,7 +1287,11 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr) * 0 < tuple_fraction < 1: expect the given fraction of tuples available * from the plan to be retrieved * tuple_fraction >= 1: tuple_fraction is the absolute number of tuples - * expected to be retrieved (ie, a LIMIT specification) + * expected to be retrieved (ie, a LIMIT specification). + * setops is used for set operation subqueries to provide the subquery with + * the context in which it's being used so that Paths correctly sorted for the + * set operation can be generated. NULL when not planning a set operation + * child. * * Returns nothing; the useful output is in the Paths we attach to the * (UPPERREL_FINAL, NULL) upperrel in *root. In addition, @@ -1294,7 +1302,8 @@ preprocess_phv_expression(PlannerInfo *root, Expr *expr) *-------------------- */ static void -grouping_planner(PlannerInfo *root, double tuple_fraction) +grouping_planner(PlannerInfo *root, double tuple_fraction, + SetOperationStmt *setops) { Query *parse = root->parse; int64 offset_est = 0; @@ -1510,16 +1519,10 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) qp_extra.gset_data = gset_data; /* - * Check if we're a subquery for a set operation. If we are, store - * the SetOperationStmt in qp_extra. + * If we're a subquery for a set operation, store the SetOperationStmt + * in qp_extra. */ - if (root->parent_root != NULL && - root->parent_root->parse->setOperations != NULL && - IsA(root->parent_root->parse->setOperations, SetOperationStmt)) - qp_extra.setop = - (SetOperationStmt *) root->parent_root->parse->setOperations; - else - qp_extra.setop = NULL; + qp_extra.setop = setops; /* * Generate the best unsorted and presorted paths for the scan/join |