61 int strategy,
bool nulls_first)
69 elog(
ERROR,
"too soon to build canonical pathkeys");
150 foreach(lc, pathkeys)
212 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
216 elog(
ERROR,
"could not find opfamilies for equality operator %u",
221 opfamilies, opcintype, collation,
222 sortref, rel, create_it);
230 strategy, nulls_first);
256 &opfamily, &opcintype, &strategy))
257 elog(
ERROR,
"operator %u is not a valid ordering operator",
303 forboth(key1, keys1, key2, keys2)
308 if (pathkey1 != pathkey2)
353 List **group_clauses)
355 List *new_group_pathkeys =
NIL,
356 *new_group_clauses =
NIL;
360 if (pathkeys ==
NIL || *group_pathkeys ==
NIL)
374 foreach(lc, pathkeys)
383 new_group_pathkeys =
lappend(new_group_pathkeys, pathkey);
388 new_group_clauses =
lappend(new_group_clauses, sgc);
438 state->mutatorNColumns = n;
482 while (
j >= 0 &&
a[
j] >=
a[
j + 1])
490 while (k >= 0 &&
a[
j] >=
a[k])
519 if (
state->count == 1)
520 return state->elemsList;
535 for (
i = 0;
i <
state->mutatorNColumns;
i++)
539 return state->elemsList;
557 if (
a->cost <
b->cost)
559 else if (
a->cost ==
b->cost)
585 List **group_pathkeys,
List **group_clauses,
588 List *new_group_pathkeys =
NIL,
589 *new_group_clauses =
NIL,
594 double cheapest_sort_cost = -1.0;
600 if (
list_length(*group_pathkeys) - n_preordered < 2)
619 nFreeKeys =
list_length(*group_pathkeys) - n_preordered;
621 if (nFreeKeys > nToPermute)
630 for (
i = 0; cell != NULL;
i++, (cell =
lnext(*group_pathkeys, cell)))
651 for (
i = 0;
i < nFreeKeys;
i++)
652 new_group_pathkeys =
lappend(new_group_pathkeys, costs[
i].pathkey);
659 new_group_pathkeys =
list_copy(*group_pathkeys);
660 nToPermute = nFreeKeys;
684 PathkeyMutatorInit(&mstate, new_group_pathkeys, n_preordered, n_preordered + nToPermute);
692 if (cost < cheapest_sort_cost || cheapest_sort_cost < 0)
695 new_group_pathkeys =
list_copy(var_group_pathkeys);
696 cheapest_sort_cost = cost;
701 foreach(cell, new_group_pathkeys)
705 new_group_clauses =
lappend(new_group_clauses,
714 *group_pathkeys = new_group_pathkeys;
715 *group_clauses = new_group_clauses;
747 List *group_pathkeys,
List *group_clauses)
752 int n_preordered = 0;
754 List *pathkeys = group_pathkeys;
755 List *clauses = group_clauses;
773 if (
parse->groupingSets)
881 else if (keys1 ==
NIL)
886 else if (keys2 ==
NIL)
896 forboth(key1, keys1, key2, keys2)
901 if (pathkey1 != pathkey2)
911 return (key1 == NULL);
930 bool require_parallel_safe)
932 Path *matched_path = NULL;
943 if (matched_path != NULL &&
977 Path *matched_path = NULL;
988 if (matched_path != NULL &&
1054 if (
index->sortopfamily == NULL)
1058 foreach(lc,
index->indextlist)
1070 if (
i >=
index->nkeycolumns)
1074 indexkey = indextle->
expr;
1078 reverse_sort = !
index->reverse_sort[
i];
1079 nulls_first = !
index->nulls_first[
i];
1083 reverse_sort =
index->reverse_sort[
i];
1084 nulls_first =
index->nulls_first[
i];
1096 index->indexcollations[
i],
1110 retval =
lappend(retval, cpathkey);
1158 if (!IsBooleanOpfamily(partscheme->
partopfamily[partkeycol]))
1194 if (
equal(partexpr, clause))
1229 Assert(partscheme != NULL);
1267 retval =
lappend(retval, cpathkey);
1283 *partialkeys =
true;
1289 *partialkeys =
false;
1320 &opfamily, &opcintype, &strategy))
1321 elog(
ERROR,
"operator %u is not a valid ordering operator",
1362 List *subquery_pathkeys,
1363 List *subquery_tlist)
1370 foreach(
i, subquery_pathkeys)
1387 elog(
ERROR,
"volatile EquivalenceClass has no sortref");
1453 int best_score = -1;
1467 foreach(k, subquery_tlist)
1490 if (!
equal(tle_expr, sub_expr))
1519 if (retvallen < outer_query_keys &&
1522 if (score > best_score)
1524 best_pathkey = outer_pk;
1544 retval =
lappend(retval, best_pathkey);
1608 List *outer_pathkeys)
1655 foreach(l, sortclauses)
1673 pathkeys =
lappend(pathkeys, pathkey);
1724 ((
OpExpr *) clause)->inputcollid,
1734 ((
OpExpr *) clause)->inputcollid,
1787 List *restrictinfos)
1793 foreach(
i, restrictinfos)
1800 foreach(
i, pathkeys)
1804 List *matched_restrictinfos =
NIL;
1844 foreach(
j, restrictinfos)
1851 if (clause_ec == pathkey_ec)
1852 matched_restrictinfos =
lappend(matched_restrictinfos, rinfo);
1860 if (matched_restrictinfos ==
NIL)
1867 mergeclauses =
list_concat(mergeclauses, matched_restrictinfos);
1870 return mergeclauses;
1919 scores = (
int *)
palloc(nClauses *
sizeof(
int));
1922 foreach(lc, mergeclauses)
1938 for (
j = 0;
j < necs;
j++)
1940 if (ecs[
j] == oeclass)
1958 ecs[necs] = oeclass;
1959 scores[necs] = score;
1975 for (
j = 0;
j < necs;
j++)
1977 if (ecs[
j] == query_ec)
1994 for (
j = 0;
j < necs;
j++)
1996 if (ecs[
j] == query_ec)
2019 best_score = scores[0];
2020 for (
j = 1;
j < necs;
j++)
2022 if (scores[
j] > best_score)
2025 best_score = scores[
j];
2031 scores[best_j] = -1;
2039 pathkeys =
lappend(pathkeys, pathkey);
2072 List *outer_pathkeys)
2084 foreach(lc, mergeclauses)
2106 if (oeclass != lastoeclass)
2109 elog(
ERROR,
"too few pathkeys for mergeclauses");
2111 lop =
lnext(outer_pathkeys, lop);
2113 if (oeclass != lastoeclass)
2114 elog(
ERROR,
"outer pathkeys do not match mergeclause");
2122 if (ieclass == oeclass)
2141 pathkeys =
lappend(pathkeys, pathkey);
2180 bool matched_pathkey;
2185 if (pathkeys ==
NIL)
2191 lip =
lnext(pathkeys, lip);
2192 matched_pathkey =
false;
2195 foreach(
i, mergeclauses)
2207 if (clause_ec != pathkey_ec)
2210 if (!matched_pathkey)
2218 lip =
lnext(pathkeys, lip);
2219 matched_pathkey =
false;
2223 if (clause_ec == pathkey_ec)
2225 new_mergeclauses =
lappend(new_mergeclauses, rinfo);
2226 matched_pathkey =
true;
2235 return new_mergeclauses;
2273 foreach(
i, pathkeys)
2276 bool matched =
false;
2374 int n_common_pathkeys;
2379 if (pathkeys ==
NIL)
2383 &n_common_pathkeys);
2385 return n_common_pathkeys;
2418 if (pathkeys ==
NIL)
2422 foreach(
key, pathkeys)
2450 if (nuseful2 > nuseful)
2453 if (nuseful2 > nuseful)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
bool bms_is_empty(const Bitmapset *a)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
#define OidIsValid(objectId)
Cost cost_sort_estimate(PlannerInfo *root, List *pathkeys, int nPresortedKeys, double tuples)
bool equal(const void *a, const void *b)
EquivalenceClass * get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, Relids nullable_relids, List *opfamilies, Oid opcintype, Oid collation, Index sortref, Relids rel, bool create_it)
Expr * canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation)
bool eclass_useful_for_merging(PlannerInfo *root, EquivalenceClass *eclass, RelOptInfo *rel)
bool indexcol_is_bool_constant_for_query(PlannerInfo *root, IndexOptInfo *index, int indexcol)
Assert(fmt[strlen(fmt) - 1] !='\n')
List * list_truncate(List *list, int new_size)
List * lappend(List *list, void *datum)
List * list_copy(const List *oldlist)
bool list_member_ptr(const List *list, const void *datum)
List * list_concat_unique_ptr(List *list1, const List *list2)
void list_free(List *list)
List * list_concat(List *list1, const List *list2)
List * get_mergejoin_opfamilies(Oid opno)
Oid get_opfamily_member(Oid opfamily, Oid lefttype, Oid righttype, int16 strategy)
bool get_ordering_op_properties(Oid opno, Oid *opfamily, Oid *opcintype, int16 *strategy)
void op_input_types(Oid opno, Oid *lefttype, Oid *righttype)
void pfree(void *pointer)
Oid exprCollation(const Node *expr)
static Expr * get_notclausearg(const void *notclause)
static Node * get_rightop(const void *clause)
static bool is_notclause(const void *clause)
static Node * get_leftop(const void *clause)
#define IsA(nodeptr, _type_)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
bool partitions_are_ordered(PartitionBoundInfo boundinfo, Bitmapset *live_parts)
static void PathkeyMutatorSwap(int *a, int i, int j)
static bool matches_boolean_partition_clause(RestrictInfo *rinfo, RelOptInfo *partrel, int partkeycol)
List * build_join_pathkeys(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, List *outer_pathkeys)
struct PathkeyMutatorState PathkeyMutatorState
static bool PathkeyMutatorNextSet(int *a, int n)
static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey)
List * make_inner_pathkeys_for_merge(PlannerInfo *root, List *mergeclauses, List *outer_pathkeys)
Path * get_cheapest_path_for_pathkeys(List *paths, List *pathkeys, Relids required_outer, CostSelector cost_criterion, bool require_parallel_safe)
bool pathkeys_count_contained_in(List *keys1, List *keys2, int *n_common)
static bool get_cheapest_group_keys_order(PlannerInfo *root, double nrows, List **group_pathkeys, List **group_clauses, int n_preordered)
static int pathkey_sort_cost_comparator(const void *_a, const void *_b)
List * find_mergeclauses_for_outer_pathkeys(PlannerInfo *root, List *pathkeys, List *restrictinfos)
bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)
List * truncate_useless_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
struct PathkeySortCost PathkeySortCost
List * get_useful_group_keys_orderings(PlannerInfo *root, double nrows, List *path_pathkeys, List *group_pathkeys, List *group_clauses)
static PathKey * make_pathkey_from_sortop(PlannerInfo *root, Expr *expr, Relids nullable_relids, Oid ordering_op, bool nulls_first, Index sortref, bool create_it)
List * build_expression_pathkey(PlannerInfo *root, Expr *expr, Relids nullable_relids, Oid opno, Relids rel, bool create_it)
static int pathkeys_useful_for_ordering(PlannerInfo *root, List *pathkeys)
List * trim_mergeclauses_for_inner_pathkeys(PlannerInfo *root, List *mergeclauses, List *pathkeys)
List * select_outer_pathkeys_for_merge(PlannerInfo *root, List *mergeclauses, RelOptInfo *joinrel)
void update_mergeclause_eclasses(PlannerInfo *root, RestrictInfo *restrictinfo)
static Var * find_var_for_subquery_tle(RelOptInfo *rel, TargetEntry *tle)
List * build_index_pathkeys(PlannerInfo *root, IndexOptInfo *index, ScanDirection scandir)
static int pathkeys_useful_for_grouping(PlannerInfo *root, List *pathkeys)
static bool partkey_is_bool_constant_for_query(RelOptInfo *partrel, int partkeycol)
bool enable_group_by_reordering
static bool pathkey_is_redundant(PathKey *new_pathkey, List *pathkeys)
PathKey * make_canonical_pathkey(PlannerInfo *root, EquivalenceClass *eclass, Oid opfamily, int strategy, bool nulls_first)
static PathKey * make_pathkey_from_sortinfo(PlannerInfo *root, Expr *expr, Relids nullable_relids, Oid opfamily, Oid opcintype, Oid collation, bool reverse_sort, bool nulls_first, Index sortref, Relids rel, bool create_it)
int group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys, List **group_clauses)
static List * PathkeyMutatorNext(PathkeyMutatorState *state)
Path * get_cheapest_parallel_safe_total_inner(List *paths)
List * make_pathkeys_for_sortclauses(PlannerInfo *root, List *sortclauses, List *tlist)
static int pathkeys_useful_for_merging(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
List * convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *subquery_pathkeys, List *subquery_tlist)
void initialize_mergeclause_eclasses(PlannerInfo *root, RestrictInfo *restrictinfo)
Path * get_cheapest_fractional_path_for_pathkeys(List *paths, List *pathkeys, Relids required_outer, double fraction)
bool pathkeys_contained_in(List *keys1, List *keys2)
PathKeysComparison compare_pathkeys(List *keys1, List *keys2)
static void PathkeyMutatorInit(PathkeyMutatorState *state, List *elems, int start, int end)
List * build_partition_pathkeys(PlannerInfo *root, RelOptInfo *partrel, ScanDirection scandir, bool *partialkeys)
int compare_fractional_path_costs(Path *path1, Path *path2, double fraction)
int compare_path_costs(Path *path1, Path *path2, CostSelector criterion)
#define EC_MUST_BE_REDUNDANT(eclass)
#define IS_SIMPLE_REL(rel)
#define PATH_REQ_OUTER(path)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define for_each_cell(cell, lst, initcell)
static ListCell * list_head(const List *l)
static ListCell * list_nth_cell(const List *list, int n)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
#define qsort(a, b, c, d)
static struct cvec * eclass(struct vars *v, chr c, int cases)
static struct subre * parse(struct vars *, int, int, struct state *, struct state *)
#define ScanDirectionIsBackward(direction)
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
struct EquivalenceClass * ec_merged
EquivalenceClass * pk_eclass
MemoryContext planner_cxt
struct PathTarget * reltarget
struct PartitionBoundInfoData * boundinfo
PartitionScheme part_scheme
EquivalenceClass * left_ec
EquivalenceClass * right_ec
TargetEntry * get_sortgroupref_tle(Index sortref, List *targetList)
Node * get_sortgroupclause_expr(SortGroupClause *sgClause, List *targetList)
SortGroupClause * get_sortgroupref_clause(Index sortref, List *clauses)