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

Commit 622f678

Browse files
committed
Integrate GistTranslateCompareType() into IndexAmTranslateCompareType()
This turns GistTranslateCompareType() into a callback function of the gist index AM instead of a standalone function. The existing callers are changed to use IndexAmTranslateCompareType(). This then makes that code not hardcoded toward gist. This means in particular that the temporal keys code is now independent of gist. Also, this generalizes commit 74edabc, so other index access methods other than the previously hardcoded ones could now work as REPLICA IDENTITY in a logical replication subscriber. 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 43a15eb commit 622f678

File tree

8 files changed

+25
-82
lines changed

8 files changed

+25
-82
lines changed

src/backend/access/gist/gist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ gisthandler(PG_FUNCTION_ARGS)
108108
amroutine->aminitparallelscan = NULL;
109109
amroutine->amparallelrescan = NULL;
110110
amroutine->amtranslatestrategy = NULL;
111-
amroutine->amtranslatecmptype = NULL;
111+
amroutine->amtranslatecmptype = gisttranslatecmptype;
112112

113113
PG_RETURN_POINTER(amroutine);
114114
}

src/backend/access/gist/gistutil.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,17 +1095,11 @@ gist_stratnum_common(PG_FUNCTION_ARGS)
10951095
* Returns InvalidStrategy if the function is not defined.
10961096
*/
10971097
StrategyNumber
1098-
GistTranslateCompareType(Oid opclass, CompareType cmptype)
1098+
gisttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype)
10991099
{
1100-
Oid opfamily;
1101-
Oid opcintype;
11021100
Oid funcid;
11031101
Datum result;
11041102

1105-
/* Look up the opclass family and input datatype. */
1106-
if (!get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype))
1107-
return InvalidStrategy;
1108-
11091103
/* Check whether the function is provided. */
11101104
funcid = get_opfamily_proc(opfamily, opcintype, opcintype, GIST_STRATNUM_PROC);
11111105
if (!OidIsValid(funcid))

src/backend/commands/indexcmds.c

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2422,38 +2422,30 @@ void
24222422
GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype,
24232423
Oid *opid, StrategyNumber *strat)
24242424
{
2425+
Oid amid;
24252426
Oid opfamily;
24262427
Oid opcintype;
24272428

24282429
Assert(cmptype == COMPARE_EQ || cmptype == COMPARE_OVERLAP || cmptype == COMPARE_CONTAINED_BY);
24292430

2431+
amid = get_opclass_method(opclass);
2432+
24302433
*opid = InvalidOid;
24312434

24322435
if (get_opclass_opfamily_and_input_type(opclass, &opfamily, &opcintype))
24332436
{
24342437
/*
2435-
* Ask the opclass to translate to its internal stratnum
2436-
*
2437-
* For now we only need GiST support, but this could support other
2438-
* indexams if we wanted.
2438+
* Ask the index AM to translate to its internal stratnum
24392439
*/
2440-
*strat = GistTranslateCompareType(opclass, cmptype);
2440+
*strat = IndexAmTranslateCompareType(cmptype, amid, opfamily, opcintype, true);
24412441
if (*strat == InvalidStrategy)
2442-
{
2443-
HeapTuple tuple;
2444-
2445-
tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclass));
2446-
if (!HeapTupleIsValid(tuple))
2447-
elog(ERROR, "cache lookup failed for operator class %u", opclass);
2448-
24492442
ereport(ERROR,
24502443
errcode(ERRCODE_UNDEFINED_OBJECT),
24512444
cmptype = COMPARE_EQ ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) :
24522445
cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
24532446
cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
2454-
errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".",
2455-
cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
2456-
}
2447+
errdetail("Could not translate compare type %d for operator family \"%s\", input type %s, access method \"%s\".",
2448+
cmptype, get_opfamily_name(opfamily, false), format_type_be(opcintype), get_am_name(amid)));
24572449

24582450
/*
24592451
* We parameterize rhstype so foreign keys can ask for a <@ operator
@@ -2472,7 +2464,7 @@ GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype,
24722464
cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) :
24732465
cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0,
24742466
errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".",
2475-
get_opfamily_name(opfamily, false), "gist"));
2467+
get_opfamily_name(opfamily, false), get_am_name(amid)));
24762468
}
24772469

24782470
/*

src/backend/commands/tablecmds.c

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -10002,37 +10002,21 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
1000210002
CompareType cmptype;
1000310003
bool for_overlaps = with_period && i == numpks - 1;
1000410004

10005-
/*
10006-
* GiST indexes are required to support temporal foreign keys
10007-
* because they combine equals and overlaps.
10008-
*/
10009-
if (amid != GIST_AM_OID)
10010-
elog(ERROR, "only GiST indexes are supported for temporal foreign keys");
10011-
1001210005
cmptype = for_overlaps ? COMPARE_OVERLAP : COMPARE_EQ;
1001310006

1001410007
/*
10015-
* An opclass can use whatever strategy numbers it wants, so we
10016-
* ask the opclass what number it actually uses instead of our RT*
10017-
* constants.
10008+
* An index AM can use whatever strategy numbers it wants, so we
10009+
* ask it what number it actually uses.
1001810010
*/
10019-
eqstrategy = GistTranslateCompareType(opclasses[i], cmptype);
10011+
eqstrategy = IndexAmTranslateCompareType(cmptype, amid, opfamily, opcintype, true);
1002010012
if (eqstrategy == InvalidStrategy)
10021-
{
10022-
HeapTuple tuple;
10023-
10024-
tuple = SearchSysCache1(CLAOID, ObjectIdGetDatum(opclasses[i]));
10025-
if (!HeapTupleIsValid(tuple))
10026-
elog(ERROR, "cache lookup failed for operator class %u", opclasses[i]);
10027-
1002810013
ereport(ERROR,
1002910014
errcode(ERRCODE_UNDEFINED_OBJECT),
1003010015
for_overlaps
1003110016
? errmsg("could not identify an overlaps operator for foreign key")
1003210017
: errmsg("could not identify an equality operator for foreign key"),
10033-
errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".",
10034-
cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist"));
10035-
}
10018+
errdetail("Could not translate compare type %d for operator family \"%s\", input type %s, access method \"%s\".",
10019+
cmptype, get_opfamily_name(opfamily, false), format_type_be(opcintype), get_am_name(amid)));
1003610020
}
1003710021
else
1003810022
{
@@ -10041,7 +10025,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel,
1004110025
* other index AMs support unique indexes. If we ever did have
1004210026
* other types of unique indexes, we'd need a way to determine
1004310027
* which operator strategy number is equality. (We could use
10044-
* something like GistTranslateCompareType.)
10028+
* IndexAmTranslateCompareType.)
1004510029
*/
1004610030
if (amid != BTREE_AM_OID)
1004710031
elog(ERROR, "only b-tree indexes are supported for foreign keys");

src/backend/executor/execReplication.c

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -38,35 +38,6 @@
3838
static bool tuples_equal(TupleTableSlot *slot1, TupleTableSlot *slot2,
3939
TypeCacheEntry **eq);
4040

41-
/*
42-
* Returns the fixed strategy number, if any, of the equality operator for the
43-
* given operator class, otherwise, InvalidStrategy.
44-
*/
45-
StrategyNumber
46-
get_equal_strategy_number(Oid opclass)
47-
{
48-
Oid am = get_opclass_method(opclass);
49-
int ret;
50-
51-
switch (am)
52-
{
53-
case BTREE_AM_OID:
54-
ret = BTEqualStrategyNumber;
55-
break;
56-
case HASH_AM_OID:
57-
ret = HTEqualStrategyNumber;
58-
break;
59-
case GIST_AM_OID:
60-
ret = GistTranslateCompareType(opclass, COMPARE_EQ);
61-
break;
62-
default:
63-
ret = InvalidStrategy;
64-
break;
65-
}
66-
67-
return ret;
68-
}
69-
7041
/*
7142
* Setup a ScanKey for a search in the relation 'rel' for a tuple 'key' that
7243
* is setup to match 'rel' (*NOT* idxrel!).
@@ -120,10 +91,7 @@ build_replindex_scan_key(ScanKey skey, Relation rel, Relation idxrel,
12091
*/
12192
optype = get_opclass_input_type(opclass->values[index_attoff]);
12293
opfamily = get_opclass_family(opclass->values[index_attoff]);
123-
eq_strategy = get_equal_strategy_number(opclass->values[index_attoff]);
124-
if (!eq_strategy)
125-
elog(ERROR, "missing equal strategy for opclass %u", opclass->values[index_attoff]);
126-
94+
eq_strategy = IndexAmTranslateCompareType(COMPARE_EQ, idxrel->rd_rel->relam, opfamily, optype, false);
12795
operator = get_opfamily_member(opfamily, optype,
12896
optype,
12997
eq_strategy);

src/backend/replication/logical/relation.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "replication/logicalrelation.h"
2828
#include "replication/worker_internal.h"
2929
#include "utils/inval.h"
30+
#include "utils/lsyscache.h"
3031
#include "utils/syscache.h"
3132

3233

@@ -835,7 +836,12 @@ IsIndexUsableForReplicaIdentityFull(Relation idxrel, AttrMap *attrmap)
835836
/* Ensure that the index has a valid equal strategy for each key column */
836837
for (int i = 0; i < idxrel->rd_index->indnkeyatts; i++)
837838
{
838-
if (get_equal_strategy_number(indclass->values[i]) == InvalidStrategy)
839+
Oid opfamily;
840+
Oid opcintype;
841+
842+
if (!get_opclass_opfamily_and_input_type(indclass->values[i], &opfamily, &opcintype))
843+
return false;
844+
if (IndexAmTranslateCompareType(COMPARE_EQ, idxrel->rd_rel->relam, opfamily, opcintype, true) == InvalidStrategy)
839845
return false;
840846
}
841847

src/include/access/gist.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,6 @@ typedef struct
248248
do { (e).key = (k); (e).rel = (r); (e).page = (pg); \
249249
(e).offset = (o); (e).leafkey = (l); } while (0)
250250

251-
extern StrategyNumber GistTranslateCompareType(Oid opclass, CompareType cmptype);
251+
extern StrategyNumber gisttranslatecmptype(CompareType cmptype, Oid opfamily, Oid opcintype);
252252

253253
#endif /* GIST_H */

src/include/executor/executor.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -664,7 +664,6 @@ extern void check_exclusion_constraint(Relation heap, Relation index,
664664
/*
665665
* prototypes from functions in execReplication.c
666666
*/
667-
extern StrategyNumber get_equal_strategy_number(Oid opclass);
668667
extern bool RelationFindReplTupleByIndex(Relation rel, Oid idxoid,
669668
LockTupleMode lockmode,
670669
TupleTableSlot *searchslot,

0 commit comments

Comments
 (0)