1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-18 02:02:55 +03:00

Convert PathKey to use CompareType

Change the PathKey struct to use CompareType to record the sort
direction instead of hardcoding btree strategy numbers.  The
CompareType is then converted to the index-type-specific strategy when
the plan is created.

This reduces the number of places btree strategy numbers are
hardcoded, and it's a self-contained subset of a larger effort to
allow non-btree indexes to behave like btrees.

Author: Mark Dilger <mark.dilger@enterprisedb.com>
Co-authored-by: Peter Eisentraut <peter@eisentraut.org>
Discussion: https://www.postgresql.org/message-id/flat/E72EAA49-354D-4C2E-8EB9-255197F55330@enterprisedb.com
This commit is contained in:
Peter Eisentraut
2025-04-04 11:13:54 +02:00
parent daa16893fa
commit 8123e91f5a
8 changed files with 44 additions and 47 deletions

View File

@@ -3608,7 +3608,7 @@ initial_cost_mergejoin(PlannerInfo *root, JoinCostWorkspace *workspace,
/* debugging check */
if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation ||
opathkey->pk_strategy != ipathkey->pk_strategy ||
opathkey->pk_cmptype != ipathkey->pk_cmptype ||
opathkey->pk_nulls_first != ipathkey->pk_nulls_first)
elog(ERROR, "left and right pathkeys do not match in mergejoin");
@@ -4093,7 +4093,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
cache = (MergeScanSelCache *) lfirst(lc);
if (cache->opfamily == pathkey->pk_opfamily &&
cache->collation == pathkey->pk_eclass->ec_collation &&
cache->strategy == pathkey->pk_strategy &&
cache->cmptype == pathkey->pk_cmptype &&
cache->nulls_first == pathkey->pk_nulls_first)
return cache;
}
@@ -4102,7 +4102,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
mergejoinscansel(root,
(Node *) rinfo->clause,
pathkey->pk_opfamily,
pathkey->pk_strategy,
pathkey->pk_cmptype,
pathkey->pk_nulls_first,
&leftstartsel,
&leftendsel,
@@ -4115,7 +4115,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
cache = (MergeScanSelCache *) palloc(sizeof(MergeScanSelCache));
cache->opfamily = pathkey->pk_opfamily;
cache->collation = pathkey->pk_eclass->ec_collation;
cache->strategy = pathkey->pk_strategy;
cache->cmptype = pathkey->pk_cmptype;
cache->nulls_first = pathkey->pk_nulls_first;
cache->leftstartsel = leftstartsel;
cache->leftendsel = leftendsel;

View File

@@ -3817,8 +3817,7 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
/* Pathkey must request default sort order for the target opfamily */
if (pathkey->pk_strategy != BTLessStrategyNumber ||
pathkey->pk_nulls_first)
if (pathkey->pk_cmptype != COMPARE_LT || pathkey->pk_nulls_first)
return;
/* If eclass is volatile, no hope of using an indexscan */

View File

@@ -55,7 +55,7 @@ static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey);
PathKey *
make_canonical_pathkey(PlannerInfo *root,
EquivalenceClass *eclass, Oid opfamily,
int strategy, bool nulls_first)
CompareType cmptype, bool nulls_first)
{
PathKey *pk;
ListCell *lc;
@@ -74,7 +74,7 @@ make_canonical_pathkey(PlannerInfo *root,
pk = (PathKey *) lfirst(lc);
if (eclass == pk->pk_eclass &&
opfamily == pk->pk_opfamily &&
strategy == pk->pk_strategy &&
cmptype == pk->pk_cmptype &&
nulls_first == pk->pk_nulls_first)
return pk;
}
@@ -88,7 +88,7 @@ make_canonical_pathkey(PlannerInfo *root,
pk = makeNode(PathKey);
pk->pk_eclass = eclass;
pk->pk_opfamily = opfamily;
pk->pk_strategy = strategy;
pk->pk_cmptype = cmptype;
pk->pk_nulls_first = nulls_first;
root->canon_pathkeys = lappend(root->canon_pathkeys, pk);
@@ -206,12 +206,12 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
Relids rel,
bool create_it)
{
int16 strategy;
CompareType cmptype;
Oid equality_op;
List *opfamilies;
EquivalenceClass *eclass;
strategy = reverse_sort ? BTGreaterStrategyNumber : BTLessStrategyNumber;
cmptype = reverse_sort ? COMPARE_GT : COMPARE_LT;
/*
* EquivalenceClasses need to contain opfamily lists based on the family
@@ -242,7 +242,7 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
/* And finally we can find or create a PathKey node */
return make_canonical_pathkey(root, eclass, opfamily,
strategy, nulls_first);
cmptype, nulls_first);
}
/*
@@ -1118,7 +1118,7 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
make_canonical_pathkey(root,
outer_ec,
sub_pathkey->pk_opfamily,
sub_pathkey->pk_strategy,
sub_pathkey->pk_cmptype,
sub_pathkey->pk_nulls_first);
}
}
@@ -1200,7 +1200,7 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
outer_pk = make_canonical_pathkey(root,
outer_ec,
sub_pathkey->pk_opfamily,
sub_pathkey->pk_strategy,
sub_pathkey->pk_cmptype,
sub_pathkey->pk_nulls_first);
/* score = # of equivalence peers */
score = list_length(outer_ec->ec_members) - 1;
@@ -1816,7 +1816,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
pathkey = make_canonical_pathkey(root,
ec,
linitial_oid(ec->ec_opfamilies),
BTLessStrategyNumber,
COMPARE_LT,
false);
/* can't be redundant because no duplicate ECs */
Assert(!pathkey_is_redundant(pathkey, pathkeys));
@@ -1909,7 +1909,7 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
pathkey = make_canonical_pathkey(root,
ieclass,
opathkey->pk_opfamily,
opathkey->pk_strategy,
opathkey->pk_cmptype,
opathkey->pk_nulls_first);
/*
@@ -2134,12 +2134,12 @@ right_merge_direction(PlannerInfo *root, PathKey *pathkey)
* want to prefer only one of the two possible directions, and we
* might as well use this one.
*/
return (pathkey->pk_strategy == query_pathkey->pk_strategy);
return (pathkey->pk_cmptype == query_pathkey->pk_cmptype);
}
}
/* If no matching ORDER BY request, prefer the ASC direction */
return (pathkey->pk_strategy == BTLessStrategyNumber);
return (pathkey->pk_cmptype == COMPARE_LT);
}
/*

View File

@@ -3129,13 +3129,13 @@ create_indexscan_plan(PlannerInfo *root,
Oid sortop;
/* Get sort operator from opfamily */
sortop = get_opfamily_member(pathkey->pk_opfamily,
exprtype,
exprtype,
pathkey->pk_strategy);
sortop = get_opfamily_member_for_cmptype(pathkey->pk_opfamily,
exprtype,
exprtype,
pathkey->pk_cmptype);
if (!OidIsValid(sortop))
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
pathkey->pk_strategy, exprtype, exprtype, pathkey->pk_opfamily);
pathkey->pk_cmptype, exprtype, exprtype, pathkey->pk_opfamily);
indexorderbyops = lappend_oid(indexorderbyops, sortop);
}
}
@@ -4739,14 +4739,14 @@ create_mergejoin_plan(PlannerInfo *root,
opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)
elog(ERROR, "left and right pathkeys do not match in mergejoin");
if (first_inner_match &&
(opathkey->pk_strategy != ipathkey->pk_strategy ||
(opathkey->pk_cmptype != ipathkey->pk_cmptype ||
opathkey->pk_nulls_first != ipathkey->pk_nulls_first))
elog(ERROR, "left and right pathkeys do not match in mergejoin");
/* OK, save info for executor */
mergefamilies[i] = opathkey->pk_opfamily;
mergecollations[i] = opathkey->pk_eclass->ec_collation;
mergereversals[i] = (opathkey->pk_strategy == BTGreaterStrategyNumber ? true : false);
mergereversals[i] = (opathkey->pk_cmptype == COMPARE_GT ? true : false);
mergenullsfirst[i] = opathkey->pk_nulls_first;
i++;
}
@@ -6374,13 +6374,13 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
* Look up the correct sort operator from the PathKey's slightly
* abstracted representation.
*/
sortop = get_opfamily_member(pathkey->pk_opfamily,
pk_datatype,
pk_datatype,
pathkey->pk_strategy);
sortop = get_opfamily_member_for_cmptype(pathkey->pk_opfamily,
pk_datatype,
pk_datatype,
pathkey->pk_cmptype);
if (!OidIsValid(sortop)) /* should not happen */
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
pathkey->pk_strategy, pk_datatype, pk_datatype,
pathkey->pk_cmptype, pk_datatype, pk_datatype,
pathkey->pk_opfamily);
/* Add the column to the sort arrays */