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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 17 additions & 17 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 4 additions & 4 deletions
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

Lines changed: 4 additions & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 3 additions & 3 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy