Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit c09e5a6

Browse files
committed
Convert strategies to and from compare types
For each Index AM, provide a mapping between operator strategies and the system-wide generic concept of a comparison type. For example, for btree, BTLessStrategyNumber maps to and from COMPARE_LT. Numerous places in the planner and executor think directly in terms of btree strategy numbers (and a few in terms of hash strategy numbers.) These should be converted over subsequent commits to think in terms of CompareType instead. (This commit doesn't make any use of this API yet.) Author: Mark Dilger <mark.dilger@enterprisedb.com> Reviewed-by: Peter Eisentraut <peter@eisentraut.org> Discussion: https://www.postgresql.org/message-id/flat/E72EAA49-354D-4C2E-8EB9-255197F55330@enterprisedb.com
1 parent 119fc30 commit c09e5a6

File tree

13 files changed

+169
-0
lines changed

13 files changed

+169
-0
lines changed

contrib/bloom/blutils.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,8 @@ blhandler(PG_FUNCTION_ARGS)
150150
amroutine->amestimateparallelscan = NULL;
151151
amroutine->aminitparallelscan = NULL;
152152
amroutine->amparallelrescan = NULL;
153+
amroutine->amtranslatestrategy = NULL;
154+
amroutine->amtranslatecmptype = NULL;
153155

154156
PG_RETURN_POINTER(amroutine);
155157
}

doc/src/sgml/indexam.sgml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,10 @@ typedef struct IndexAmRoutine
164164
amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
165165
aminitparallelscan_function aminitparallelscan; /* can be NULL */
166166
amparallelrescan_function amparallelrescan; /* can be NULL */
167+
168+
/* interface functions to support planning */
169+
amtranslate_strategy_function amtranslatestrategy; /* can be NULL */
170+
amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */
167171
} IndexAmRoutine;
168172
</programlisting>
169173
</para>
@@ -876,6 +880,28 @@ amparallelrescan (IndexScanDesc scan);
876880
the beginning.
877881
</para>
878882

883+
<para>
884+
<programlisting>
885+
CompareType
886+
amtranslatestrategy (StrategyNumber strategy, Oid opfamily, Oid opcintype);
887+
888+
StrategyNumber
889+
amtranslatecmptype (CompareType cmptype, Oid opfamily, Oid opcintype);
890+
</programlisting>
891+
These functions, if implemented, will be called by the planer and executor
892+
to convert between fixed <type>CompareType</type> values and the specific
893+
strategy numbers used by the access method. These functions can be
894+
implemented by access methods that implement functionality similar to the
895+
built-in btree or hash access methods, and by implementing these
896+
translations, the system can learn about the semantics of the access
897+
method's operations and can use them in place of btree or hash indexes in
898+
various places. If the functionality of the access method is not similar
899+
to those built-in access methods, these functions do not need to be
900+
implemented. If the functions are not implemented, the access method will
901+
be ignored for certain planner and executor decisions, but is otherwise
902+
fully functional.
903+
</para>
904+
879905
</sect1>
880906

881907
<sect1 id="index-scanning">

src/backend/access/brin/brin.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,8 @@ brinhandler(PG_FUNCTION_ARGS)
298298
amroutine->amestimateparallelscan = NULL;
299299
amroutine->aminitparallelscan = NULL;
300300
amroutine->amparallelrescan = NULL;
301+
amroutine->amtranslatestrategy = NULL;
302+
amroutine->amtranslatecmptype = NULL;
301303

302304
PG_RETURN_POINTER(amroutine);
303305
}

src/backend/access/gist/gist.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ gisthandler(PG_FUNCTION_ARGS)
107107
amroutine->amestimateparallelscan = NULL;
108108
amroutine->aminitparallelscan = NULL;
109109
amroutine->amparallelrescan = NULL;
110+
amroutine->amtranslatestrategy = NULL;
111+
amroutine->amtranslatecmptype = NULL;
110112

111113
PG_RETURN_POINTER(amroutine);
112114
}

src/backend/access/hash/hash.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "access/hash.h"
2222
#include "access/hash_xlog.h"
2323
#include "access/relscan.h"
24+
#include "access/stratnum.h"
2425
#include "access/tableam.h"
2526
#include "access/xloginsert.h"
2627
#include "commands/progress.h"
@@ -105,6 +106,8 @@ hashhandler(PG_FUNCTION_ARGS)
105106
amroutine->amestimateparallelscan = NULL;
106107
amroutine->aminitparallelscan = NULL;
107108
amroutine->amparallelrescan = NULL;
109+
amroutine->amtranslatestrategy = hashtranslatestrategy;
110+
amroutine->amtranslatecmptype = hashtranslatecmptype;
108111

109112
PG_RETURN_POINTER(amroutine);
110113
}
@@ -922,3 +925,19 @@ hashbucketcleanup(Relation rel, Bucket cur_bucket, Buffer bucket_buf,
922925
else
923926
LockBuffer(bucket_buf, BUFFER_LOCK_UNLOCK);
924927
}
928+
929+
CompareType
930+
hashtranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype)
931+
{
932+
if (strategy == HTEqualStrategyNumber)
933+
return COMPARE_EQ;
934+
return COMPARE_INVALID;
935+
}
936+
937+
StrategyNumber
938+
hashtranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype)
939+
{
940+
if (cmptype == COMPARE_EQ)
941+
return HTEqualStrategyNumber;
942+
return InvalidStrategy;
943+
}

src/backend/access/index/amapi.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,56 @@ GetIndexAmRoutineByAmId(Oid amoid, bool noerror)
107107
}
108108

109109

110+
/*
111+
* IndexAmTranslateStrategy - given an access method and strategy, get the
112+
* corresponding compare type.
113+
*
114+
* If missing_ok is false, throw an error if no compare type is found. If
115+
* true, just return COMPARE_INVALID.
116+
*/
117+
CompareType
118+
IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok)
119+
{
120+
CompareType result;
121+
IndexAmRoutine *amroutine;
122+
123+
amroutine = GetIndexAmRoutineByAmId(amoid, false);
124+
if (amroutine->amtranslatestrategy)
125+
result = amroutine->amtranslatestrategy(strategy, opfamily, opcintype);
126+
else
127+
result = COMPARE_INVALID;
128+
129+
if (!missing_ok && result == COMPARE_INVALID)
130+
elog(ERROR, "could not translate strategy number %d for index AM %u", strategy, amoid);
131+
132+
return result;
133+
}
134+
135+
/*
136+
* IndexAmTranslateCompareType - given an access method and compare type, get
137+
* the corresponding strategy number.
138+
*
139+
* If missing_ok is false, throw an error if no strategy is found correlating
140+
* to the given cmptype. If true, just return InvalidStrategy.
141+
*/
142+
StrategyNumber
143+
IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok)
144+
{
145+
StrategyNumber result;
146+
IndexAmRoutine *amroutine;
147+
148+
amroutine = GetIndexAmRoutineByAmId(amoid, false);
149+
if (amroutine->amtranslatecmptype)
150+
result = amroutine->amtranslatecmptype(cmptype, opfamily, opcintype);
151+
else
152+
result = InvalidStrategy;
153+
154+
if (!missing_ok && result == InvalidStrategy)
155+
elog(ERROR, "could not translate compare type %u for index AM %u", cmptype, amoid);
156+
157+
return result;
158+
}
159+
110160
/*
111161
* Ask appropriate access method to validate the specified opclass.
112162
*/

src/backend/access/nbtree/nbtree.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020

2121
#include "access/nbtree.h"
2222
#include "access/relscan.h"
23+
#include "access/stratnum.h"
2324
#include "commands/progress.h"
2425
#include "commands/vacuum.h"
2526
#include "nodes/execnodes.h"
@@ -148,6 +149,8 @@ bthandler(PG_FUNCTION_ARGS)
148149
amroutine->amestimateparallelscan = btestimateparallelscan;
149150
amroutine->aminitparallelscan = btinitparallelscan;
150151
amroutine->amparallelrescan = btparallelrescan;
152+
amroutine->amtranslatestrategy = bttranslatestrategy;
153+
amroutine->amtranslatecmptype = bttranslatecmptype;
151154

152155
PG_RETURN_POINTER(amroutine);
153156
}
@@ -1508,3 +1511,43 @@ btgettreeheight(Relation rel)
15081511
{
15091512
return _bt_getrootheight(rel);
15101513
}
1514+
1515+
CompareType
1516+
bttranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype)
1517+
{
1518+
switch (strategy)
1519+
{
1520+
case BTLessStrategyNumber:
1521+
return COMPARE_LT;
1522+
case BTLessEqualStrategyNumber:
1523+
return COMPARE_LE;
1524+
case BTEqualStrategyNumber:
1525+
return COMPARE_EQ;
1526+
case BTGreaterEqualStrategyNumber:
1527+
return COMPARE_GE;
1528+
case BTGreaterStrategyNumber:
1529+
return COMPARE_GT;
1530+
default:
1531+
return COMPARE_INVALID;
1532+
}
1533+
}
1534+
1535+
StrategyNumber
1536+
bttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype)
1537+
{
1538+
switch (cmptype)
1539+
{
1540+
case COMPARE_LT:
1541+
return BTLessStrategyNumber;
1542+
case COMPARE_LE:
1543+
return BTLessEqualStrategyNumber;
1544+
case COMPARE_EQ:
1545+
return BTEqualStrategyNumber;
1546+
case COMPARE_GE:
1547+
return BTGreaterEqualStrategyNumber;
1548+
case COMPARE_GT:
1549+
return BTGreaterStrategyNumber;
1550+
default:
1551+
return InvalidStrategy;
1552+
}
1553+
}

src/backend/access/spgist/spgutils.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ spghandler(PG_FUNCTION_ARGS)
9292
amroutine->amestimateparallelscan = NULL;
9393
amroutine->aminitparallelscan = NULL;
9494
amroutine->amparallelrescan = NULL;
95+
amroutine->amtranslatestrategy = NULL;
96+
amroutine->amtranslatecmptype = NULL;
9597

9698
PG_RETURN_POINTER(amroutine);
9799
}

src/include/access/amapi.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,9 @@
1212
#ifndef AMAPI_H
1313
#define AMAPI_H
1414

15+
#include "access/cmptype.h"
1516
#include "access/genam.h"
17+
#include "access/stratnum.h"
1618

1719
/*
1820
* We don't wish to include planner header files here, since most of an index
@@ -99,6 +101,12 @@ typedef struct OpFamilyMember
99101
* Callback function signatures --- see indexam.sgml for more info.
100102
*/
101103

104+
/* translate AM-specific strategies to general operator types */
105+
typedef CompareType (*amtranslate_strategy_function) (StrategyNumber strategy, Oid opfamily, Oid opcintype);
106+
107+
/* translate general operator types to AM-specific strategies */
108+
typedef StrategyNumber (*amtranslate_cmptype_function) (CompareType cmptype, Oid opfamily, Oid opcintype);
109+
102110
/* build new index */
103111
typedef IndexBuildResult *(*ambuild_function) (Relation heapRelation,
104112
Relation indexRelation,
@@ -301,11 +309,17 @@ typedef struct IndexAmRoutine
301309
amestimateparallelscan_function amestimateparallelscan; /* can be NULL */
302310
aminitparallelscan_function aminitparallelscan; /* can be NULL */
303311
amparallelrescan_function amparallelrescan; /* can be NULL */
312+
313+
/* interface functions to support planning */
314+
amtranslate_strategy_function amtranslatestrategy; /* can be NULL */
315+
amtranslate_cmptype_function amtranslatecmptype; /* can be NULL */
304316
} IndexAmRoutine;
305317

306318

307319
/* Functions in access/index/amapi.c */
308320
extern IndexAmRoutine *GetIndexAmRoutine(Oid amhandler);
309321
extern IndexAmRoutine *GetIndexAmRoutineByAmId(Oid amoid, bool noerror);
322+
extern CompareType IndexAmTranslateStrategy(StrategyNumber strategy, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok);
323+
extern StrategyNumber IndexAmTranslateCompareType(CompareType cmptype, Oid amoid, Oid opfamily, Oid opcintype, bool missing_ok);
310324

311325
#endif /* AMAPI_H */

src/include/access/cmptype.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
*/
3131
typedef enum CompareType
3232
{
33+
COMPARE_INVALID = 0,
3334
COMPARE_LT = 1, /* BTLessStrategyNumber */
3435
COMPARE_LE = 2, /* BTLessEqualStrategyNumber */
3536
COMPARE_EQ = 3, /* BTEqualStrategyNumber */

src/include/access/hash.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,9 @@ extern void hashadjustmembers(Oid opfamilyoid,
387387
List *operators,
388388
List *functions);
389389

390+
extern CompareType hashtranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype);
391+
extern StrategyNumber hashtranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype);
392+
390393
/* private routines */
391394

392395
/* hashinsert.c */

src/include/access/nbtree.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1183,6 +1183,9 @@ extern IndexBulkDeleteResult *btvacuumcleanup(IndexVacuumInfo *info,
11831183
extern bool btcanreturn(Relation index, int attno);
11841184
extern int btgettreeheight(Relation rel);
11851185

1186+
extern CompareType bttranslatestrategy(StrategyNumber strategy, Oid opfamily, Oid opcintype);
1187+
extern StrategyNumber bttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype);
1188+
11861189
/*
11871190
* prototypes for internal functions in nbtree.c
11881191
*/

src/tools/pgindent/typedefs.list

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3318,6 +3318,8 @@ amparallelrescan_function
33183318
amproperty_function
33193319
amrescan_function
33203320
amrestrpos_function
3321+
amtranslate_strategy_function amtranslatestrategy;
3322+
amtranslate_cmptype_function amtranslatecmptype;
33213323
amvacuumcleanup_function
33223324
amvalidate_function
33233325
array_iter

0 commit comments

Comments
 (0)