diff options
author | Peter Eisentraut | 2025-01-15 10:28:39 +0000 |
---|---|---|
committer | Peter Eisentraut | 2025-01-15 10:34:04 +0000 |
commit | 630f9a43cece93cb4a5c243b30e34abce6a89514 (patch) | |
tree | ef3a4a65f971bd526919b0ee67fad92bb4590ef9 /src | |
parent | 6339f6468e8217f556e38482626250dc72d7cd00 (diff) |
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.
Discussion: https://www.postgresql.org/message-id/flat/[email protected]
Diffstat (limited to 'src')
-rw-r--r-- | src/backend/access/gist/gistutil.c | 35 | ||||
-rw-r--r-- | src/backend/access/gist/gistvalidate.c | 2 | ||||
-rw-r--r-- | src/backend/catalog/pg_constraint.c | 20 | ||||
-rw-r--r-- | src/backend/commands/indexcmds.c | 50 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 10 | ||||
-rw-r--r-- | src/backend/executor/execReplication.c | 2 | ||||
-rw-r--r-- | src/include/access/gist.h | 3 | ||||
-rw-r--r-- | src/include/catalog/pg_amproc.dat | 12 | ||||
-rw-r--r-- | src/include/catalog/pg_proc.dat | 6 | ||||
-rw-r--r-- | src/include/commands/defrem.h | 4 | ||||
-rw-r--r-- | src/include/nodes/primnodes.h | 4 | ||||
-rw-r--r-- | src/test/regress/expected/misc_functions.out | 16 | ||||
-rw-r--r-- | src/test/regress/sql/misc_functions.sql | 4 |
13 files changed, 93 insertions, 75 deletions
diff --git a/src/backend/access/gist/gistutil.c b/src/backend/access/gist/gistutil.c index a2fcfbe4807..48db718b904 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 499ed8c8748..bb86b559486 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 8693ec3c884..bbf4742e18c 100644 --- a/src/backend/catalog/pg_constraint.c +++ b/src/backend/catalog/pg_constraint.c @@ -1647,22 +1647,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 d6e23caef17..59c836fc24d 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 4fc54bd6eba..d02d564883a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -9997,7 +9997,7 @@ ATAddForeignKeyConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, if (with_period) { - StrategyNumber rtstrategy; + CompareType cmptype; bool for_overlaps = with_period && i == numpks - 1; /* @@ -10007,14 +10007,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; @@ -10028,8 +10028,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/backend/executor/execReplication.c b/src/backend/executor/execReplication.c index e3e4e41ac38..3985e84d3a6 100644 --- a/src/backend/executor/execReplication.c +++ b/src/backend/executor/execReplication.c @@ -57,7 +57,7 @@ get_equal_strategy_number(Oid opclass) ret = HTEqualStrategyNumber; break; case GIST_AM_OID: - ret = GistTranslateStratnum(opclass, RTEqualStrategyNumber); + ret = GistTranslateStratnum(opclass, COMPARE_EQ); break; default: ret = InvalidStrategy; diff --git a/src/include/access/gist.h b/src/include/access/gist.h index 8ccaecfa1f4..446871263f6 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 b334a5fb882..508f48d345c 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 872cd6e01a3..ba02ba53b29 100644 --- a/src/include/catalog/pg_proc.dat +++ b/src/include/catalog/pg_proc.dat @@ -12425,8 +12425,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 adf6c634670..6d9348bac80 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 2893dba31c3..cb09df9e745 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 384e751663a..106dedb519a 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 ac792abedf2..753a0f41c03 100644 --- a/src/test/regress/sql/misc_functions.sql +++ b/src/test/regress/sql/misc_functions.sql @@ -401,5 +401,5 @@ 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); -SELECT gist_stratnum_identity(18::smallint); +SELECT gist_stratnum_common(7); +SELECT gist_stratnum_common(3); |