diff options
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 118 |
1 files changed, 9 insertions, 109 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 84f2d186d95..f7cd738eeac 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -259,9 +259,6 @@ static Plan *prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Oid **p_sortOperators, Oid **p_collations, bool **p_nullsFirst); -static EquivalenceMember *find_ec_member_for_tle(EquivalenceClass *ec, - TargetEntry *tle, - Relids relids); static Sort *make_sort_from_pathkeys(Plan *lefttree, List *pathkeys, Relids relids); static IncrementalSort *make_incrementalsort_from_pathkeys(Plan *lefttree, @@ -1993,7 +1990,7 @@ create_sort_plan(PlannerInfo *root, SortPath *best_path, int flags) flags | CP_SMALL_TLIST); /* - * make_sort_from_pathkeys() indirectly calls find_ec_member_for_tle(), + * make_sort_from_pathkeys indirectly calls find_ec_member_matching_expr, * which will ignore any child EC members that don't belong to the given * relids. Thus, if this sort path is based on a child relation, we must * pass its relids. @@ -5844,9 +5841,6 @@ make_incrementalsort(Plan *lefttree, int numCols, int nPresortedCols, * * Returns the node which is to be the input to the Sort (either lefttree, * or a Result stacked atop lefttree). - * - * Note: Restrictions on what expressions are safely sortable may also need to - * be added to find_em_expr_usable_for_sorting_rel. */ static Plan * prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, @@ -5916,7 +5910,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, tle = get_tle_by_resno(tlist, reqColIdx[numsortkeys]); if (tle) { - em = find_ec_member_for_tle(ec, tle, relids); + em = find_ec_member_matching_expr(ec, tle->expr, relids); if (em) { /* found expr at right place in tlist */ @@ -5947,7 +5941,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, foreach(j, tlist) { tle = (TargetEntry *) lfirst(j); - em = find_ec_member_for_tle(ec, tle, relids); + em = find_ec_member_matching_expr(ec, tle->expr, relids); if (em) { /* found expr already in tlist */ @@ -5961,56 +5955,12 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, if (!tle) { /* - * No matching tlist item; look for a computable expression. Note - * that we treat Aggrefs as if they were variables; this is - * necessary when attempting to sort the output from an Agg node - * for use in a WindowFunc (since grouping_planner will have - * treated the Aggrefs as variables, too). Likewise, if we find a - * WindowFunc in a sort expression, treat it as a variable. + * No matching tlist item; look for a computable expression. */ - Expr *sortexpr = NULL; - - foreach(j, ec->ec_members) - { - EquivalenceMember *em = (EquivalenceMember *) lfirst(j); - List *exprvars; - ListCell *k; - - /* - * We shouldn't be trying to sort by an equivalence class that - * contains a constant, so no need to consider such cases any - * further. - */ - if (em->em_is_const) - continue; - - /* - * Ignore child members unless they belong to the rel being - * sorted. - */ - if (em->em_is_child && - !bms_is_subset(em->em_relids, relids)) - continue; - - sortexpr = em->em_expr; - exprvars = pull_var_clause((Node *) sortexpr, - PVC_INCLUDE_AGGREGATES | - PVC_INCLUDE_WINDOWFUNCS | - PVC_INCLUDE_PLACEHOLDERS); - foreach(k, exprvars) - { - if (!tlist_member_ignore_relabel(lfirst(k), tlist)) - break; - } - list_free(exprvars); - if (!k) - { - pk_datatype = em->em_datatype; - break; /* found usable expression */ - } - } - if (!j) + em = find_computable_ec_member(NULL, ec, tlist, relids, false); + if (!em) elog(ERROR, "could not find pathkey item to sort"); + pk_datatype = em->em_datatype; /* * Do we need to insert a Result node? @@ -6030,7 +5980,7 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, /* * Add resjunk entry to input's tlist */ - tle = makeTargetEntry(sortexpr, + tle = makeTargetEntry(copyObject(em->em_expr), list_length(tlist) + 1, NULL, true); @@ -6070,56 +6020,6 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys, } /* - * find_ec_member_for_tle - * Locate an EquivalenceClass member matching the given TLE, if any - * - * Child EC members are ignored unless they belong to given 'relids'. - */ -static EquivalenceMember * -find_ec_member_for_tle(EquivalenceClass *ec, - TargetEntry *tle, - Relids relids) -{ - Expr *tlexpr; - ListCell *lc; - - /* We ignore binary-compatible relabeling on both ends */ - tlexpr = tle->expr; - while (tlexpr && IsA(tlexpr, RelabelType)) - tlexpr = ((RelabelType *) tlexpr)->arg; - - foreach(lc, ec->ec_members) - { - EquivalenceMember *em = (EquivalenceMember *) lfirst(lc); - Expr *emexpr; - - /* - * We shouldn't be trying to sort by an equivalence class that - * contains a constant, so no need to consider such cases any further. - */ - if (em->em_is_const) - continue; - - /* - * Ignore child members unless they belong to the rel being sorted. - */ - if (em->em_is_child && - !bms_is_subset(em->em_relids, relids)) - continue; - - /* Match if same expression (after stripping relabel) */ - emexpr = em->em_expr; - while (emexpr && IsA(emexpr, RelabelType)) - emexpr = ((RelabelType *) emexpr)->arg; - - if (equal(emexpr, tlexpr)) - return em; - } - - return NULL; -} - -/* * make_sort_from_pathkeys * Create sort plan to sort according to given pathkeys * @@ -6558,7 +6458,7 @@ make_unique_from_pathkeys(Plan *lefttree, List *pathkeys, int numCols) foreach(j, plan->targetlist) { tle = (TargetEntry *) lfirst(j); - em = find_ec_member_for_tle(ec, tle, NULL); + em = find_ec_member_matching_expr(ec, tle->expr, NULL); if (em) { /* found expr already in tlist */ |