57 int strategy,
bool nulls_first)
65 elog(
ERROR,
"too soon to build canonical pathkeys");
74 if (
eclass == pk->pk_eclass &&
168 foreach(lc, pathkeys)
172 if (new_ec == old_pathkey->pk_eclass)
226 elog(
ERROR,
"missing operator %d(%u,%u) in opfamily %u",
230 elog(
ERROR,
"could not find opfamilies for equality operator %u",
235 opfamilies, opcintype, collation,
236 sortref, rel, create_it);
244 strategy, nulls_first);
269 &opfamily, &opcintype, &strategy))
270 elog(
ERROR,
"operator %u is not a valid ordering operator",
315 forboth(key1, keys1, key2, keys2)
320 if (pathkey1 != pathkey2)
369 List **group_clauses,
370 int num_groupby_pathkeys)
372 List *new_group_pathkeys =
NIL,
373 *new_group_clauses =
NIL;
374 List *grouping_pathkeys;
378 if (pathkeys ==
NIL || *group_pathkeys ==
NIL)
390 grouping_pathkeys =
list_copy_head(*group_pathkeys, num_groupby_pathkeys);
401 foreach(lc, pathkeys)
413 pathkey->pk_eclass->ec_sortref == 0)
433 new_group_pathkeys =
lappend(new_group_pathkeys, pathkey);
434 new_group_clauses =
lappend(new_group_clauses, sgc);
511 if (
parse->groupingSets)
588 else if (keys1 ==
NIL)
593 else if (keys2 ==
NIL)
603 forboth(key1, keys1, key2, keys2)
608 if (pathkey1 != pathkey2)
618 return (key1 == NULL);
638 bool require_parallel_safe)
640 Path *matched_path = NULL;
655 if (matched_path != NULL &&
686 Path *matched_path = NULL;
697 if (matched_path != NULL &&
763 if (
index->sortopfamily == NULL)
767 foreach(lc,
index->indextlist)
779 if (
i >=
index->nkeycolumns)
783 indexkey = indextle->
expr;
787 reverse_sort = !
index->reverse_sort[
i];
788 nulls_first = !
index->nulls_first[
i];
792 reverse_sort =
index->reverse_sort[
i];
793 nulls_first =
index->nulls_first[
i];
803 index->indexcollations[
i],
817 retval =
lappend(retval, cpathkey);
870 if (!IsBuiltinBooleanOpfamily(partscheme->
partopfamily[partkeycol]))
879 if (rinfo->pseudoconstant)
906 if (
equal(partexpr, clause))
941 Assert(partscheme != NULL);
977 retval =
lappend(retval, cpathkey);
999 *partialkeys =
false;
1029 &opfamily, &opcintype, &strategy))
1030 elog(
ERROR,
"operator %u is not a valid ordering operator",
1070 List *subquery_pathkeys,
1071 List *subquery_tlist)
1078 foreach(
i, subquery_pathkeys)
1095 elog(
ERROR,
"volatile EquivalenceClass has no sortref");
1158 int best_score = -1;
1172 foreach(k, subquery_tlist)
1195 if (!
equal(tle_expr, sub_expr))
1223 if (retvallen < outer_query_keys &&
1226 if (score > best_score)
1228 best_pathkey = outer_pk;
1248 retval =
lappend(retval, best_pathkey);
1312 List *outer_pathkeys)
1387 bool remove_redundant,
1394 foreach(l, *sortclauses)
1415 pathkeys =
lappend(pathkeys, pathkey);
1416 else if (remove_redundant)
1453 Assert(restrictinfo->mergeopfamilies !=
NIL);
1455 Assert(restrictinfo->left_ec == NULL);
1456 Assert(restrictinfo->right_ec == NULL);
1462 restrictinfo->left_ec =
1465 restrictinfo->mergeopfamilies,
1467 ((
OpExpr *) clause)->inputcollid,
1471 restrictinfo->right_ec =
1474 restrictinfo->mergeopfamilies,
1476 ((
OpExpr *) clause)->inputcollid,
1496 Assert(restrictinfo->mergeopfamilies !=
NIL);
1498 Assert(restrictinfo->left_ec != NULL);
1499 Assert(restrictinfo->right_ec != NULL);
1502 while (restrictinfo->left_ec->ec_merged)
1503 restrictinfo->left_ec = restrictinfo->left_ec->ec_merged;
1504 while (restrictinfo->right_ec->ec_merged)
1505 restrictinfo->right_ec = restrictinfo->right_ec->ec_merged;
1529 List *restrictinfos)
1535 foreach(
i, restrictinfos)
1542 foreach(
i, pathkeys)
1546 List *matched_restrictinfos =
NIL;
1586 foreach(
j, restrictinfos)
1591 clause_ec = rinfo->outer_is_left ?
1592 rinfo->left_ec : rinfo->right_ec;
1593 if (clause_ec == pathkey_ec)
1594 matched_restrictinfos =
lappend(matched_restrictinfos, rinfo);
1602 if (matched_restrictinfos ==
NIL)
1609 mergeclauses =
list_concat(mergeclauses, matched_restrictinfos);
1612 return mergeclauses;
1663 scores = (
int *)
palloc(nClauses *
sizeof(
int));
1666 foreach(lc, mergeclauses)
1676 if (rinfo->outer_is_left)
1677 oeclass = rinfo->left_ec;
1679 oeclass = rinfo->right_ec;
1682 for (
j = 0;
j < necs;
j++)
1684 if (ecs[
j] == oeclass)
1702 ecs[necs] = oeclass;
1703 scores[necs] = score;
1724 for (
j = 0;
j < necs;
j++)
1726 if (ecs[
j] == query_ec)
1745 for (
j = 0;
j < necs;
j++)
1747 if (ecs[
j] == query_ec)
1762 else if (matches == nClauses)
1787 best_score = scores[0];
1788 for (
j = 1;
j < necs;
j++)
1790 if (scores[
j] > best_score)
1793 best_score = scores[
j];
1799 scores[best_j] = -1;
1807 pathkeys =
lappend(pathkeys, pathkey);
1840 List *outer_pathkeys)
1852 foreach(lc, mergeclauses)
1861 if (rinfo->outer_is_left)
1863 oeclass = rinfo->left_ec;
1864 ieclass = rinfo->right_ec;
1868 oeclass = rinfo->right_ec;
1869 ieclass = rinfo->left_ec;
1874 if (oeclass != lastoeclass)
1877 elog(
ERROR,
"too few pathkeys for mergeclauses");
1879 lop =
lnext(outer_pathkeys, lop);
1880 lastoeclass = opathkey->pk_eclass;
1881 if (oeclass != lastoeclass)
1882 elog(
ERROR,
"outer pathkeys do not match mergeclause");
1890 if (ieclass == oeclass)
1909 pathkeys =
lappend(pathkeys, pathkey);
1948 bool matched_pathkey;
1953 if (pathkeys ==
NIL)
1958 pathkey_ec = pathkey->pk_eclass;
1959 lip =
lnext(pathkeys, lip);
1960 matched_pathkey =
false;
1963 foreach(
i, mergeclauses)
1971 clause_ec = rinfo->outer_is_left ?
1972 rinfo->right_ec : rinfo->left_ec;
1975 if (clause_ec != pathkey_ec)
1978 if (!matched_pathkey)
1985 pathkey_ec = pathkey->pk_eclass;
1986 lip =
lnext(pathkeys, lip);
1987 matched_pathkey =
false;
1991 if (clause_ec == pathkey_ec)
1993 new_mergeclauses =
lappend(new_mergeclauses, rinfo);
1994 matched_pathkey =
true;
2003 return new_mergeclauses;
2041 foreach(
i, pathkeys)
2044 bool matched =
false;
2070 if (restrictinfo->mergeopfamilies ==
NIL)
2074 if (pathkey->pk_eclass == restrictinfo->left_ec ||
2075 pathkey->pk_eclass == restrictinfo->right_ec)
2111 if (pathkey->pk_eclass == query_pathkey->pk_eclass &&
2142 int n_common_pathkeys;
2145 &n_common_pathkeys);
2147 return n_common_pathkeys;
2180 foreach(
key, pathkeys)
2208 if (nuseful2 > nuseful)
2211 if (nuseful2 > nuseful)
bool bms_is_subset(const Bitmapset *a, const Bitmapset *b)
bool bms_overlap(const Bitmapset *a, const Bitmapset *b)
#define OidIsValid(objectId)
bool enable_incremental_sort
bool equal(const void *a, const void *b)
Expr * canonicalize_ec_expression(Expr *expr, Oid req_type, Oid req_collation)
EquivalenceClass * get_eclass_for_sort_expr(PlannerInfo *root, Expr *expr, List *opfamilies, Oid opcintype, Oid collation, Index sortref, Relids rel, bool create_it)
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 * lappend(List *list, void *datum)
List * list_copy_head(const List *oldlist, int len)
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 bool matches_boolean_partition_clause(RestrictInfo *rinfo, RelOptInfo *partrel, int partkeycol)
List * build_join_pathkeys(PlannerInfo *root, RelOptInfo *joinrel, JoinType jointype, List *outer_pathkeys)
List * get_useful_group_keys_orderings(PlannerInfo *root, Path *path)
List * build_expression_pathkey(PlannerInfo *root, Expr *expr, Oid opno, Relids rel, bool create_it)
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)
List * find_mergeclauses_for_outer_pathkeys(PlannerInfo *root, List *pathkeys, List *restrictinfos)
static int group_keys_reorder_by_pathkeys(List *pathkeys, List **group_pathkeys, List **group_clauses, int num_groupby_pathkeys)
static PathKey * make_pathkey_from_sortop(PlannerInfo *root, Expr *expr, Oid ordering_op, bool nulls_first, Index sortref, bool create_it)
bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel)
List * append_pathkeys(List *target, List *source)
List * truncate_useless_pathkeys(PlannerInfo *root, RelOptInfo *rel, List *pathkeys)
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)
List * make_pathkeys_for_sortclauses_extended(PlannerInfo *root, List **sortclauses, List *tlist, bool remove_redundant, bool *sortable)
PathKey * make_canonical_pathkey(PlannerInfo *root, EquivalenceClass *eclass, Oid opfamily, int strategy, bool nulls_first)
static bool pathkeys_are_duplicate(List *infos, List *pathkeys)
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)
static PathKey * make_pathkey_from_sortinfo(PlannerInfo *root, Expr *expr, Oid opfamily, Oid opcintype, Oid collation, bool reverse_sort, bool nulls_first, Index sortref, Relids rel, bool create_it)
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)
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)
#define lfirst_node(type, lc)
static int list_length(const List *l)
#define forboth(cell1, list1, cell2, list2)
#define foreach_current_index(var_or_cell)
#define foreach_delete_current(lst, var_or_cell)
static ListCell * list_head(const List *l)
static void * list_nth(const List *list, int n)
static ListCell * lnext(const List *l, const ListCell *c)
static rewind_source * source
static struct cvec * eclass(struct vars *v, chr c, int cases)
static struct subre * parse(struct vars *v, int stopper, int type, struct state *init, struct state *final)
#define ScanDirectionIsBackward(direction)
#define BTGreaterStrategyNumber
#define BTLessStrategyNumber
#define BTEqualStrategyNumber
List * processed_groupClause
struct PathTarget * reltarget
TargetEntry * get_sortgroupref_tle(Index sortref, List *targetList)
SortGroupClause * get_sortgroupref_clause_noerr(Index sortref, List *clauses)
Node * get_sortgroupclause_expr(SortGroupClause *sgClause, List *targetList)