From 9509de62880094562eb234e4bdecbaed5062ff91 Mon Sep 17 00:00:00 2001 From: Peter Eisentraut Date: Wed, 4 Dec 2024 15:31:18 +0100 Subject: [PATCH v19.1 2/2] Change gist stratnum function to use CompareType This changes commit 7406ab623fe in that the gist strategy number mapping support function is changed to use the CompareType enum as input, instead of the "well-known" RT*StrategyNumber strategy numbers. This is a bit cleaner, since you are not dealing with two sets of strategy numbers. Also, this will enable us to subsume this system into a more general system of using CompareType to define operator semantics across index methods. --- contrib/btree_gist/btree_gist--1.7--1.8.sql | 54 ++++++++++---------- contrib/btree_gist/btree_gist.c | 15 +++--- contrib/btree_gist/expected/stratnum.out | 4 +- contrib/btree_gist/sql/stratnum.sql | 4 +- doc/src/sgml/gist.sgml | 24 ++++----- doc/src/sgml/xindex.sgml | 2 +- src/backend/access/gist/gistutil.c | 35 +++++++++---- src/backend/access/gist/gistvalidate.c | 2 +- src/backend/catalog/pg_constraint.c | 20 ++++---- src/backend/commands/indexcmds.c | 50 +++++++++--------- src/backend/commands/tablecmds.c | 10 ++-- src/include/access/gist.h | 3 +- src/include/catalog/pg_amproc.dat | 12 ++--- src/include/catalog/pg_proc.dat | 6 +-- src/include/commands/defrem.h | 4 +- src/include/nodes/primnodes.h | 4 +- src/test/regress/expected/misc_functions.out | 16 +++--- src/test/regress/sql/misc_functions.sql | 4 +- 18 files changed, 144 insertions(+), 125 deletions(-) diff --git a/contrib/btree_gist/btree_gist--1.7--1.8.sql b/contrib/btree_gist/btree_gist--1.7--1.8.sql index 307bfe574b0..c702426deab 100644 --- a/contrib/btree_gist/btree_gist--1.7--1.8.sql +++ b/contrib/btree_gist/btree_gist--1.7--1.8.sql @@ -3,85 +3,85 @@ -- complain if script is sourced in psql, rather than via CREATE EXTENSION \echo Use "ALTER EXTENSION btree_gist UPDATE TO '1.8'" to load this file. \quit -CREATE FUNCTION gist_stratnum_btree(smallint) +CREATE FUNCTION gist_stratnum_btree(int) RETURNS smallint AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE PARALLEL SAFE STRICT; ALTER OPERATOR FAMILY gist_oid_ops USING gist ADD - FUNCTION 12 (oid, oid) gist_stratnum_btree (int2) ; + FUNCTION 12 (oid, oid) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_int2_ops USING gist ADD - FUNCTION 12 (int2, int2) gist_stratnum_btree (int2) ; + FUNCTION 12 (int2, int2) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_int4_ops USING gist ADD - FUNCTION 12 (int4, int4) gist_stratnum_btree (int2) ; + FUNCTION 12 (int4, int4) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_int8_ops USING gist ADD - FUNCTION 12 (int8, int8) gist_stratnum_btree (int2) ; + FUNCTION 12 (int8, int8) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_float4_ops USING gist ADD - FUNCTION 12 (float4, float4) gist_stratnum_btree (int2) ; + FUNCTION 12 (float4, float4) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_float8_ops USING gist ADD - FUNCTION 12 (float8, float8) gist_stratnum_btree (int2) ; + FUNCTION 12 (float8, float8) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_timestamp_ops USING gist ADD - FUNCTION 12 (timestamp, timestamp) gist_stratnum_btree (int2) ; + FUNCTION 12 (timestamp, timestamp) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_timestamptz_ops USING gist ADD - FUNCTION 12 (timestamptz, timestamptz) gist_stratnum_btree (int2) ; + FUNCTION 12 (timestamptz, timestamptz) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_time_ops USING gist ADD - FUNCTION 12 (time, time) gist_stratnum_btree (int2) ; + FUNCTION 12 (time, time) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_date_ops USING gist ADD - FUNCTION 12 (date, date) gist_stratnum_btree (int2) ; + FUNCTION 12 (date, date) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_interval_ops USING gist ADD - FUNCTION 12 (interval, interval) gist_stratnum_btree (int2) ; + FUNCTION 12 (interval, interval) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_cash_ops USING gist ADD - FUNCTION 12 (money, money) gist_stratnum_btree (int2) ; + FUNCTION 12 (money, money) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_macaddr_ops USING gist ADD - FUNCTION 12 (macaddr, macaddr) gist_stratnum_btree (int2) ; + FUNCTION 12 (macaddr, macaddr) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_text_ops USING gist ADD - FUNCTION 12 (text, text) gist_stratnum_btree (int2) ; + FUNCTION 12 (text, text) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_bpchar_ops USING gist ADD - FUNCTION 12 (bpchar, bpchar) gist_stratnum_btree (int2) ; + FUNCTION 12 (bpchar, bpchar) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_bytea_ops USING gist ADD - FUNCTION 12 (bytea, bytea) gist_stratnum_btree (int2) ; + FUNCTION 12 (bytea, bytea) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_numeric_ops USING gist ADD - FUNCTION 12 (numeric, numeric) gist_stratnum_btree (int2) ; + FUNCTION 12 (numeric, numeric) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_bit_ops USING gist ADD - FUNCTION 12 (bit, bit) gist_stratnum_btree (int2) ; + FUNCTION 12 (bit, bit) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_vbit_ops USING gist ADD - FUNCTION 12 (varbit, varbit) gist_stratnum_btree (int2) ; + FUNCTION 12 (varbit, varbit) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_inet_ops USING gist ADD - FUNCTION 12 (inet, inet) gist_stratnum_btree (int2) ; + FUNCTION 12 (inet, inet) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_cidr_ops USING gist ADD - FUNCTION 12 (cidr, cidr) gist_stratnum_btree (int2) ; + FUNCTION 12 (cidr, cidr) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_timetz_ops USING gist ADD - FUNCTION 12 (timetz, timetz) gist_stratnum_btree (int2) ; + FUNCTION 12 (timetz, timetz) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_uuid_ops USING gist ADD - FUNCTION 12 (uuid, uuid) gist_stratnum_btree (int2) ; + FUNCTION 12 (uuid, uuid) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_macaddr8_ops USING gist ADD - FUNCTION 12 (macaddr8, macaddr8) gist_stratnum_btree (int2) ; + FUNCTION 12 (macaddr8, macaddr8) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_enum_ops USING gist ADD - FUNCTION 12 (anyenum, anyenum) gist_stratnum_btree (int2) ; + FUNCTION 12 (anyenum, anyenum) gist_stratnum_btree (int) ; ALTER OPERATOR FAMILY gist_bool_ops USING gist ADD - FUNCTION 12 (bool, bool) gist_stratnum_btree (int2) ; + FUNCTION 12 (bool, bool) gist_stratnum_btree (int) ; diff --git a/contrib/btree_gist/btree_gist.c b/contrib/btree_gist/btree_gist.c index 5fd4cce27d0..fc6c7091795 100644 --- a/contrib/btree_gist/btree_gist.c +++ b/contrib/btree_gist/btree_gist.c @@ -4,6 +4,7 @@ #include "postgres.h" #include "access/stratnum.h" +#include "nodes/primnodes.h" #include "utils/builtins.h" PG_MODULE_MAGIC; @@ -60,19 +61,19 @@ gbt_decompress(PG_FUNCTION_ARGS) Datum gist_stratnum_btree(PG_FUNCTION_ARGS) { - StrategyNumber strat = PG_GETARG_UINT16(0); + CompareType cmptype = PG_GETARG_INT32(0); - switch (strat) + switch (cmptype) { - case RTEqualStrategyNumber: + case COMPARE_EQ: PG_RETURN_UINT16(BTEqualStrategyNumber); - case RTLessStrategyNumber: + case COMPARE_LT: PG_RETURN_UINT16(BTLessStrategyNumber); - case RTLessEqualStrategyNumber: + case COMPARE_LE: PG_RETURN_UINT16(BTLessEqualStrategyNumber); - case RTGreaterStrategyNumber: + case COMPARE_GT: PG_RETURN_UINT16(BTGreaterStrategyNumber); - case RTGreaterEqualStrategyNumber: + case COMPARE_GE: PG_RETURN_UINT16(BTGreaterEqualStrategyNumber); default: PG_RETURN_UINT16(InvalidStrategy); diff --git a/contrib/btree_gist/expected/stratnum.out b/contrib/btree_gist/expected/stratnum.out index 9d80c6590d9..dd0edaf4a20 100644 --- a/contrib/btree_gist/expected/stratnum.out +++ b/contrib/btree_gist/expected/stratnum.out @@ -1,11 +1,11 @@ -- test stratnum support func -SELECT gist_stratnum_btree(3::smallint); +SELECT gist_stratnum_btree(7); gist_stratnum_btree --------------------- 0 (1 row) -SELECT gist_stratnum_btree(18::smallint); +SELECT gist_stratnum_btree(3); gist_stratnum_btree --------------------- 3 diff --git a/contrib/btree_gist/sql/stratnum.sql b/contrib/btree_gist/sql/stratnum.sql index f58cdbe93da..75adddad849 100644 --- a/contrib/btree_gist/sql/stratnum.sql +++ b/contrib/btree_gist/sql/stratnum.sql @@ -1,3 +1,3 @@ -- test stratnum support func -SELECT gist_stratnum_btree(3::smallint); -SELECT gist_stratnum_btree(18::smallint); +SELECT gist_stratnum_btree(7); +SELECT gist_stratnum_btree(3); diff --git a/doc/src/sgml/gist.sgml b/doc/src/sgml/gist.sgml index 638d912dc2d..99098ab2522 100644 --- a/doc/src/sgml/gist.sgml +++ b/doc/src/sgml/gist.sgml @@ -290,8 +290,8 @@ Extensibility The optional eleventh method sortsupport is used to speed up building a GiST index. The optional twelfth method stratnum is used to - translate well-known RT*StrategyNumbers (from - src/include/access/stratnum.h) into strategy numbers + translate compare types (from + src/include/nodes/primnodes.h) into strategy numbers used by the operator class. This lets the core code look up operators for temporal constraint indexes. @@ -1173,8 +1173,8 @@ Extensibility stratnum - Given an RT*StrategyNumber value from - src/include/access/stratnum.h, returns a strategy + Given a CompareType value from + src/include/nodes/primnodes.h, returns a strategy number used by this operator class for matching functionality. The function should return InvalidStrategy if the operator class has no matching strategy. @@ -1184,7 +1184,7 @@ Extensibility This is used for temporal index constraints (i.e., PRIMARY KEY and UNIQUE). If the operator class provides this function and it returns results for - RTEqualStrategyNumber, it can be used in the + COMPARE_EQ, it can be used in the non-WITHOUT OVERLAPS part(s) of an index constraint. @@ -1194,7 +1194,7 @@ Extensibility CREATE OR REPLACE FUNCTION my_stratnum(integer) -RETURNS integer +RETURNS smallint AS 'MODULE_PATHNAME' LANGUAGE C STRICT; @@ -1209,12 +1209,12 @@ Extensibility Datum my_stratnum(PG_FUNCTION_ARGS) { - StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(1); + CompareType cmptype = PG_GETARG_INT32(0); StrategyNumber ret = InvalidStrategy; - switch (strategy) + switch (cmptype) { - case RTEqualStrategyNumber: + case COMPARE_EQ: ret = BTEqualStrategyNumber; } @@ -1226,9 +1226,9 @@ Extensibility One translation function is provided by PostgreSQL: - gist_stratnum_identity is for operator classes that - already use the RT*StrategyNumber constants. It - returns whatever is passed to it. The btree_gist + gist_stratnum_common is for operator classes that + use the RT*StrategyNumber constants. + The btree_gist extension defines a second translation function, gist_stratnum_btree, for operator classes that use the BT*StrategyNumber constants. diff --git a/doc/src/sgml/xindex.sgml b/doc/src/sgml/xindex.sgml index 3a19dab15e0..05361962495 100644 --- a/doc/src/sgml/xindex.sgml +++ b/doc/src/sgml/xindex.sgml @@ -592,7 +592,7 @@ GiST Support Functions stratnum - translate well-known strategy numbers to ones + translate compare types to strategy numbers used by the operator class (optional) 12 diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index d2d0b36d4ea..bde541a6251 100644 --- a/src/backend/access/gist/gistutil.c +++ b/src/backend/access/gist/gistutil.c @@ -1058,27 +1058,44 @@ gistGetFakeLSN(Relation rel) } /* - * Returns the same number that was received. - * - * This is for GiST opclasses that use the RT*StrategyNumber constants. + * This is a stratnum support function for GiST opclasses that use the + * RT*StrategyNumber constants. */ Datum -gist_stratnum_identity(PG_FUNCTION_ARGS) +gist_stratnum_common(PG_FUNCTION_ARGS) { - StrategyNumber strat = PG_GETARG_UINT16(0); + CompareType cmptype = PG_GETARG_INT32(0); - PG_RETURN_UINT16(strat); + switch (cmptype) + { + case COMPARE_EQ: + PG_RETURN_UINT16(RTEqualStrategyNumber); + case COMPARE_LT: + PG_RETURN_UINT16(RTLessStrategyNumber); + case COMPARE_LE: + PG_RETURN_UINT16(RTLessEqualStrategyNumber); + case COMPARE_GT: + PG_RETURN_UINT16(RTGreaterStrategyNumber); + case COMPARE_GE: + PG_RETURN_UINT16(RTGreaterEqualStrategyNumber); + case COMPARE_OVERLAP: + PG_RETURN_UINT16(RTOverlapStrategyNumber); + case COMPARE_CONTAINED_BY: + PG_RETURN_UINT16(RTContainedByStrategyNumber); + default: + PG_RETURN_UINT16(InvalidStrategy); + } } /* - * Returns the opclass's private stratnum used for the given strategy. + * Returns the opclass's private stratnum used for the given compare type. * * Calls the opclass's GIST_STRATNUM_PROC support function, if any, * and returns the result. * Returns InvalidStrategy if the function is not defined. */ StrategyNumber -GistTranslateStratnum(Oid opclass, StrategyNumber strat) +GistTranslateStratnum(Oid opclass, CompareType cmptype) { Oid opfamily; Oid opcintype; @@ -1095,6 +1112,6 @@ GistTranslateStratnum(Oid opclass, StrategyNumber strat) return InvalidStrategy; /* Ask the translation function */ - result = OidFunctionCall1Coll(funcid, InvalidOid, UInt16GetDatum(strat)); + result = OidFunctionCall1Coll(funcid, InvalidOid, Int32GetDatum(cmptype)); return DatumGetUInt16(result); } diff --git a/src/backend/access/gist/gistvalidate.c b/src/backend/access/gist/gistvalidate.c index 0901543a60a..7d51fc167d6 100644 --- a/src/backend/access/gist/gistvalidate.c +++ b/src/backend/access/gist/gistvalidate.c @@ -148,7 +148,7 @@ gistvalidate(Oid opclassoid) break; case GIST_STRATNUM_PROC: ok = check_amproc_signature(procform->amproc, INT2OID, true, - 1, 1, INT2OID); + 1, 1, INT4OID); break; default: ereport(INFO, diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c index 9c05a98d28c..4a076e2874e 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -1638,22 +1638,22 @@ FindFKPeriodOpers(Oid opclass, * of the old value, then we can treat the attribute as if it didn't * change, and skip the RI check. */ - strat = RTContainedByStrategyNumber; - GetOperatorFromWellKnownStrategy(opclass, - InvalidOid, - containedbyoperoid, - &strat); + GetOperatorFromCompareType(opclass, + InvalidOid, + COMPARE_CONTAINED_BY, + containedbyoperoid, + &strat); /* * Now look up the ContainedBy operator. Its left arg must be the type of * the column (or rather of the opclass). Its right arg must match the * return type of the support proc. */ - strat = RTContainedByStrategyNumber; - GetOperatorFromWellKnownStrategy(opclass, - ANYMULTIRANGEOID, - aggedcontainedbyoperoid, - &strat); + GetOperatorFromCompareType(opclass, + ANYMULTIRANGEOID, + COMPARE_CONTAINED_BY, + aggedcontainedbyoperoid, + &strat); } /* diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c index 4049ce1a10f..9c1a159754c 100644 --- a/src/backend/commands/indexcmds.c +++ b/src/backend/commands/indexcmds.c @@ -2178,15 +2178,15 @@ ComputeIndexAttrs(IndexInfo *indexInfo, } else if (iswithoutoverlaps) { + CompareType cmptype; StrategyNumber strat; Oid opid; if (attn == nkeycols - 1) - strat = RTOverlapStrategyNumber; + cmptype = COMPARE_OVERLAP; else - strat = RTEqualStrategyNumber; - GetOperatorFromWellKnownStrategy(opclassOids[attn], InvalidOid, - &opid, &strat); + cmptype = COMPARE_EQ; + GetOperatorFromCompareType(opclassOids[attn], InvalidOid, cmptype, &opid, &strat); indexInfo->ii_ExclusionOps[attn] = opid; indexInfo->ii_ExclusionProcs[attn] = get_opcode(opid); indexInfo->ii_ExclusionStrats[attn] = strat; @@ -2422,30 +2422,28 @@ GetDefaultOpClass(Oid type_id, Oid am_id) } /* - * GetOperatorFromWellKnownStrategy + * GetOperatorFromCompareType * * opclass - the opclass to use * rhstype - the type for the right-hand side, or InvalidOid to use the type of the given opclass. + * cmptype - kind of operator to find * opid - holds the operator we found - * strat - holds the input and output strategy number + * strat - holds the output strategy number * - * Finds an operator from a "well-known" strategy number. This is used for - * temporal index constraints (and other temporal features) to look up - * equality and overlaps operators, since the strategy numbers for non-btree - * indexams need not follow any fixed scheme. We ask an opclass support - * function to translate from the well-known number to the internal value. If - * the function isn't defined or it gives no result, we return - * InvalidStrategy. + * Finds an operator from a CompareType. This is used for temporal index + * constraints (and other temporal features) to look up equality and overlaps + * operators. We ask an opclass support function to translate from the + * compare type to the internal strategy numbers. If the function isn't + * defined or it gives no result, we set *strat to InvalidStrategy. */ void -GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, - Oid *opid, StrategyNumber *strat) +GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype, + Oid *opid, StrategyNumber *strat) { Oid opfamily; Oid opcintype; - StrategyNumber instrat = *strat; - Assert(instrat == RTEqualStrategyNumber || instrat == RTOverlapStrategyNumber || instrat == RTContainedByStrategyNumber); + Assert(cmptype == COMPARE_EQ || cmptype == COMPARE_OVERLAP || cmptype == COMPARE_CONTAINED_BY); *opid = InvalidOid; @@ -2457,7 +2455,7 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, * For now we only need GiST support, but this could support other * indexams if we wanted. */ - *strat = GistTranslateStratnum(opclass, instrat); + *strat = GistTranslateStratnum(opclass, cmptype); if (*strat == InvalidStrategy) { HeapTuple tuple; @@ -2468,11 +2466,11 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, ereport(ERROR, errcode(ERRCODE_UNDEFINED_OBJECT), - instrat == RTEqualStrategyNumber ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) : - instrat == RTOverlapStrategyNumber ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) : - instrat == RTContainedByStrategyNumber ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0, - errdetail("Could not translate strategy number %d for operator class \"%s\" for access method \"%s\".", - instrat, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist")); + cmptype = COMPARE_EQ ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) : + cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) : + cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0, + errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".", + cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist")); } /* @@ -2495,9 +2493,9 @@ GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, ereport(ERROR, errcode(ERRCODE_UNDEFINED_OBJECT), - instrat == RTEqualStrategyNumber ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) : - instrat == RTOverlapStrategyNumber ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) : - instrat == RTContainedByStrategyNumber ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0, + cmptype == COMPARE_EQ ? errmsg("could not identify an equality operator for type %s", format_type_be(opcintype)) : + cmptype == COMPARE_OVERLAP ? errmsg("could not identify an overlaps operator for type %s", format_type_be(opcintype)) : + cmptype == COMPARE_CONTAINED_BY ? errmsg("could not identify a contained-by operator for type %s", format_type_be(opcintype)) : 0, errdetail("There is no suitable operator in operator family \"%s\" for access method \"%s\".", NameStr(((Form_pg_opfamily) GETSTRUCT(tuple))->opfname), "gist")); } diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 6ccae4cb4a8..aef672d278d 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -9972,7 +9972,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, if (with_period) { - StrategyNumber rtstrategy; + CompareType cmptype; bool for_overlaps = with_period && i == numpks - 1; /* @@ -9982,14 +9982,14 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, if (amid != GIST_AM_OID) elog(ERROR, "only GiST indexes are supported for temporal foreign keys"); - rtstrategy = for_overlaps ? RTOverlapStrategyNumber : RTEqualStrategyNumber; + cmptype = for_overlaps ? COMPARE_OVERLAP : COMPARE_EQ; /* * An opclass can use whatever strategy numbers it wants, so we * ask the opclass what number it actually uses instead of our RT* * constants. */ - eqstrategy = GistTranslateStratnum(opclasses[i], rtstrategy); + eqstrategy = GistTranslateStratnum(opclasses[i], cmptype); if (eqstrategy == InvalidStrategy) { HeapTuple tuple; @@ -10003,8 +10003,8 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, for_overlaps ? errmsg("could not identify an overlaps operator for foreign key") : errmsg("could not identify an equality operator for foreign key"), - errdetail("Could not translate strategy number %d for operator class \"%s\" for access method \"%s\".", - rtstrategy, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist")); + errdetail("Could not translate compare type %d for operator class \"%s\" for access method \"%s\".", + cmptype, NameStr(((Form_pg_opclass) GETSTRUCT(tuple))->opcname), "gist")); } } else diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 22dd04c1418..a8689cfcefe 100644 --- a/src/include/access/gist.h +++ b/src/include/access/gist.h @@ -247,6 +247,7 @@ typedef struct do { (e).key = (k); (e).rel = (r); (e).page = (pg); \ (e).offset = (o); (e).leafkey = (l); } while (0) -extern StrategyNumber GistTranslateStratnum(Oid opclass, StrategyNumber strat); +enum CompareType; +extern StrategyNumber GistTranslateStratnum(Oid opclass, enum CompareType cmp); #endif /* GIST_H */ diff --git a/src/include/catalog/pg_amproc.dat b/src/include/catalog/pg_amproc.dat index 5d7fe292bf6..a04828fde96 100644 --- a/src/include/catalog/pg_amproc.dat +++ b/src/include/catalog/pg_amproc.dat @@ -508,7 +508,7 @@ amprocrighttype => 'box', amprocnum => '8', amproc => 'gist_box_distance' }, { amprocfamily => 'gist/box_ops', amproclefttype => 'box', amprocrighttype => 'box', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, { amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon', amprocrighttype => 'polygon', amprocnum => '1', amproc => 'gist_poly_consistent' }, @@ -530,7 +530,7 @@ amproc => 'gist_poly_distance' }, { amprocfamily => 'gist/poly_ops', amproclefttype => 'polygon', amprocrighttype => 'polygon', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, { amprocfamily => 'gist/circle_ops', amproclefttype => 'circle', amprocrighttype => 'circle', amprocnum => '1', amproc => 'gist_circle_consistent' }, @@ -551,7 +551,7 @@ amproc => 'gist_circle_distance' }, { amprocfamily => 'gist/circle_ops', amproclefttype => 'circle', amprocrighttype => 'circle', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, { amprocfamily => 'gist/tsvector_ops', amproclefttype => 'tsvector', amprocrighttype => 'tsvector', amprocnum => '1', amproc => 'gtsvector_consistent(internal,tsvector,int2,oid,internal)' }, @@ -608,7 +608,7 @@ amproc => 'range_gist_same' }, { amprocfamily => 'gist/range_ops', amproclefttype => 'anyrange', amprocrighttype => 'anyrange', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, { amprocfamily => 'gist/network_ops', amproclefttype => 'inet', amprocrighttype => 'inet', amprocnum => '1', amproc => 'inet_gist_consistent' }, @@ -627,7 +627,7 @@ amprocrighttype => 'inet', amprocnum => '9', amproc => 'inet_gist_fetch' }, { amprocfamily => 'gist/network_ops', amproclefttype => 'inet', amprocrighttype => 'inet', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, { amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange', amprocrighttype => 'anymultirange', amprocnum => '1', amproc => 'multirange_gist_consistent' }, @@ -648,7 +648,7 @@ amproc => 'range_gist_same' }, { amprocfamily => 'gist/multirange_ops', amproclefttype => 'anymultirange', amprocrighttype => 'anymultirange', amprocnum => '12', - amproc => 'gist_stratnum_identity' }, + amproc => 'gist_stratnum_common' }, # gin { amprocfamily => 'gin/array_ops', amproclefttype => 'anyarray', diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat index 9575524007f..988b8a336f7 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12403,8 +12403,8 @@ # GiST stratnum implementations { oid => '8047', descr => 'GiST support', - proname => 'gist_stratnum_identity', prorettype => 'int2', - proargtypes => 'int2', - prosrc => 'gist_stratnum_identity' }, + proname => 'gist_stratnum_common', prorettype => 'int2', + proargtypes => 'int4', + prosrc => 'gist_stratnum_common' }, ] diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h index 5fd095ea177..bf44d111c00 100644 --- a/src/include/commands/defrem.h +++ b/src/include/commands/defrem.h @@ -50,8 +50,8 @@ extern bool CheckIndexCompatible(Oid oldId, extern Oid GetDefaultOpClass(Oid type_id, Oid am_id); extern Oid ResolveOpClass(const List *opclass, Oid attrType, const char *accessMethodName, Oid accessMethodId); -extern void GetOperatorFromWellKnownStrategy(Oid opclass, Oid rhstype, - Oid *opid, StrategyNumber *strat); +extern void GetOperatorFromCompareType(Oid opclass, Oid rhstype, CompareType cmptype, + Oid *opid, StrategyNumber *strat); /* commands/functioncmds.c */ extern ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt); diff --git a/src/include/nodes/primnodes.h b/src/include/nodes/primnodes.h index 107eb36a340..60a8c62fca4 100644 --- a/src/include/nodes/primnodes.h +++ b/src/include/nodes/primnodes.h @@ -1446,7 +1446,7 @@ typedef struct RowExpr * (some of) the operators without needing hardcoded knowledge of index AM's * strategy numbering. * - * XXX Currently, this mapping is not fully developed and the values are + * XXX Currently, this mapping is not fully developed and most values are * chosen to match btree strategy numbers, which is not going to work very * well for other access methods. */ @@ -1458,6 +1458,8 @@ typedef enum CompareType COMPARE_GE = 4, /* BTGreaterEqualStrategyNumber */ COMPARE_GT = 5, /* BTGreaterStrategyNumber */ COMPARE_NE = 6, /* no such btree strategy */ + COMPARE_OVERLAP, + COMPARE_CONTAINED_BY, } CompareType; /* diff --git a/src/test/regress/expected/misc_functions.out b/src/test/regress/expected/misc_functions.out index 8c73d2b621e..dc28fcb310e 100644 --- a/src/test/regress/expected/misc_functions.out +++ b/src/test/regress/expected/misc_functions.out @@ -891,15 +891,15 @@ SELECT pg_column_toast_chunk_id(a) IS NULL, DROP TABLE test_chunk_id; DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool); -- test stratnum support functions -SELECT gist_stratnum_identity(3::smallint); - gist_stratnum_identity ------------------------- - 3 +SELECT gist_stratnum_common(7); + gist_stratnum_common +---------------------- + 3 (1 row) -SELECT gist_stratnum_identity(18::smallint); - gist_stratnum_identity ------------------------- - 18 +SELECT gist_stratnum_common(3); + gist_stratnum_common +---------------------- + 18 (1 row) diff --git a/src/test/regress/sql/misc_functions.sql b/src/test/regress/sql/misc_functions.sql index 0a0c6e5a6bb..81ef45d128c 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -401,5 +401,5 @@ CREATE TABLE test_chunk_id (a TEXT, b TEXT STORAGE EXTERNAL); DROP FUNCTION explain_mask_costs(text, bool, bool, bool, bool); -- test stratnum support functions -SELECT gist_stratnum_identity(3::smallint); -SELECT gist_stratnum_identity(18::smallint); +SELECT gist_stratnum_common(7); +SELECT gist_stratnum_common(3); -- 2.47.1