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

Commit ce62f2f

Browse files
committed
Generalize hash and ordering support in amapi
Stop comparing access method OID values against HASH_AM_OID and BTREE_AM_OID, and instead check the IndexAmRoutine for an index to see if it advertises its ability to perform the necessary ordering, hashing, or cross-type comparing functionality. A field amcanorder already existed, this uses it more widely. Fields amcanhash and amcancrosscompare are added for the other purposes. Author: Mark Dilger <mark.dilger@enterprisedb.com> Discussion: https://www.postgresql.org/message-id/flat/E72EAA49-354D-4C2E-8EB9-255197F55330@enterprisedb.com
1 parent 6eb8a1a commit ce62f2f

File tree

14 files changed

+50
-26
lines changed

14 files changed

+50
-26
lines changed

contrib/bloom/blutils.c

+2
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,8 @@ blhandler(PG_FUNCTION_ARGS)
109109
amroutine->amoptsprocnum = BLOOM_OPTIONS_PROC;
110110
amroutine->amcanorder = false;
111111
amroutine->amcanorderbyop = false;
112+
amroutine->amcanhash = false;
113+
amroutine->amcancrosscompare = false;
112114
amroutine->amcanbackward = false;
113115
amroutine->amcanunique = false;
114116
amroutine->amcanmulticol = true;

doc/src/sgml/indexam.sgml

+4
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,10 @@ typedef struct IndexAmRoutine
103103
bool amcanorder;
104104
/* does AM support ORDER BY result of an operator on indexed column? */
105105
bool amcanorderbyop;
106+
/* does AM support hashing using API consistent with the hash AM? */
107+
bool amcanhash;
108+
/* does AM support cross-type comparisons? */
109+
bool amcancrosscompare;
106110
/* does AM support backward scanning? */
107111
bool amcanbackward;
108112
/* does AM support UNIQUE indexes? */

src/backend/access/brin/brin.c

+2
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,8 @@ brinhandler(PG_FUNCTION_ARGS)
256256
amroutine->amoptsprocnum = BRIN_PROCNUM_OPTIONS;
257257
amroutine->amcanorder = false;
258258
amroutine->amcanorderbyop = false;
259+
amroutine->amcanhash = false;
260+
amroutine->amcancrosscompare = false;
259261
amroutine->amcanbackward = false;
260262
amroutine->amcanunique = false;
261263
amroutine->amcanmulticol = true;

src/backend/access/gin/ginutil.c

+2
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ ginhandler(PG_FUNCTION_ARGS)
4343
amroutine->amoptsprocnum = GIN_OPTIONS_PROC;
4444
amroutine->amcanorder = false;
4545
amroutine->amcanorderbyop = false;
46+
amroutine->amcanhash = false;
47+
amroutine->amcancrosscompare = false;
4648
amroutine->amcanbackward = false;
4749
amroutine->amcanunique = false;
4850
amroutine->amcanmulticol = true;

src/backend/access/gist/gist.c

+2
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ gisthandler(PG_FUNCTION_ARGS)
6565
amroutine->amoptsprocnum = GIST_OPTIONS_PROC;
6666
amroutine->amcanorder = false;
6767
amroutine->amcanorderbyop = true;
68+
amroutine->amcanhash = false;
69+
amroutine->amcancrosscompare = false;
6870
amroutine->amcanbackward = false;
6971
amroutine->amcanunique = false;
7072
amroutine->amcanmulticol = true;

src/backend/access/hash/hash.c

+2
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,8 @@ hashhandler(PG_FUNCTION_ARGS)
6464
amroutine->amoptsprocnum = HASHOPTIONS_PROC;
6565
amroutine->amcanorder = false;
6666
amroutine->amcanorderbyop = false;
67+
amroutine->amcanhash = true;
68+
amroutine->amcancrosscompare = false;
6769
amroutine->amcanbackward = true;
6870
amroutine->amcanunique = false;
6971
amroutine->amcanmulticol = false;

src/backend/access/nbtree/nbtree.c

+2
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ bthandler(PG_FUNCTION_ARGS)
107107
amroutine->amoptsprocnum = BTOPTIONS_PROC;
108108
amroutine->amcanorder = true;
109109
amroutine->amcanorderbyop = false;
110+
amroutine->amcanhash = false;
111+
amroutine->amcancrosscompare = true;
110112
amroutine->amcanbackward = true;
111113
amroutine->amcanunique = true;
112114
amroutine->amcanmulticol = true;

src/backend/access/spgist/spgutils.c

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ spghandler(PG_FUNCTION_ARGS)
5050
amroutine->amoptsprocnum = SPGIST_OPTIONS_PROC;
5151
amroutine->amcanorder = false;
5252
amroutine->amcanorderbyop = true;
53+
amroutine->amcanhash = false;
54+
amroutine->amcancrosscompare = false;
5355
amroutine->amcanbackward = false;
5456
amroutine->amcanunique = false;
5557
amroutine->amcanmulticol = false;

src/backend/commands/opclasscmds.c

+17-17
Original file line numberDiff line numberDiff line change
@@ -1242,25 +1242,25 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
12421242
}
12431243

12441244
/*
1245-
* btree comparison procs must be 2-arg procs returning int4. btree
1246-
* sortsupport procs must take internal and return void. btree in_range
1247-
* procs must be 5-arg procs returning bool. btree equalimage procs must
1248-
* take 1 arg and return bool. hash support proc 1 must be a 1-arg proc
1249-
* returning int4, while proc 2 must be a 2-arg proc returning int8.
1250-
* Otherwise we don't know.
1245+
* Ordering comparison procs must be 2-arg procs returning int4. Ordering
1246+
* sortsupport procs must take internal and return void. Ordering
1247+
* in_range procs must be 5-arg procs returning bool. Ordering equalimage
1248+
* procs must take 1 arg and return bool. Hashing support proc 1 must be
1249+
* a 1-arg proc returning int4, while proc 2 must be a 2-arg proc
1250+
* returning int8. Otherwise we don't know.
12511251
*/
1252-
else if (amoid == BTREE_AM_OID)
1252+
else if (GetIndexAmRoutineByAmId(amoid, false)->amcanorder)
12531253
{
12541254
if (member->number == BTORDER_PROC)
12551255
{
12561256
if (procform->pronargs != 2)
12571257
ereport(ERROR,
12581258
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1259-
errmsg("btree comparison functions must have two arguments")));
1259+
errmsg("ordering comparison functions must have two arguments")));
12601260
if (procform->prorettype != INT4OID)
12611261
ereport(ERROR,
12621262
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1263-
errmsg("btree comparison functions must return integer")));
1263+
errmsg("ordering comparison functions must return integer")));
12641264

12651265
/*
12661266
* If lefttype/righttype isn't specified, use the proc's input
@@ -1277,11 +1277,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
12771277
procform->proargtypes.values[0] != INTERNALOID)
12781278
ereport(ERROR,
12791279
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1280-
errmsg("btree sort support functions must accept type \"internal\"")));
1280+
errmsg("ordering sort support functions must accept type \"internal\"")));
12811281
if (procform->prorettype != VOIDOID)
12821282
ereport(ERROR,
12831283
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1284-
errmsg("btree sort support functions must return void")));
1284+
errmsg("ordering sort support functions must return void")));
12851285

12861286
/*
12871287
* Can't infer lefttype/righttype from proc, so use default rule
@@ -1292,11 +1292,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
12921292
if (procform->pronargs != 5)
12931293
ereport(ERROR,
12941294
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1295-
errmsg("btree in_range functions must have five arguments")));
1295+
errmsg("ordering in_range functions must have five arguments")));
12961296
if (procform->prorettype != BOOLOID)
12971297
ereport(ERROR,
12981298
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1299-
errmsg("btree in_range functions must return boolean")));
1299+
errmsg("ordering in_range functions must return boolean")));
13001300

13011301
/*
13021302
* If lefttype/righttype isn't specified, use the proc's input
@@ -1312,11 +1312,11 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
13121312
if (procform->pronargs != 1)
13131313
ereport(ERROR,
13141314
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1315-
errmsg("btree equal image functions must have one argument")));
1315+
errmsg("ordering equal image functions must have one argument")));
13161316
if (procform->prorettype != BOOLOID)
13171317
ereport(ERROR,
13181318
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1319-
errmsg("btree equal image functions must return boolean")));
1319+
errmsg("ordering equal image functions must return boolean")));
13201320

13211321
/*
13221322
* pg_amproc functions are indexed by (lefttype, righttype), but
@@ -1329,10 +1329,10 @@ assignProcTypes(OpFamilyMember *member, Oid amoid, Oid typeoid,
13291329
if (member->lefttype != member->righttype)
13301330
ereport(ERROR,
13311331
(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
1332-
errmsg("btree equal image functions must not be cross-type")));
1332+
errmsg("ordering equal image functions must not be cross-type")));
13331333
}
13341334
}
1335-
else if (amoid == HASH_AM_OID)
1335+
else if (GetIndexAmRoutineByAmId(amoid, false)->amcanhash)
13361336
{
13371337
if (member->number == HASHSTANDARD_PROC)
13381338
{

src/backend/executor/nodeIndexscan.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -1331,10 +1331,10 @@ ExecIndexBuildScanKeys(PlanState *planstate, Relation index,
13311331
varattno = ((Var *) leftop)->varattno;
13321332

13331333
/*
1334-
* We have to look up the operator's associated btree support
1334+
* We have to look up the operator's associated support
13351335
* function
13361336
*/
1337-
if (index->rd_rel->relam != BTREE_AM_OID ||
1337+
if (!index->rd_indam->amcanorder ||
13381338
varattno < 1 || varattno > indnkeyatts)
13391339
elog(ERROR, "bogus RowCompare index qualification");
13401340
opfamily = index->rd_opfamily[varattno - 1];

src/backend/utils/cache/lsyscache.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -716,10 +716,9 @@ equality_ops_are_compatible(Oid opno1, Oid opno2)
716716
{
717717
HeapTuple op_tuple = &catlist->members[i]->tuple;
718718
Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
719+
IndexAmRoutine *amroutine = GetIndexAmRoutineByAmId(op_form->amopmethod, false);
719720

720-
/* must be btree or hash */
721-
if (op_form->amopmethod == BTREE_AM_OID ||
722-
op_form->amopmethod == HASH_AM_OID)
721+
if (amroutine->amcancrosscompare)
723722
{
724723
if (op_in_opfamily(opno2, op_form->amopfamily))
725724
{
@@ -767,8 +766,9 @@ comparison_ops_are_compatible(Oid opno1, Oid opno2)
767766
{
768767
HeapTuple op_tuple = &catlist->members[i]->tuple;
769768
Form_pg_amop op_form = (Form_pg_amop) GETSTRUCT(op_tuple);
769+
IndexAmRoutine *amroutine = GetIndexAmRoutineByAmId(op_form->amopmethod, false);
770770

771-
if (op_form->amopmethod == BTREE_AM_OID)
771+
if (amroutine->amcanorder && amroutine->amcancrosscompare)
772772
{
773773
if (op_in_opfamily(opno2, op_form->amopfamily))
774774
{

src/include/access/amapi.h

+4
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,10 @@ typedef struct IndexAmRoutine
243243
bool amcanorder;
244244
/* does AM support ORDER BY result of an operator on indexed column? */
245245
bool amcanorderbyop;
246+
/* does AM support hashing using API consistent with the hash AM? */
247+
bool amcanhash;
248+
/* does AM support cross-type comparisons? */
249+
bool amcancrosscompare;
246250
/* does AM support backward scanning? */
247251
bool amcanbackward;
248252
/* does AM support UNIQUE indexes? */

src/test/modules/dummy_index_am/dummy_index_am.c

+2
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,8 @@ dihandler(PG_FUNCTION_ARGS)
282282
amroutine->amsupport = 1;
283283
amroutine->amcanorder = false;
284284
amroutine->amcanorderbyop = false;
285+
amroutine->amcanhash = false;
286+
amroutine->amcancrosscompare = false;
285287
amroutine->amcanbackward = false;
286288
amroutine->amcanunique = false;
287289
amroutine->amcanmulticol = false;

src/test/regress/expected/alter_generic.out

+3-3
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ BEGIN TRANSACTION;
420420
CREATE OPERATOR FAMILY alt_opf12 USING btree;
421421
CREATE FUNCTION fn_opf12 (int4, int2) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
422422
ALTER OPERATOR FAMILY alt_opf12 USING btree ADD FUNCTION 1 fn_opf12(int4, int2);
423-
ERROR: btree comparison functions must return integer
423+
ERROR: ordering comparison functions must return integer
424424
DROP OPERATOR FAMILY alt_opf12 USING btree;
425425
ERROR: current transaction is aborted, commands ignored until end of transaction block
426426
ROLLBACK;
@@ -438,7 +438,7 @@ BEGIN TRANSACTION;
438438
CREATE OPERATOR FAMILY alt_opf14 USING btree;
439439
CREATE FUNCTION fn_opf14 (int4) RETURNS BIGINT AS 'SELECT NULL::BIGINT;' LANGUAGE SQL;
440440
ALTER OPERATOR FAMILY alt_opf14 USING btree ADD FUNCTION 1 fn_opf14(int4);
441-
ERROR: btree comparison functions must have two arguments
441+
ERROR: ordering comparison functions must have two arguments
442442
DROP OPERATOR FAMILY alt_opf14 USING btree;
443443
ERROR: current transaction is aborted, commands ignored until end of transaction block
444444
ROLLBACK;
@@ -504,7 +504,7 @@ ALTER OPERATOR FAMILY alt_opf18 USING btree ADD
504504
-- Should fail. Not allowed to have cross-type equalimage function.
505505
ALTER OPERATOR FAMILY alt_opf18 USING btree
506506
ADD FUNCTION 4 (int4, int2) btequalimage(oid);
507-
ERROR: btree equal image functions must not be cross-type
507+
ERROR: ordering equal image functions must not be cross-type
508508
ALTER OPERATOR FAMILY alt_opf18 USING btree DROP FUNCTION 2 (int4, int4);
509509
ERROR: function 2(integer,integer) does not exist in operator family "alt_opf18"
510510
DROP OPERATOR FAMILY alt_opf18 USING btree;

0 commit comments

Comments
 (0)