Change gist stratnum function to use CompareType
authorPeter Eisentraut <[email protected]>
Wed, 15 Jan 2025 10:28:39 +0000 (11:28 +0100)
committerPeter Eisentraut <[email protected]>
Wed, 15 Jan 2025 10:34:04 +0000 (11:34 +0100)
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/E72EAA49-354D-4C2E-8EB9-255197F55330@enterprisedb.com

19 files changed:
contrib/btree_gist/btree_gist--1.7--1.8.sql
contrib/btree_gist/btree_gist.c
contrib/btree_gist/expected/stratnum.out
contrib/btree_gist/sql/stratnum.sql
doc/src/sgml/gist.sgml
doc/src/sgml/xindex.sgml
src/backend/access/gist/gistutil.c
src/backend/access/gist/gistvalidate.c
src/backend/catalog/pg_constraint.c
src/backend/commands/indexcmds.c
src/backend/commands/tablecmds.c
src/backend/executor/execReplication.c
src/include/access/gist.h
src/include/catalog/pg_amproc.dat
src/include/catalog/pg_proc.dat
src/include/commands/defrem.h
src/include/nodes/primnodes.h
src/test/regress/expected/misc_functions.out
src/test/regress/sql/misc_functions.sql

index 307bfe574b0b66d83ee7e0afe82a4ab6481b17f4..c702426deabb5eca0f3e2c7cd2d8237482d5a6a1 100644 (file)
@@ -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) ;
index 5fd4cce27d05c65c6312739061334ce29286d3a3..fc6c7091795091ff0e3517b0c40377dbdf8944b9 100644 (file)
@@ -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);
index 9d80c6590d97777149f0883a4cc532d24309c0cb..dd0edaf4a206274ad3118f702f7d52d815e9d8bb 100644 (file)
@@ -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
index f58cdbe93da5238bd519ad972c0f20bb2ba3f710..75adddad8492583761418b9152b6afbe14531851 100644 (file)
@@ -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);
index 638d912dc2d11c2d030183a434d5710a62fd2989..99098ab2522831815f9b40d805656328bede09a2 100644 (file)
@@ -290,8 +290,8 @@ CREATE INDEX ON my_table USING GIST (my_inet_column inet_ops);
    The optional eleventh method <function>sortsupport</function> is used to
    speed up building a <acronym>GiST</acronym> index.
    The optional twelfth method <function>stratnum</function> is used to
-   translate well-known <literal>RT*StrategyNumber</literal>s (from
-   <filename>src/include/access/stratnum.h</filename>) into strategy numbers
+   translate compare types (from
+   <filename>src/include/nodes/primnodes.h</filename>) into strategy numbers
    used by the operator class.  This lets the core code look up operators for
    temporal constraint indexes.
  </para>
@@ -1173,8 +1173,8 @@ my_sortsupport(PG_FUNCTION_ARGS)
      <term><function>stratnum</function></term>
      <listitem>
       <para>
-       Given an <literal>RT*StrategyNumber</literal> value from
-       <filename>src/include/access/stratnum.h</filename>, returns a strategy
+       Given a <literal>CompareType</literal> value from
+       <filename>src/include/nodes/primnodes.h</filename>, returns a strategy
        number used by this operator class for matching functionality.  The
        function should return <literal>InvalidStrategy</literal> if the
        operator class has no matching strategy.
@@ -1184,7 +1184,7 @@ my_sortsupport(PG_FUNCTION_ARGS)
        This is used for temporal index constraints (i.e., <literal>PRIMARY
        KEY</literal> and <literal>UNIQUE</literal>).  If the operator class
        provides this function and it returns results for
-       <literal>RTEqualStrategyNumber</literal>, it can be used in the
+       <literal>COMPARE_EQ</literal>, it can be used in the
        non-<literal>WITHOUT OVERLAPS</literal> part(s) of an index constraint.
       </para>
 
@@ -1194,7 +1194,7 @@ my_sortsupport(PG_FUNCTION_ARGS)
 
 <programlisting>
 CREATE OR REPLACE FUNCTION my_stratnum(integer)
-RETURNS integer
+RETURNS smallint
 AS 'MODULE_PATHNAME'
 LANGUAGE C STRICT;
 </programlisting>
@@ -1209,12 +1209,12 @@ PG_FUNCTION_INFO_V1(my_stratnum);
 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 @@ my_stratnum(PG_FUNCTION_ARGS)
       <para>
        One translation function is provided by
        <productname>PostgreSQL</productname>:
-       <literal>gist_stratnum_identity</literal> is for operator classes that
-       already use the <literal>RT*StrategyNumber</literal> constants.  It
-       returns whatever is passed to it.  The <literal>btree_gist</literal>
+       <literal>gist_stratnum_common</literal> is for operator classes that
+       use the <literal>RT*StrategyNumber</literal> constants.
+       The <literal>btree_gist</literal>
        extension defines a second translation function,
        <literal>gist_stratnum_btree</literal>, for operator classes that use
        the <literal>BT*StrategyNumber</literal> constants.
index 3a19dab15e031d865ab71de45bf0705a1d45a4fa..053619624950c26234ead7b7466849b5ece4cb32 100644 (file)
       </row>
       <row>
        <entry><function>stratnum</function></entry>
-       <entry>translate well-known strategy numbers to ones
+       <entry>translate compare types to strategy numbers
         used by the operator class (optional)</entry>
        <entry>12</entry>
       </row>
index a2fcfbe480717539be528e10a163b07641490c12..48db718b904032ad5ed7b9527f63c2532055d31b 100644 (file)
@@ -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);
 }
index 499ed8c8748ac4346c50d6004ba1d948ee3bba03..bb86b5594868e2c75905629cedc7ed7d103eafe9 100644 (file)
@@ -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,
index 8693ec3c884c98d1e45255cf5a5cc9999fc21d0d..bbf4742e18c2798a959e6a36a0035962bb543b20 100644 (file)
@@ -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);
 }
 
 /*
index d6e23caef17168c95b65c5adc784a8fbd37dc24c..59c836fc24d34f321cb125871dfd5eeb2267805e 100644 (file)
@@ -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"));
        }
index 4fc54bd6ebad12999298605692608348b3aaea44..d02d564883ae2a00366855098df2a52b38f7b1f5 100644 (file)
@@ -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
index e3e4e41ac382bba822fc7939360fa92e1930f31a..3985e84d3a6a2ee5c35c59f8feb2ea20735a7cfb 100644 (file)
@@ -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;
index 8ccaecfa1f4f409fdfe2df77153028e8db6e9965..446871263f63af79babe0c02caf8ed28af433f92 100644 (file)
@@ -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 */
index b334a5fb882f8e4c034be91f13356e0fbe4f1ba4..508f48d345c135517d2629f3b54c2f004fd51de3 100644 (file)
   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' },
   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' },
   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)' },
   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' },
   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' },
   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',
index 872cd6e01a369d6c0e2bfed04be2882e55579c5e..ba02ba53b29adf74e18d681576dd01abd0347b8f 100644 (file)
 
 # 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' },
 
 ]
index adf6c63467000c0b6bfd1cc21109aa9ccdda95b8..6d9348bac8049dfa682a35fdea715504e16d6393 100644 (file)
@@ -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);
index 2893dba31c37f5206e9c96c7888f7e805d21920a..cb09df9e745acb3a4b68dc911530ed1e0d6a116a 100644 (file)
@@ -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;
 
 /*
index 384e751663abc3e680611e9243a01352abcd820e..106dedb519abeb755e66e25459320dbc20eced46 100644 (file)
@@ -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)
 
index ac792abedf2d293d148cc052d12335c1aed0d39c..753a0f41c033d997a72c7fb6aa1470dc7a9c8eba 100644 (file)
@@ -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);