Skip to content

Commit 8123e91

Browse files
committed
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
1 parent daa1689 commit 8123e91

File tree

8 files changed

+44
-47
lines changed

8 files changed

+44
-47
lines changed

contrib/postgres_fdw/deparse.c

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3969,17 +3969,17 @@ appendOrderByClause(List *pathkeys, bool has_final_sort,
39693969
appendStringInfoString(buf, ", ");
39703970

39713971
/*
3972-
* Lookup the operator corresponding to the strategy in the opclass.
3973-
* The datatype used by the opfamily is not necessarily the same as
3974-
* the expression type (for array types for example).
3972+
* Lookup the operator corresponding to the compare type in the
3973+
* opclass. The datatype used by the opfamily is not necessarily the
3974+
* same as the expression type (for array types for example).
39753975
*/
3976-
oprid = get_opfamily_member(pathkey->pk_opfamily,
3977-
em->em_datatype,
3978-
em->em_datatype,
3979-
pathkey->pk_strategy);
3976+
oprid = get_opfamily_member_for_cmptype(pathkey->pk_opfamily,
3977+
em->em_datatype,
3978+
em->em_datatype,
3979+
pathkey->pk_cmptype);
39803980
if (!OidIsValid(oprid))
39813981
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
3982-
pathkey->pk_strategy, em->em_datatype, em->em_datatype,
3982+
pathkey->pk_cmptype, em->em_datatype, em->em_datatype,
39833983
pathkey->pk_opfamily);
39843984

39853985
deparseExpr(em_expr, context);

contrib/postgres_fdw/postgres_fdw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -999,7 +999,7 @@ get_useful_pathkeys_for_relation(PlannerInfo *root, RelOptInfo *rel)
999999
/* Looks like we can generate a pathkey, so let's do it. */
10001000
pathkey = make_canonical_pathkey(root, cur_ec,
10011001
linitial_oid(cur_ec->ec_opfamilies),
1002-
BTLessStrategyNumber,
1002+
COMPARE_LT,
10031003
false);
10041004
useful_pathkeys_list = lappend(useful_pathkeys_list,
10051005
list_make1(pathkey));

src/backend/optimizer/path/costsize.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3608,7 +3608,7 @@ initial_cost_mergejoin(PlannerInfo *root, JoinCostWorkspace *workspace,
36083608
/* debugging check */
36093609
if (opathkey->pk_opfamily != ipathkey->pk_opfamily ||
36103610
opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation ||
3611-
opathkey->pk_strategy != ipathkey->pk_strategy ||
3611+
opathkey->pk_cmptype != ipathkey->pk_cmptype ||
36123612
opathkey->pk_nulls_first != ipathkey->pk_nulls_first)
36133613
elog(ERROR, "left and right pathkeys do not match in mergejoin");
36143614

@@ -4093,7 +4093,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
40934093
cache = (MergeScanSelCache *) lfirst(lc);
40944094
if (cache->opfamily == pathkey->pk_opfamily &&
40954095
cache->collation == pathkey->pk_eclass->ec_collation &&
4096-
cache->strategy == pathkey->pk_strategy &&
4096+
cache->cmptype == pathkey->pk_cmptype &&
40974097
cache->nulls_first == pathkey->pk_nulls_first)
40984098
return cache;
40994099
}
@@ -4102,7 +4102,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
41024102
mergejoinscansel(root,
41034103
(Node *) rinfo->clause,
41044104
pathkey->pk_opfamily,
4105-
pathkey->pk_strategy,
4105+
pathkey->pk_cmptype,
41064106
pathkey->pk_nulls_first,
41074107
&leftstartsel,
41084108
&leftendsel,
@@ -4115,7 +4115,7 @@ cached_scansel(PlannerInfo *root, RestrictInfo *rinfo, PathKey *pathkey)
41154115
cache = (MergeScanSelCache *) palloc(sizeof(MergeScanSelCache));
41164116
cache->opfamily = pathkey->pk_opfamily;
41174117
cache->collation = pathkey->pk_eclass->ec_collation;
4118-
cache->strategy = pathkey->pk_strategy;
4118+
cache->cmptype = pathkey->pk_cmptype;
41194119
cache->nulls_first = pathkey->pk_nulls_first;
41204120
cache->leftstartsel = leftstartsel;
41214121
cache->leftendsel = leftendsel;

src/backend/optimizer/path/indxpath.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3817,8 +3817,7 @@ match_pathkeys_to_index(IndexOptInfo *index, List *pathkeys,
38173817

38183818

38193819
/* Pathkey must request default sort order for the target opfamily */
3820-
if (pathkey->pk_strategy != BTLessStrategyNumber ||
3821-
pathkey->pk_nulls_first)
3820+
if (pathkey->pk_cmptype != COMPARE_LT || pathkey->pk_nulls_first)
38223821
return;
38233822

38243823
/* If eclass is volatile, no hope of using an indexscan */

src/backend/optimizer/path/pathkeys.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ static bool right_merge_direction(PlannerInfo *root, PathKey *pathkey);
5555
PathKey *
5656
make_canonical_pathkey(PlannerInfo *root,
5757
EquivalenceClass *eclass, Oid opfamily,
58-
int strategy, bool nulls_first)
58+
CompareType cmptype, bool nulls_first)
5959
{
6060
PathKey *pk;
6161
ListCell *lc;
@@ -74,7 +74,7 @@ make_canonical_pathkey(PlannerInfo *root,
7474
pk = (PathKey *) lfirst(lc);
7575
if (eclass == pk->pk_eclass &&
7676
opfamily == pk->pk_opfamily &&
77-
strategy == pk->pk_strategy &&
77+
cmptype == pk->pk_cmptype &&
7878
nulls_first == pk->pk_nulls_first)
7979
return pk;
8080
}
@@ -88,7 +88,7 @@ make_canonical_pathkey(PlannerInfo *root,
8888
pk = makeNode(PathKey);
8989
pk->pk_eclass = eclass;
9090
pk->pk_opfamily = opfamily;
91-
pk->pk_strategy = strategy;
91+
pk->pk_cmptype = cmptype;
9292
pk->pk_nulls_first = nulls_first;
9393

9494
root->canon_pathkeys = lappend(root->canon_pathkeys, pk);
@@ -206,12 +206,12 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
206206
Relids rel,
207207
bool create_it)
208208
{
209-
int16 strategy;
209+
CompareType cmptype;
210210
Oid equality_op;
211211
List *opfamilies;
212212
EquivalenceClass *eclass;
213213

214-
strategy = reverse_sort ? BTGreaterStrategyNumber : BTLessStrategyNumber;
214+
cmptype = reverse_sort ? COMPARE_GT : COMPARE_LT;
215215

216216
/*
217217
* EquivalenceClasses need to contain opfamily lists based on the family
@@ -242,7 +242,7 @@ make_pathkey_from_sortinfo(PlannerInfo *root,
242242

243243
/* And finally we can find or create a PathKey node */
244244
return make_canonical_pathkey(root, eclass, opfamily,
245-
strategy, nulls_first);
245+
cmptype, nulls_first);
246246
}
247247

248248
/*
@@ -1118,7 +1118,7 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
11181118
make_canonical_pathkey(root,
11191119
outer_ec,
11201120
sub_pathkey->pk_opfamily,
1121-
sub_pathkey->pk_strategy,
1121+
sub_pathkey->pk_cmptype,
11221122
sub_pathkey->pk_nulls_first);
11231123
}
11241124
}
@@ -1200,7 +1200,7 @@ convert_subquery_pathkeys(PlannerInfo *root, RelOptInfo *rel,
12001200
outer_pk = make_canonical_pathkey(root,
12011201
outer_ec,
12021202
sub_pathkey->pk_opfamily,
1203-
sub_pathkey->pk_strategy,
1203+
sub_pathkey->pk_cmptype,
12041204
sub_pathkey->pk_nulls_first);
12051205
/* score = # of equivalence peers */
12061206
score = list_length(outer_ec->ec_members) - 1;
@@ -1816,7 +1816,7 @@ select_outer_pathkeys_for_merge(PlannerInfo *root,
18161816
pathkey = make_canonical_pathkey(root,
18171817
ec,
18181818
linitial_oid(ec->ec_opfamilies),
1819-
BTLessStrategyNumber,
1819+
COMPARE_LT,
18201820
false);
18211821
/* can't be redundant because no duplicate ECs */
18221822
Assert(!pathkey_is_redundant(pathkey, pathkeys));
@@ -1909,7 +1909,7 @@ make_inner_pathkeys_for_merge(PlannerInfo *root,
19091909
pathkey = make_canonical_pathkey(root,
19101910
ieclass,
19111911
opathkey->pk_opfamily,
1912-
opathkey->pk_strategy,
1912+
opathkey->pk_cmptype,
19131913
opathkey->pk_nulls_first);
19141914

19151915
/*
@@ -2134,12 +2134,12 @@ right_merge_direction(PlannerInfo *root, PathKey *pathkey)
21342134
* want to prefer only one of the two possible directions, and we
21352135
* might as well use this one.
21362136
*/
2137-
return (pathkey->pk_strategy == query_pathkey->pk_strategy);
2137+
return (pathkey->pk_cmptype == query_pathkey->pk_cmptype);
21382138
}
21392139
}
21402140

21412141
/* If no matching ORDER BY request, prefer the ASC direction */
2142-
return (pathkey->pk_strategy == BTLessStrategyNumber);
2142+
return (pathkey->pk_cmptype == COMPARE_LT);
21432143
}
21442144

21452145
/*

src/backend/optimizer/plan/createplan.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3129,13 +3129,13 @@ create_indexscan_plan(PlannerInfo *root,
31293129
Oid sortop;
31303130

31313131
/* Get sort operator from opfamily */
3132-
sortop = get_opfamily_member(pathkey->pk_opfamily,
3133-
exprtype,
3134-
exprtype,
3135-
pathkey->pk_strategy);
3132+
sortop = get_opfamily_member_for_cmptype(pathkey->pk_opfamily,
3133+
exprtype,
3134+
exprtype,
3135+
pathkey->pk_cmptype);
31363136
if (!OidIsValid(sortop))
31373137
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
3138-
pathkey->pk_strategy, exprtype, exprtype, pathkey->pk_opfamily);
3138+
pathkey->pk_cmptype, exprtype, exprtype, pathkey->pk_opfamily);
31393139
indexorderbyops = lappend_oid(indexorderbyops, sortop);
31403140
}
31413141
}
@@ -4739,14 +4739,14 @@ create_mergejoin_plan(PlannerInfo *root,
47394739
opathkey->pk_eclass->ec_collation != ipathkey->pk_eclass->ec_collation)
47404740
elog(ERROR, "left and right pathkeys do not match in mergejoin");
47414741
if (first_inner_match &&
4742-
(opathkey->pk_strategy != ipathkey->pk_strategy ||
4742+
(opathkey->pk_cmptype != ipathkey->pk_cmptype ||
47434743
opathkey->pk_nulls_first != ipathkey->pk_nulls_first))
47444744
elog(ERROR, "left and right pathkeys do not match in mergejoin");
47454745

47464746
/* OK, save info for executor */
47474747
mergefamilies[i] = opathkey->pk_opfamily;
47484748
mergecollations[i] = opathkey->pk_eclass->ec_collation;
4749-
mergereversals[i] = (opathkey->pk_strategy == BTGreaterStrategyNumber ? true : false);
4749+
mergereversals[i] = (opathkey->pk_cmptype == COMPARE_GT ? true : false);
47504750
mergenullsfirst[i] = opathkey->pk_nulls_first;
47514751
i++;
47524752
}
@@ -6374,13 +6374,13 @@ prepare_sort_from_pathkeys(Plan *lefttree, List *pathkeys,
63746374
* Look up the correct sort operator from the PathKey's slightly
63756375
* abstracted representation.
63766376
*/
6377-
sortop = get_opfamily_member(pathkey->pk_opfamily,
6378-
pk_datatype,
6379-
pk_datatype,
6380-
pathkey->pk_strategy);
6377+
sortop = get_opfamily_member_for_cmptype(pathkey->pk_opfamily,
6378+
pk_datatype,
6379+
pk_datatype,
6380+
pathkey->pk_cmptype);
63816381
if (!OidIsValid(sortop)) /* should not happen */
63826382
elog(ERROR, "missing operator %d(%u,%u) in opfamily %u",
6383-
pathkey->pk_strategy, pk_datatype, pk_datatype,
6383+
pathkey->pk_cmptype, pk_datatype, pk_datatype,
63846384
pathkey->pk_opfamily);
63856385

63866386
/* Add the column to the sort arrays */

src/include/nodes/pathnodes.h

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,9 +1506,7 @@ typedef struct EquivalenceMember
15061506
* equivalent and closely-related orderings. (See optimizer/README for more
15071507
* information.)
15081508
*
1509-
* Note: pk_strategy is either BTLessStrategyNumber (for ASC) or
1510-
* BTGreaterStrategyNumber (for DESC). We assume that all ordering-capable
1511-
* index types will use btree-compatible strategy numbers.
1509+
* Note: pk_strategy is either COMPARE_LT (for ASC) or COMPARE_GT (for DESC).
15121510
*/
15131511
typedef struct PathKey
15141512
{
@@ -1518,8 +1516,8 @@ typedef struct PathKey
15181516

15191517
/* the value that is ordered */
15201518
EquivalenceClass *pk_eclass pg_node_attr(copy_as_scalar, equal_as_scalar);
1521-
Oid pk_opfamily; /* btree opfamily defining the ordering */
1522-
int pk_strategy; /* sort direction (ASC or DESC) */
1519+
Oid pk_opfamily; /* index opfamily defining the ordering */
1520+
CompareType pk_cmptype; /* sort direction (ASC or DESC) */
15231521
bool pk_nulls_first; /* do NULLs come before normal values? */
15241522
} PathKey;
15251523

@@ -2784,9 +2782,9 @@ typedef struct RestrictInfo
27842782
typedef struct MergeScanSelCache
27852783
{
27862784
/* Ordering details (cache lookup key) */
2787-
Oid opfamily; /* btree opfamily defining the ordering */
2785+
Oid opfamily; /* index opfamily defining the ordering */
27882786
Oid collation; /* collation for the ordering */
2789-
int strategy; /* sort direction (ASC or DESC) */
2787+
CompareType cmptype; /* sort direction (ASC or DESC) */
27902788
bool nulls_first; /* do NULLs come before normal values? */
27912789
/* Results */
27922790
Selectivity leftstartsel; /* first-join fraction for clause left side */

src/include/optimizer/paths.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ extern bool has_useful_pathkeys(PlannerInfo *root, RelOptInfo *rel);
272272
extern List *append_pathkeys(List *target, List *source);
273273
extern PathKey *make_canonical_pathkey(PlannerInfo *root,
274274
EquivalenceClass *eclass, Oid opfamily,
275-
int strategy, bool nulls_first);
275+
CompareType cmptype, bool nulls_first);
276276
extern void add_paths_to_append_rel(PlannerInfo *root, RelOptInfo *rel,
277277
List *live_childrels);
278278

0 commit comments

Comments
 (0)