Cross-data-type comparisons are now indexable by btrees, pursuant to my
authorTom Lane
Wed, 12 Nov 2003 21:15:59 +0000 (21:15 +0000)
committerTom Lane
Wed, 12 Nov 2003 21:15:59 +0000 (21:15 +0000)
pghackers proposal of 8-Nov.  All the existing cross-type comparison
operators (int2/int4/int8 and float4/float8) have appropriate support.
The original proposal of storing the right-hand-side datatype as part of
the primary key for pg_amop and pg_amproc got modified a bit in the event;
it is easier to store zero as the 'default' case and only store a nonzero
when the operator is actually cross-type.  Along the way, remove the
long-since-defunct bigbox_ops operator class.

76 files changed:
contrib/dblink/dblink.c
contrib/miscutil/misc_utils.c
doc/src/sgml/catalogs.sgml
doc/src/sgml/xindex.sgml
src/backend/access/common/scankey.c
src/backend/access/gist/gistget.c
src/backend/access/gist/gistscan.c
src/backend/access/heap/tuptoaster.c
src/backend/access/nbtree/nbtcompare.c
src/backend/access/nbtree/nbtinsert.c
src/backend/access/nbtree/nbtree.c
src/backend/access/nbtree/nbtsearch.c
src/backend/access/nbtree/nbtsort.c
src/backend/access/nbtree/nbtutils.c
src/backend/access/rtree/rtproc.c
src/backend/access/rtree/rtscan.c
src/backend/catalog/aclchk.c
src/backend/catalog/dependency.c
src/backend/catalog/heap.c
src/backend/catalog/index.c
src/backend/catalog/pg_constraint.c
src/backend/catalog/pg_conversion.c
src/backend/catalog/pg_depend.c
src/backend/catalog/pg_largeobject.c
src/backend/commands/async.c
src/backend/commands/cluster.c
src/backend/commands/comment.c
src/backend/commands/dbcommands.c
src/backend/commands/functioncmds.c
src/backend/commands/indexcmds.c
src/backend/commands/opclasscmds.c
src/backend/commands/tablecmds.c
src/backend/commands/trigger.c
src/backend/commands/typecmds.c
src/backend/commands/user.c
src/backend/commands/vacuum.c
src/backend/executor/nodeIndexscan.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/outfuncs.c
src/backend/optimizer/path/indxpath.c
src/backend/optimizer/plan/createplan.c
src/backend/optimizer/util/plancat.c
src/backend/parser/parse_func.c
src/backend/rewrite/rewriteRemove.c
src/backend/storage/large_object/inv_api.c
src/backend/utils/adt/float.c
src/backend/utils/adt/regproc.c
src/backend/utils/adt/ruleutils.c
src/backend/utils/adt/selfuncs.c
src/backend/utils/cache/catcache.c
src/backend/utils/cache/lsyscache.c
src/backend/utils/cache/relcache.c
src/backend/utils/cache/syscache.c
src/backend/utils/cache/typcache.c
src/backend/utils/init/postinit.c
src/backend/utils/sort/tuplesort.c
src/include/access/nbtree.h
src/include/access/skey.h
src/include/catalog/catversion.h
src/include/catalog/indexing.h
src/include/catalog/namespace.h
src/include/catalog/pg_amop.h
src/include/catalog/pg_amproc.h
src/include/catalog/pg_opclass.h
src/include/catalog/pg_proc.h
src/include/nodes/plannodes.h
src/include/utils/builtins.h
src/include/utils/geo_decls.h
src/include/utils/lsyscache.h
src/include/utils/rel.h
src/test/regress/expected/create_index.out
src/test/regress/expected/oidjoins.out
src/test/regress/expected/opr_sanity.out
src/test/regress/sql/create_index.sql
src/test/regress/sql/oidjoins.sql
src/test/regress/sql/opr_sanity.sql

index 5728682ccc8d600ae9e3b64eba0599d8aad5c830..bb601c5436acc0cd8fa9993e11c7da0bfc4fb497 100644 (file)
@@ -1357,10 +1357,10 @@ get_pkey_attnames(Oid relid, int16 *numatts)
 
    /* use relid to get all related indexes */
    indexRelation = heap_openr(IndexRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry, 0,
-                          Anum_pg_index_indrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
+   ScanKeyInit(&entry,
+               Anum_pg_index_indrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
    scan = heap_beginscan(indexRelation, SnapshotNow, 1, &entry);
 
    while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
index bf84f3b3c2e120cc2b828a2023b71e0143205a0d..fb121e83803b3f7f0282242ee34085fc5f7fe53c 100644 (file)
@@ -21,7 +21,6 @@
 #include "access/tupdesc.h"
 #include "catalog/catname.h"
 #include "catalog/pg_listener.h"
-#include "catalog/pg_type.h"
 #include "commands/async.h"
 #include "fmgr.h"
 #include "storage/lmgr.h"
@@ -87,10 +86,10 @@ active_listeners(text *relname)
        MemSet(listen_name, 0, NAMEDATALEN);
        len = MIN(VARSIZE(relname) - VARHDRSZ, NAMEDATALEN - 1);
        memcpy(listen_name, VARDATA(relname), len);
-       ScanKeyEntryInitialize(&key, 0,
-                              Anum_pg_listener_relname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              PointerGetDatum(listen_name), NAMEOID);
+       ScanKeyInit(&key,
+                   Anum_pg_listener_relname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   PointerGetDatum(listen_name));
        sRel = heap_beginscan(lRel, SnapshotNow, 1, &key);
    }
    else
index bd208906dfe50f965eb1a3fa6a58339d176411c2..37f8b9cd659025f201c3f2d582861db59ce63e09 100644 (file)
@@ -1,6 +1,6 @@
 
 
 
       The index operator class this entry is for
      
 
+     
+      amopsubtype
+      oid
+      pg_type.oid
+      Subtype to distinguish multiple entries for one strategy;
+             zero for default
+     
+
      
       amopstrategy
       int2
       The index operator class this entry is for
      
 
+     
+      amprocsubtype
+      oid
+      pg_type.oid
+      Subtype, if cross-type routine, else zero
+     
+
      
       amprocnum
       int2
       opcintype
       oid
       pg_type.oid
-      Input data type of the operator class
+      Data type that the operator class indexes
      
 
      
       opckeytype
       oid
       pg_type.oid
-      Type of index data, or zero if same as opcintype
+      Type of data stored in index, or zero if same as opcintype
      
 
     
index 85aba8abe7058d61aa4990336bb2b83905d82e71..877709cee687d83447b0f623a288bb776834cd80 100644 (file)
@@ -1,5 +1,5 @@
 
 
 
@@ -80,7 +80,7 @@ $Header: /cvsroot/pgsql/doc/src/sgml/xindex.sgml,v 1.34 2003/11/01 01:56:29 pete
    The same operator class name
    can be used for several different index methods (for example, both B-tree
    and hash index methods have operator classes named
-   oid_ops), but each such class is an independent
+   int4_ops), but each such class is an independent
    entity and must be defined separately.
   
  
@@ -589,6 +589,71 @@ CREATE OPERATOR CLASS complex_abs_ops
   
  
 
+  Cross-Data-Type Operator Classes
+
+  
+   So far we have implicitly assumed that an operator class deals with
+   only one data type.  While there certainly can be only one data type in
+   a particular index column, it is often useful to index operations that
+   compare an indexed column to a value of a different data type.  This is
+   presently supported by the B-tree and GiST index methods.
+  
+
+  
+   B-trees require the left-hand operand of each operator to be the indexed
+   data type, but the right-hand operand can be of a different type.  There
+   must be a support function having a matching signature.  For example,
+   the built-in operator class for type bigint (int8)
+   allows cross-type comparisons to int4 and int2.  It
+   could be duplicated by this definition:
+
+
+CREATE OPERATOR CLASS int8_ops
+DEFAULT FOR TYPE int8 USING btree AS
+  -- standard int8 comparisons
+  OPERATOR 1 < ,
+  OPERATOR 2 <= ,
+  OPERATOR 3 = ,
+  OPERATOR 4 >= ,
+  OPERATOR 5 > ,
+  FUNCTION 1 btint8cmp(int8, int8) ,
+
+  -- cross-type comparisons to int2 (smallint)
+  OPERATOR 1 < (int8, int2) ,
+  OPERATOR 2 <= (int8, int2) ,
+  OPERATOR 3 = (int8, int2) ,
+  OPERATOR 4 >= (int8, int2) ,
+  OPERATOR 5 > (int8, int2) ,
+  FUNCTION 1 btint82cmp(int8, int2) ,
+
+  -- cross-type comparisons to int4 (integer)
+  OPERATOR 1 < (int8, int4) ,
+  OPERATOR 2 <= (int8, int4) ,
+  OPERATOR 3 = (int8, int4) ,
+  OPERATOR 4 >= (int8, int4) ,
+  OPERATOR 5 > (int8, int4) ,
+  FUNCTION 1 btint84cmp(int8, int4) ;
+
+
+   Notice that this definition overloads the operator strategy and
+   support function numbers.  This is allowed (for B-tree operator classes
+   only) so long as each instance of a particular number has a different
+   right-hand data type.  The instances that are not cross-type are the
+   default or primary operators of the operator class.
+  
+
+  
+   GiST indexes do not allow overloading of strategy or support function
+   numbers, but it is still possible to get the effect of supporting
+   multiple right-hand data types, by assigning a distinct strategy number
+   to each operator that needs to be supported.  The consistent
+   support function must determine what it needs to do based on the strategy
+   number, and must be prepared to accept comparison values of the appropriate
+   data types.
+  
+
  
   System Dependencies on Operator Classes
 
index 93741cbb849d9e8673f8cc9d380fdb6951dce7a3..2fa02b7d91ffeb62e22a2985db061b900f8c7e87 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.23 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.24 2003/11/12 21:15:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,15 +31,43 @@ ScanKeyEntryInitialize(ScanKey entry,
                       int flags,
                       AttrNumber attributeNumber,
                       StrategyNumber strategy,
+                      Oid subtype,
                       RegProcedure procedure,
-                      Datum argument,
-                      Oid argtype)
+                      Datum argument)
 {
    entry->sk_flags = flags;
    entry->sk_attno = attributeNumber;
    entry->sk_strategy = strategy;
+   entry->sk_subtype = subtype;
+   entry->sk_argument = argument;
+   fmgr_info(procedure, &entry->sk_func);
+}
+
+/*
+ * ScanKeyInit
+ *     Shorthand version of ScanKeyEntryInitialize: flags and subtype
+ *     are assumed to be zero (the usual value).
+ *
+ * This is the recommended version for hardwired lookups in system catalogs.
+ * It cannot handle NULL arguments, unary operators, or nondefault operators,
+ * but we need none of those features for most hardwired lookups.
+ *
+ * Note: CurrentMemoryContext at call should be as long-lived as the ScanKey
+ * itself, because that's what will be used for any subsidiary info attached
+ * to the ScanKey's FmgrInfo record.
+ */
+void
+ScanKeyInit(ScanKey entry,
+           AttrNumber attributeNumber,
+           StrategyNumber strategy,
+           RegProcedure procedure,
+           Datum argument)
+{
+   entry->sk_flags = 0;
+   entry->sk_attno = attributeNumber;
+   entry->sk_strategy = strategy;
+   entry->sk_subtype = InvalidOid;
    entry->sk_argument = argument;
-   entry->sk_argtype = argtype;
    fmgr_info(procedure, &entry->sk_func);
 }
 
@@ -57,14 +85,14 @@ ScanKeyEntryInitializeWithInfo(ScanKey entry,
                               int flags,
                               AttrNumber attributeNumber,
                               StrategyNumber strategy,
+                              Oid subtype,
                               FmgrInfo *finfo,
-                              Datum argument,
-                              Oid argtype)
+                              Datum argument)
 {
    entry->sk_flags = flags;
    entry->sk_attno = attributeNumber;
    entry->sk_strategy = strategy;
+   entry->sk_subtype = subtype;
    entry->sk_argument = argument;
-   entry->sk_argtype = argtype;
    fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
 }
index 24168c992693c18d48ab5355cf2a68384233dca4..5db69a6b40a0638c666933570db53ea81c9719f4 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.37 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.38 2003/11/12 21:15:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -221,40 +221,50 @@ gistindex_keytest(IndexTuple tuple,
                  Page p,
                  OffsetNumber offset)
 {
-   bool        isNull;
-   Datum       datum;
-   Datum       test;
-   GISTENTRY   de;
-
    IncrIndexProcessed();
 
    while (scanKeySize > 0)
    {
+       Datum       datum;
+       bool        isNull;
+       Datum       test;
+       GISTENTRY   de;
+
        datum = index_getattr(tuple,
-                             key[0].sk_attno,
+                             key->sk_attno,
                              giststate->tupdesc,
                              &isNull);
+       /* is the index entry NULL? */
        if (isNull)
        {
            /* XXX eventually should check if SK_ISNULL */
            return false;
        }
-
-/* this code from backend/access/common/indexvalid.c. But why and what???
-       if (key[0].sk_flags & SK_ISNULL)
+       /* is the compared-to datum NULL? */
+       if (key->sk_flags & SK_ISNULL)
            return false;
-*/
-       gistdentryinit(giststate, key[0].sk_attno - 1, &de,
+
+       gistdentryinit(giststate, key->sk_attno - 1, &de,
                       datum, r, p, offset,
                       IndexTupleSize(tuple) - sizeof(IndexTupleData),
                       FALSE, isNull);
 
-       test = FunctionCall3(&key[0].sk_func,
+       /*
+        * Call the Consistent function to evaluate the test.  The arguments
+        * are the index datum (as a GISTENTRY*), the comparison datum, and
+        * the comparison operator's strategy number and subtype from pg_amop.
+        *
+        * (Presently there's no need to pass the subtype since it'll always
+        * be zero, but might as well pass it for possible future use.)
+        */
+       test = FunctionCall4(&key->sk_func,
                             PointerGetDatum(&de),
-                            key[0].sk_argument,
-                            Int32GetDatum(key[0].sk_strategy));
+                            key->sk_argument,
+                            Int32GetDatum(key->sk_strategy),
+                            ObjectIdGetDatum(key->sk_subtype));
 
-       if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1))
+       /* if index datum had to be decompressed, free it */
+       if (de.key != datum && !isAttByVal(giststate, key->sk_attno - 1))
            if (DatumGetPointer(de.key) != NULL)
                pfree(DatumGetPointer(de.key));
 
@@ -264,6 +274,7 @@ gistindex_keytest(IndexTuple tuple,
        scanKeySize--;
        key++;
    }
+
    return true;
 }
 
index 960d1c2f25bcd207855ac5043c2b5fd0bbf4bd83..9b9d1f603411c44d053a6aaaba17ef676c1de724 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.49 2003/11/12 21:15:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -109,7 +109,8 @@ gistrescan(PG_FUNCTION_ARGS)
         * Modify the scan key so that the Consistent function is called
         * for all comparisons.  The original operator is passed to the
         * Consistent function in the form of its strategy number, which
-        * is available from the sk_strategy field.
+        * is available from the sk_strategy field, and its subtype from
+        * the sk_subtype field.
         */
        for (i = 0; i < s->numberOfKeys; i++)
        {
index 0bfe3c01b8fa55be8d825e5f39dde98c02dff504..f643906da1f92bfce24f69f7875f00cb7dfcf244 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.39 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.40 2003/11/12 21:15:46 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -31,7 +31,6 @@
 #include "access/genam.h"
 #include "access/tuptoaster.h"
 #include "catalog/catalog.h"
-#include "catalog/pg_type.h"
 #include "utils/rel.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -968,11 +967,10 @@ toast_delete_datum(Relation rel, Datum value)
     * Setup a scan key to fetch from the index by va_valueid (we don't
     * particularly care whether we see them in sequence or not)
     */
-   ScanKeyEntryInitialize(&toastkey, 0,
-                          (AttrNumber) 1,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
-                          OIDOID);
+   ScanKeyInit(&toastkey,
+               (AttrNumber) 1,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
 
    /*
     * Find the chunks by index
@@ -1040,11 +1038,10 @@ toast_fetch_datum(varattrib *attr)
    /*
     * Setup a scan key to fetch from the index by va_valueid
     */
-   ScanKeyEntryInitialize(&toastkey, 0,
-                          (AttrNumber) 1,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
-                          OIDOID);
+   ScanKeyInit(&toastkey,
+               (AttrNumber) 1,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
 
    /*
     * Read the chunks by index
@@ -1195,33 +1192,32 @@ toast_fetch_datum_slice(varattrib *attr, int32 sliceoffset, int32 length)
     * Setup a scan key to fetch from the index. This is either two keys
     * or three depending on the number of chunks.
     */
-   ScanKeyEntryInitialize(&toastkey[0], 0,
-                          (AttrNumber) 1,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
-                          OIDOID);
+   ScanKeyInit(&toastkey[0],
+               (AttrNumber) 1,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
 
    /*
     * Use equality condition for one chunk, a range condition otherwise:
     */
    if (numchunks == 1)
    {
-       ScanKeyEntryInitialize(&toastkey[1], 0,
-                              (AttrNumber) 2,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(startchunk), INT4OID);
+       ScanKeyInit(&toastkey[1],
+                   (AttrNumber) 2,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(startchunk));
        nscankeys = 2;
    }
    else
    {
-       ScanKeyEntryInitialize(&toastkey[1], 0,
-                              (AttrNumber) 2,
-                              BTGreaterEqualStrategyNumber, F_INT4GE,
-                              Int32GetDatum(startchunk), INT4OID);
-       ScanKeyEntryInitialize(&toastkey[2], 0,
-                              (AttrNumber) 2,
-                              BTLessEqualStrategyNumber, F_INT4LE,
-                              Int32GetDatum(endchunk), INT4OID);
+       ScanKeyInit(&toastkey[1],
+                   (AttrNumber) 2,
+                   BTGreaterEqualStrategyNumber, F_INT4GE,
+                   Int32GetDatum(startchunk));
+       ScanKeyInit(&toastkey[2],
+                   (AttrNumber) 2,
+                   BTLessEqualStrategyNumber, F_INT4LE,
+                   Int32GetDatum(endchunk));
        nscankeys = 3;
    }
 
index 79756513abf72e340d42c73c2eddc469d1fba673..bd6988583050e34dd612d93390e90e31160ab395 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.46 2003/08/04 02:39:57 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtcompare.c,v 1.47 2003/11/12 21:15:46 tgl Exp $
  *
  * NOTES
  *
@@ -97,6 +97,90 @@ btint8cmp(PG_FUNCTION_ARGS)
        PG_RETURN_INT32(-1);
 }
 
+Datum
+btint48cmp(PG_FUNCTION_ARGS)
+{
+   int32       a = PG_GETARG_INT32(0);
+   int64       b = PG_GETARG_INT64(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
+Datum
+btint84cmp(PG_FUNCTION_ARGS)
+{
+   int64       a = PG_GETARG_INT64(0);
+   int32       b = PG_GETARG_INT32(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
+Datum
+btint24cmp(PG_FUNCTION_ARGS)
+{
+   int16       a = PG_GETARG_INT16(0);
+   int32       b = PG_GETARG_INT32(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
+Datum
+btint42cmp(PG_FUNCTION_ARGS)
+{
+   int32       a = PG_GETARG_INT32(0);
+   int16       b = PG_GETARG_INT16(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
+Datum
+btint28cmp(PG_FUNCTION_ARGS)
+{
+   int16       a = PG_GETARG_INT16(0);
+   int64       b = PG_GETARG_INT64(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
+Datum
+btint82cmp(PG_FUNCTION_ARGS)
+{
+   int64       a = PG_GETARG_INT64(0);
+   int16       b = PG_GETARG_INT16(1);
+
+   if (a > b)
+       PG_RETURN_INT32(1);
+   else if (a == b)
+       PG_RETURN_INT32(0);
+   else
+       PG_RETURN_INT32(-1);
+}
+
 Datum
 btoidcmp(PG_FUNCTION_ARGS)
 {
index 98f3abb511fc28894fbe20b83fb94acd6f589cff..719b1e1f0ed9ca868fa7e099329f6c9a967987e4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.107 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.108 2003/11/12 21:15:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1577,26 +1577,27 @@ _bt_isequal(TupleDesc itupdesc, Page page, OffsetNumber offnum,
 
    for (i = 1; i <= keysz; i++)
    {
-       ScanKey     entry = &scankey[i - 1];
        AttrNumber  attno;
        Datum       datum;
        bool        isNull;
        int32       result;
 
-       attno = entry->sk_attno;
+       attno = scankey->sk_attno;
        Assert(attno == i);
        datum = index_getattr(itup, attno, itupdesc, &isNull);
 
        /* NULLs are never equal to anything */
-       if ((entry->sk_flags & SK_ISNULL) || isNull)
+       if (isNull || (scankey->sk_flags & SK_ISNULL))
            return false;
 
-       result = DatumGetInt32(FunctionCall2(&entry->sk_func,
-                                            entry->sk_argument,
-                                            datum));
+       result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
+                                            datum,
+                                            scankey->sk_argument));
 
        if (result != 0)
            return false;
+
+       scankey++;
    }
 
    /* if we get here, the keys are equal */
index 3979f79c3585103c7e560ae2e26ab3c1097d0bbe..f920d2497ee65990d50c892bbdeb9f312dc186d3 100644 (file)
@@ -12,7 +12,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.106 2003/09/29 23:40:26 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtree.c,v 1.107 2003/11/12 21:15:46 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -397,7 +397,6 @@ btrescan(PG_FUNCTION_ARGS)
            so->keyData = (ScanKey) palloc(scan->numberOfKeys * sizeof(ScanKeyData));
        else
            so->keyData = (ScanKey) NULL;
-       so->numberOfKeys = scan->numberOfKeys;
        scan->opaque = so;
    }
 
@@ -423,38 +422,14 @@ btrescan(PG_FUNCTION_ARGS)
     * _bt_first.      - vadim 05/05/97
     */
    if (scankey && scan->numberOfKeys > 0)
-   {
        memmove(scan->keyData,
                scankey,
                scan->numberOfKeys * sizeof(ScanKeyData));
-       so->numberOfKeys = scan->numberOfKeys;
-       memmove(so->keyData,
-               scankey,
-               so->numberOfKeys * sizeof(ScanKeyData));
-   }
+   so->numberOfKeys = 0;       /* until _bt_preprocess_keys sets it */
 
    PG_RETURN_VOID();
 }
 
-void
-btmovescan(IndexScanDesc scan, Datum v)
-{
-   ItemPointer iptr;
-   BTScanOpaque so;
-
-   so = (BTScanOpaque) scan->opaque;
-
-   /* we aren't holding any read locks, but gotta drop the pin */
-   if (ItemPointerIsValid(iptr = &(scan->currentItemData)))
-   {
-       ReleaseBuffer(so->btso_curbuf);
-       so->btso_curbuf = InvalidBuffer;
-       ItemPointerSetInvalid(iptr);
-   }
-
-   so->keyData[0].sk_argument = v;
-}
-
 /*
  * btendscan() -- close down a scan
  */
index 432a1ab0c2a26e4eba41f683310059f0bfba9560..87178d124245077c1a2ce34c6ae87d39170293c3 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.81 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.82 2003/11/12 21:15:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,6 +17,7 @@
 
 #include "access/genam.h"
 #include "access/nbtree.h"
+#include "utils/lsyscache.h"
 
 
 static Buffer _bt_walk_left(Relation rel, Buffer buf);
@@ -325,17 +326,16 @@ _bt_compare(Relation rel,
     * (see _bt_first).
     */
 
-   for (i = 0; i < keysz; i++)
+   for (i = 1; i <= keysz; i++)
    {
-       ScanKey     entry = &scankey[i];
        Datum       datum;
        bool        isNull;
        int32       result;
 
-       datum = index_getattr(itup, entry->sk_attno, itupdesc, &isNull);
+       datum = index_getattr(itup, scankey->sk_attno, itupdesc, &isNull);
 
        /* see comments about NULLs handling in btbuild */
-       if (entry->sk_flags & SK_ISNULL)        /* key is NULL */
+       if (scankey->sk_flags & SK_ISNULL)      /* key is NULL */
        {
            if (isNull)
                result = 0;     /* NULL "=" NULL */
@@ -348,14 +348,28 @@ _bt_compare(Relation rel,
        }
        else
        {
-           result = DatumGetInt32(FunctionCall2(&entry->sk_func,
-                                                entry->sk_argument,
-                                                datum));
+           /*
+            * The sk_func needs to be passed the index value as left arg
+            * and the sk_argument as right arg (they might be of different
+            * types).  Since it is convenient for callers to think of
+            * _bt_compare as comparing the scankey to the index item,
+            * we have to flip the sign of the comparison result.
+            *
+            * Note: curious-looking coding is to avoid overflow if
+            * comparison function returns INT_MIN.  There is no risk of
+            * overflow for positive results.
+            */
+           result = DatumGetInt32(FunctionCall2(&scankey->sk_func,
+                                                datum,
+                                                scankey->sk_argument));
+           result = (result < 0) ? 1 : -result;
        }
 
        /* if the keys are unequal, return the difference */
        if (result != 0)
            return result;
+
+       scankey++;
    }
 
    /* if we get here, the keys are equal */
@@ -448,126 +462,203 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
    StrategyNumber strat;
    bool        res;
    int32       result;
-   bool        scanFromEnd;
    bool        continuescan;
    ScanKey     scankeys = NULL;
+   ScanKey    *startKeys = NULL;
    int         keysCount = 0;
-   int        *nKeyIs = NULL;
-   int         i,
-               j;
+   int         i;
    StrategyNumber strat_total;
 
    /*
-    * Order the scan keys in our canonical fashion and eliminate any
-    * redundant keys.
+    * Examine the scan keys and eliminate any redundant keys; also
+    * discover how many keys must be matched to continue the scan.
     */
-   _bt_orderkeys(scan);
+   _bt_preprocess_keys(scan);
 
    /*
-    * Quit now if _bt_orderkeys() discovered that the scan keys can never
-    * be satisfied (eg, x == 1 AND x > 2).
+    * Quit now if _bt_preprocess_keys() discovered that the scan keys can
+    * never be satisfied (eg, x == 1 AND x > 2).
     */
    if (!so->qual_ok)
        return false;
 
-   /*
+   /*----------
     * Examine the scan keys to discover where we need to start the scan.
+    *
+    * We want to identify the keys that can be used as starting boundaries;
+    * these are =, >, or >= keys for a forward scan or =, <, <= keys for
+    * a backwards scan.  We can use keys for multiple attributes so long as
+    * the prior attributes had only =, >= (resp. =, <=) keys.  Once we accept
+    * a > or < boundary or find an attribute with no boundary (which can be
+    * thought of as the same as "> -infinity"), we can't use keys for any
+    * attributes to its right, because it would break our simplistic notion
+    * of what initial positioning strategy to use.
+    *
+    * When the scan keys include non-default operators, _bt_preprocess_keys
+    * may not be able to eliminate redundant keys; in such cases we will
+    * arbitrarily pick a usable one for each attribute.  This is correct
+    * but possibly not optimal behavior.  (For example, with keys like
+    * "x >= 4 AND x >= 5" we would elect to scan starting at x=4 when
+    * x=5 would be more efficient.)  Since the situation only arises in
+    * hokily-worded queries, live with it.
+    *
+    * When both equality and inequality keys appear for a single attribute
+    * (again, only possible when non-default operators appear), we *must*
+    * select one of the equality keys for the starting point, because
+    * _bt_checkkeys() will stop the scan as soon as an equality qual fails.
+    * For example, if we have keys like "x >= 4 AND x = 10" and we elect to
+    * start at x=4, we will fail and stop before reaching x=10.  If multiple
+    * equality quals survive preprocessing, however, it doesn't matter which
+    * one we use --- by definition, they are either redundant or
+    * contradictory.
+    *----------
     */
-   scanFromEnd = false;
    strat_total = BTEqualStrategyNumber;
    if (so->numberOfKeys > 0)
    {
-       nKeyIs = (int *) palloc(so->numberOfKeys * sizeof(int));
-       for (i = 0; i < so->numberOfKeys; i++)
-       {
-           AttrNumber  attno = so->keyData[i].sk_attno;
-
-           /* ignore keys for already-determined attrs */
-           if (attno <= keysCount)
-               continue;
-           /* if we didn't find a boundary for the preceding attr, quit */
-           if (attno > keysCount + 1)
-               break;
+       AttrNumber  curattr;
+       ScanKey     chosen;
+       ScanKey     cur;
 
-           /*
-            * Can we use this key as a starting boundary for this attr?
-            *
-            * We can use multiple keys if they look like, say, = >= = but we
-            * have to stop after accepting a > or < boundary.
-            */
-           strat = so->keyData[i].sk_strategy;
-           if (strat == strat_total ||
-               strat == BTEqualStrategyNumber)
-               nKeyIs[keysCount++] = i;
-           else if (ScanDirectionIsBackward(dir) &&
-                    (strat == BTLessStrategyNumber ||
-                     strat == BTLessEqualStrategyNumber))
+       startKeys = (ScanKey *) palloc(so->numberOfKeys * sizeof(ScanKey));
+       /*
+        * chosen is the so-far-chosen key for the current attribute, if any.
+        * We don't cast the decision in stone until we reach keys for the
+        * next attribute.
+        */
+       curattr = 1;
+       chosen = NULL;
+       /*
+        * Loop iterates from 0 to numberOfKeys inclusive; we use the last
+        * pass to handle after-last-key processing.  Actual exit from the
+        * loop is at one of the "break" statements below.
+        */
+       for (cur = so->keyData, i = 0;; cur++, i++)
+       {
+           if (i >= so->numberOfKeys || cur->sk_attno != curattr)
            {
-               nKeyIs[keysCount++] = i;
-               strat_total = strat;
-               if (strat == BTLessStrategyNumber)
+               /*
+                * Done looking at keys for curattr.  If we didn't find a
+                * usable boundary key, quit; else save the boundary key
+                * pointer in startKeys.
+                */
+               if (chosen == NULL)
+                   break;
+               startKeys[keysCount++] = chosen;
+               /*
+                * Adjust strat_total, and quit if we have stored a > or < key.
+                */
+               strat = chosen->sk_strategy;
+               if (strat != BTEqualStrategyNumber)
+               {
+                   strat_total = strat;
+                   if (strat == BTGreaterStrategyNumber ||
+                       strat == BTLessStrategyNumber)
+                       break;
+               }
+               /*
+                * Done if that was the last attribute.
+                */
+               if (i >= so->numberOfKeys)
                    break;
+               /*
+                * Reset for next attr, which should be in sequence.
+                */
+               Assert(cur->sk_attno == curattr + 1);
+               curattr = cur->sk_attno;
+               chosen = NULL;
            }
-           else if (ScanDirectionIsForward(dir) &&
-                    (strat == BTGreaterStrategyNumber ||
-                     strat == BTGreaterEqualStrategyNumber))
+
+           /* Can we use this key as a starting boundary for this attr? */
+           switch (cur->sk_strategy)
            {
-               nKeyIs[keysCount++] = i;
-               strat_total = strat;
-               if (strat == BTGreaterStrategyNumber)
+               case BTLessStrategyNumber:
+               case BTLessEqualStrategyNumber:
+                   if (chosen == NULL && ScanDirectionIsBackward(dir))
+                       chosen = cur;
+                   break;
+               case BTEqualStrategyNumber:
+                   /* override any non-equality choice */
+                   chosen = cur;
+                   break;
+               case BTGreaterEqualStrategyNumber:
+               case BTGreaterStrategyNumber:
+                   if (chosen == NULL && ScanDirectionIsForward(dir))
+                       chosen = cur;
                    break;
            }
        }
-       if (keysCount == 0)
-           scanFromEnd = true;
    }
-   else
-       scanFromEnd = true;
 
-   /* if we just need to walk down one edge of the tree, do that */
-   if (scanFromEnd)
+   /*
+    * If we found no usable boundary keys, we have to start from one end
+    * of the tree.  Walk down that edge to the first or last key, and
+    * scan from there.
+    */
+   if (keysCount == 0)
    {
-       if (nKeyIs)
-           pfree(nKeyIs);
+       if (startKeys)
+           pfree(startKeys);
        return _bt_endpoint(scan, dir);
    }
 
    /*
     * We want to start the scan somewhere within the index.  Set up a
-    * scankey we can use to search for the correct starting point.
+    * 3-way-comparison scankey we can use to search for the boundary
+    * point we identified above.
     */
    scankeys = (ScanKey) palloc(keysCount * sizeof(ScanKeyData));
    for (i = 0; i < keysCount; i++)
    {
-       FmgrInfo   *procinfo;
-
-       j = nKeyIs[i];
+       ScanKey     cur = startKeys[i];
 
        /*
-        * _bt_orderkeys disallows it, but it's place to add some code
+        * _bt_preprocess_keys disallows it, but it's place to add some code
         * later
         */
-       if (so->keyData[j].sk_flags & SK_ISNULL)
+       if (cur->sk_flags & SK_ISNULL)
        {
-           pfree(nKeyIs);
+           pfree(startKeys);
            pfree(scankeys);
            elog(ERROR, "btree doesn't support is(not)null, yet");
            return false;
        }
        /*
-        * XXX what if sk_argtype is not same as index?
+        * If scankey operator is of default subtype, we can use the
+        * cached comparison procedure; otherwise gotta look it up in
+        * the catalogs.
         */
-       procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
-       ScanKeyEntryInitializeWithInfo(scankeys + i,
-                                      so->keyData[j].sk_flags,
-                                      i + 1,
-                                      InvalidStrategy,
-                                      procinfo,
-                                      so->keyData[j].sk_argument,
-                                      so->keyData[j].sk_argtype);
+       if (cur->sk_subtype == InvalidOid)
+       {
+           FmgrInfo   *procinfo;
+
+           procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
+           ScanKeyEntryInitializeWithInfo(scankeys + i,
+                                          cur->sk_flags,
+                                          i + 1,
+                                          InvalidStrategy,
+                                          InvalidOid,
+                                          procinfo,
+                                          cur->sk_argument);
+       }
+       else
+       {
+           RegProcedure cmp_proc;
+
+           cmp_proc = get_opclass_proc(rel->rd_index->indclass[i],
+                                       cur->sk_subtype,
+                                       BTORDER_PROC);
+           ScanKeyEntryInitialize(scankeys + i,
+                                  cur->sk_flags,
+                                  i + 1,
+                                  InvalidStrategy,
+                                  cur->sk_subtype,
+                                  cmp_proc,
+                                  cur->sk_argument);
+       }
    }
-   if (nKeyIs)
-       pfree(nKeyIs);
+
+   pfree(startKeys);
 
    current = &(scan->currentItemData);
 
@@ -607,7 +698,8 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
     *
     * We could step forward in the latter case, but that'd be a waste of
     * time if we want to scan backwards.  So, it's now time to examine
-    * the scan strategy to find the exact place to start the scan.
+    * the initial-positioning strategy to find the exact place to start
+    * the scan.
     *
     * Note: if _bt_step fails (meaning we fell off the end of the index in
     * one direction or the other), we either return false (no matches) or
@@ -855,8 +947,8 @@ _bt_step(IndexScanDesc scan, Buffer *bufP, ScanDirection dir)
        }
    }
    else
-/* backwards scan */
    {
+       /* backwards scan */
        if (offnum > P_FIRSTDATAKEY(opaque))
            offnum = OffsetNumberPrev(offnum);
        else
@@ -1115,7 +1207,8 @@ _bt_get_endpoint(Relation rel, uint32 level, bool rightmost)
 }
 
 /*
- * _bt_endpoint() -- Find the first or last key in the index.
+ * _bt_endpoint() -- Find the first or last key in the index, and scan
+ * from there to the first key satisfying all the quals.
  *
  * This is used by _bt_first() to set up a scan when we've determined
  * that the scan must start at the beginning or end of the index (for
@@ -1205,7 +1298,9 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
    btitem = (BTItem) PageGetItem(page, PageGetItemId(page, start));
    itup = &(btitem->bti_itup);
 
-   /* see if we picked a winner */
+   /*
+    * Okay, we are on the first or last tuple.  Does it pass all the quals?
+    */
    if (_bt_checkkeys(scan, itup, dir, &continuescan))
    {
        /* yes, return it */
@@ -1214,7 +1309,7 @@ _bt_endpoint(IndexScanDesc scan, ScanDirection dir)
    }
    else if (continuescan)
    {
-       /* no, but there might be another one that is */
+       /* no, but there might be another one that does */
        res = _bt_next(scan, dir);
    }
    else
index a56665be5c4642830917868dc5f0a235aac9160a..ed920eafd33dfff13d267459175b61c9ebe041ec 100644 (file)
@@ -36,7 +36,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.77 2003/09/29 23:40:26 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsort.c,v 1.78 2003/11/12 21:15:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -594,33 +594,37 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
         * Another BTSpool for dead tuples exists. Now we have to merge
         * btspool and btspool2.
         */
-       ScanKey     entry;
-       Datum       attrDatum1,
-                   attrDatum2;
-       bool        isFirstNull,
-                   isSecondNull;
-       int32       compare;
 
        /* the preparation of merge */
-       bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free);
-       bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate, true, &should_free2);
+       bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
+                                              true, &should_free);
+       bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate,
+                                               true, &should_free2);
        indexScanKey = _bt_mkscankey_nodata(index);
+
        for (;;)
        {
            load1 = true;       /* load BTSpool next ? */
-           if (NULL == bti2)
+           if (bti2 == NULL)
            {
-               if (NULL == bti)
+               if (bti == NULL)
                    break;
            }
-           else if (NULL != bti)
+           else if (bti != NULL)
            {
-
                for (i = 1; i <= keysz; i++)
                {
+                   ScanKey     entry;
+                   Datum       attrDatum1,
+                               attrDatum2;
+                   bool        isFirstNull,
+                               isSecondNull;
+
                    entry = indexScanKey + i - 1;
-                   attrDatum1 = index_getattr((IndexTuple) bti, i, tupdes, &isFirstNull);
-                   attrDatum2 = index_getattr((IndexTuple) bti2, i, tupdes, &isSecondNull);
+                   attrDatum1 = index_getattr((IndexTuple) bti, i, tupdes,
+                                              &isFirstNull);
+                   attrDatum2 = index_getattr((IndexTuple) bti2, i, tupdes,
+                                              &isSecondNull);
                    if (isFirstNull)
                    {
                        if (!isSecondNull)
@@ -633,7 +637,11 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
                        break;
                    else
                    {
-                       compare = DatumGetInt32(FunctionCall2(&entry->sk_func, attrDatum1, attrDatum2));
+                       int32       compare;
+
+                       compare = DatumGetInt32(FunctionCall2(&entry->sk_func,
+                                                             attrDatum1,
+                                                             attrDatum2));
                        if (compare > 0)
                        {
                            load1 = false;
@@ -656,14 +664,16 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
                _bt_buildadd(index, state, bti);
                if (should_free)
                    pfree((void *) bti);
-               bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free);
+               bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
+                                                      true, &should_free);
            }
            else
            {
                _bt_buildadd(index, state, bti2);
                if (should_free2)
                    pfree((void *) bti2);
-               bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate, true, &should_free2);
+               bti2 = (BTItem) tuplesort_getindextuple(btspool2->sortstate,
+                                                       true, &should_free2);
            }
        }
        _bt_freeskey(indexScanKey);
@@ -671,7 +681,8 @@ _bt_load(Relation index, BTSpool *btspool, BTSpool *btspool2)
    else
    {
        /* merge is unnecessary */
-       while (bti = (BTItem) tuplesort_getindextuple(btspool->sortstate, true, &should_free), bti != (BTItem) NULL)
+       while ((bti = (BTItem) tuplesort_getindextuple(btspool->sortstate,
+                                               true, &should_free)) != NULL)
        {
            /* When we see first tuple, create first index page */
            if (state == NULL)
index 54cd7c8cd018a9b5150cc3054bc541d6d7de51da..2c9fd741ff39aa4959ca7665bbcd4d9936c64ced 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.55 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.56 2003/11/12 21:15:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,7 +19,6 @@
 #include "access/nbtree.h"
 #include "catalog/catalog.h"
 #include "executor/execdebug.h"
-#include "utils/lsyscache.h"
 
 
 /*
@@ -49,8 +48,8 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
        bool        null;
 
        /*
-        * We can use the cached support procs since no cross-type comparison
-        * can be needed.
+        * We can use the cached (default) support procs since no cross-type
+        * comparison can be needed.
         */
        procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
        arg = index_getattr(itup, i + 1, itupdesc, &null);
@@ -58,9 +57,9 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
                                       null ? SK_ISNULL : 0,
                                       (AttrNumber) (i + 1),
                                       InvalidStrategy,
+                                      InvalidOid,
                                       procinfo,
-                                      arg,
-                                      itupdesc->attrs[i]->atttypid);
+                                      arg);
    }
 
    return skey;
@@ -94,17 +93,17 @@ _bt_mkscankey_nodata(Relation rel)
        FmgrInfo   *procinfo;
 
        /*
-        * We can use the cached support procs since no cross-type comparison
-        * can be needed.
+        * We can use the cached (default) support procs since no cross-type
+        * comparison can be needed.
         */
        procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
        ScanKeyEntryInitializeWithInfo(&skey[i],
                                       SK_ISNULL,
                                       (AttrNumber) (i + 1),
                                       InvalidStrategy,
+                                      InvalidOid,
                                       procinfo,
-                                      (Datum) 0,
-                                      itupdesc->attrs[i]->atttypid);
+                                      (Datum) 0);
    }
 
    return skey;
@@ -161,105 +160,104 @@ _bt_formitem(IndexTuple itup)
 }
 
 /*----------
- * _bt_orderkeys() -- Put keys in a sensible order for conjunctive quals.
+ * _bt_preprocess_keys() -- Preprocess scan keys
  *
- * After this routine runs, the scan keys are ordered by index attribute
- * (all quals for attr 1, then all for attr 2, etc) and within each attr
- * the keys are ordered by constraint type: ">", ">=", "=", "<=", "<".
- * Furthermore, redundant keys are eliminated: we keep only the tightest
- * >/>= bound and the tightest 
- * that's the only one returned.  (So, we return either a single = key,
- * or one or two boundary-condition keys for each attr.)
+ * The caller-supplied keys (in scan->keyData[]) are copied to
+ * so->keyData[] with possible transformation.  scan->numberOfKeys is
+ * the number of input keys, so->numberOfKeys gets the number of output
+ * keys (possibly less, never greater).
  *
- * As a byproduct of this work, we can detect contradictory quals such
- * as "x = 1 AND x > 2".  If we see that, we return so->quals_ok = FALSE,
- * indicating the scan need not be run at all since no tuples can match.
+ * The primary purpose of this routine is to discover how many scan keys
+ * must be satisfied to continue the scan.  It also attempts to eliminate
+ * redundant keys and detect contradictory keys.  At present, redundant and
+ * contradictory keys can only be detected for same-data-type comparisons,
+ * but that's the usual case so it seems worth doing.
+ *
+ * The output keys must be sorted by index attribute.  Presently we expect
+ * (but verify) that the input keys are already so sorted --- this is done
+ * by group_clauses_by_indexkey() in indxpath.c.  Some reordering of the keys
+ * within each attribute may be done as a byproduct of the processing here,
+ * but no other code depends on that.
  *
- * Another byproduct is to determine how many quals must be satisfied to
+ * Aside from preparing so->keyData[], this routine sets
+ * so->numberOfRequiredKeys to the number of quals that must be satisfied to
  * continue the scan.  _bt_checkkeys uses this.  For example, if the quals
  * are "x = 1 AND y < 4 AND z < 5", then _bt_checkkeys will reject a tuple
  * (1,2,7), but we must continue the scan in case there are tuples (1,3,z).
  * But once we reach tuples like (1,4,z) we can stop scanning because no
  * later tuples could match.  This is reflected by setting
- * so->numberOfRequiredKeys to the number of leading keys that must be
- * matched to continue the scan.  numberOfRequiredKeys is equal to the
- * number of leading "=" keys plus the key(s) for the first non "="
- * attribute, which can be seen to be correct by considering the above
- * example.
+ * so->numberOfRequiredKeys to 2, the number of leading keys that must be
+ * matched to continue the scan.  In general, numberOfRequiredKeys is equal
+ * to the number of keys for leading attributes with "=" keys, plus the
+ * key(s) for the first non "=" attribute, which can be seen to be correct
+ * by considering the above example.
+ *
+ * If possible, redundant keys are eliminated: we keep only the tightest
+ * >/>= bound and the tightest 
+ * that's the only one returned.  (So, we return either a single = key,
+ * or one or two boundary-condition keys for each attr.)  However, we can
+ * only detect redundant keys when the right-hand datatypes are all equal
+ * to the index datatype, because we do not know suitable operators for
+ * comparing right-hand values of two different datatypes.  (In theory
+ * we could handle comparison of a RHS of the index datatype with a RHS of
+ * another type, but that seems too much pain for too little gain.)  So,
+ * keys whose operator has a nondefault subtype (ie, its RHS is not of the
+ * index datatype) are ignored here, except for noting whether they impose
+ * an "=" condition or not.
+ *
+ * As a byproduct of this work, we can detect contradictory quals such
+ * as "x = 1 AND x > 2".  If we see that, we return so->quals_ok = FALSE,
+ * indicating the scan need not be run at all since no tuples can match.
+ * Again though, only keys with RHS datatype equal to the index datatype
+ * can be checked for contradictions.
  *
  * Furthermore, we detect the case where the index is unique and we have
  * equality quals for all columns. In this case there can be at most one
  * (visible) matching tuple.  index_getnext uses this to avoid uselessly
  * continuing the scan after finding one match.
- *
- * The initial ordering of the keys is expected to be by attribute already
- * (see group_clauses_by_indexkey() in indxpath.c).  The task here is to
- * standardize the appearance of multiple keys for the same attribute.
  *----------
  */
 void
-_bt_orderkeys(IndexScanDesc scan)
+_bt_preprocess_keys(IndexScanDesc scan)
 {
    Relation    relation = scan->indexRelation;
    BTScanOpaque so = (BTScanOpaque) scan->opaque;
-   ScanKeyData xform[BTMaxStrategyNumber];
-   bool        init[BTMaxStrategyNumber];
-   int         numberOfKeys = so->numberOfKeys;
-   ScanKey     key;
+   int         numberOfKeys = scan->numberOfKeys;
+   int         new_numberOfKeys;
+   ScanKey     inkeys;
+   ScanKey     outkeys;
    ScanKey     cur;
+   ScanKey     xform[BTMaxStrategyNumber];
+   bool        allEqualSoFar;
+   bool        hasOtherTypeEqual;
    Datum       test;
    int         i,
                j;
    AttrNumber  attno;
-   int         new_numberOfKeys;
-   bool        allEqualSoFar;
 
+   /* initialize result variables */
    so->qual_ok = true;
+   so->numberOfKeys = 0;
    so->numberOfRequiredKeys = 0;
    scan->keys_are_unique = false;
 
    if (numberOfKeys < 1)
        return;                 /* done if qual-less scan */
 
-   key = so->keyData;
-   cur = &key[0];
-   /* check input keys are correctly ordered */
+   inkeys = scan->keyData;
+   outkeys = so->keyData;
+   cur = &inkeys[0];
+   /* we check that input keys are correctly ordered */
    if (cur->sk_attno != 1)
        elog(ERROR, "key(s) for attribute 1 missed");
 
-#if 0
-   /* XXX verify that operator strategy info is correct */
-   /* XXX this is temporary for debugging; it's pretty expensive */
-   /* XXX can't do it during bootstrap, else will recurse infinitely */
-   {
-       extern bool criticalRelcachesBuilt;
-       static bool inRecursion = false;
-
-       if (criticalRelcachesBuilt && !inRecursion)
-       {
-           inRecursion = true;
-           for (i = 0; i < numberOfKeys; i++)
-           {
-               AttrNumber  attno = key[i].sk_attno;
-               Oid         opclass;
-               Oid         chk_oper;
-
-               opclass = relation->rd_index->indclass[attno-1];
-               chk_oper = get_opclass_member(opclass, key[i].sk_strategy);
-               Assert(key[i].sk_func.fn_oid == get_opcode(chk_oper));
-           }
-           inRecursion = false;
-       }
-   }
-#endif
-
    /* We can short-circuit most of the work if there's just one key */
    if (numberOfKeys == 1)
    {
        /*
         * We don't use indices for 'A is null' and 'A is not null'
         * currently and 'A < = > <> NULL' will always fail - so qual is
-        * not Ok if comparison value is NULL.      - vadim 03/21/97
+        * not OK if comparison value is NULL.      - vadim 03/21/97
         */
        if (cur->sk_flags & SK_ISNULL)
            so->qual_ok = false;
@@ -270,6 +268,8 @@ _bt_orderkeys(IndexScanDesc scan)
            if (cur->sk_strategy == BTEqualStrategyNumber)
                scan->keys_are_unique = true;
        }
+       memcpy(outkeys, inkeys, sizeof(ScanKeyData));
+       so->numberOfKeys = 1;
        so->numberOfRequiredKeys = 1;
        return;
    }
@@ -283,12 +283,15 @@ _bt_orderkeys(IndexScanDesc scan)
    /*
     * Initialize for processing of keys for attr 1.
     *
-    * xform[i] holds a copy of the current scan key of strategy type i+1, if
-    * any; init[i] is TRUE if we have found such a key for this attr.
+    * xform[i] points to the currently best scan key of strategy type i+1,
+    * if any is found with a default operator subtype; it is NULL if we
+    * haven't yet found such a key for this attr.  Scan keys of nondefault
+    * subtypes are transferred to the output with no processing except for
+    * noting if they are of "=" type.
     */
    attno = 1;
-   MemSet(xform, 0, sizeof(xform));    /* not really necessary */
-   MemSet(init, 0, sizeof(init));
+   memset(xform, 0, sizeof(xform));
+   hasOtherTypeEqual = false;
 
    /*
     * Loop iterates from 0 to numberOfKeys inclusive; we use the last
@@ -329,80 +332,78 @@ _bt_orderkeys(IndexScanDesc scan)
             * of key > 2 && key == 1 and so on we have to set qual_ok to
             * false before discarding the other keys.
             */
-           if (init[BTEqualStrategyNumber - 1])
+           if (xform[BTEqualStrategyNumber - 1])
            {
-               ScanKeyData *eq,
-                          *chk;
+               ScanKey     eq = xform[BTEqualStrategyNumber - 1];
 
-               eq = &xform[BTEqualStrategyNumber - 1];
                for (j = BTMaxStrategyNumber; --j >= 0;)
                {
-                   if (!init[j] ||
-                       j == (BTEqualStrategyNumber - 1))
+                   ScanKey     chk = xform[j];
+
+                   if (!chk || j == (BTEqualStrategyNumber - 1))
                        continue;
-                   chk = &xform[j];
                    test = FunctionCall2(&chk->sk_func,
                                         eq->sk_argument,
                                         chk->sk_argument);
                    if (!DatumGetBool(test))
+                   {
                        so->qual_ok = false;
+                       break;
+                   }
                }
-               init[BTLessStrategyNumber - 1] = false;
-               init[BTLessEqualStrategyNumber - 1] = false;
-               init[BTGreaterEqualStrategyNumber - 1] = false;
-               init[BTGreaterStrategyNumber - 1] = false;
+               xform[BTLessStrategyNumber - 1] = NULL;
+               xform[BTLessEqualStrategyNumber - 1] = NULL;
+               xform[BTGreaterEqualStrategyNumber - 1] = NULL;
+               xform[BTGreaterStrategyNumber - 1] = NULL;
            }
            else
            {
                /*
-                * No "=" for this key, so we're done with required keys
+                * If no "=" for this key, we're done with required keys
                 */
-               allEqualSoFar = false;
+               if (! hasOtherTypeEqual)
+                   allEqualSoFar = false;
            }
 
            /* keep only one of <, <= */
-           if (init[BTLessStrategyNumber - 1]
-               && init[BTLessEqualStrategyNumber - 1])
+           if (xform[BTLessStrategyNumber - 1]
+               && xform[BTLessEqualStrategyNumber - 1])
            {
-               ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];
-               ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];
+               ScanKey lt = xform[BTLessStrategyNumber - 1];
+               ScanKey le = xform[BTLessEqualStrategyNumber - 1];
 
                test = FunctionCall2(&le->sk_func,
                                     lt->sk_argument,
                                     le->sk_argument);
                if (DatumGetBool(test))
-                   init[BTLessEqualStrategyNumber - 1] = false;
+                   xform[BTLessEqualStrategyNumber - 1] = NULL;
                else
-                   init[BTLessStrategyNumber - 1] = false;
+                   xform[BTLessStrategyNumber - 1] = NULL;
            }
 
            /* keep only one of >, >= */
-           if (init[BTGreaterStrategyNumber - 1]
-               && init[BTGreaterEqualStrategyNumber - 1])
+           if (xform[BTGreaterStrategyNumber - 1]
+               && xform[BTGreaterEqualStrategyNumber - 1])
            {
-               ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];
-               ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];
+               ScanKey gt = xform[BTGreaterStrategyNumber - 1];
+               ScanKey ge = xform[BTGreaterEqualStrategyNumber - 1];
 
                test = FunctionCall2(&ge->sk_func,
                                     gt->sk_argument,
                                     ge->sk_argument);
                if (DatumGetBool(test))
-                   init[BTGreaterEqualStrategyNumber - 1] = false;
+                   xform[BTGreaterEqualStrategyNumber - 1] = NULL;
                else
-                   init[BTGreaterStrategyNumber - 1] = false;
+                   xform[BTGreaterStrategyNumber - 1] = NULL;
            }
 
            /*
-            * Emit the cleaned-up keys back into the key[] array in the
-            * correct order.  Note we are overwriting our input here!
-            * It's OK because (a) xform[] is a physical copy of the keys
-            * we want, (b) we cannot emit more keys than we input, so we
-            * won't overwrite as-yet-unprocessed keys.
+            * Emit the cleaned-up keys into the outkeys[] array.
             */
            for (j = BTMaxStrategyNumber; --j >= 0;)
            {
-               if (init[j])
-                   memcpy(&key[new_numberOfKeys++], &xform[j],
+               if (xform[j])
+                   memcpy(&outkeys[new_numberOfKeys++], xform[j],
                           sizeof(ScanKeyData));
            }
 
@@ -421,31 +422,43 @@ _bt_orderkeys(IndexScanDesc scan)
 
            /* Re-initialize for new attno */
            attno = cur->sk_attno;
-           MemSet(xform, 0, sizeof(xform));    /* not really necessary */
-           MemSet(init, 0, sizeof(init));
+           memset(xform, 0, sizeof(xform));
+           hasOtherTypeEqual = false;
        }
 
-       /* figure out which strategy this key's operator corresponds to */
+       /* check strategy this key's operator corresponds to */
        j = cur->sk_strategy - 1;
 
+       /* if wrong RHS data type, punt */
+       if (cur->sk_subtype != InvalidOid)
+       {
+           memcpy(&outkeys[new_numberOfKeys++], cur,
+                  sizeof(ScanKeyData));
+           if (j == (BTEqualStrategyNumber - 1))
+               hasOtherTypeEqual = true;
+           continue;
+       }
+
        /* have we seen one of these before? */
-       if (init[j])
+       if (xform[j])
        {
-           /* yup, keep the more restrictive value */
+           /* yup, keep the more restrictive key */
            test = FunctionCall2(&cur->sk_func,
                                 cur->sk_argument,
-                                xform[j].sk_argument);
+                                xform[j]->sk_argument);
            if (DatumGetBool(test))
-               xform[j].sk_argument = cur->sk_argument;
+               xform[j] = cur;
            else if (j == (BTEqualStrategyNumber - 1))
+           {
+               /* key == a && key == b, but a != b */
                so->qual_ok = false;
-           /* key == a && key == b, but a != b */
+               return;
+           }
        }
        else
        {
            /* nope, so remember this scankey */
-           memcpy(&xform[j], cur, sizeof(ScanKeyData));
-           init[j] = true;
+           xform[j] = cur;
        }
    }
 
@@ -465,8 +478,8 @@ _bt_orderkeys(IndexScanDesc scan)
  *
  * If the tuple fails to pass the qual, we also determine whether there's
  * any need to continue the scan beyond this tuple, and set *continuescan
- * accordingly.  See comments for _bt_orderkeys(), above, about how this is
- * done.
+ * accordingly.  See comments for _bt_preprocess_keys(), above, about how
+ * this is done.
  */
 bool
 _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
@@ -474,7 +487,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
 {
    BTScanOpaque so = (BTScanOpaque) scan->opaque;
    int         keysz = so->numberOfKeys;
-   int         keysok;
+   int         ikey;
    TupleDesc   tupdesc;
    ScanKey     key;
 
@@ -484,13 +497,11 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
    if (keysz == 0)
        return true;
 
-   tupdesc = RelationGetDescr(scan->indexRelation);
-   key = so->keyData;
-   keysok = 0;
-
    IncrIndexProcessed();
 
-   while (keysz > 0)
+   tupdesc = RelationGetDescr(scan->indexRelation);
+
+   for (key = so->keyData, ikey = 0; ikey < keysz; key++, ikey++)
    {
        Datum       datum;
        bool        isNull;
@@ -504,7 +515,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
        /* btree doesn't support 'A is null' clauses, yet */
        if (key->sk_flags & SK_ISNULL)
        {
-           /* we shouldn't get here, really; see _bt_orderkeys() */
+           /* we shouldn't get here, really; see _bt_preprocess_keys() */
            *continuescan = false;
            return false;
        }
@@ -518,7 +529,7 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
             * one of the "must match" subset.  On a backward scan,
             * however, we should keep going.
             */
-           if (keysok < so->numberOfRequiredKeys &&
+           if (ikey < so->numberOfRequiredKeys &&
                ScanDirectionIsForward(dir))
                *continuescan = false;
 
@@ -534,16 +545,50 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
        {
            /*
             * Tuple fails this qual.  If it's a required qual, then we
-            * can conclude no further tuples will pass, either.
+            * may be able to conclude no further tuples will pass, either.
+            * We have to look at the scan direction and the qual type.
+            *
+            * Note: the only case in which we would keep going after failing
+            * a required qual is if there are partially-redundant quals that
+            * _bt_preprocess_keys() was unable to eliminate.  For example,
+            * given "x > 4 AND x > 10" where both are cross-type comparisons
+            * and so not removable, we might start the scan at the x = 4
+            * boundary point.  The "x > 10" condition will fail until we
+            * pass x = 10, but we must not stop the scan on its account.
+            *
+            * Note: because we stop the scan as soon as any required equality
+            * qual fails, it is critical that equality quals be used for the
+            * initial positioning in _bt_first() when they are available.
+            * See comments in _bt_first().
+            */
+           if (ikey < so->numberOfRequiredKeys)
+           {
+               switch (key->sk_strategy)
+               {
+                   case BTLessStrategyNumber:
+                   case BTLessEqualStrategyNumber:
+                       if (ScanDirectionIsForward(dir))
+                           *continuescan = false;
+                       break;
+                   case BTEqualStrategyNumber:
+                       *continuescan = false;
+                       break;
+                   case BTGreaterEqualStrategyNumber:
+                   case BTGreaterStrategyNumber:
+                       if (ScanDirectionIsBackward(dir))
+                           *continuescan = false;
+                       break;
+                   default:
+                       elog(ERROR, "unrecognized StrategyNumber: %d",
+                            key->sk_strategy);
+               }
+           }
+
+           /*
+            * In any case, this indextuple doesn't match the qual.
             */
-           if (keysok < so->numberOfRequiredKeys)
-               *continuescan = false;
            return false;
        }
-
-       keysok++;
-       key++;
-       keysz--;
    }
 
    /* If we get here, the tuple passes all quals. */
index 790f6bc7b69b8c4bc09ede30771b70154db3b81a..985993fb687a32c0021d2b7c02369b874ef6a3be 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.37 2003/08/04 02:39:57 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.38 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -82,20 +82,6 @@ rt_box_size(PG_FUNCTION_ARGS)
    PG_RETURN_VOID();
 }
 
-/*
- * rt_bigbox_size() -- Compute a size for big boxes.
- *
- *     In an earlier release of the system, this routine did something
- *     different from rt_box_size.  We now use floats, rather than ints,
- *     as the return type for the size routine, so we no longer need to
- *     have a special return type for big boxes.
- */
-Datum
-rt_bigbox_size(PG_FUNCTION_ARGS)
-{
-   return rt_box_size(fcinfo);
-}
-
 Datum
 rt_poly_union(PG_FUNCTION_ARGS)
 {
index 263fff4bf26c30ab899b861c6400bce0535e79e4..5026bd78a70c02ba4de51cf22485a59ba886d66e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.49 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -123,15 +123,17 @@ rtrescan(PG_FUNCTION_ARGS)
 
            opclass = s->indexRelation->rd_index->indclass[attno-1];
            int_strategy = RTMapToInternalOperator(s->keyData[i].sk_strategy);
-           int_oper = get_opclass_member(opclass, int_strategy);
+           int_oper = get_opclass_member(opclass,
+                                         s->keyData[i].sk_subtype,
+                                         int_strategy);
            int_proc = get_opcode(int_oper);
            ScanKeyEntryInitialize(&(p->s_internalKey[i]),
                                   s->keyData[i].sk_flags,
                                   attno,
                                   int_strategy,
+                                  s->keyData[i].sk_subtype,
                                   int_proc,
-                                  s->keyData[i].sk_argument,
-                                  s->keyData[i].sk_argtype);
+                                  s->keyData[i].sk_argument);
        }
    }
 
index a1b697bee8544f1ead267fc02e3d6f417e8ad47e..7534750c99eb2051b4c3c83d8eb798bb15529ca4 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.92 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.93 2003/11/12 21:15:48 tgl Exp $
  *
  * NOTES
  *   See acl.h.
@@ -366,10 +366,10 @@ ExecuteGrantStmt_Database(GrantStmt *stmt)
        char        replaces[Natts_pg_database];
 
        relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
-       ScanKeyEntryInitialize(&entry[0], 0,
-                              Anum_pg_database_datname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(dbname), NAMEOID);
+       ScanKeyInit(&entry[0],
+                   Anum_pg_database_datname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(dbname));
        scan = heap_beginscan(relation, SnapshotNow, 1, entry);
        tuple = heap_getnext(scan, ForwardScanDirection);
        if (!HeapTupleIsValid(tuple))
@@ -1131,10 +1131,10 @@ pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode)
     * There's no syscache for pg_database, so must look the hard way
     */
    pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(db_oid), OIDOID);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(db_oid));
    scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
    tuple = heap_getnext(scan, ForwardScanDirection);
    if (!HeapTupleIsValid(tuple))
@@ -1531,10 +1531,10 @@ pg_database_ownercheck(Oid db_oid, AclId userid)
 
    /* There's no syscache for pg_database, so must look the hard way */
    pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(db_oid), OIDOID);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(db_oid));
    scan = heap_beginscan(pg_database, SnapshotNow, 1, entry);
 
    dbtuple = heap_getnext(scan, ForwardScanDirection);
index b0e17652c749db4f76b1c8586009abf3372ec697..d64f027ef64a21a14440221d8353ebbeb431d28a 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.32 2003/11/09 21:30:35 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/dependency.c,v 1.33 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,7 +31,6 @@
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_rewrite.h"
 #include "catalog/pg_trigger.h"
-#include "catalog/pg_type.h"
 #include "commands/comment.h"
 #include "commands/defrem.h"
 #include "commands/proclang.h"
@@ -283,20 +282,20 @@ findAutoDeletableObjects(const ObjectAddress *object,
     * When dropping a whole object (subId = 0), find pg_depend records for
     * its sub-objects too.
     */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_refclassid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->classId), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_refobjid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->objectId), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_refclassid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->classId));
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_refobjid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->objectId));
    if (object->objectSubId != 0)
    {
-       ScanKeyEntryInitialize(&key[2], 0,
-                              Anum_pg_depend_refobjsubid,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(object->objectSubId), INT4OID);
+       ScanKeyInit(&key[2],
+                   Anum_pg_depend_refobjsubid,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(object->objectSubId));
        nkeys = 3;
    }
    else
@@ -418,20 +417,20 @@ recursiveDeletion(const ObjectAddress *object,
     * When dropping a whole object (subId = 0), remove all pg_depend records
     * for its sub-objects too.
     */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_classid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->classId), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_objid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->objectId), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_classid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->classId));
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_objid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->objectId));
    if (object->objectSubId != 0)
    {
-       ScanKeyEntryInitialize(&key[2], 0,
-                              Anum_pg_depend_objsubid,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(object->objectSubId), INT4OID);
+       ScanKeyInit(&key[2],
+                   Anum_pg_depend_objsubid,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(object->objectSubId));
        nkeys = 3;
    }
    else
@@ -651,20 +650,20 @@ deleteDependentObjects(const ObjectAddress *object,
    HeapTuple   tup;
    ObjectAddress otherObject;
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_refclassid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->classId), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_refobjid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->objectId), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_refclassid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->classId));
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_refobjid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->objectId));
    if (object->objectSubId != 0)
    {
-       ScanKeyEntryInitialize(&key[2], 0,
-                              Anum_pg_depend_refobjsubid,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(object->objectSubId), INT4OID);
+       ScanKeyInit(&key[2],
+                   Anum_pg_depend_refobjsubid,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(object->objectSubId));
        nkeys = 3;
    }
    else
@@ -1473,11 +1472,10 @@ getObjectDescription(const ObjectAddress *object)
 
                castDesc = heap_openr(CastRelationName, AccessShareLock);
 
-               ScanKeyEntryInitialize(&skey[0], 0,
-                                      ObjectIdAttributeNumber,
-                                      BTEqualStrategyNumber, F_OIDEQ,
-                                      ObjectIdGetDatum(object->objectId),
-                                      OIDOID);
+               ScanKeyInit(&skey[0],
+                           ObjectIdAttributeNumber,
+                           BTEqualStrategyNumber, F_OIDEQ,
+                           ObjectIdGetDatum(object->objectId));
 
                rcscan = systable_beginscan(castDesc, CastOidIndex, true,
                                            SnapshotNow, 1, skey);
@@ -1509,11 +1507,10 @@ getObjectDescription(const ObjectAddress *object)
 
                conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
 
-               ScanKeyEntryInitialize(&skey[0], 0,
-                                      ObjectIdAttributeNumber,
-                                      BTEqualStrategyNumber, F_OIDEQ,
-                                      ObjectIdGetDatum(object->objectId),
-                                      OIDOID);
+               ScanKeyInit(&skey[0],
+                           ObjectIdAttributeNumber,
+                           BTEqualStrategyNumber, F_OIDEQ,
+                           ObjectIdGetDatum(object->objectId));
 
                rcscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
                                            SnapshotNow, 1, skey);
@@ -1570,11 +1567,10 @@ getObjectDescription(const ObjectAddress *object)
 
                attrdefDesc = heap_openr(AttrDefaultRelationName, AccessShareLock);
 
-               ScanKeyEntryInitialize(&skey[0], 0,
-                                      ObjectIdAttributeNumber,
-                                      BTEqualStrategyNumber, F_OIDEQ,
-                                      ObjectIdGetDatum(object->objectId),
-                                      OIDOID);
+               ScanKeyInit(&skey[0],
+                           ObjectIdAttributeNumber,
+                           BTEqualStrategyNumber, F_OIDEQ,
+                           ObjectIdGetDatum(object->objectId));
 
                adscan = systable_beginscan(attrdefDesc, AttrDefaultOidIndex,
                                            true, SnapshotNow, 1, skey);
@@ -1672,11 +1668,10 @@ getObjectDescription(const ObjectAddress *object)
 
                ruleDesc = heap_openr(RewriteRelationName, AccessShareLock);
 
-               ScanKeyEntryInitialize(&skey[0], 0,
-                                      ObjectIdAttributeNumber,
-                                      BTEqualStrategyNumber, F_OIDEQ,
-                                      ObjectIdGetDatum(object->objectId),
-                                      OIDOID);
+               ScanKeyInit(&skey[0],
+                           ObjectIdAttributeNumber,
+                           BTEqualStrategyNumber, F_OIDEQ,
+                           ObjectIdGetDatum(object->objectId));
 
                rcscan = systable_beginscan(ruleDesc, RewriteOidIndex, true,
                                            SnapshotNow, 1, skey);
@@ -1708,11 +1703,10 @@ getObjectDescription(const ObjectAddress *object)
 
                trigDesc = heap_openr(TriggerRelationName, AccessShareLock);
 
-               ScanKeyEntryInitialize(&skey[0], 0,
-                                      ObjectIdAttributeNumber,
-                                      BTEqualStrategyNumber, F_OIDEQ,
-                                      ObjectIdGetDatum(object->objectId),
-                                      OIDOID);
+               ScanKeyInit(&skey[0],
+                           ObjectIdAttributeNumber,
+                           BTEqualStrategyNumber, F_OIDEQ,
+                           ObjectIdGetDatum(object->objectId));
 
                tgscan = systable_beginscan(trigDesc, TriggerOidIndex, true,
                                            SnapshotNow, 1, skey);
index 75445334ec7d4254eb30fecede5992c3177b24d2..a0962f487dd0521741c772f0318b95cd3d5da6e0 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.254 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.255 2003/11/12 21:15:48 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -853,11 +853,10 @@ RelationRemoveInheritance(Relation relation)
 
    catalogRelation = heap_openr(InheritsRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_inherits_inhrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&key,
+               Anum_pg_inherits_inhrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndex, true,
                              SnapshotNow, 1, &key);
@@ -920,10 +919,10 @@ DeleteAttributeTuples(Oid relid)
    attrel = heap_openr(AttributeRelationName, RowExclusiveLock);
 
    /* Use the index to scan only attributes of the target relation */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_attribute_attrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_attribute_attrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
 
    scan = systable_beginscan(attrel, AttributeRelidNumIndex, true,
                              SnapshotNow, 1, key);
@@ -1035,14 +1034,14 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
 
    attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&scankeys[0], 0,
-                          Anum_pg_attrdef_adrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
-   ScanKeyEntryInitialize(&scankeys[1], 0,
-                          Anum_pg_attrdef_adnum,
-                          BTEqualStrategyNumber, F_INT2EQ,
-                          Int16GetDatum(attnum), INT2OID);
+   ScanKeyInit(&scankeys[0],
+               Anum_pg_attrdef_adrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
+   ScanKeyInit(&scankeys[1],
+               Anum_pg_attrdef_adnum,
+               BTEqualStrategyNumber, F_INT2EQ,
+               Int16GetDatum(attnum));
 
    scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
                              SnapshotNow, 2, scankeys);
@@ -1092,10 +1091,10 @@ RemoveAttrDefaultById(Oid attrdefId)
    attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
 
    /* Find the pg_attrdef tuple */
-   ScanKeyEntryInitialize(&scankeys[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(attrdefId), OIDOID);
+   ScanKeyInit(&scankeys[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(attrdefId));
 
    scan = systable_beginscan(attrdef_rel, AttrDefaultOidIndex, true,
                              SnapshotNow, 1, scankeys);
@@ -1829,10 +1828,10 @@ RemoveRelConstraints(Relation rel, const char *constrName,
    conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
 
    /* Use the index to scan only constraints of the target relation */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_constraint_conrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_constraint_conrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(rel)));
 
    conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
                                 SnapshotNow, 1, key);
@@ -1883,19 +1882,19 @@ RemoveStatistics(Relation rel, AttrNumber attnum)
 
    pgstatistic = heap_openr(StatisticRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_statistic_starelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_statistic_starelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(rel)));
 
    if (attnum == 0)
        nkeys = 1;
    else
    {
-       ScanKeyEntryInitialize(&key[1], 0,
-                              Anum_pg_statistic_staattnum,
-                              BTEqualStrategyNumber, F_INT2EQ,
-                              Int16GetDatum(attnum), INT2OID);
+       ScanKeyInit(&key[1],
+                   Anum_pg_statistic_staattnum,
+                   BTEqualStrategyNumber, F_INT2EQ,
+                   Int16GetDatum(attnum));
        nkeys = 2;
    }
 
@@ -2050,10 +2049,10 @@ heap_truncate_check_FKs(Relation rel)
     */
    fkeyRel = heap_openr(ConstraintRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_constraint_confrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
+   ScanKeyInit(&key,
+               Anum_pg_constraint_confrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
 
    fkeyScan = systable_beginscan(fkeyRel, NULL, false,
                                  SnapshotNow, 1, &key);
index 67f970c55d78c53c38bf25f8813bf265caac930c..72f76b01b06d2e18e7e81fed3aee12932d3bd716 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.220 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.221 2003/11/12 21:15:48 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -992,10 +992,10 @@ setRelhasindex(Oid relid, bool hasindex, bool isprimary, Oid reltoastidxid)
    {
        ScanKeyData key[1];
 
-       ScanKeyEntryInitialize(&key[0], 0,
-                              ObjectIdAttributeNumber,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(relid), OIDOID);
+       ScanKeyInit(&key[0],
+                   ObjectIdAttributeNumber,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(relid));
 
        pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
        tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
@@ -1195,10 +1195,10 @@ UpdateStats(Oid relid, double reltuples)
    {
        ScanKeyData key[1];
 
-       ScanKeyEntryInitialize(&key[0], 0,
-                              ObjectIdAttributeNumber,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(relid), OIDOID);
+       ScanKeyInit(&key[0],
+                   ObjectIdAttributeNumber,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(relid));
 
        pg_class_scan = heap_beginscan(pg_class, SnapshotNow, 1, key);
        tuple = heap_getnext(pg_class_scan, ForwardScanDirection);
index 0fa665a568d3422095a09faa6ad98b7e20a5dec0..2cb71f6bfccade2ada0339f3156094984129ac77 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.17 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_constraint.c,v 1.18 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -281,15 +281,15 @@ ConstraintNameIsUsed(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, con
 
    found = false;
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_constraint_conname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          CStringGetDatum(cname), NAMEOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_constraint_conname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               CStringGetDatum(cname));
 
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_constraint_connamespace,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(objNamespace), OIDOID);
+   ScanKeyInit(&skey[1],
+               Anum_pg_constraint_connamespace,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(objNamespace));
 
    conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
                                 SnapshotNow, 2, skey);
@@ -355,15 +355,15 @@ GenerateConstraintName(CONSTRAINTCATEGORY conCat, Oid objId, Oid objNamespace, i
         */
        found = false;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_constraint_conname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(cname), NAMEOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_constraint_conname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(cname));
 
-       ScanKeyEntryInitialize(&skey[1], 0,
-                              Anum_pg_constraint_connamespace,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(objNamespace), OIDOID);
+       ScanKeyInit(&skey[1],
+                   Anum_pg_constraint_connamespace,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(objNamespace));
 
        conscan = systable_beginscan(conDesc, ConstraintNameNspIndex, true,
                                     SnapshotNow, 2, skey);
@@ -422,10 +422,10 @@ RemoveConstraintById(Oid conId)
 
    conDesc = heap_openr(ConstraintRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(conId), OIDOID);
+   ScanKeyInit(&skey[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(conId));
 
    conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
                                 SnapshotNow, 1, skey);
index 709f50f2a5d01159bc37ca533775a30e8b9d52b5..7f7811c88df7d8b8c37e7a1c2f86dc0831302b26 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.16 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_conversion.c,v 1.17 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,7 +21,6 @@
 #include "catalog/pg_class.h"
 #include "catalog/pg_conversion.h"
 #include "catalog/namespace.h"
-#include "catalog/pg_type.h"
 #include "utils/builtins.h"
 #include "utils/lsyscache.h"
 #include "utils/syscache.h"
@@ -177,10 +176,10 @@ RemoveConversionById(Oid conversionOid)
    HeapScanDesc scan;
    ScanKeyData scanKeyData;
 
-   ScanKeyEntryInitialize(&scanKeyData, 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(conversionOid), OIDOID);
+   ScanKeyInit(&scanKeyData,
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(conversionOid));
 
    /* open pg_conversion */
    rel = heap_openr(ConversionRelationName, RowExclusiveLock);
index 21eeb3e6543600abc32867df21a5c5225be65d98..2bdb5b12d8d18e788c74f7d7a56eb0543c7daa38 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.8 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_depend.c,v 1.9 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,7 +20,6 @@
 #include "catalog/indexing.h"
 #include "catalog/dependency.h"
 #include "catalog/pg_depend.h"
-#include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "utils/fmgroids.h"
 
@@ -139,14 +138,14 @@ deleteDependencyRecordsFor(Oid classId, Oid objectId)
 
    depRel = heap_openr(DependRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_classid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(classId), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_objid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(objectId), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_classid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(classId));
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_objid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(objectId));
 
    scan = systable_beginscan(depRel, DependDependerIndex, true,
                              SnapshotNow, 2, key);
@@ -181,15 +180,15 @@ isObjectPinned(const ObjectAddress *object, Relation rel)
    HeapTuple   tup;
    ScanKeyData key[2];
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_refclassid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->classId), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_refclassid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->classId));
 
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_refobjid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(object->objectId), OIDOID);
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_refobjid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(object->objectId));
 
    scan = systable_beginscan(rel, DependReferenceIndex, true,
                              SnapshotNow, 2, key);
index 96f73056cf2ad799302b1e6fb21ee4d582e759fa..022ca67d10e9a6ece6a1904d78502ae414dc690c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.18 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/catalog/pg_largeobject.c,v 1.19 2003/11/12 21:15:48 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -19,7 +19,6 @@
 #include "catalog/catname.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_largeobject.h"
-#include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
@@ -82,10 +81,10 @@ LargeObjectDrop(Oid loid)
    SysScanDesc sd;
    HeapTuple   tuple;
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_largeobject_loid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(loid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_largeobject_loid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(loid));
 
    pg_largeobject = heap_openr(LargeObjectRelationName, RowExclusiveLock);
 
@@ -120,10 +119,10 @@ LargeObjectExists(Oid loid)
    /*
     * See if we can find any tuples belonging to the specified LO
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_largeobject_loid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(loid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_largeobject_loid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(loid));
 
    pg_largeobject = heap_openr(LargeObjectRelationName, AccessShareLock);
 
index 2cda1f94a97caabb07ba49f02141c3c0c8da5f0e..560a134aa86a556c4741ce737c15d30213fead34 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.103 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.104 2003/11/12 21:15:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -80,7 +80,6 @@
 #include "access/heapam.h"
 #include "catalog/catname.h"
 #include "catalog/pg_listener.h"
-#include "catalog/pg_type.h"
 #include "commands/async.h"
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
@@ -353,10 +352,10 @@ Async_UnlistenAll(void)
    tdesc = RelationGetDescr(lRel);
 
    /* Find and delete all entries with my listenerPID */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_listener_pid,
-                          BTEqualStrategyNumber, F_INT4EQ,
-                          Int32GetDatum(MyProcPid), INT4OID);
+   ScanKeyInit(&key[0],
+               Anum_pg_listener_pid,
+               BTEqualStrategyNumber, F_INT4EQ,
+               Int32GetDatum(MyProcPid));
    scan = heap_beginscan(lRel, SnapshotNow, 1, key);
 
    while ((lTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
@@ -817,10 +816,10 @@ ProcessIncomingNotify(void)
    tdesc = RelationGetDescr(lRel);
 
    /* Scan only entries with my listenerPID */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_listener_pid,
-                          BTEqualStrategyNumber, F_INT4EQ,
-                          Int32GetDatum(MyProcPid), INT4OID);
+   ScanKeyInit(&key[0],
+               Anum_pg_listener_pid,
+               BTEqualStrategyNumber, F_INT4EQ,
+               Int32GetDatum(MyProcPid));
    scan = heap_beginscan(lRel, SnapshotNow, 1, key);
 
    /* Prepare data for rewriting 0 into notification field */
index 780a60f7966e548a01360b124e5df01d1a055083..4d5bc491c71dfc4434edda27e9f1b3b86b8e405d 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.117 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/cluster.c,v 1.118 2003/11/12 21:15:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,7 +26,6 @@
 #include "catalog/index.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
-#include "catalog/pg_type.h"
 #include "commands/cluster.h"
 #include "commands/tablecmds.h"
 #include "miscadmin.h"
@@ -879,10 +878,10 @@ get_tables_to_cluster(MemoryContext cluster_context)
     * when called with one of them as argument.
     */
    indRelation = relation_openr(IndexRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry, 0,
-                          Anum_pg_index_indisclustered,
-                          BTEqualStrategyNumber, F_BOOLEQ,
-                          BoolGetDatum(true), BOOLOID);
+   ScanKeyInit(&entry,
+               Anum_pg_index_indisclustered,
+               BTEqualStrategyNumber, F_BOOLEQ,
+               BoolGetDatum(true));
    scan = heap_beginscan(indRelation, SnapshotNow, 1, &entry);
    while ((indexTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
    {
index fbce38ca577b04cdc25567127f7b604bb3c71ad4..62765a96e0a2f313f58b56814e9dd7514dc34ee9 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 1996-2003, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.72 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.73 2003/11/12 21:15:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -156,18 +156,18 @@ CreateComments(Oid oid, Oid classoid, int32 subid, char *comment)
 
    /* Use the index to search for a matching old tuple */
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_description_objoid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(oid), OIDOID);
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_description_classoid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(classoid), OIDOID);
-   ScanKeyEntryInitialize(&skey[2], 0,
-                          Anum_pg_description_objsubid,
-                          BTEqualStrategyNumber, F_INT4EQ,
-                          Int32GetDatum(subid), INT4OID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_description_objoid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(oid));
+   ScanKeyInit(&skey[1],
+               Anum_pg_description_classoid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(classoid));
+   ScanKeyInit(&skey[2],
+               Anum_pg_description_objsubid,
+               BTEqualStrategyNumber, F_INT4EQ,
+               Int32GetDatum(subid));
 
    description = heap_openr(DescriptionRelationName, RowExclusiveLock);
 
@@ -231,21 +231,21 @@ DeleteComments(Oid oid, Oid classoid, int32 subid)
 
    /* Use the index to search for all matching old tuples */
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_description_objoid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(oid), OIDOID);
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_description_classoid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(classoid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_description_objoid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(oid));
+   ScanKeyInit(&skey[1],
+               Anum_pg_description_classoid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(classoid));
 
    if (subid != 0)
    {
-       ScanKeyEntryInitialize(&skey[2], 0,
-                              Anum_pg_description_objsubid,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(subid), INT4OID);
+       ScanKeyInit(&skey[2],
+                   Anum_pg_description_objsubid,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(subid));
        nkeys = 3;
    }
    else
@@ -538,10 +538,10 @@ CommentRule(List *qualname, char *comment)
        rulename = strVal(lfirst(qualname));
 
        /* Search pg_rewrite for such a rule */
-       ScanKeyEntryInitialize(&scanKeyData, 0,
-                              Anum_pg_rewrite_rulename,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              PointerGetDatum(rulename), NAMEOID);
+       ScanKeyInit(&scanKeyData,
+                   Anum_pg_rewrite_rulename,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   PointerGetDatum(rulename));
 
        RewriteRelation = heap_openr(RewriteRelationName, AccessShareLock);
        scanDesc = heap_beginscan(RewriteRelation, SnapshotNow,
@@ -791,15 +791,14 @@ CommentTrigger(List *qualname, char *comment)
     * because of the unique index.
     */
    pg_trigger = heap_openr(TriggerRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
-   ScanKeyEntryInitialize(&entry[1], 0,
-                          Anum_pg_trigger_tgname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          CStringGetDatum(trigname), NAMEOID);
+   ScanKeyInit(&entry[0],
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
+   ScanKeyInit(&entry[1],
+               Anum_pg_trigger_tgname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               CStringGetDatum(trigname));
    scan = systable_beginscan(pg_trigger, TriggerRelidNameIndex, true,
                              SnapshotNow, 2, entry);
    triggertuple = systable_getnext(scan);
@@ -872,11 +871,10 @@ CommentConstraint(List *qualname, char *comment)
     */
    pg_constraint = heap_openr(ConstraintRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_constraint_conrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_constraint_conrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    scan = systable_beginscan(pg_constraint, ConstraintRelidIndex, true,
                              SnapshotNow, 1, skey);
index 5ac51bc84d326b24ba885d6b34333d7710842a69..320f1fc0deddf1f54d01980786250bf0ac9f0f9d 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.125 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.126 2003/11/12 21:15:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -27,7 +27,6 @@
 #include "catalog/pg_database.h"
 #include "catalog/pg_shadow.h"
 #include "catalog/indexing.h"
-#include "catalog/pg_type.h"
 #include "commands/comment.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
@@ -531,10 +530,10 @@ dropdb(const char *dbname)
    /*
     * Find the database's tuple by OID (should be unique).
     */
-   ScanKeyEntryInitialize(&key, 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(db_id), OIDOID);
+   ScanKeyInit(&key,
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(db_id));
 
    pgdbscan = systable_beginscan(pgdbrel, DatabaseOidIndex, true,
                                  SnapshotNow, 1, &key);
@@ -616,10 +615,10 @@ RenameDatabase(const char *oldname, const char *newname)
     */
    rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
 
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          NameGetDatum(oldname), NAMEOID);
+   ScanKeyInit(&key,
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               NameGetDatum(oldname));
    scan = systable_beginscan(rel, DatabaseNameIndex, true,
                              SnapshotNow, 1, &key);
 
@@ -651,10 +650,10 @@ RenameDatabase(const char *oldname, const char *newname)
                      oldname)));
 
    /* make sure the new name doesn't exist */
-   ScanKeyEntryInitialize(&key2, 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          NameGetDatum(newname), NAMEOID);
+   ScanKeyInit(&key2,
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               NameGetDatum(newname));
    scan2 = systable_beginscan(rel, DatabaseNameIndex, true,
                               SnapshotNow, 1, &key2);
    if (HeapTupleIsValid(systable_getnext(scan2)))
@@ -712,10 +711,10 @@ AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
    valuestr = flatten_set_variable_args(stmt->variable, stmt->value);
 
    rel = heap_openr(DatabaseRelationName, RowExclusiveLock);
-   ScanKeyEntryInitialize(&scankey, 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          NameGetDatum(stmt->dbname), NAMEOID);
+   ScanKeyInit(&scankey,
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               NameGetDatum(stmt->dbname));
    scan = systable_beginscan(rel, DatabaseNameIndex, true,
                              SnapshotNow, 1, &scankey);
    tuple = systable_getnext(scan);
@@ -795,10 +794,10 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
    /* Caller may wish to grab a better lock on pg_database beforehand... */
    relation = heap_openr(DatabaseRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&scanKey, 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          NameGetDatum(name), NAMEOID);
+   ScanKeyInit(&scanKey,
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               NameGetDatum(name));
 
    scan = systable_beginscan(relation, DatabaseNameIndex, true,
                              SnapshotNow, 1, &scanKey);
@@ -1001,10 +1000,10 @@ get_database_oid(const char *dbname)
 
    /* There's no syscache for pg_database, so must look the hard way */
    pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          CStringGetDatum(dbname), NAMEOID);
+   ScanKeyInit(&entry[0],
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               CStringGetDatum(dbname));
    scan = systable_beginscan(pg_database, DatabaseNameIndex, true,
                              SnapshotNow, 1, entry);
 
@@ -1041,10 +1040,10 @@ get_database_name(Oid dbid)
 
    /* There's no syscache for pg_database, so must look the hard way */
    pg_database = heap_openr(DatabaseRelationName, AccessShareLock);
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(dbid), OIDOID);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(dbid));
    scan = systable_beginscan(pg_database, DatabaseOidIndex, true,
                              SnapshotNow, 1, entry);
 
index 9e1e0746f554091101f05789b00b8ea5702af451..7e3c7410a10462aa1841ab0a0d697bddb2dbb6f5 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.39 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.40 2003/11/12 21:15:50 tgl Exp $
  *
  * DESCRIPTION
  *   These routines take the parse tree and pick out the
@@ -1097,10 +1097,10 @@ DropCastById(Oid castOid)
 
    relation = heap_openr(CastRelationName, RowExclusiveLock);
 
-   ScanKeyEntryInitialize(&scankey, 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(castOid), OIDOID);
+   ScanKeyInit(&scankey,
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(castOid));
    scan = systable_beginscan(relation, CastOidIndex, true,
                              SnapshotNow, 1, &scankey);
 
index dbbbc376e004280443f338abc8c31b64f66d87fe..2f83e22a276bcb9d0313b86809dc7bac1da22bb9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.114 2003/10/02 06:34:03 petere Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.115 2003/11/12 21:15:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -416,6 +416,9 @@ GetIndexOpClass(List *opclass, Oid attrType,
     * Release 7.2 renames timestamp_ops to timestamptz_ops, so suppress that
     * too for awhile.  I'm starting to think we need a better approach.
     * tgl 2000/10/01
+    *
+    * Release 7.5 removes bigbox_ops (which was dead code for a long while
+    * anyway).  tgl 2003/11/11
     */
    if (length(opclass) == 1)
    {
@@ -425,7 +428,8 @@ GetIndexOpClass(List *opclass, Oid attrType,
            strcmp(claname, "timespan_ops") == 0 ||
            strcmp(claname, "datetime_ops") == 0 ||
            strcmp(claname, "lztext_ops") == 0 ||
-           strcmp(claname, "timestamp_ops") == 0)
+           strcmp(claname, "timestamp_ops") == 0 ||
+           strcmp(claname, "bigbox_ops") == 0)
            opclass = NIL;
    }
 
index 599d2eb8259d0aa1f77a5e4aa3713d302e2fc551..e251f8577da811c965e2e2aefc1322f54f712006 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.22 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/opclasscmds.c,v 1.23 2003/11/12 21:15:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +25,8 @@
 #include "catalog/pg_amop.h"
 #include "catalog/pg_amproc.h"
 #include "catalog/pg_opclass.h"
+#include "catalog/pg_operator.h"
+#include "catalog/pg_proc.h"
 #include "catalog/pg_type.h"
 #include "commands/defrem.h"
 #include "miscadmin.h"
 #include "utils/syscache.h"
 
 
-static void storeOperators(Oid opclassoid, int numOperators,
-              Oid *operators, bool *recheck);
-static void storeProcedures(Oid opclassoid, int numProcs, Oid *procedures);
+/*
+ * We use lists of this struct type to keep track of both operators and
+ * procedures during DefineOpClass.
+ */
+typedef struct
+{
+   Oid         object;         /* operator or support proc's OID */
+   int         number;         /* strategy or support proc number */
+   Oid         subtype;        /* subtype */
+   bool        recheck;        /* oper recheck flag (unused for proc) */
+} OpClassMember;
+
+
+static Oid assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid);
+static Oid assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid);
+static void addClassMember(List **list, OpClassMember *member, bool isProc);
+static void storeOperators(Oid opclassoid, List *operators);
+static void storeProcedures(Oid opclassoid, List *procedures);
 
 
 /*
@@ -58,10 +75,9 @@ DefineOpClass(CreateOpClassStmt *stmt)
                opclassoid;     /* oid of opclass we create */
    int         numOperators,   /* amstrategies value */
                numProcs;       /* amsupport value */
-   Oid        *operators,      /* oids of operators, by strategy num */
-              *procedures;     /* oids of support procs */
-   bool       *recheck;        /* do operators need recheck */
-   List       *iteml;
+   List       *operators;      /* OpClassMember list for operators */
+   List       *procedures;     /* OpClassMember list for support procs */
+   List       *l;
    Relation    rel;
    HeapTuple   tup;
    Datum       values[Natts_pg_opclass];
@@ -123,26 +139,21 @@ DefineOpClass(CreateOpClassStmt *stmt)
                       format_type_be(typeoid));
 #endif
 
+   operators = NIL;
+   procedures = NIL;
+
    /* Storage datatype is optional */
    storageoid = InvalidOid;
 
-   /*
-    * Create work arrays to hold info about operators and procedures. We
-    * do this mainly so that we can detect duplicate strategy numbers and
-    * support-proc numbers.
-    */
-   operators = (Oid *) palloc0(sizeof(Oid) * numOperators);
-   procedures = (Oid *) palloc0(sizeof(Oid) * numProcs);
-   recheck = (bool *) palloc0(sizeof(bool) * numOperators);
-
    /*
     * Scan the "items" list to obtain additional info.
     */
-   foreach(iteml, stmt->items)
+   foreach(l, stmt->items)
    {
-       CreateOpClassItem *item = lfirst(iteml);
+       CreateOpClassItem *item = lfirst(l);
        Oid         operOid;
        Oid         funcOid;
+       OpClassMember *member;
        AclResult   aclresult;
 
        Assert(IsA(item, CreateOpClassItem));
@@ -155,11 +166,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
                             errmsg("invalid operator number %d,"
                                    " must be between 1 and %d",
                                    item->number, numOperators)));
-               if (operators[item->number - 1] != InvalidOid)
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                     errmsg("operator number %d appears more than once",
-                            item->number)));
                if (item->args != NIL)
                {
                    TypeName   *typeName1 = (TypeName *) lfirst(item->args);
@@ -183,8 +189,13 @@ DefineOpClass(CreateOpClassStmt *stmt)
                if (aclresult != ACLCHECK_OK)
                    aclcheck_error(aclresult, ACL_KIND_PROC,
                                   get_func_name(funcOid));
-               operators[item->number - 1] = operOid;
-               recheck[item->number - 1] = item->recheck;
+               /* Save the info */
+               member = (OpClassMember *) palloc0(sizeof(OpClassMember));
+               member->object = operOid;
+               member->number = item->number;
+               member->subtype = assignOperSubtype(amoid, typeoid, operOid);
+               member->recheck = item->recheck;
+               addClassMember(&operators, member, false);
                break;
            case OPCLASS_ITEM_FUNCTION:
                if (item->number <= 0 || item->number > numProcs)
@@ -193,11 +204,6 @@ DefineOpClass(CreateOpClassStmt *stmt)
                             errmsg("invalid procedure number %d,"
                                    " must be between 1 and %d",
                                    item->number, numProcs)));
-               if (procedures[item->number - 1] != InvalidOid)
-                   ereport(ERROR,
-                           (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
-                            errmsg("procedure number %d appears more than once",
-                                   item->number)));
                funcOid = LookupFuncNameTypeNames(item->name, item->args,
                                                  false);
                /* Caller must have execute permission on functions */
@@ -206,7 +212,12 @@ DefineOpClass(CreateOpClassStmt *stmt)
                if (aclresult != ACLCHECK_OK)
                    aclcheck_error(aclresult, ACL_KIND_PROC,
                                   get_func_name(funcOid));
-               procedures[item->number - 1] = funcOid;
+               /* Save the info */
+               member = (OpClassMember *) palloc0(sizeof(OpClassMember));
+               member->object = funcOid;
+               member->number = item->number;
+               member->subtype = assignProcSubtype(amoid, typeoid, funcOid);
+               addClassMember(&procedures, member, true);
                break;
            case OPCLASS_ITEM_STORAGETYPE:
                if (OidIsValid(storageoid))
@@ -271,10 +282,10 @@ DefineOpClass(CreateOpClassStmt *stmt)
        ScanKeyData skey[1];
        SysScanDesc scan;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_opclass_opcamid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(amoid), OIDOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_opclass_opcamid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(amoid));
 
        scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
                                  SnapshotNow, 1, skey);
@@ -327,8 +338,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
     * Now add tuples to pg_amop and pg_amproc tying in the operators and
     * functions.
     */
-   storeOperators(opclassoid, numOperators, operators, recheck);
-   storeProcedures(opclassoid, numProcs, procedures);
+   storeOperators(opclassoid, operators);
+   storeProcedures(opclassoid, procedures);
 
    /*
     * Create dependencies.  Note: we do not create a dependency link to
@@ -361,22 +372,22 @@ DefineOpClass(CreateOpClassStmt *stmt)
 
    /* dependencies on operators */
    referenced.classId = get_system_catalog_relid(OperatorRelationName);
-   for (i = 0; i < numOperators; i++)
+   foreach(l, operators)
    {
-       if (operators[i] == InvalidOid)
-           continue;
-       referenced.objectId = operators[i];
+       OpClassMember *op = (OpClassMember *) lfirst(l);
+
+       referenced.objectId = op->object;
        referenced.objectSubId = 0;
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    }
 
    /* dependencies on procedures */
-   for (i = 0; i < numProcs; i++)
+   foreach(l, procedures)
    {
-       if (procedures[i] == InvalidOid)
-           continue;
+       OpClassMember *proc = (OpClassMember *) lfirst(l);
+
        referenced.classId = RelOid_pg_proc;
-       referenced.objectId = procedures[i];
+       referenced.objectId = proc->object;
        referenced.objectSubId = 0;
        recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
    }
@@ -384,26 +395,159 @@ DefineOpClass(CreateOpClassStmt *stmt)
    heap_close(rel, RowExclusiveLock);
 }
 
+/*
+ * Determine the subtype to assign to an operator, and do any validity
+ * checking we can manage
+ *
+ * Currently this is done using hardwired rules; we don't let the user
+ * specify it directly.
+ */
+static Oid
+assignOperSubtype(Oid amoid, Oid typeoid, Oid operOid)
+{
+   Oid         subtype;
+   Operator    optup;
+   Form_pg_operator opform;
+
+   /* Subtypes are currently only supported by btree, others use 0 */
+   if (amoid != BTREE_AM_OID)
+       return InvalidOid;
+
+   optup = SearchSysCache(OPEROID,
+                          ObjectIdGetDatum(operOid),
+                          0, 0, 0);
+   if (optup == NULL)
+       elog(ERROR, "cache lookup failed for operator %u", operOid);
+   opform = (Form_pg_operator) GETSTRUCT(optup);
+   /*
+    * btree operators must be binary ops returning boolean, and the
+    * left-side input type must match the operator class' input type.
+    */
+   if (opform->oprkind != 'b')
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree operators must be binary")));
+   if (opform->oprresult != BOOLOID)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree operators must return boolean")));
+   if (opform->oprleft != typeoid)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree operators must have index type as left input")));
+   /*
+    * The subtype is "default" (0) if oprright matches the operator class,
+    * otherwise it is oprright.
+    */
+   if (opform->oprright == typeoid)
+       subtype = InvalidOid;
+   else
+       subtype = opform->oprright;
+   ReleaseSysCache(optup);
+   return subtype;
+}
+
+/*
+ * Determine the subtype to assign to a support procedure, and do any validity
+ * checking we can manage
+ *
+ * Currently this is done using hardwired rules; we don't let the user
+ * specify it directly.
+ */
+static Oid
+assignProcSubtype(Oid amoid, Oid typeoid, Oid procOid)
+{
+   Oid         subtype;
+   HeapTuple   proctup;
+   Form_pg_proc procform;
+
+   /* Subtypes are currently only supported by btree, others use 0 */
+   if (amoid != BTREE_AM_OID)
+       return InvalidOid;
+
+   proctup = SearchSysCache(PROCOID,
+                            ObjectIdGetDatum(procOid),
+                            0, 0, 0);
+   if (proctup == NULL)
+       elog(ERROR, "cache lookup failed for function %u", procOid);
+   procform = (Form_pg_proc) GETSTRUCT(proctup);
+   /*
+    * btree support procs must be 2-arg procs returning int4, and the
+    * first input type must match the operator class' input type.
+    */
+   if (procform->pronargs != 2)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree procedures must have two arguments")));
+   if (procform->prorettype != INT4OID)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree procedures must return integer")));
+   if (procform->proargtypes[0] != typeoid)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                errmsg("btree procedures must have index type as first input")));
+   /*
+    * The subtype is "default" (0) if second input type matches the operator
+    * class, otherwise it is the second input type.
+    */
+   if (procform->proargtypes[1] == typeoid)
+       subtype = InvalidOid;
+   else
+       subtype = procform->proargtypes[1];
+   ReleaseSysCache(proctup);
+   return subtype;
+}
+
+/*
+ * Add a new class member to the appropriate list, after checking for
+ * duplicated strategy or proc number.
+ */
+static void
+addClassMember(List **list, OpClassMember *member, bool isProc)
+{
+   List       *l;
+
+   foreach(l, *list)
+   {
+       OpClassMember *old = (OpClassMember *) lfirst(l);
+
+       if (old->number == member->number &&
+           old->subtype == member->subtype)
+       {
+           if (isProc)
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                        errmsg("procedure number %d appears more than once",
+                               member->number)));
+           else
+               ereport(ERROR,
+                       (errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
+                        errmsg("operator number %d appears more than once",
+                               member->number)));
+       }
+   }
+   *list = lappend(*list, member);
+}
+
 /*
  * Dump the operators to pg_amop
  */
 static void
-storeOperators(Oid opclassoid, int numOperators,
-              Oid *operators, bool *recheck)
+storeOperators(Oid opclassoid, List *operators)
 {
    Relation    rel;
    Datum       values[Natts_pg_amop];
    char        nulls[Natts_pg_amop];
    HeapTuple   tup;
-   int         i,
-               j;
+   List       *l;
+   int         i;
 
    rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
 
-   for (j = 0; j < numOperators; j++)
+   foreach(l, operators)
    {
-       if (operators[j] == InvalidOid)
-           continue;
+       OpClassMember *op = (OpClassMember *) lfirst(l);
 
        for (i = 0; i < Natts_pg_amop; ++i)
        {
@@ -413,9 +557,10 @@ storeOperators(Oid opclassoid, int numOperators,
 
        i = 0;
        values[i++] = ObjectIdGetDatum(opclassoid);     /* amopclaid */
-       values[i++] = Int16GetDatum(j + 1);     /* amopstrategy */
-       values[i++] = BoolGetDatum(recheck[j]); /* amopreqcheck */
-       values[i++] = ObjectIdGetDatum(operators[j]);   /* amopopr */
+       values[i++] = ObjectIdGetDatum(op->subtype);    /* amopsubtype */
+       values[i++] = Int16GetDatum(op->number);        /* amopstrategy */
+       values[i++] = BoolGetDatum(op->recheck);        /* amopreqcheck */
+       values[i++] = ObjectIdGetDatum(op->object);     /* amopopr */
 
        tup = heap_formtuple(rel->rd_att, values, nulls);
 
@@ -433,21 +578,20 @@ storeOperators(Oid opclassoid, int numOperators,
  * Dump the procedures (support routines) to pg_amproc
  */
 static void
-storeProcedures(Oid opclassoid, int numProcs, Oid *procedures)
+storeProcedures(Oid opclassoid, List *procedures)
 {
    Relation    rel;
    Datum       values[Natts_pg_amproc];
    char        nulls[Natts_pg_amproc];
    HeapTuple   tup;
-   int         i,
-               j;
+   List       *l;
+   int         i;
 
    rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
 
-   for (j = 0; j < numProcs; j++)
+   foreach(l, procedures)
    {
-       if (procedures[j] == InvalidOid)
-           continue;
+       OpClassMember *proc = (OpClassMember *) lfirst(l);
 
        for (i = 0; i < Natts_pg_amproc; ++i)
        {
@@ -457,8 +601,9 @@ storeProcedures(Oid opclassoid, int numProcs, Oid *procedures)
 
        i = 0;
        values[i++] = ObjectIdGetDatum(opclassoid);     /* amopclaid */
-       values[i++] = Int16GetDatum(j + 1);     /* amprocnum */
-       values[i++] = ObjectIdGetDatum(procedures[j]);  /* amproc */
+       values[i++] = ObjectIdGetDatum(proc->subtype);  /* amprocsubtype */
+       values[i++] = Int16GetDatum(proc->number);      /* amprocnum */
+       values[i++] = ObjectIdGetDatum(proc->object);   /* amproc */
 
        tup = heap_formtuple(rel->rd_att, values, nulls);
 
@@ -590,10 +735,10 @@ RemoveOpClassById(Oid opclassOid)
    /*
     * Remove associated entries in pg_amop.
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_amop_amopclaid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(opclassOid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_amop_amopclaid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(opclassOid));
 
    rel = heap_openr(AccessMethodOperatorRelationName, RowExclusiveLock);
 
@@ -609,10 +754,10 @@ RemoveOpClassById(Oid opclassOid)
    /*
     * Remove associated entries in pg_amproc.
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_amproc_amopclaid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(opclassOid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_amproc_amopclaid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(opclassOid));
 
    rel = heap_openr(AccessMethodProcedureRelationName, RowExclusiveLock);
 
index df441ca476c743aca6ab4b6dea5ede33c485ca1b..feb9720a847765a560ef3796fffafc5fe4b1796b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.92 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.93 2003/11/12 21:15:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1393,20 +1393,20 @@ update_ri_trigger_args(Oid relid,
    tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
    if (fk_scan)
    {
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_trigger_tgconstrrelid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(relid), OIDOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_trigger_tgconstrrelid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(relid));
        trigscan = systable_beginscan(tgrel, TriggerConstrRelidIndex,
                                      true, SnapshotNow,
                                      1, skey);
    }
    else
    {
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_trigger_tgrelid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(relid), OIDOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_trigger_tgrelid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(relid));
        trigscan = systable_beginscan(tgrel, TriggerRelidNameIndex,
                                      true, SnapshotNow,
                                      1, skey);
index 80225f8f25f3415951a927d59d86b47dba282172..4788d90e587d27e005277d6a805798ca9628bd4d 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.161 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.162 2003/11/12 21:15:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -253,10 +253,10 @@ CreateTrigger(CreateTrigStmt *stmt, bool forConstraint)
     * relation, so the trigger set won't be changing underneath us.
     */
    tgrel = heap_openr(TriggerRelationName, RowExclusiveLock);
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(rel)), OIDOID);
+   ScanKeyInit(&key,
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(rel)));
    tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
                                SnapshotNow, 1, &key);
    while (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
@@ -465,15 +465,15 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
     */
    tgrel = heap_openr(TriggerRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
 
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_trigger_tgname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          CStringGetDatum(trigname), NAMEOID);
+   ScanKeyInit(&skey[1],
+               Anum_pg_trigger_tgname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               CStringGetDatum(trigname));
 
    tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
                                SnapshotNow, 2, skey);
@@ -524,10 +524,10 @@ RemoveTriggerById(Oid trigOid)
    /*
     * Find the trigger to delete.
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(trigOid), OIDOID);
+   ScanKeyInit(&skey[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(trigOid));
 
    tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
                                SnapshotNow, 1, skey);
@@ -641,14 +641,14 @@ renametrig(Oid relid,
    /*
     * First pass -- look for name conflict
     */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_trigger_tgname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          PointerGetDatum(newname), NAMEOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
+   ScanKeyInit(&key[1],
+               Anum_pg_trigger_tgname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               PointerGetDatum(newname));
    tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
                                SnapshotNow, 2, key);
    if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
@@ -661,14 +661,14 @@ renametrig(Oid relid,
    /*
     * Second pass -- look for trigger existing with oldname and update
     */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(relid), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_trigger_tgname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          PointerGetDatum(oldname), NAMEOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relid));
+   ScanKeyInit(&key[1],
+               Anum_pg_trigger_tgname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               PointerGetDatum(oldname));
    tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
                                SnapshotNow, 2, key);
    if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
@@ -744,11 +744,10 @@ RelationBuildTriggers(Relation relation)
     * emergency-recovery operations (ie, IsIgnoringSystemIndexes). This
     * in turn ensures that triggers will be fired in name order.
     */
-   ScanKeyEntryInitialize(&skey, 0,
-                          Anum_pg_trigger_tgrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&skey,
+               Anum_pg_trigger_tgrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    tgrel = heap_openr(TriggerRelationName, AccessShareLock);
    tgscan = systable_beginscan(tgrel, TriggerRelidNameIndex, true,
@@ -2262,10 +2261,10 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
            /*
             * Setup to scan pg_trigger by tgconstrname ...
             */
-           ScanKeyEntryInitialize(&skey, 0,
-                                  Anum_pg_trigger_tgconstrname,
-                                  BTEqualStrategyNumber, F_NAMEEQ,
-                                  PointerGetDatum(cname), NAMEOID);
+           ScanKeyInit(&skey,
+                       Anum_pg_trigger_tgconstrname,
+                       BTEqualStrategyNumber, F_NAMEEQ,
+                       PointerGetDatum(cname));
 
            tgscan = systable_beginscan(tgrel, TriggerConstrNameIndex, true,
                                        SnapshotNow, 1, &skey);
index 17b4df92179e5c15186dcd8b090f066d82f09c91..896f10470709add84cc60236b559198ade13f0ea 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.49 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.50 2003/11/12 21:15:51 tgl Exp $
  *
  * DESCRIPTION
  *   The "DefineFoo" routines take the parse tree and pick out the
@@ -1362,10 +1362,10 @@ AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior beha
    conrel = heap_openr(ConstraintRelationName, RowExclusiveLock);
 
    /* Use the index to scan only constraints of the target relation */
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_constraint_contypid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(HeapTupleGetOid(tup)), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_constraint_contypid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(HeapTupleGetOid(tup)));
 
    conscan = systable_beginscan(conrel, ConstraintTypidIndex, true,
                                 SnapshotNow, 1, key);
@@ -1615,14 +1615,14 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
     */
    depRel = relation_openr(DependRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_depend_refclassid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelOid_pg_type), OIDOID);
-   ScanKeyEntryInitialize(&key[1], 0,
-                          Anum_pg_depend_refobjid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(domainOid), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_depend_refclassid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelOid_pg_type));
+   ScanKeyInit(&key[1],
+               Anum_pg_depend_refobjid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(domainOid));
 
    depScan = systable_beginscan(depRel, DependReferenceIndex, true,
                                 SnapshotNow, 2, key);
@@ -1901,10 +1901,10 @@ GetDomainConstraints(Oid typeOid)
            notNull = true;
 
        /* Look for CHECK Constraints on this domain */
-       ScanKeyEntryInitialize(&key[0], 0,
-                              Anum_pg_constraint_contypid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(typeOid), OIDOID);
+       ScanKeyInit(&key[0],
+                   Anum_pg_constraint_contypid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(typeOid));
 
        scan = systable_beginscan(conRel, ConstraintTypidIndex, true,
                                  SnapshotNow, 1, key);
index 4fad67f43a3f208d5e830959a8f7140ab0f47d1b..869cd84792731c7e906d96601b1b685e2d35e352 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.129 2003/11/09 21:30:36 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.130 2003/11/12 21:15:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1074,10 +1074,10 @@ DropUser(DropUserStmt *stmt)
        pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
        pg_dsc = RelationGetDescr(pg_rel);
 
-       ScanKeyEntryInitialize(&scankey, 0,
-                              Anum_pg_database_datdba,
-                              BTEqualStrategyNumber, F_INT4EQ,
-                              Int32GetDatum(usesysid), INT4OID);
+       ScanKeyInit(&scankey,
+                   Anum_pg_database_datdba,
+                   BTEqualStrategyNumber, F_INT4EQ,
+                   Int32GetDatum(usesysid));
 
        scan = heap_beginscan(pg_rel, SnapshotNow, 1, &scankey);
 
index a4d6de2282c72b3dc51a87ad438781d54165c00e..c1c5d64ea2fa534ea4ed3f374c5028f482830d63 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.264 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.265 2003/11/12 21:15:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -30,7 +30,6 @@
 #include "catalog/namespace.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_index.h"
-#include "catalog/pg_type.h"
 #include "commands/vacuum.h"
 #include "executor/executor.h"
 #include "miscadmin.h"
@@ -400,10 +399,10 @@ getrels(const RangeVar *vacrel, const char *stmttype)
        HeapTuple   tuple;
        ScanKeyData key;
 
-       ScanKeyEntryInitialize(&key, 0,
-                              Anum_pg_class_relkind,
-                              BTEqualStrategyNumber, F_CHAREQ,
-                              CharGetDatum(RELKIND_RELATION), CHAROID);
+       ScanKeyInit(&key,
+                   Anum_pg_class_relkind,
+                   BTEqualStrategyNumber, F_CHAREQ,
+                   CharGetDatum(RELKIND_RELATION));
 
        pgclass = heap_openr(RelationRelationName, AccessShareLock);
 
@@ -583,10 +582,10 @@ vac_update_dbstats(Oid dbid,
    relation = heap_openr(DatabaseRelationName, RowExclusiveLock);
 
    /* Must use a heap scan, since there's no syscache for pg_database */
-   ScanKeyEntryInitialize(&entry[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(dbid), OIDOID);
+   ScanKeyInit(&entry[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(dbid));
 
    scan = heap_beginscan(relation, SnapshotNow, 1, entry);
 
index 54114ad92459f2e5b5187d63ee07f3df1d3fee84..98158a00c9c674c5b7c8915adadd2b50dd696470 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.85 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/executor/nodeIndexscan.c,v 1.86 2003/11/12 21:15:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -31,7 +31,6 @@
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
 #include "optimizer/clauses.h"
-#include "parser/parse_expr.h"
 #include "parser/parsetree.h"
 
 
@@ -615,6 +614,7 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
    IndexScanState *indexstate;
    List       *indxqual;
    List       *indxstrategy;
+   List       *indxsubtype;
    List       *indxid;
    int         i;
    int         numIndices;
@@ -711,10 +711,12 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
     */
    indxqual = node->indxqual;
    indxstrategy = node->indxstrategy;
+   indxsubtype = node->indxsubtype;
    for (i = 0; i < numIndices; i++)
    {
        List       *quals;
        List       *strategies;
+       List       *subtypes;
        int         n_keys;
        ScanKey     scan_keys;
        ExprState **run_keys;
@@ -724,6 +726,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
        indxqual = lnext(indxqual);
        strategies = lfirst(indxstrategy);
        indxstrategy = lnext(indxstrategy);
+       subtypes = lfirst(indxsubtype);
+       indxsubtype = lnext(indxsubtype);
        n_keys = length(quals);
        scan_keys = (n_keys <= 0) ? (ScanKey) NULL :
            (ScanKey) palloc(n_keys * sizeof(ScanKeyData));
@@ -742,9 +746,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
            int         flags = 0;
            AttrNumber  varattno;       /* att number used in scan */
            StrategyNumber strategy;    /* op's strategy number */
+           Oid         subtype;        /* op's strategy subtype */
            RegProcedure opfuncid;      /* operator proc id used in scan */
            Datum       scanvalue;      /* value used in scan (if const) */
-           Oid         rhstype;        /* datatype of comparison value */
 
            /*
             * extract clause information from the qualification
@@ -753,6 +757,8 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
            quals = lnext(quals);
            strategy = lfirsti(strategies);
            strategies = lnext(strategies);
+           subtype = lfirsto(subtypes);
+           subtypes = lnext(subtypes);
 
            if (!IsA(clause, OpExpr))
                elog(ERROR, "indxqual is not an OpExpr");
@@ -795,8 +801,6 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
             */
            rightop = (Expr *) get_rightop((Expr *) clause);
 
-           rhstype = exprType((Node *) rightop);
-
            if (rightop && IsA(rightop, RelabelType))
                rightop = ((RelabelType *) rightop)->arg;
 
@@ -832,9 +836,9 @@ ExecInitIndexScan(IndexScan *node, EState *estate)
                                   varattno,    /* attribute number to
                                                 * scan */
                                   strategy,    /* op's strategy */
+                                  subtype,     /* strategy subtype */
                                   opfuncid,    /* reg proc to use */
-                                  scanvalue,   /* constant */
-                                  rhstype);    /* constant's type */
+                                  scanvalue);  /* constant */
        }
 
        /*
index c02270fa2e71cd2535cc109d6731901716a53646..6cf8450567aa20e5567e64d996896d4b7502559a 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.266 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.267 2003/11/12 21:15:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -273,6 +273,17 @@ _copyIndexScan(IndexScan *from)
        }
        newnode->indxstrategy = newstrat;
    }
+   /* this can become COPY_NODE_FIELD when OID lists are normal objects: */
+   {
+       List    *newsubtype = NIL;
+       List    *tmp;
+
+       foreach(tmp, from->indxsubtype)
+       {
+           newsubtype = lappend(newsubtype, listCopy(lfirst(tmp)));
+       }
+       newnode->indxsubtype = newsubtype;
+   }
    COPY_SCALAR_FIELD(indxorderdir);
 
    return newnode;
index b2fa96bd5d26da5674947cd4aeb684f4450b2929..cb875bd6769c446da3ffaebb6cd1360573699d0f 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.219 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/nodes/outfuncs.c,v 1.220 2003/11/12 21:15:52 tgl Exp $
  *
  * NOTES
  *   Every node type that can appear in stored rules' parsetrees *must*
@@ -346,6 +346,16 @@ _outIndexScan(StringInfo str, IndexScan *node)
            _outIntList(str, lfirst(tmp));
        }
    }
+   /* this can become WRITE_NODE_FIELD when OID lists are normal objects: */
+   {
+       List    *tmp;
+
+       appendStringInfo(str, " :indxsubtype ");
+       foreach(tmp, node->indxsubtype)
+       {
+           _outOidList(str, lfirst(tmp));
+       }
+   }
    WRITE_ENUM_FIELD(indxorderdir, ScanDirection);
 }
 
index 563bd17f41d2a4ae6784f555d766014df93aac82..9c57f12ca62a654c9b91b0fcf6735dfd91453d08 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.147 2003/08/04 02:40:00 momjian Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/path/indxpath.c,v 1.148 2003/11/12 21:15:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1072,7 +1072,7 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
  *
  *  If you know, for some ATTR, that "ATTR given_op CONST1" is true, and you
  *  want to determine whether "ATTR target_op CONST2" must also be true, then
- *  you can use "CONST1 test_op CONST2" as a test.  If this test returns true,
+ *  you can use "CONST2 test_op CONST1" as a test.  If this test returns true,
  *  then the target expression must be true; if the test returns false, then
  *  the target expression may be false.
  *
@@ -1082,11 +1082,11 @@ pred_test_recurse_pred(Expr *predicate, Node *clause)
 
 static const StrategyNumber
            BT_implic_table[BTMaxStrategyNumber][BTMaxStrategyNumber] = {
-   {2, 2, 0, 0, 0},
-   {1, 2, 0, 0, 0},
-   {1, 2, 3, 4, 5},
-   {0, 0, 0, 4, 5},
-   {0, 0, 0, 4, 4}
+   {4, 4, 0, 0, 0},
+   {5, 4, 0, 0, 0},
+   {5, 4, 3, 2, 1},
+   {0, 0, 0, 2, 1},
+   {0, 0, 0, 2, 2}
 };
 
 
@@ -1118,12 +1118,13 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
               *clause_const;
    Oid         pred_op,
                clause_op,
-               test_op;
-   Oid         opclass_id = InvalidOid;
+               test_op = InvalidOid;
+   Oid         opclass_id;
    bool        found = false;
-   StrategyNumber pred_strategy = 0,
-               clause_strategy = 0,
+   StrategyNumber pred_strategy,
+               clause_strategy,
                test_strategy;
+   Oid         clause_subtype;
    Expr       *test_expr;
    ExprState  *test_exprstate;
    Datum       test_result;
@@ -1140,7 +1141,9 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
    /*
     * Can't do anything more unless they are both binary opclauses with a
     * Var on the left and a Const on the right.  (XXX someday try to
-    * commute Const/Var cases?)
+    * commute Const/Var cases?)  Note we don't have to think about binary
+    * relabeling of the Const node, since that would have been folded right
+    * into the Const.
     */
    if (!is_opclause(predicate))
        return false;
@@ -1173,14 +1176,20 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
    clause_op = ((OpExpr *) clause)->opno;
 
    /*
-    * 1. Find "btree" strategy numbers for the pred_op and clause_op.
+    * Try to find a btree opclass containing the needed operators.
     *
     * We must find a btree opclass that contains both operators, else the
-    * implication can't be determined.  If there are multiple such
-    * opclasses, assume we can use any one to determine the logical
-    * relationship of the two operators and the correct corresponding
-    * test operator.  This should work for any logically consistent
-    * opclasses.
+    * implication can't be determined.  Also, the pred_op has to be of
+    * default subtype (implying left and right input datatypes are the same);
+    * otherwise it's unsafe to put the pred_const on the left side of the
+    * test.  Also, the opclass must contain a suitable test operator
+    * matching the clause_const's type (which we take to mean that it has
+    * the same subtype as the original clause_operator).
+    *
+    * If there are multiple matching opclasses, assume we can use any one to
+    * determine the logical relationship of the two operators and the correct
+    * corresponding test operator.  This should work for any logically
+    * consistent opclasses.
     */
    catlist = SearchSysCacheList(AMOPOPID, 1,
                                 ObjectIdGetDatum(pred_op),
@@ -1192,7 +1201,13 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
        Form_pg_amop pred_form = (Form_pg_amop) GETSTRUCT(pred_tuple);
        HeapTuple   clause_tuple;
 
-       if (!opclass_is_btree(pred_form->amopclaid))
+       opclass_id = pred_form->amopclaid;
+
+       /* must be btree */
+       if (!opclass_is_btree(opclass_id))
+           continue;
+       /* predicate operator must be default within this opclass */
+       if (pred_form->amopsubtype != InvalidOid)
            continue;
 
        /* Get the predicate operator's btree strategy number */
@@ -1200,12 +1215,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
        Assert(pred_strategy >= 1 && pred_strategy <= 5);
 
        /*
-        * Remember which operator class this strategy number came from
-        */
-       opclass_id = pred_form->amopclaid;
-
-       /*
-        * From the same opclass, find a strategy num for the clause_op,
+        * From the same opclass, find a strategy number for the clause_op,
         * if possible
         */
        clause_tuple = SearchSysCache(AMOPOPID,
@@ -1216,13 +1226,35 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
        {
            Form_pg_amop clause_form = (Form_pg_amop) GETSTRUCT(clause_tuple);
 
-           /* Get the restriction clause operator's strategy number */
+           /* Get the restriction clause operator's strategy/subtype */
            clause_strategy = (StrategyNumber) clause_form->amopstrategy;
            Assert(clause_strategy >= 1 && clause_strategy <= 5);
+           clause_subtype = clause_form->amopsubtype;
 
+           /* done with clause_tuple */
            ReleaseSysCache(clause_tuple);
-           found = true;
-           break;
+
+           /*
+            * Look up the "test" strategy number in the implication table
+            */
+           test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
+           if (test_strategy == 0)
+           {
+               /* Can't determine implication using this interpretation */
+               continue;
+           }
+
+           /*
+            * See if opclass has an operator for the test strategy and the
+            * clause datatype.
+            */
+           test_op = get_opclass_member(opclass_id, clause_subtype,
+                                        test_strategy);
+           if (OidIsValid(test_op))
+           {
+               found = true;
+               break;
+           }
        }
    }
 
@@ -1235,25 +1267,7 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
    }
 
    /*
-    * 2. Look up the "test" strategy number in the implication table
-    */
-   test_strategy = BT_implic_table[clause_strategy - 1][pred_strategy - 1];
-   if (test_strategy == 0)
-       return false;           /* the implication cannot be determined */
-
-   /*
-    * 3. From the same opclass, find the operator for the test strategy
-    */
-   test_op = get_opclass_member(opclass_id, test_strategy);
-   if (!OidIsValid(test_op))
-   {
-       /* This should not fail, else pg_amop entry is missing */
-       elog(ERROR, "missing pg_amop entry for opclass %u strategy %d",
-            opclass_id, test_strategy);
-   }
-
-   /*
-    * 4. Evaluate the test.  For this we need an EState.
+    * Evaluate the test.  For this we need an EState.
     */
    estate = CreateExecutorState();
 
@@ -1264,8 +1278,8 @@ pred_test_simple_clause(Expr *predicate, Node *clause)
    test_expr = make_opclause(test_op,
                              BOOLOID,
                              false,
-                             (Expr *) clause_const,
-                             (Expr *) pred_const);
+                             (Expr *) pred_const,
+                             (Expr *) clause_const);
 
    /* Prepare it for execution */
    test_exprstate = ExecPrepareExpr(test_expr, estate);
@@ -1907,7 +1921,7 @@ match_special_index_operator(Expr *clause, Oid opclass,
  * (The latter is not depended on by any part of the planner, so far as I can
  * tell; but some parts of the executor do assume that the indxqual list
  * ultimately delivered to the executor is so ordered. One such place is
- * _bt_orderkeys() in the btree support.  Perhaps that ought to be fixed
+ * _bt_preprocess_keys() in the btree support.  Perhaps that ought to be fixed
  * someday --- tgl 7/00)
  */
 List *
@@ -2103,7 +2117,8 @@ prefix_quals(Node *leftop, Oid opclass,
     */
    if (pstatus == Pattern_Prefix_Exact)
    {
-       oproid = get_opclass_member(opclass, BTEqualStrategyNumber);
+       oproid = get_opclass_member(opclass, InvalidOid,
+                                   BTEqualStrategyNumber);
        if (oproid == InvalidOid)
            elog(ERROR, "no = operator for opclass %u", opclass);
        expr = make_opclause(oproid, BOOLOID, false,
@@ -2117,7 +2132,8 @@ prefix_quals(Node *leftop, Oid opclass,
     *
     * We can always say "x >= prefix".
     */
-   oproid = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
+   oproid = get_opclass_member(opclass, InvalidOid,
+                               BTGreaterEqualStrategyNumber);
    if (oproid == InvalidOid)
        elog(ERROR, "no >= operator for opclass %u", opclass);
    expr = make_opclause(oproid, BOOLOID, false,
@@ -2132,7 +2148,8 @@ prefix_quals(Node *leftop, Oid opclass,
    greaterstr = make_greater_string(prefix_const);
    if (greaterstr)
    {
-       oproid = get_opclass_member(opclass, BTLessStrategyNumber);
+       oproid = get_opclass_member(opclass, InvalidOid,
+                                   BTLessStrategyNumber);
        if (oproid == InvalidOid)
            elog(ERROR, "no < operator for opclass %u", opclass);
        expr = make_opclause(oproid, BOOLOID, false,
@@ -2189,13 +2206,15 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
     */
    if (is_eq)
    {
-       opr1oid = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
+       opr1oid = get_opclass_member(opclass, InvalidOid,
+                                    BTGreaterEqualStrategyNumber);
        if (opr1oid == InvalidOid)
            elog(ERROR, "no >= operator for opclass %u", opclass);
    }
    else
    {
-       opr1oid = get_opclass_member(opclass, BTGreaterStrategyNumber);
+       opr1oid = get_opclass_member(opclass, InvalidOid,
+                                    BTGreaterStrategyNumber);
        if (opr1oid == InvalidOid)
            elog(ERROR, "no > operator for opclass %u", opclass);
    }
@@ -2210,7 +2229,8 @@ network_prefix_quals(Node *leftop, Oid expr_op, Oid opclass, Datum rightop)
 
    /* create clause "key <= network_scan_last( rightop )" */
 
-   opr2oid = get_opclass_member(opclass, BTLessEqualStrategyNumber);
+   opr2oid = get_opclass_member(opclass, InvalidOid,
+                                BTLessEqualStrategyNumber);
    if (opr2oid == InvalidOid)
        elog(ERROR, "no <= operator for opclass %u", opclass);
 
index 37478d7de0ae11ca6b59c386d2ccc54143352121..a5efcb339e0a3f06f3efcd09e7b4affb2988a4c8 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.158 2003/11/09 21:30:36 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.159 2003/11/12 21:15:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,13 +63,15 @@ static HashJoin *create_hashjoin_plan(Query *root, HashPath *best_path,
 static void fix_indxqual_references(List *indexquals, IndexPath *index_path,
                        List **fixed_indexquals,
                        List **recheck_indexquals,
-                       List **indxstrategy);
+                       List **indxstrategy,
+                       List **indxsubtype);
 static void fix_indxqual_sublist(List *indexqual,
                     Relids baserelids, int baserelid,
                     IndexOptInfo *index,
                     List **fixed_quals,
                     List **recheck_quals,
-                    List **strategy);
+                    List **strategy,
+                    List **subtype);
 static Node *fix_indxqual_operand(Node *node, int baserelid,
                     IndexOptInfo *index,
                     Oid *opclass);
@@ -79,8 +81,8 @@ static void copy_path_costsize(Plan *dest, Path *src);
 static void copy_plan_costsize(Plan *dest, Plan *src);
 static SeqScan *make_seqscan(List *qptlist, List *qpqual, Index scanrelid);
 static IndexScan *make_indexscan(List *qptlist, List *qpqual, Index scanrelid,
-              List *indxid, List *indxqual,
-              List *indxqualorig, List *indxstrategy,
+              List *indxid, List *indxqual, List *indxqualorig,
+              List *indxstrategy, List *indxsubtype,
               ScanDirection indexscandir);
 static TidScan *make_tidscan(List *qptlist, List *qpqual, Index scanrelid,
             List *tideval);
@@ -704,6 +706,7 @@ create_indexscan_plan(Query *root,
    List       *fixed_indxqual;
    List       *recheck_indxqual;
    List       *indxstrategy;
+   List       *indxsubtype;
    FastList    indexids;
    List       *ixinfo;
    IndexScan  *scan_plan;
@@ -771,7 +774,7 @@ create_indexscan_plan(Query *root,
     */
    fix_indxqual_references(indxqual, best_path,
                            &fixed_indxqual, &recheck_indxqual,
-                           &indxstrategy);
+                           &indxstrategy, &indxsubtype);
 
    /*
     * If there were any "lossy" operators, need to add back the
@@ -804,6 +807,7 @@ create_indexscan_plan(Query *root,
                               fixed_indxqual,
                               indxqual,
                               indxstrategy,
+                              indxsubtype,
                               best_path->indexscandir);
 
    copy_path_costsize(&scan_plan->scan.plan, &best_path->path);
@@ -1151,8 +1155,8 @@ create_hashjoin_plan(Query *root,
  *   must add (the original form of) the indexqual clause to the "qpquals"
  *   of the indexscan node, where the operator will be re-evaluated to
  *   ensure it passes.
- * * We must construct a list of operator strategy numbers corresponding
- *   to the top-level operators of each index clause.
+ * * We must construct lists of operator strategy numbers and subtypes for
+ *   the top-level operators of each index clause.
  *
  * Both the input list and the output lists have the form of lists of sublists
  * of qual clauses --- the top-level list has one entry for each indexscan
@@ -1167,11 +1171,12 @@ create_hashjoin_plan(Query *root,
  * need rechecking.
  *
  * indxstrategy receives a list of integer sublists of strategy numbers.
+ * indxsubtype receives a list of OID sublists of strategy subtypes.
  */
 static void
 fix_indxqual_references(List *indexquals, IndexPath *index_path,
                        List **fixed_indexquals, List **recheck_indexquals,
-                       List **indxstrategy)
+                       List **indxstrategy, List **indxsubtype)
 {
    FastList    fixed_quals;
    FastList    recheck_quals;
@@ -1183,6 +1188,7 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
    FastListInit(&fixed_quals);
    FastListInit(&recheck_quals);
    *indxstrategy = NIL;
+   *indxsubtype = NIL;
    foreach(i, indexquals)
    {
        List       *indexqual = lfirst(i);
@@ -1190,13 +1196,16 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
        List       *fixed_qual;
        List       *recheck_qual;
        List       *strategy;
+       List       *subtype;
 
        fix_indxqual_sublist(indexqual, baserelids, baserelid, index,
-                            &fixed_qual, &recheck_qual, &strategy);
+                            &fixed_qual, &recheck_qual,
+                            &strategy, &subtype);
        FastAppend(&fixed_quals, fixed_qual);
        if (recheck_qual != NIL)
            FastAppend(&recheck_quals, recheck_qual);
        *indxstrategy = lappend(*indxstrategy, strategy);
+       *indxsubtype = lappend(*indxsubtype, subtype);
 
        ixinfo = lnext(ixinfo);
    }
@@ -1211,12 +1220,15 @@ fix_indxqual_references(List *indexquals, IndexPath *index_path,
  * For each qual clause, commute if needed to put the indexkey operand on the
  * left, and then fix its varattno.  (We do not need to change the other side
  * of the clause.) Also change the operator if necessary, check for
- * lossy index behavior, and determine the operator's strategy number.
+ * lossy index behavior, and determine the operator's strategy number and
+ * subtype number.
  *
- * Returns three lists: the list of fixed indexquals, the list (usually
- * empty) of original clauses that must be rechecked as qpquals because
- * the index is lossy for this operator type, and the integer list of
- * strategy numbers.
+ * Returns four lists:
+ *     the list of fixed indexquals
+ *     the list (usually empty) of original clauses that must be rechecked
+ *         as qpquals because the index is lossy for this operator type
+ *     the integer list of strategy numbers
+ *     the OID list of strategy subtypes
  */
 static void
 fix_indxqual_sublist(List *indexqual,
@@ -1224,7 +1236,8 @@ fix_indxqual_sublist(List *indexqual,
                     IndexOptInfo *index,
                     List **fixed_quals,
                     List **recheck_quals,
-                    List **strategy)
+                    List **strategy,
+                    List **subtype)
 {
    FastList    fixed_qual;
    FastList    recheck_qual;
@@ -1233,6 +1246,7 @@ fix_indxqual_sublist(List *indexqual,
    FastListInit(&fixed_qual);
    FastListInit(&recheck_qual);
    *strategy = NIL;
+   *subtype = NIL;
    foreach(i, indexqual)
    {
        OpExpr     *clause = (OpExpr *) lfirst(i);
@@ -1240,6 +1254,7 @@ fix_indxqual_sublist(List *indexqual,
        Relids      leftvarnos;
        Oid         opclass;
        int         stratno;
+       Oid         stratsubtype;
        bool        recheck;
 
        if (!IsA(clause, OpExpr) ||
@@ -1278,13 +1293,14 @@ fix_indxqual_sublist(List *indexqual,
 
        /*
         * Look up the operator in the operator class to get its strategy
-        * number and the recheck indicator.  This also double-checks that
+        * numbers and the recheck indicator.  This also double-checks that
         * we found an operator matching the index.
         */
        get_op_opclass_properties(newclause->opno, opclass,
-                                 &stratno, &recheck);
+                                 &stratno, &stratsubtype, &recheck);
 
        *strategy = lappendi(*strategy, stratno);
+       *subtype = lappendo(*subtype, stratsubtype);
 
        /*
         * If index is lossy for this operator, add (a copy of) original form
@@ -1540,6 +1556,7 @@ make_indexscan(List *qptlist,
               List *indxqual,
               List *indxqualorig,
               List *indxstrategy,
+              List *indxsubtype,
               ScanDirection indexscandir)
 {
    IndexScan  *node = makeNode(IndexScan);
@@ -1555,6 +1572,7 @@ make_indexscan(List *qptlist,
    node->indxqual = indxqual;
    node->indxqualorig = indxqualorig;
    node->indxstrategy = indxstrategy;
+   node->indxsubtype = indxsubtype;
    node->indxorderdir = indexscandir;
 
    return node;
index 8e621dd063a7f324544a4a88e657d145d626a64e..8c42b431aa33a00b2994be5c4cadf5c2669cdcc5 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.88 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/optimizer/util/plancat.c,v 1.89 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -23,7 +23,6 @@
 #include "catalog/pg_amop.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_index.h"
-#include "catalog/pg_type.h"
 #include "nodes/makefuncs.h"
 #include "optimizer/clauses.h"
 #include "optimizer/plancat.h"
@@ -329,10 +328,10 @@ find_inheritance_children(Oid inhparent)
    if (!has_subclass(inhparent))
        return NIL;
 
-   ScanKeyEntryInitialize(&key[0], 0,
-                          Anum_pg_inherits_inhparent,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(inhparent), OIDOID);
+   ScanKeyInit(&key[0],
+               Anum_pg_inherits_inhparent,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(inhparent));
    relation = heap_openr(InheritsRelationName, AccessShareLock);
    scan = heap_beginscan(relation, SnapshotNow, 1, key);
    while ((inheritsTuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
index 95b5dc37cc62afe3b7060875ec700302e5a3ec40..1068f036d1b0b969f3b332fac254a7190aad242e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.162 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.163 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1039,10 +1039,10 @@ find_inheritors(Oid relid, Oid **supervec)
    {
        /* find all types this relid inherits from, and add them to queue */
 
-       ScanKeyEntryInitialize(&skey, 0,
-                              Anum_pg_inherits_inhrelid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(relid), OIDOID);
+       ScanKeyInit(&skey,
+                   Anum_pg_inherits_inhrelid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(relid));
 
        inhscan = heap_beginscan(inhrel, SnapshotNow, 1, &skey);
 
index 53f94137e1643418d95cb504c76353e6a36f0829..0c36b127a1e944c757edb5721b2790d86fc681fa 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.57 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.58 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,7 +20,6 @@
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_rewrite.h"
-#include "catalog/pg_type.h"
 #include "miscadmin.h"
 #include "rewrite/rewriteRemove.h"
 #include "rewrite/rewriteSupport.h"
@@ -105,10 +104,10 @@ RemoveRewriteRuleById(Oid ruleOid)
    /*
     * Find the tuple for the target rule.
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(ruleOid), OIDOID);
+   ScanKeyInit(&skey[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(ruleOid));
 
    rcscan = systable_beginscan(RewriteRelation, RewriteOidIndex, true,
                                SnapshotNow, 1, skey);
index 33e40109d3edf0cd39f3b4cd7b8c02d030ce6094..f777fb33b95a776a957a1d6bc20f95672975e17b 100644 (file)
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.99 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.100 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -202,10 +202,10 @@ inv_getsize(LargeObjectDesc *obj_desc)
 
    Assert(PointerIsValid(obj_desc));
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_largeobject_loid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(obj_desc->id), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_largeobject_loid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(obj_desc->id));
 
    sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
                         SnapshotNow, 1, skey);
@@ -306,15 +306,15 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
    if (nbytes <= 0)
        return 0;
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_largeobject_loid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(obj_desc->id), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_largeobject_loid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(obj_desc->id));
 
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_largeobject_pageno,
-                          BTGreaterEqualStrategyNumber, F_INT4GE,
-                          Int32GetDatum(pageno), INT4OID);
+   ScanKeyInit(&skey[1],
+               Anum_pg_largeobject_pageno,
+               BTGreaterEqualStrategyNumber, F_INT4GE,
+               Int32GetDatum(pageno));
 
    sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
                         SnapshotNow, 2, skey);
@@ -413,15 +413,15 @@ inv_write(LargeObjectDesc *obj_desc, char *buf, int nbytes)
 
    indstate = CatalogOpenIndexes(obj_desc->heap_r);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_largeobject_loid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(obj_desc->id), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_largeobject_loid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(obj_desc->id));
 
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_largeobject_pageno,
-                          BTGreaterEqualStrategyNumber, F_INT4GE,
-                          Int32GetDatum(pageno), INT4OID);
+   ScanKeyInit(&skey[1],
+               Anum_pg_largeobject_pageno,
+               BTGreaterEqualStrategyNumber, F_INT4GE,
+               Int32GetDatum(pageno));
 
    sd = index_beginscan(obj_desc->heap_r, obj_desc->index_r,
                         SnapshotNow, 2, skey);
index 9f0fa0de32d2e971588841c72935cb8404b66d97..1493a58de742058947aa20f0cfc9471360f83e9d 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.94 2003/09/25 06:58:03 petere Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.95 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -839,6 +839,26 @@ btfloat8cmp(PG_FUNCTION_ARGS)
    PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
 }
 
+Datum
+btfloat48cmp(PG_FUNCTION_ARGS)
+{
+   float4      arg1 = PG_GETARG_FLOAT4(0);
+   float8      arg2 = PG_GETARG_FLOAT8(1);
+
+   /* widen float4 to float8 and then compare */
+   PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
+}
+
+Datum
+btfloat84cmp(PG_FUNCTION_ARGS)
+{
+   float8      arg1 = PG_GETARG_FLOAT8(0);
+   float4      arg2 = PG_GETARG_FLOAT4(1);
+
+   /* widen float4 to float8 and then compare */
+   PG_RETURN_INT32(float8_cmp_internal(arg1, arg2));
+}
+
 
 /*
  *     ===================
index 211549afeaf633d78c320c2bc5348ebb3f75c09d..ee8a00912a26763aee46c2ca53b86efb782088f4 100644 (file)
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.83 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.84 2003/11/12 21:15:54 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,10 +92,10 @@ regprocin(PG_FUNCTION_ARGS)
        SysScanDesc sysscan;
        HeapTuple   tuple;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_proc_proname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(pro_name_or_oid), NAMEOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_proc_proname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(pro_name_or_oid));
 
        hdesc = heap_openr(ProcedureRelationName, AccessShareLock);
        sysscan = systable_beginscan(hdesc, ProcedureNameNspIndex, true,
@@ -442,10 +442,10 @@ regoperin(PG_FUNCTION_ARGS)
        SysScanDesc sysscan;
        HeapTuple   tuple;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_operator_oprname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(opr_name_or_oid), NAMEOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_operator_oprname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(opr_name_or_oid));
 
        hdesc = heap_openr(OperatorRelationName, AccessShareLock);
        sysscan = systable_beginscan(hdesc, OperatorNameNspIndex, true,
@@ -820,10 +820,10 @@ regclassin(PG_FUNCTION_ARGS)
        SysScanDesc sysscan;
        HeapTuple   tuple;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_class_relname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(class_name_or_oid), NAMEOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_class_relname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(class_name_or_oid));
 
        hdesc = heap_openr(RelationRelationName, AccessShareLock);
        sysscan = systable_beginscan(hdesc, ClassNameNspIndex, true,
@@ -986,10 +986,10 @@ regtypein(PG_FUNCTION_ARGS)
        SysScanDesc sysscan;
        HeapTuple   tuple;
 
-       ScanKeyEntryInitialize(&skey[0], 0,
-                              Anum_pg_type_typname,
-                              BTEqualStrategyNumber, F_NAMEEQ,
-                              CStringGetDatum(typ_name_or_oid), NAMEOID);
+       ScanKeyInit(&skey[0],
+                   Anum_pg_type_typname,
+                   BTEqualStrategyNumber, F_NAMEEQ,
+                   CStringGetDatum(typ_name_or_oid));
 
        hdesc = heap_openr(TypeRelationName, AccessShareLock);
        sysscan = systable_beginscan(hdesc, TypeNameNspIndex, true,
index fe749cc9b12a9950117e4881f56e09d0aa6f332a..70d5626948a2802e21c4b5c9810fc94db46f2507 100644 (file)
@@ -3,7 +3,7 @@
  *             back to source text
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.158 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.159 2003/11/12 21:15:55 tgl Exp $
  *
  *   This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -488,10 +488,10 @@ pg_get_triggerdef(PG_FUNCTION_ARGS)
     */
    tgrel = heap_openr(TriggerRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(trigid), OIDOID);
+   ScanKeyInit(&skey[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(trigid));
 
    tgscan = systable_beginscan(tgrel, TriggerOidIndex, true,
                                SnapshotNow, 1, skey);
@@ -886,10 +886,10 @@ pg_get_constraintdef_worker(Oid constraintId, int prettyFlags)
     */
    conDesc = heap_openr(ConstraintRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          ObjectIdAttributeNumber,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(constraintId), OIDOID);
+   ScanKeyInit(&skey[0],
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(constraintId));
 
    conscan = systable_beginscan(conDesc, ConstraintOidIndex, true,
                                 SnapshotNow, 1, skey);
index 978c0201466b60ef6578a21431b9219deb8e6374..3c4b780c56ce35c121a633b3697283212e9e5169 100644 (file)
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.147 2003/10/16 21:37:54 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.148 2003/11/12 21:15:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -952,7 +952,8 @@ patternsel(PG_FUNCTION_ARGS, Pattern_Type ptype)
        /*
         * Pattern specifies an exact match, so pretend operator is '='
         */
-       Oid         eqopr = get_opclass_member(opclass, BTEqualStrategyNumber);
+       Oid         eqopr = get_opclass_member(opclass, InvalidOid,
+                                              BTEqualStrategyNumber);
        List       *eqargs;
 
        if (eqopr == InvalidOid)
@@ -3382,7 +3383,8 @@ prefix_selectivity(Query *root, Var *var, Oid opclass, Const *prefixcon)
    List       *cmpargs;
    Const      *greaterstrcon;
 
-   cmpopr = get_opclass_member(opclass, BTGreaterEqualStrategyNumber);
+   cmpopr = get_opclass_member(opclass, InvalidOid,
+                               BTGreaterEqualStrategyNumber);
    if (cmpopr == InvalidOid)
        elog(ERROR, "no >= operator for opclass %u", opclass);
    cmpargs = makeList2(var, prefixcon);
@@ -3403,7 +3405,8 @@ prefix_selectivity(Query *root, Var *var, Oid opclass, Const *prefixcon)
    {
        Selectivity topsel;
 
-       cmpopr = get_opclass_member(opclass, BTLessStrategyNumber);
+       cmpopr = get_opclass_member(opclass, InvalidOid,
+                                   BTLessStrategyNumber);
        if (cmpopr == InvalidOid)
            elog(ERROR, "no < operator for opclass %u", opclass);
        cmpargs = makeList2(var, greaterstrcon);
index 640629c3a04fc17933587809b21261b13b76045e..36125c2374ae0693a7cdec9a9d29abbbdea923ff 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -967,9 +967,9 @@ CatalogCacheInitializeCache(CatCache *cache)
        /* Initialize sk_attno suitably for HeapKeyTest() and heap scans */
        cache->cc_skey[i].sk_attno = cache->cc_key[i];
 
-       /* Fill in sk_strategy and sk_argtype correctly as well */
+       /* Fill in sk_strategy as well --- always standard equality */
        cache->cc_skey[i].sk_strategy = BTEqualStrategyNumber;
-       cache->cc_skey[i].sk_argtype = keytype;
+       cache->cc_skey[i].sk_subtype = InvalidOid;
 
        CACHE4_elog(DEBUG2, "CatalogCacheInit %s %d %p",
                    cache->cc_relname,
index bed4fcdbce68d250b9b71c95b49bbbc729b9214c..20c10802bc4346dfd99387f1f1ad054e9f690895 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.109 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/lsyscache.c,v 1.110 2003/11/12 21:15:55 tgl Exp $
  *
  * NOTES
  *   Eventually, the index information should go through here, too.
@@ -55,7 +55,7 @@ op_in_opclass(Oid opno, Oid opclass)
 /*
  * get_op_opclass_properties
  *
- *     Get the operator's strategy number and recheck (lossy) flag
+ *     Get the operator's strategy number, subtype, and recheck (lossy) flag
  *     within the specified opclass.
  *
  * Caller should already have verified that opno is a member of opclass,
@@ -63,7 +63,7 @@ op_in_opclass(Oid opno, Oid opclass)
  */
 void
 get_op_opclass_properties(Oid opno, Oid opclass,
-                         int *strategy, bool *recheck)
+                         int *strategy, Oid *subtype, bool *recheck)
 {
    HeapTuple   tp;
    Form_pg_amop amop_tup;
@@ -77,6 +77,7 @@ get_op_opclass_properties(Oid opno, Oid opclass,
             opno, opclass);
    amop_tup = (Form_pg_amop) GETSTRUCT(tp);
    *strategy = amop_tup->amopstrategy;
+   *subtype = amop_tup->amopsubtype;
    *recheck = amop_tup->amopreqcheck;
    ReleaseSysCache(tp);
 }
@@ -84,12 +85,12 @@ get_op_opclass_properties(Oid opno, Oid opclass,
 /*
  * get_opclass_member
  *     Get the OID of the operator that implements the specified strategy
- *     for the specified opclass.
+ *     with the specified subtype for the specified opclass.
  *
  * Returns InvalidOid if there is no pg_amop entry for the given keys.
  */
 Oid
-get_opclass_member(Oid opclass, int16 strategy)
+get_opclass_member(Oid opclass, Oid subtype, int16 strategy)
 {
    HeapTuple   tp;
    Form_pg_amop amop_tup;
@@ -97,8 +98,9 @@ get_opclass_member(Oid opclass, int16 strategy)
 
    tp = SearchSysCache(AMOPSTRATEGY,
                        ObjectIdGetDatum(opclass),
+                       ObjectIdGetDatum(subtype),
                        Int16GetDatum(strategy),
-                       0, 0);
+                       0);
    if (!HeapTupleIsValid(tp))
        return InvalidOid;
    amop_tup = (Form_pg_amop) GETSTRUCT(tp);
@@ -149,8 +151,8 @@ get_op_hash_function(Oid opno)
 
    if (OidIsValid(opclass))
    {
-       /* Found a suitable opclass, get its hash support function */
-       return get_opclass_proc(opclass, HASHPROC);
+       /* Found a suitable opclass, get its default hash support function */
+       return get_opclass_proc(opclass, InvalidOid, HASHPROC);
    }
 
    /* Didn't find a match... */
@@ -163,12 +165,12 @@ get_op_hash_function(Oid opno)
 /*
  * get_opclass_proc
  *     Get the OID of the specified support function
- *     for the specified opclass.
+ *     for the specified opclass and subtype.
  *
  * Returns InvalidOid if there is no pg_amproc entry for the given keys.
  */
 Oid
-get_opclass_proc(Oid opclass, int16 procnum)
+get_opclass_proc(Oid opclass, Oid subtype, int16 procnum)
 {
    HeapTuple   tp;
    Form_pg_amproc amproc_tup;
@@ -176,8 +178,9 @@ get_opclass_proc(Oid opclass, int16 procnum)
 
    tp = SearchSysCache(AMPROCNUM,
                        ObjectIdGetDatum(opclass),
+                       ObjectIdGetDatum(subtype),
                        Int16GetDatum(procnum),
-                       0, 0);
+                       0);
    if (!HeapTupleIsValid(tp))
        return InvalidOid;
    amproc_tup = (Form_pg_amproc) GETSTRUCT(tp);
index 88c8cbb1418154691e06adfa4a83c09b0f155a20..ac5e53a91ae5d967f0985bf3c9013835af4c881c 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.191 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.192 2003/11/12 21:15:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -262,7 +262,7 @@ do { \
 /*
  * Special cache for opclass-related information
  *
- * Note: only non-cross-type operators and support procs get cached
+ * Note: only default-subtype operators and support procs get cached
  */
 typedef struct opclasscacheent
 {
@@ -336,26 +336,23 @@ ScanPgRelation(RelationBuildDescInfo buildinfo, bool indexOK)
    switch (buildinfo.infotype)
    {
        case INFO_RELID:
-           ScanKeyEntryInitialize(&key[0], 0,
-                                  ObjectIdAttributeNumber,
-                                  BTEqualStrategyNumber, F_OIDEQ,
-                                  ObjectIdGetDatum(buildinfo.i.info_id),
-                                  OIDOID);
+           ScanKeyInit(&key[0],
+                       ObjectIdAttributeNumber,
+                       BTEqualStrategyNumber, F_OIDEQ,
+                       ObjectIdGetDatum(buildinfo.i.info_id));
            nkeys = 1;
            indexRelname = ClassOidIndex;
            break;
 
        case INFO_RELNAME:
-           ScanKeyEntryInitialize(&key[0], 0,
-                                  Anum_pg_class_relname,
-                                  BTEqualStrategyNumber, F_NAMEEQ,
-                                  NameGetDatum(buildinfo.i.info_name),
-                                  NAMEOID);
-           ScanKeyEntryInitialize(&key[1], 0,
-                                  Anum_pg_class_relnamespace,
-                                  BTEqualStrategyNumber, F_OIDEQ,
-                                  ObjectIdGetDatum(PG_CATALOG_NAMESPACE),
-                                  OIDOID);
+           ScanKeyInit(&key[0],
+                       Anum_pg_class_relname,
+                       BTEqualStrategyNumber, F_NAMEEQ,
+                       NameGetDatum(buildinfo.i.info_name));
+           ScanKeyInit(&key[1],
+                       Anum_pg_class_relnamespace,
+                       BTEqualStrategyNumber, F_OIDEQ,
+                       ObjectIdGetDatum(PG_CATALOG_NAMESPACE));
            nkeys = 2;
            indexRelname = ClassNameNspIndex;
            break;
@@ -483,15 +480,14 @@ RelationBuildTupleDesc(RelationBuildDescInfo buildinfo,
     * (Eliminating system attribute rows at the index level is lots
     * faster than fetching them.)
     */
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_attribute_attrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
-   ScanKeyEntryInitialize(&skey[1], 0,
-                          Anum_pg_attribute_attnum,
-                          BTGreaterStrategyNumber, F_INT2GT,
-                          Int16GetDatum(0), INT2OID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_attribute_attrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
+   ScanKeyInit(&skey[1],
+               Anum_pg_attribute_attnum,
+               BTGreaterStrategyNumber, F_INT2GT,
+               Int16GetDatum(0));
 
    /*
     * Open pg_attribute and begin a scan.  Force heap scan if we haven't
@@ -673,11 +669,10 @@ RelationBuildRuleLock(Relation relation)
    /*
     * form a scan key
     */
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_rewrite_ev_class,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&key,
+               Anum_pg_rewrite_ev_class,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    /*
     * open pg_rewrite and begin a scan
@@ -1058,7 +1053,7 @@ RelationInitIndexAccessInfo(Relation relation)
 
 /*
  * IndexSupportInitialize
- *     Initializes an index's cached lists of operators and support procs,
+ *     Initializes an index's cached opclass information,
  *     given the index's pg_index tuple.
  *
  * Data is returned into *indexOperator and *indexSupport, which are arrays
@@ -1131,11 +1126,9 @@ LookupOpclassInfo(Oid operatorClassOid,
 {
    OpClassCacheEnt *opcentry;
    bool        found;
-   Relation    pg_amop_desc;
-   Relation    pg_amproc_desc;
-   SysScanDesc pg_amop_scan;
-   SysScanDesc pg_amproc_scan;
-   ScanKeyData key;
+   Relation    rel;
+   SysScanDesc scan;
+   ScanKeyData skey[2];
    HeapTuple   htup;
    bool        indexOK;
 
@@ -1191,7 +1184,7 @@ LookupOpclassInfo(Oid operatorClassOid,
        opcentry->supportProcs = NULL;
 
    /*
-    * To avoid infinite recursion during startup, force a heap scan if
+    * To avoid infinite recursion during startup, force heap scans if
     * we're looking up info for the opclasses used by the indexes we
     * would like to reference here.
     */
@@ -1200,24 +1193,25 @@ LookupOpclassInfo(Oid operatorClassOid,
         operatorClassOid != INT2_BTREE_OPS_OID);
 
    /*
-    * Scan pg_amop to obtain operators for the opclass
+    * Scan pg_amop to obtain operators for the opclass.  We only fetch
+    * the default ones (those with subtype zero).
     */
    if (numStrats > 0)
    {
-       ScanKeyEntryInitialize(&key, 0,
-                              Anum_pg_amop_amopclaid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(operatorClassOid),
-                              OIDOID);
-       pg_amop_desc = heap_openr(AccessMethodOperatorRelationName,
-                                 AccessShareLock);
-       pg_amop_scan = systable_beginscan(pg_amop_desc,
-                                         AccessMethodStrategyIndex,
-                                         indexOK,
-                                         SnapshotNow,
-                                         1, &key);
-
-       while (HeapTupleIsValid(htup = systable_getnext(pg_amop_scan)))
+       ScanKeyInit(&skey[0],
+                   Anum_pg_amop_amopclaid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(operatorClassOid));
+       ScanKeyInit(&skey[1],
+                   Anum_pg_amop_amopsubtype,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(InvalidOid));
+       rel = heap_openr(AccessMethodOperatorRelationName,
+                        AccessShareLock);
+       scan = systable_beginscan(rel, AccessMethodStrategyIndex, indexOK,
+                                 SnapshotNow, 2, skey);
+
+       while (HeapTupleIsValid(htup = systable_getnext(scan)))
        {
            Form_pg_amop amopform = (Form_pg_amop) GETSTRUCT(htup);
 
@@ -1229,29 +1223,30 @@ LookupOpclassInfo(Oid operatorClassOid,
                amopform->amopopr;
        }
 
-       systable_endscan(pg_amop_scan);
-       heap_close(pg_amop_desc, AccessShareLock);
+       systable_endscan(scan);
+       heap_close(rel, AccessShareLock);
    }
 
    /*
-    * Scan pg_amproc to obtain support procs for the opclass
+    * Scan pg_amproc to obtain support procs for the opclass.  We only fetch
+    * the default ones (those with subtype zero).
     */
    if (numSupport > 0)
    {
-       ScanKeyEntryInitialize(&key, 0,
-                              Anum_pg_amproc_amopclaid,
-                              BTEqualStrategyNumber, F_OIDEQ,
-                              ObjectIdGetDatum(operatorClassOid),
-                              OIDOID);
-       pg_amproc_desc = heap_openr(AccessMethodProcedureRelationName,
-                                   AccessShareLock);
-       pg_amproc_scan = systable_beginscan(pg_amproc_desc,
-                                           AccessMethodProcedureIndex,
-                                           indexOK,
-                                           SnapshotNow,
-                                           1, &key);
-
-       while (HeapTupleIsValid(htup = systable_getnext(pg_amproc_scan)))
+       ScanKeyInit(&skey[0],
+                   Anum_pg_amproc_amopclaid,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(operatorClassOid));
+       ScanKeyInit(&skey[1],
+                   Anum_pg_amproc_amprocsubtype,
+                   BTEqualStrategyNumber, F_OIDEQ,
+                   ObjectIdGetDatum(InvalidOid));
+       rel = heap_openr(AccessMethodProcedureRelationName,
+                        AccessShareLock);
+       scan = systable_beginscan(rel, AccessMethodProcedureIndex, indexOK,
+                                 SnapshotNow, 2, skey);
+
+       while (HeapTupleIsValid(htup = systable_getnext(scan)))
        {
            Form_pg_amproc amprocform = (Form_pg_amproc) GETSTRUCT(htup);
 
@@ -1264,8 +1259,8 @@ LookupOpclassInfo(Oid operatorClassOid,
                amprocform->amproc;
        }
 
-       systable_endscan(pg_amproc_scan);
-       heap_close(pg_amproc_desc, AccessShareLock);
+       systable_endscan(scan);
+       heap_close(rel, AccessShareLock);
    }
 
    opcentry->valid = true;
@@ -2483,16 +2478,14 @@ AttrDefaultFetch(Relation relation)
    int         found;
    int         i;
 
-   ScanKeyEntryInitialize(&skey, 0,
-                          Anum_pg_attrdef_adrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&skey,
+               Anum_pg_attrdef_adrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    adrel = heap_openr(AttrDefaultRelationName, AccessShareLock);
    adscan = systable_beginscan(adrel, AttrDefaultIndex, true,
-                               SnapshotNow,
-                               1, &skey);
+                               SnapshotNow, 1, &skey);
    found = 0;
 
    while (HeapTupleIsValid(htup = systable_getnext(adscan)))
@@ -2550,11 +2543,10 @@ CheckConstraintFetch(Relation relation)
    bool        isnull;
    int         found = 0;
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_constraint_conrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_constraint_conrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    conrel = heap_openr(ConstraintRelationName, AccessShareLock);
    conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
@@ -2642,16 +2634,14 @@ RelationGetIndexList(Relation relation)
    result = NIL;
 
    /* Prepare to scan pg_index for entries having indrelid = this rel. */
-   ScanKeyEntryInitialize(&skey, 0,
-                          Anum_pg_index_indrelid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(RelationGetRelid(relation)),
-                          OIDOID);
+   ScanKeyInit(&skey,
+               Anum_pg_index_indrelid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(RelationGetRelid(relation)));
 
    indrel = heap_openr(IndexRelationName, AccessShareLock);
    indscan = systable_beginscan(indrel, IndexIndrelidIndex, true,
-                                SnapshotNow,
-                                1, &skey);
+                                SnapshotNow, 1, &skey);
 
    while (HeapTupleIsValid(htup = systable_getnext(indscan)))
    {
index 9b250eef62ec3c52a0d277a15bbf613b572a017e..eb2f6eb1af7bbd5b3722a3637399a07590c52481 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.91 2003/09/24 18:54:01 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.92 2003/11/12 21:15:56 tgl Exp $
  *
  * NOTES
  *   These routines allow the parser/planner/executor to perform
@@ -136,21 +136,21 @@ static const struct cachedesc cacheinfo[] = {
    {AccessMethodOperatorRelationName,  /* AMOPSTRATEGY */
        AccessMethodStrategyIndex,
        0,
-       2,
+       3,
        {
            Anum_pg_amop_amopclaid,
+           Anum_pg_amop_amopsubtype,
            Anum_pg_amop_amopstrategy,
-           0,
            0
    }},
    {AccessMethodProcedureRelationName, /* AMPROCNUM */
        AccessMethodProcedureIndex,
        0,
-       2,
+       3,
        {
            Anum_pg_amproc_amopclaid,
+           Anum_pg_amproc_amprocsubtype,
            Anum_pg_amproc_amprocnum,
-           0,
            0
    }},
    {AttributeRelationName,     /* ATTNAME */
index 9b7620b0f0afc248fbae301771df4bc07d2154f7..12d295c5a593727f09f81ce19d8b7516d030dcfe 100644 (file)
@@ -33,7 +33,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.2 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/cache/typcache.c,v 1.3 2003/11/12 21:15:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -158,22 +158,26 @@ lookup_type_cache(Oid type_id, int flags)
    {
        if (typentry->btree_opc != InvalidOid)
            typentry->eq_opr = get_opclass_member(typentry->btree_opc,
+                                                 InvalidOid,
                                                  BTEqualStrategyNumber);
        if (typentry->eq_opr == InvalidOid &&
            typentry->hash_opc != InvalidOid)
            typentry->eq_opr = get_opclass_member(typentry->hash_opc,
+                                                 InvalidOid,
                                                  HTEqualStrategyNumber);
    }
    if ((flags & TYPECACHE_LT_OPR) && typentry->lt_opr == InvalidOid)
    {
        if (typentry->btree_opc != InvalidOid)
            typentry->lt_opr = get_opclass_member(typentry->btree_opc,
+                                                 InvalidOid,
                                                  BTLessStrategyNumber);
    }
    if ((flags & TYPECACHE_GT_OPR) && typentry->gt_opr == InvalidOid)
    {
        if (typentry->btree_opc != InvalidOid)
            typentry->gt_opr = get_opclass_member(typentry->btree_opc,
+                                                 InvalidOid,
                                                  BTGreaterStrategyNumber);
    }
    if ((flags & (TYPECACHE_CMP_PROC | TYPECACHE_CMP_PROC_FINFO)) &&
@@ -181,6 +185,7 @@ lookup_type_cache(Oid type_id, int flags)
    {
        if (typentry->btree_opc != InvalidOid)
            typentry->cmp_proc = get_opclass_proc(typentry->btree_opc,
+                                                 InvalidOid,
                                                  BTORDER_PROC);
    }
 
@@ -248,10 +253,10 @@ lookup_default_opclass(Oid type_id, Oid am_id)
     */
    rel = heap_openr(OperatorClassRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&skey[0], 0,
-                          Anum_pg_opclass_opcamid,
-                          BTEqualStrategyNumber, F_OIDEQ,
-                          ObjectIdGetDatum(am_id), OIDOID);
+   ScanKeyInit(&skey[0],
+               Anum_pg_opclass_opcamid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(am_id));
 
    scan = systable_beginscan(rel, OpclassAmNameNspIndex, true,
                              SnapshotNow, 1, skey);
index 21e2efdda75ed8e049c6972d95fce5903ee002c3..54175189df500b270aff37ee4a9744d228f3eb21 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.128 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.129 2003/11/12 21:15:56 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -26,7 +26,6 @@
 #include "catalog/namespace.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_shadow.h"
-#include "catalog/pg_type.h"
 #include "commands/trigger.h"
 #include "mb/pg_wchar.h"
 #include "miscadmin.h"
@@ -92,10 +91,10 @@ ReverifyMyDatabase(const char *name)
     */
    pgdbrel = heap_openr(DatabaseRelationName, AccessShareLock);
 
-   ScanKeyEntryInitialize(&key, 0,
-                          Anum_pg_database_datname,
-                          BTEqualStrategyNumber, F_NAMEEQ,
-                          NameGetDatum(name), NAMEOID);
+   ScanKeyInit(&key,
+               Anum_pg_database_datname,
+               BTEqualStrategyNumber, F_NAMEEQ,
+               NameGetDatum(name));
 
    pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
 
index 9b3c0bb4075eb0bd6e7acec6dba2c2d43b5c993c..a6accb5db4d8c3ad0c379b34e20072680a4d9603 100644 (file)
@@ -78,7 +78,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *   $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.38 2003/11/09 21:30:37 tgl Exp $
+ *   $Header: /cvsroot/pgsql/src/backend/utils/sort/tuplesort.c,v 1.39 2003/11/12 21:15:56 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -472,15 +472,14 @@ tuplesort_begin_heap(TupleDesc tupDesc,
                           &state->sortFnKinds[i]);
 
        /*
-        * We needn't fill in sk_strategy or sk_argtype since these scankeys
+        * We needn't fill in sk_strategy or sk_subtype since these scankeys
         * will never be passed to an index.
         */
-       ScanKeyEntryInitialize(&state->scanKeys[i], 0,
-                              attNums[i],
-                              InvalidStrategy,
-                              sortFunction,
-                              (Datum) 0,
-                              InvalidOid);
+       ScanKeyInit(&state->scanKeys[i],
+                   attNums[i],
+                   InvalidStrategy,
+                   sortFunction,
+                   (Datum) 0);
    }
 
    return state;
@@ -1739,6 +1738,10 @@ SelectSortFunction(Oid sortOperator,
 
        if (!opclass_is_btree(aform->amopclaid))
            continue;
+       /* must be of default subtype, too */
+       if (aform->amopsubtype != InvalidOid)
+           continue;
+
        if (aform->amopstrategy == BTLessStrategyNumber)
        {
            opclass = aform->amopclaid;
@@ -1757,8 +1760,8 @@ SelectSortFunction(Oid sortOperator,
 
    if (OidIsValid(opclass))
    {
-       /* Found a suitable opclass, get its comparator support function */
-       *sortFunction = get_opclass_proc(opclass, BTORDER_PROC);
+       /* Found a suitable opclass, get its default comparator function */
+       *sortFunction = get_opclass_proc(opclass, InvalidOid, BTORDER_PROC);
        Assert(RegProcedureIsValid(*sortFunction));
        return;
    }
index 80d412a52e59004c0b7f055ef28d027026cc246f..2d75fa5b23f01d218f20f3d8fb1d36bee3d0eecb 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nbtree.h,v 1.72 2003/11/09 21:30:37 tgl Exp $
+ * $Id: nbtree.h,v 1.73 2003/11/12 21:15:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -341,7 +341,7 @@ typedef struct xl_btree_newpage
 
 /*
  * Operator strategy numbers for B-tree have been moved to access/skey.h,
- * because many places need to use them in ScanKeyEntryInitialize() calls.
+ * because many places need to use them in ScanKeyInit() calls.
  */
 
 /*
@@ -404,12 +404,12 @@ typedef struct BTScanOpaqueData
    Buffer      btso_mrkbuf;
    ItemPointerData curHeapIptr;
    ItemPointerData mrkHeapIptr;
-   /* these fields are set by _bt_orderkeys(), which see for more info: */
+   /* these fields are set by _bt_preprocess_keys(): */
    bool        qual_ok;        /* false if qual can never be satisfied */
-   int         numberOfKeys;   /* number of scan keys */
+   int         numberOfKeys;   /* number of preprocessed scan keys */
    int         numberOfRequiredKeys;   /* number of keys that must be
                                         * matched to continue the scan */
-   ScanKey     keyData;        /* array of scan keys */
+   ScanKey     keyData;        /* array of preprocessed scan keys */
 } BTScanOpaqueData;
 
 typedef BTScanOpaqueData *BTScanOpaque;
@@ -424,7 +424,6 @@ extern Datum btinsert(PG_FUNCTION_ARGS);
 extern Datum btgettuple(PG_FUNCTION_ARGS);
 extern Datum btbeginscan(PG_FUNCTION_ARGS);
 extern Datum btrescan(PG_FUNCTION_ARGS);
-extern void btmovescan(IndexScanDesc scan, Datum v);
 extern Datum btendscan(PG_FUNCTION_ARGS);
 extern Datum btmarkpos(PG_FUNCTION_ARGS);
 extern Datum btrestrpos(PG_FUNCTION_ARGS);
@@ -480,7 +479,7 @@ extern ScanKey _bt_mkscankey(Relation rel, IndexTuple itup);
 extern ScanKey _bt_mkscankey_nodata(Relation rel);
 extern void _bt_freeskey(ScanKey skey);
 extern void _bt_freestack(BTStack stack);
-extern void _bt_orderkeys(IndexScanDesc scan);
+extern void _bt_preprocess_keys(IndexScanDesc scan);
 extern bool _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
              ScanDirection dir, bool *continuescan);
 extern BTItem _bt_formitem(IndexTuple itup);
index b7373dd641064655de278c7b1a43c80c1d0f55e0..5cce3249fb57fa1f5acf8f5e07513a4d2e44766e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: skey.h,v 1.23 2003/11/09 21:30:37 tgl Exp $
+ * $Id: skey.h,v 1.24 2003/11/12 21:15:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -20,7 +20,8 @@
 
 /*
  * Strategy numbers identify the semantics that particular operators have
- * with respect to particular operator classes.
+ * with respect to particular operator classes.  In some cases a strategy
+ * subtype (an OID) is used as further information.
  */
 typedef uint16 StrategyNumber;
 
@@ -47,23 +48,23 @@ typedef uint16 StrategyNumber;
  * (The data structure can support unary indexable operators too; in that
  * case sk_argument would go unused.  This is not currently implemented.)
  *
- * For an index scan, sk_strategy must be set correctly for the operator.
- * When using a ScanKey in a heap scan, sk_strategy is not used and may be
- * set to InvalidStrategy.
+ * For an index scan, sk_strategy and sk_subtype must be set correctly for
+ * the operator.  When using a ScanKey in a heap scan, these fields are not
+ * used and may be set to InvalidStrategy/InvalidOid.
  *
  * Note: in some places, ScanKeys are used as a convenient representation
  * for the invocation of an access method support procedure.  In this case
- * sk_strategy is not meaningful, and sk_func may refer to a function that
- * returns something other than boolean.
+ * sk_strategy/sk_subtype are not meaningful, and sk_func may refer to a
+ * function that returns something other than boolean.
  */
 typedef struct ScanKeyData
 {
    int         sk_flags;       /* flags, see below */
    AttrNumber  sk_attno;       /* table or index column number */
    StrategyNumber sk_strategy; /* operator strategy number */
+   Oid         sk_subtype;     /* strategy subtype */
    FmgrInfo    sk_func;        /* lookup info for function to call */
    Datum       sk_argument;    /* data to compare */
-   Oid         sk_argtype;     /* datatype of sk_argument */
 } ScanKeyData;
 
 typedef ScanKeyData *ScanKey;
@@ -76,19 +77,24 @@ typedef ScanKeyData *ScanKey;
 /*
  * prototypes for functions in access/common/scankey.c
  */
+extern void ScanKeyInit(ScanKey entry,
+                       AttrNumber attributeNumber,
+                       StrategyNumber strategy,
+                       RegProcedure procedure,
+                       Datum argument);
 extern void ScanKeyEntryInitialize(ScanKey entry,
                                   int flags,
                                   AttrNumber attributeNumber,
                                   StrategyNumber strategy,
+                                  Oid subtype,
                                   RegProcedure procedure,
-                                  Datum argument,
-                                  Oid argtype);
+                                  Datum argument);
 extern void ScanKeyEntryInitializeWithInfo(ScanKey entry,
                                           int flags,
                                           AttrNumber attributeNumber,
                                           StrategyNumber strategy,
+                                          Oid subtype,
                                           FmgrInfo *finfo,
-                                          Datum argument,
-                                          Oid argtype);
+                                          Datum argument);
 
 #endif   /* SKEY_H */
index 9efcfe447d5bf03ff41e86d9bd5f0060f8b26c5e..8209b34880d9027e40a47fea09cf4ba009de938e 100644 (file)
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.210 2003/10/21 16:23:16 tgl Exp $
+ * $Id: catversion.h,v 1.211 2003/11/12 21:15:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*                         yyyymmddN */
-#define CATALOG_VERSION_NO 200310211
+#define CATALOG_VERSION_NO 200311101
 
 #endif
index 1150f1e47c5a3f1db1172d0ea12e7c6b5db2da14..720c8eec0a9e56aa41589c19c2995ba07f75c084 100644 (file)
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: indexing.h,v 1.79 2003/08/04 02:40:10 momjian Exp $
+ * $Id: indexing.h,v 1.80 2003/11/12 21:15:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -24,8 +24,8 @@
  * macros rather than hardwiring the actual index name.
  */
 #define AccessMethodOperatorIndex  "pg_amop_opr_opc_index"
-#define AccessMethodStrategyIndex  "pg_amop_opc_strategy_index"
-#define AccessMethodProcedureIndex "pg_amproc_opc_procnum_index"
+#define AccessMethodStrategyIndex  "pg_amop_opc_strat_index"
+#define AccessMethodProcedureIndex "pg_amproc_opc_proc_index"
 #define AggregateFnoidIndex            "pg_aggregate_fnoid_index"
 #define AmNameIndex                    "pg_am_name_index"
 #define AmOidIndex                 "pg_am_oid_index"
@@ -115,9 +115,9 @@ extern void CatalogUpdateIndexes(Relation heapRel, HeapTuple heapTuple);
 DECLARE_UNIQUE_INDEX(pg_aggregate_fnoid_index on pg_aggregate using btree(aggfnoid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
 DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
+DECLARE_UNIQUE_INDEX(pg_amop_opc_strat_index on pg_amop using btree(amopclaid oid_ops, amopsubtype oid_ops, amopstrategy int2_ops));
 DECLARE_UNIQUE_INDEX(pg_amop_opr_opc_index on pg_amop using btree(amopopr oid_ops, amopclaid oid_ops));
-DECLARE_UNIQUE_INDEX(pg_amop_opc_strategy_index on pg_amop using btree(amopclaid oid_ops, amopstrategy int2_ops));
-DECLARE_UNIQUE_INDEX(pg_amproc_opc_procnum_index on pg_amproc using btree(amopclaid oid_ops, amprocnum int2_ops));
+DECLARE_UNIQUE_INDEX(pg_amproc_opc_proc_index on pg_amproc using btree(amopclaid oid_ops, amprocsubtype oid_ops, amprocnum int2_ops));
 DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
 DECLARE_UNIQUE_INDEX(pg_attrdef_oid_index on pg_attrdef using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
index 7e70d726d14832c1e761039828e4b16256d111ca..746b9bfb6d1d9188e6e490730cb567dba34e045e 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: namespace.h,v 1.27 2003/08/04 02:40:10 momjian Exp $
+ * $Id: namespace.h,v 1.28 2003/11/12 21:15:57 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,9 +42,9 @@ typedef struct _OpclassCandidateList
    char       *opcname_tmp;    /* for internal use of namespace lookup */
    int         pathpos;        /* for internal use of namespace lookup */
    Oid         oid;            /* the opclass's OID */
-   Oid         opcintype;      /* type of input data for opclass */
+   Oid         opcintype;      /* type of data indexed by opclass */
    bool        opcdefault;     /* T if opclass is default for opcintype */
-   Oid         opckeytype;     /* type of index data, or InvalidOid */
+   Oid         opckeytype;     /* type of data in index, or InvalidOid */
 }  *OpclassCandidateList;
 
 
index bff4b21700341afa95aedeb7b11872a72cc1493a..1bab599fdb42ec44a29f42d51b68428d3a706888 100644 (file)
@@ -6,17 +6,24 @@
  *
  * The amop table identifies the operators associated with each index opclass.
  *
- * Note: the primary key for this table is .
+ * The primary key for this table is .
+ * amopsubtype is equal to zero for an opclass's "default" operators
+ * (which normally are those that accept the opclass's opcintype on both
+ * left and right sides).  Some index AMs allow nondefault operators to
+ * exist for a single strategy --- for example, in the btree AM nondefault
+ * operators can have right-hand input data types different from opcintype,
+ * and their amopsubtype is equal to the right-hand input data type.
+ *
  * We also keep a unique index on , so that we can
  * use a syscache to quickly answer questions of the form "is this operator
  * in this opclass?".  This implies that the same operator cannot be listed
- * for multiple strategy numbers of a single opclass.
+ * for multiple subtypes or strategy numbers of a single opclass.
  *
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_amop.h,v 1.55 2003/08/17 19:58:06 tgl Exp $
+ * $Id: pg_amop.h,v 1.56 2003/11/12 21:15:57 tgl Exp $
  *
  * NOTES
  *  the genbki.sh script reads this file and generates .bki
@@ -42,6 +49,7 @@
 CATALOG(pg_amop) BKI_WITHOUT_OIDS
 {
    Oid         amopclaid;      /* the index opclass this entry is for */
+   Oid         amopsubtype;    /* operator subtype, or zero if default */
    int2        amopstrategy;   /* operator strategy number */
    bool        amopreqcheck;   /* index hit must be rechecked */
    Oid         amopopr;        /* the operator's pg_operator OID */
@@ -58,11 +66,12 @@ typedef FormData_pg_amop *Form_pg_amop;
  *     compiler constants for pg_amop
  * ----------------
  */
-#define Natts_pg_amop                  4
+#define Natts_pg_amop                  5
 #define Anum_pg_amop_amopclaid         1
-#define Anum_pg_amop_amopstrategy      2
-#define Anum_pg_amop_amopreqcheck      3
-#define Anum_pg_amop_amopopr           4
+#define Anum_pg_amop_amopsubtype       2
+#define Anum_pg_amop_amopstrategy      3
+#define Anum_pg_amop_amopreqcheck      4
+#define Anum_pg_amop_amopopr           5
 
 /* ----------------
  *     initial contents of pg_amop
@@ -73,460 +82,495 @@ typedef FormData_pg_amop *Form_pg_amop;
  * rtree box_ops
  */
 
-DATA(insert (   425 1 f  493 ));
-DATA(insert (   425 2 f  494 ));
-DATA(insert (   425 3 f  500 ));
-DATA(insert (   425 4 f  495 ));
-DATA(insert (   425 5 f  496 ));
-DATA(insert (   425 6 f  499 ));
-DATA(insert (   425 7 f  498 ));
-DATA(insert (   425 8 f  497 ));
-
-/*
- * rtree bigbox_ops
- */
-
-DATA(insert (   422 1 f  493 ));
-DATA(insert (   422 2 f  494 ));
-DATA(insert (   422 3 f  500 ));
-DATA(insert (   422 4 f  495 ));
-DATA(insert (   422 5 f  496 ));
-DATA(insert (   422 6 f  499 ));
-DATA(insert (   422 7 f  498 ));
-DATA(insert (   422 8 f  497 ));
+DATA(insert (   425    0 1 f  493 ));
+DATA(insert (   425    0 2 f  494 ));
+DATA(insert (   425    0 3 f  500 ));
+DATA(insert (   425    0 4 f  495 ));
+DATA(insert (   425    0 5 f  496 ));
+DATA(insert (   425    0 6 f  499 ));
+DATA(insert (   425    0 7 f  498 ));
+DATA(insert (   425    0 8 f  497 ));
 
 /*
  * rtree poly_ops (supports polygons)
  */
 
-DATA(insert (  1993 1 f  485 ));
-DATA(insert (  1993 2 f  486 ));
-DATA(insert (  1993 3 f  492 ));
-DATA(insert (  1993 4 f  487 ));
-DATA(insert (  1993 5 f  488 ));
-DATA(insert (  1993 6 f  491 ));
-DATA(insert (  1993 7 f  490 ));
-DATA(insert (  1993 8 f  489 ));
+DATA(insert (  1993    0 1 f  485 ));
+DATA(insert (  1993    0 2 f  486 ));
+DATA(insert (  1993    0 3 f  492 ));
+DATA(insert (  1993    0 4 f  487 ));
+DATA(insert (  1993    0 5 f  488 ));
+DATA(insert (  1993    0 6 f  491 ));
+DATA(insert (  1993    0 7 f  490 ));
+DATA(insert (  1993    0 8 f  489 ));
 
 /*
  * btree int2_ops
  */
 
-DATA(insert (  1976 1 f   95 ));
-DATA(insert (  1976 2 f  522 ));
-DATA(insert (  1976 3 f   94 ));
-DATA(insert (  1976 4 f  524 ));
-DATA(insert (  1976 5 f  520 ));
+DATA(insert (  1976    0 1 f   95 ));
+DATA(insert (  1976    0 2 f  522 ));
+DATA(insert (  1976    0 3 f   94 ));
+DATA(insert (  1976    0 4 f  524 ));
+DATA(insert (  1976    0 5 f  520 ));
+/* crosstype operators int24 */
+DATA(insert (  1976   23 1 f  534 ));
+DATA(insert (  1976   23 2 f  540 ));
+DATA(insert (  1976   23 3 f  532 ));
+DATA(insert (  1976   23 4 f  542 ));
+DATA(insert (  1976   23 5 f  536 ));
+/* crosstype operators int28 */
+DATA(insert (  1976   20 1 f  1864 ));
+DATA(insert (  1976   20 2 f  1866 ));
+DATA(insert (  1976   20 3 f  1862 ));
+DATA(insert (  1976   20 4 f  1867 ));
+DATA(insert (  1976   20 5 f  1865 ));
 
 /*
  * btree int4_ops
  */
 
-DATA(insert (  1978 1 f   97 ));
-DATA(insert (  1978 2 f  523 ));
-DATA(insert (  1978 3 f   96 ));
-DATA(insert (  1978 4 f  525 ));
-DATA(insert (  1978 5 f  521 ));
+DATA(insert (  1978    0 1 f   97 ));
+DATA(insert (  1978    0 2 f  523 ));
+DATA(insert (  1978    0 3 f   96 ));
+DATA(insert (  1978    0 4 f  525 ));
+DATA(insert (  1978    0 5 f  521 ));
+/* crosstype operators int42 */
+DATA(insert (  1978   21 1 f  535 ));
+DATA(insert (  1978   21 2 f  541 ));
+DATA(insert (  1978   21 3 f  533 ));
+DATA(insert (  1978   21 4 f  543 ));
+DATA(insert (  1978   21 5 f  537 ));
+/* crosstype operators int48 */
+DATA(insert (  1978   20 1 f   37 ));
+DATA(insert (  1978   20 2 f   80 ));
+DATA(insert (  1978   20 3 f   15 ));
+DATA(insert (  1978   20 4 f   82 ));
+DATA(insert (  1978   20 5 f   76 ));
 
 /*
  * btree int8_ops
  */
 
-DATA(insert (  1980 1 f  412 ));
-DATA(insert (  1980 2 f  414 ));
-DATA(insert (  1980 3 f  410 ));
-DATA(insert (  1980 4 f  415 ));
-DATA(insert (  1980 5 f  413 ));
+DATA(insert (  1980    0 1 f  412 ));
+DATA(insert (  1980    0 2 f  414 ));
+DATA(insert (  1980    0 3 f  410 ));
+DATA(insert (  1980    0 4 f  415 ));
+DATA(insert (  1980    0 5 f  413 ));
+/* crosstype operators int82 */
+DATA(insert (  1980   21 1 f  1870 ));
+DATA(insert (  1980   21 2 f  1872 ));
+DATA(insert (  1980   21 3 f  1868 ));
+DATA(insert (  1980   21 4 f  1873 ));
+DATA(insert (  1980   21 5 f  1871 ));
+/* crosstype operators int84 */
+DATA(insert (  1980   23 1 f  418 ));
+DATA(insert (  1980   23 2 f  420 ));
+DATA(insert (  1980   23 3 f  416 ));
+DATA(insert (  1980   23 4 f  430 ));
+DATA(insert (  1980   23 5 f  419 ));
 
 /*
  * btree oid_ops
  */
 
-DATA(insert (  1989 1 f  609 ));
-DATA(insert (  1989 2 f  611 ));
-DATA(insert (  1989 3 f  607 ));
-DATA(insert (  1989 4 f  612 ));
-DATA(insert (  1989 5 f  610 ));
+DATA(insert (  1989    0 1 f  609 ));
+DATA(insert (  1989    0 2 f  611 ));
+DATA(insert (  1989    0 3 f  607 ));
+DATA(insert (  1989    0 4 f  612 ));
+DATA(insert (  1989    0 5 f  610 ));
 
 /*
  * btree oidvector_ops
  */
 
-DATA(insert (  1991 1 f  645 ));
-DATA(insert (  1991 2 f  647 ));
-DATA(insert (  1991 3 f  649 ));
-DATA(insert (  1991 4 f  648 ));
-DATA(insert (  1991 5 f  646 ));
+DATA(insert (  1991    0 1 f  645 ));
+DATA(insert (  1991    0 2 f  647 ));
+DATA(insert (  1991    0 3 f  649 ));
+DATA(insert (  1991    0 4 f  648 ));
+DATA(insert (  1991    0 5 f  646 ));
 
 /*
  * btree float4_ops
  */
 
-DATA(insert (  1970 1 f  622 ));
-DATA(insert (  1970 2 f  624 ));
-DATA(insert (  1970 3 f  620 ));
-DATA(insert (  1970 4 f  625 ));
-DATA(insert (  1970 5 f  623 ));
+DATA(insert (  1970    0 1 f  622 ));
+DATA(insert (  1970    0 2 f  624 ));
+DATA(insert (  1970    0 3 f  620 ));
+DATA(insert (  1970    0 4 f  625 ));
+DATA(insert (  1970    0 5 f  623 ));
+/* crosstype operators float48 */
+DATA(insert (  1970  701 1 f  1122 ));
+DATA(insert (  1970  701 2 f  1124 ));
+DATA(insert (  1970  701 3 f  1120 ));
+DATA(insert (  1970  701 4 f  1125 ));
+DATA(insert (  1970  701 5 f  1123 ));
 
 /*
  * btree float8_ops
  */
 
-DATA(insert (  1972 1 f  672 ));
-DATA(insert (  1972 2 f  673 ));
-DATA(insert (  1972 3 f  670 ));
-DATA(insert (  1972 4 f  675 ));
-DATA(insert (  1972 5 f  674 ));
+DATA(insert (  1972    0 1 f  672 ));
+DATA(insert (  1972    0 2 f  673 ));
+DATA(insert (  1972    0 3 f  670 ));
+DATA(insert (  1972    0 4 f  675 ));
+DATA(insert (  1972    0 5 f  674 ));
+/* crosstype operators float84 */
+DATA(insert (  1972  700 1 f  1132 ));
+DATA(insert (  1972  700 2 f  1134 ));
+DATA(insert (  1972  700 3 f  1130 ));
+DATA(insert (  1972  700 4 f  1135 ));
+DATA(insert (  1972  700 5 f  1133 ));
 
 /*
  * btree char_ops
  */
 
-DATA(insert (   429 1 f  631 ));
-DATA(insert (   429 2 f  632 ));
-DATA(insert (   429 3 f   92 ));
-DATA(insert (   429 4 f  634 ));
-DATA(insert (   429 5 f  633 ));
+DATA(insert (   429    0 1 f  631 ));
+DATA(insert (   429    0 2 f  632 ));
+DATA(insert (   429    0 3 f   92 ));
+DATA(insert (   429    0 4 f  634 ));
+DATA(insert (   429    0 5 f  633 ));
 
 /*
  * btree name_ops
  */
 
-DATA(insert (  1986 1 f  660 ));
-DATA(insert (  1986 2 f  661 ));
-DATA(insert (  1986 3 f   93 ));
-DATA(insert (  1986 4 f  663 ));
-DATA(insert (  1986 5 f  662 ));
+DATA(insert (  1986    0 1 f  660 ));
+DATA(insert (  1986    0 2 f  661 ));
+DATA(insert (  1986    0 3 f   93 ));
+DATA(insert (  1986    0 4 f  663 ));
+DATA(insert (  1986    0 5 f  662 ));
 
 /*
  * btree text_ops
  */
 
-DATA(insert (  1994 1 f  664 ));
-DATA(insert (  1994 2 f  665 ));
-DATA(insert (  1994 3 f   98 ));
-DATA(insert (  1994 4 f  667 ));
-DATA(insert (  1994 5 f  666 ));
+DATA(insert (  1994    0 1 f  664 ));
+DATA(insert (  1994    0 2 f  665 ));
+DATA(insert (  1994    0 3 f   98 ));
+DATA(insert (  1994    0 4 f  667 ));
+DATA(insert (  1994    0 5 f  666 ));
 
 /*
  * btree bpchar_ops
  */
 
-DATA(insert (   426 1 f 1058 ));
-DATA(insert (   426 2 f 1059 ));
-DATA(insert (   426 3 f 1054 ));
-DATA(insert (   426 4 f 1061 ));
-DATA(insert (   426 5 f 1060 ));
+DATA(insert (   426    0 1 f 1058 ));
+DATA(insert (   426    0 2 f 1059 ));
+DATA(insert (   426    0 3 f 1054 ));
+DATA(insert (   426    0 4 f 1061 ));
+DATA(insert (   426    0 5 f 1060 ));
 
 /*
  * btree varchar_ops (same operators as text_ops)
  */
 
-DATA(insert (  2003 1 f 664 ));
-DATA(insert (  2003 2 f 665 ));
-DATA(insert (  2003 3 f  98 ));
-DATA(insert (  2003 4 f 667 ));
-DATA(insert (  2003 5 f 666 ));
+DATA(insert (  2003    0 1 f 664 ));
+DATA(insert (  2003    0 2 f 665 ));
+DATA(insert (  2003    0 3 f  98 ));
+DATA(insert (  2003    0 4 f 667 ));
+DATA(insert (  2003    0 5 f 666 ));
 
 /*
  * btree bytea_ops
  */
 
-DATA(insert (   428 1 f 1957 ));
-DATA(insert (   428 2 f 1958 ));
-DATA(insert (   428 3 f 1955 ));
-DATA(insert (   428 4 f 1960 ));
-DATA(insert (   428 5 f 1959 ));
+DATA(insert (   428    0 1 f 1957 ));
+DATA(insert (   428    0 2 f 1958 ));
+DATA(insert (   428    0 3 f 1955 ));
+DATA(insert (   428    0 4 f 1960 ));
+DATA(insert (   428    0 5 f 1959 ));
 
 /*
  * btree abstime_ops
  */
 
-DATA(insert (   421 1 f  562 ));
-DATA(insert (   421 2 f  564 ));
-DATA(insert (   421 3 f  560 ));
-DATA(insert (   421 4 f  565 ));
-DATA(insert (   421 5 f  563 ));
+DATA(insert (   421    0 1 f  562 ));
+DATA(insert (   421    0 2 f  564 ));
+DATA(insert (   421    0 3 f  560 ));
+DATA(insert (   421    0 4 f  565 ));
+DATA(insert (   421    0 5 f  563 ));
 
 /*
  * btree date_ops
  */
 
-DATA(insert (   434 1 f 1095 ));
-DATA(insert (   434 2 f 1096 ));
-DATA(insert (   434 3 f 1093 ));
-DATA(insert (   434 4 f 1098 ));
-DATA(insert (   434 5 f 1097 ));
+DATA(insert (   434    0 1 f 1095 ));
+DATA(insert (   434    0 2 f 1096 ));
+DATA(insert (   434    0 3 f 1093 ));
+DATA(insert (   434    0 4 f 1098 ));
+DATA(insert (   434    0 5 f 1097 ));
 
 /*
  * btree time_ops
  */
 
-DATA(insert (  1996 1 f 1110 ));
-DATA(insert (  1996 2 f 1111 ));
-DATA(insert (  1996 3 f 1108 ));
-DATA(insert (  1996 4 f 1113 ));
-DATA(insert (  1996 5 f 1112 ));
+DATA(insert (  1996    0 1 f 1110 ));
+DATA(insert (  1996    0 2 f 1111 ));
+DATA(insert (  1996    0 3 f 1108 ));
+DATA(insert (  1996    0 4 f 1113 ));
+DATA(insert (  1996    0 5 f 1112 ));
 
 /*
  * btree timetz_ops
  */
 
-DATA(insert (  2000 1 f 1552 ));
-DATA(insert (  2000 2 f 1553 ));
-DATA(insert (  2000 3 f 1550 ));
-DATA(insert (  2000 4 f 1555 ));
-DATA(insert (  2000 5 f 1554 ));
+DATA(insert (  2000    0 1 f 1552 ));
+DATA(insert (  2000    0 2 f 1553 ));
+DATA(insert (  2000    0 3 f 1550 ));
+DATA(insert (  2000    0 4 f 1555 ));
+DATA(insert (  2000    0 5 f 1554 ));
 
 /*
  * btree timestamp_ops
  */
 
-DATA(insert (  2039 1 f 2062 ));
-DATA(insert (  2039 2 f 2063 ));
-DATA(insert (  2039 3 f 2060 ));
-DATA(insert (  2039 4 f 2065 ));
-DATA(insert (  2039 5 f 2064 ));
+DATA(insert (  2039    0 1 f 2062 ));
+DATA(insert (  2039    0 2 f 2063 ));
+DATA(insert (  2039    0 3 f 2060 ));
+DATA(insert (  2039    0 4 f 2065 ));
+DATA(insert (  2039    0 5 f 2064 ));
 
 /*
  * btree timestamptz_ops
  */
 
-DATA(insert (  1998 1 f 1322 ));
-DATA(insert (  1998 2 f 1323 ));
-DATA(insert (  1998 3 f 1320 ));
-DATA(insert (  1998 4 f 1325 ));
-DATA(insert (  1998 5 f 1324 ));
+DATA(insert (  1998    0 1 f 1322 ));
+DATA(insert (  1998    0 2 f 1323 ));
+DATA(insert (  1998    0 3 f 1320 ));
+DATA(insert (  1998    0 4 f 1325 ));
+DATA(insert (  1998    0 5 f 1324 ));
 
 /*
  * btree interval_ops
  */
 
-DATA(insert (  1982 1 f 1332 ));
-DATA(insert (  1982 2 f 1333 ));
-DATA(insert (  1982 3 f 1330 ));
-DATA(insert (  1982 4 f 1335 ));
-DATA(insert (  1982 5 f 1334 ));
+DATA(insert (  1982    0 1 f 1332 ));
+DATA(insert (  1982    0 2 f 1333 ));
+DATA(insert (  1982    0 3 f 1330 ));
+DATA(insert (  1982    0 4 f 1335 ));
+DATA(insert (  1982    0 5 f 1334 ));
 
 /*
  * btree macaddr
  */
 
-DATA(insert (  1984 1 f 1222 ));
-DATA(insert (  1984 2 f 1223 ));
-DATA(insert (  1984 3 f 1220 ));
-DATA(insert (  1984 4 f 1225 ));
-DATA(insert (  1984 5 f 1224 ));
+DATA(insert (  1984    0 1 f 1222 ));
+DATA(insert (  1984    0 2 f 1223 ));
+DATA(insert (  1984    0 3 f 1220 ));
+DATA(insert (  1984    0 4 f 1225 ));
+DATA(insert (  1984    0 5 f 1224 ));
 
 /*
  * btree inet
  */
 
-DATA(insert (  1974 1 f 1203 ));
-DATA(insert (  1974 2 f 1204 ));
-DATA(insert (  1974 3 f 1201 ));
-DATA(insert (  1974 4 f 1206 ));
-DATA(insert (  1974 5 f 1205 ));
+DATA(insert (  1974    0 1 f 1203 ));
+DATA(insert (  1974    0 2 f 1204 ));
+DATA(insert (  1974    0 3 f 1201 ));
+DATA(insert (  1974    0 4 f 1206 ));
+DATA(insert (  1974    0 5 f 1205 ));
 
 /*
  * btree cidr
  */
 
-DATA(insert (   432 1 f  822 ));
-DATA(insert (   432 2 f  823 ));
-DATA(insert (   432 3 f  820 ));
-DATA(insert (   432 4 f  825 ));
-DATA(insert (   432 5 f  824 ));
+DATA(insert (   432    0 1 f  822 ));
+DATA(insert (   432    0 2 f  823 ));
+DATA(insert (   432    0 3 f  820 ));
+DATA(insert (   432    0 4 f  825 ));
+DATA(insert (   432    0 5 f  824 ));
 
 /*
  * btree numeric
  */
 
-DATA(insert (  1988 1 f 1754 ));
-DATA(insert (  1988 2 f 1755 ));
-DATA(insert (  1988 3 f 1752 ));
-DATA(insert (  1988 4 f 1757 ));
-DATA(insert (  1988 5 f 1756 ));
+DATA(insert (  1988    0 1 f 1754 ));
+DATA(insert (  1988    0 2 f 1755 ));
+DATA(insert (  1988    0 3 f 1752 ));
+DATA(insert (  1988    0 4 f 1757 ));
+DATA(insert (  1988    0 5 f 1756 ));
 
 /*
  * btree bool
  */
 
-DATA(insert (   424 1 f   58 ));
-DATA(insert (   424 2 f 1694 ));
-DATA(insert (   424 3 f   91 ));
-DATA(insert (   424 4 f 1695 ));
-DATA(insert (   424 5 f   59 ));
+DATA(insert (   424    0 1 f   58 ));
+DATA(insert (   424    0 2 f 1694 ));
+DATA(insert (   424    0 3 f   91 ));
+DATA(insert (   424    0 4 f 1695 ));
+DATA(insert (   424    0 5 f   59 ));
 
 /*
  * btree bit
  */
 
-DATA(insert (   423 1 f 1786 ));
-DATA(insert (   423 2 f 1788 ));
-DATA(insert (   423 3 f 1784 ));
-DATA(insert (   423 4 f 1789 ));
-DATA(insert (   423 5 f 1787 ));
+DATA(insert (   423    0 1 f 1786 ));
+DATA(insert (   423    0 2 f 1788 ));
+DATA(insert (   423    0 3 f 1784 ));
+DATA(insert (   423    0 4 f 1789 ));
+DATA(insert (   423    0 5 f 1787 ));
 
 /*
  * btree varbit
  */
 
-DATA(insert (  2002 1 f 1806 ));
-DATA(insert (  2002 2 f 1808 ));
-DATA(insert (  2002 3 f 1804 ));
-DATA(insert (  2002 4 f 1809 ));
-DATA(insert (  2002 5 f 1807 ));
+DATA(insert (  2002    0 1 f 1806 ));
+DATA(insert (  2002    0 2 f 1808 ));
+DATA(insert (  2002    0 3 f 1804 ));
+DATA(insert (  2002    0 4 f 1809 ));
+DATA(insert (  2002    0 5 f 1807 ));
 
 /*
  * btree text pattern
  */
 
-DATA(insert (  2095 1 f 2314 ));
-DATA(insert (  2095 2 f 2315 ));
-DATA(insert (  2095 3 f 2316 ));
-DATA(insert (  2095 4 f 2317 ));
-DATA(insert (  2095 5 f 2318 ));
+DATA(insert (  2095    0 1 f 2314 ));
+DATA(insert (  2095    0 2 f 2315 ));
+DATA(insert (  2095    0 3 f 2316 ));
+DATA(insert (  2095    0 4 f 2317 ));
+DATA(insert (  2095    0 5 f 2318 ));
 
 /*
  * btree varchar pattern (same operators as text)
  */
 
-DATA(insert (  2096 1 f 2314 ));
-DATA(insert (  2096 2 f 2315 ));
-DATA(insert (  2096 3 f 2316 ));
-DATA(insert (  2096 4 f 2317 ));
-DATA(insert (  2096 5 f 2318 ));
+DATA(insert (  2096    0 1 f 2314 ));
+DATA(insert (  2096    0 2 f 2315 ));
+DATA(insert (  2096    0 3 f 2316 ));
+DATA(insert (  2096    0 4 f 2317 ));
+DATA(insert (  2096    0 5 f 2318 ));
 
 /*
  * btree bpchar pattern
  */
 
-DATA(insert (  2097 1 f 2326 ));
-DATA(insert (  2097 2 f 2327 ));
-DATA(insert (  2097 3 f 2328 ));
-DATA(insert (  2097 4 f 2329 ));
-DATA(insert (  2097 5 f 2330 ));
+DATA(insert (  2097    0 1 f 2326 ));
+DATA(insert (  2097    0 2 f 2327 ));
+DATA(insert (  2097    0 3 f 2328 ));
+DATA(insert (  2097    0 4 f 2329 ));
+DATA(insert (  2097    0 5 f 2330 ));
 
 /*
  * btree name pattern
  */
 
-DATA(insert (  2098 1 f 2332 ));
-DATA(insert (  2098 2 f 2333 ));
-DATA(insert (  2098 3 f 2334 ));
-DATA(insert (  2098 4 f 2335 ));
-DATA(insert (  2098 5 f 2336 ));
+DATA(insert (  2098    0 1 f 2332 ));
+DATA(insert (  2098    0 2 f 2333 ));
+DATA(insert (  2098    0 3 f 2334 ));
+DATA(insert (  2098    0 4 f 2335 ));
+DATA(insert (  2098    0 5 f 2336 ));
 
 /*
  * btree money_ops
  */
 
-DATA(insert (  2099 1 f  902 ));
-DATA(insert (  2099 2 f  904 ));
-DATA(insert (  2099 3 f  900 ));
-DATA(insert (  2099 4 f  905 ));
-DATA(insert (  2099 5 f  903 ));
+DATA(insert (  2099    0 1 f  902 ));
+DATA(insert (  2099    0 2 f  904 ));
+DATA(insert (  2099    0 3 f  900 ));
+DATA(insert (  2099    0 4 f  905 ));
+DATA(insert (  2099    0 5 f  903 ));
 
 /*
  * btree reltime_ops
  */
 
-DATA(insert (  2233 1 f  568 ));
-DATA(insert (  2233 2 f  570 ));
-DATA(insert (  2233 3 f  566 ));
-DATA(insert (  2233 4 f  569 ));
-DATA(insert (  2233 5 f  571 ));
+DATA(insert (  2233    0 1 f  568 ));
+DATA(insert (  2233    0 2 f  570 ));
+DATA(insert (  2233    0 3 f  566 ));
+DATA(insert (  2233    0 4 f  571 ));
+DATA(insert (  2233    0 5 f  569 ));
 
 /*
  * btree tinterval_ops
  */
 
-DATA(insert (  2234 1 f  813 ));
-DATA(insert (  2234 2 f  815 ));
-DATA(insert (  2234 3 f  811 ));
-DATA(insert (  2234 4 f  814 ));
-DATA(insert (  2234 5 f  816 ));
+DATA(insert (  2234    0 1 f  813 ));
+DATA(insert (  2234    0 2 f  815 ));
+DATA(insert (  2234    0 3 f  811 ));
+DATA(insert (  2234    0 4 f  816 ));
+DATA(insert (  2234    0 5 f  814 ));
 
 /*
  * btree array_ops
  */
 
-DATA(insert (   397 1 f 1072 ));
-DATA(insert (   397 2 f 1074 ));
-DATA(insert (   397 3 f 1070 ));
-DATA(insert (   397 4 f 1075 ));
-DATA(insert (   397 5 f 1073 ));
+DATA(insert (   397    0 1 f 1072 ));
+DATA(insert (   397    0 2 f 1074 ));
+DATA(insert (   397    0 3 f 1070 ));
+DATA(insert (   397    0 4 f 1075 ));
+DATA(insert (   397    0 5 f 1073 ));
 
 /*
  * hash index _ops
  */
 
 /* bpchar_ops */
-DATA(insert (   427 1 f 1054 ));
+DATA(insert (   427    0 1 f 1054 ));
 /* char_ops */
-DATA(insert (   431 1 f   92 ));
+DATA(insert (   431    0 1 f   92 ));
 /* cidr_ops */
-DATA(insert (   433 1 f  820 ));
+DATA(insert (   433    0 1 f  820 ));
 /* date_ops */
-DATA(insert (   435 1 f 1093 ));
+DATA(insert (   435    0 1 f 1093 ));
 /* float4_ops */
-DATA(insert (  1971 1 f  620 ));
+DATA(insert (  1971    0 1 f  620 ));
 /* float8_ops */
-DATA(insert (  1973 1 f  670 ));
+DATA(insert (  1973    0 1 f  670 ));
 /* inet_ops */
-DATA(insert (  1975 1 f 1201 ));
+DATA(insert (  1975    0 1 f 1201 ));
 /* int2_ops */
-DATA(insert (  1977 1 f   94 ));
+DATA(insert (  1977    0 1 f   94 ));
 /* int4_ops */
-DATA(insert (  1979 1 f   96 ));
+DATA(insert (  1979    0 1 f   96 ));
 /* int8_ops */
-DATA(insert (  1981 1 f  410 ));
+DATA(insert (  1981    0 1 f  410 ));
 /* interval_ops */
-DATA(insert (  1983 1 f 1330 ));
+DATA(insert (  1983    0 1 f 1330 ));
 /* macaddr_ops */
-DATA(insert (  1985 1 f 1220 ));
+DATA(insert (  1985    0 1 f 1220 ));
 /* name_ops */
-DATA(insert (  1987 1 f   93 ));
+DATA(insert (  1987    0 1 f   93 ));
 /* oid_ops */
-DATA(insert (  1990 1 f  607 ));
+DATA(insert (  1990    0 1 f  607 ));
 /* oidvector_ops */
-DATA(insert (  1992 1 f  649 ));
+DATA(insert (  1992    0 1 f  649 ));
 /* text_ops */
-DATA(insert (  1995 1 f   98 ));
+DATA(insert (  1995    0 1 f   98 ));
 /* time_ops */
-DATA(insert (  1997 1 f 1108 ));
+DATA(insert (  1997    0 1 f 1108 ));
 /* timestamptz_ops */
-DATA(insert (  1999 1 f 1320 ));
+DATA(insert (  1999    0 1 f 1320 ));
 /* timetz_ops */
-DATA(insert (  2001 1 f 1550 ));
+DATA(insert (  2001    0 1 f 1550 ));
 /* varchar_ops */
-DATA(insert (  2004 1 f   98 ));
+DATA(insert (  2004    0 1 f   98 ));
 /* timestamp_ops */
-DATA(insert (  2040 1 f 2060 ));
+DATA(insert (  2040    0 1 f 2060 ));
 /* bool_ops */
-DATA(insert (  2222 1 f   91 ));
+DATA(insert (  2222    0 1 f   91 ));
 /* bytea_ops */
-DATA(insert (  2223 1 f 1955 ));
+DATA(insert (  2223    0 1 f 1955 ));
 /* int2vector_ops */
-DATA(insert (  2224 1 f  386 ));
+DATA(insert (  2224    0 1 f  386 ));
 /* xid_ops */
-DATA(insert (  2225 1 f  352 ));
+DATA(insert (  2225    0 1 f  352 ));
 /* cid_ops */
-DATA(insert (  2226 1 f  385 ));
+DATA(insert (  2226    0 1 f  385 ));
 /* abstime_ops */
-DATA(insert (  2227 1 f  560 ));
+DATA(insert (  2227    0 1 f  560 ));
 /* reltime_ops */
-DATA(insert (  2228 1 f  566 ));
+DATA(insert (  2228    0 1 f  566 ));
 /* text_pattern_ops */
-DATA(insert (  2229 1 f 2316 ));
+DATA(insert (  2229    0 1 f 2316 ));
 /* varchar_pattern_ops */
-DATA(insert (  2230 1 f 2316 ));
+DATA(insert (  2230    0 1 f 2316 ));
 /* bpchar_pattern_ops */
-DATA(insert (  2231 1 f 2328 ));
+DATA(insert (  2231    0 1 f 2328 ));
 /* name_pattern_ops */
-DATA(insert (  2232 1 f 2334 ));
+DATA(insert (  2232    0 1 f 2334 ));
 /* aclitem_ops */
-DATA(insert (  2235 1 f  974 ));
+DATA(insert (  2235    0 1 f  974 ));
 
 #endif   /* PG_AMOP_H */
index a2607db5eb8b9f77719789c246d7ced2a6e74ff5..e284dedbf0d23c8db3e73621bf8247cc14e1b5e4 100644 (file)
@@ -6,15 +6,20 @@
  *
  * The amproc table identifies support procedures associated with index
  * opclasses.  These procedures can't be listed in pg_amop since they are
- * not associated with indexable operators for the opclass.
+ * not the implementation of any indexable operator for the opclass.
  *
- * Note: the primary key for this table is .
+ * The primary key for this table is .
+ * amprocsubtype is equal to zero for an opclass's "default" procedures.
+ * Usually a nondefault amprocsubtype indicates a support procedure to be
+ * used with operators having the same nondefault amopsubtype.  The exact
+ * behavior depends on the index AM, however, and some don't pay attention
+ * to subtype at all.
  *
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_amproc.h,v 1.44 2003/08/17 19:58:06 tgl Exp $
+ * $Id: pg_amproc.h,v 1.45 2003/11/12 21:15:57 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -40,6 +45,7 @@
 CATALOG(pg_amproc) BKI_WITHOUT_OIDS
 {
    Oid         amopclaid;      /* the index opclass this entry is for */
+   Oid         amprocsubtype;  /* procedure subtype, or zero if default */
    int2        amprocnum;      /* support procedure index */
    regproc     amproc;         /* OID of the proc */
 } FormData_pg_amproc;
@@ -55,10 +61,11 @@ typedef FormData_pg_amproc *Form_pg_amproc;
  *     compiler constants for pg_amproc
  * ----------------
  */
-#define Natts_pg_amproc                    3
+#define Natts_pg_amproc                    4
 #define Anum_pg_amproc_amopclaid       1
-#define Anum_pg_amproc_amprocnum       2
-#define Anum_pg_amproc_amproc          3
+#define Anum_pg_amproc_amprocsubtype   2
+#define Anum_pg_amproc_amprocnum       3
+#define Anum_pg_amproc_amproc          4
 
 /* ----------------
  *     initial contents of pg_amproc
@@ -66,88 +73,93 @@ typedef FormData_pg_amproc *Form_pg_amproc;
  */
 
 /* rtree */
-DATA(insert (   422 1  193 ));
-DATA(insert (   422 2  194 ));
-DATA(insert (   422 3  196 ));
-DATA(insert (   425 1  193 ));
-DATA(insert (   425 2  194 ));
-DATA(insert (   425 3  195 ));
-DATA(insert (  1993 1  197 ));
-DATA(insert (  1993 2  198 ));
-DATA(insert (  1993 3  199 ));
+DATA(insert (   425    0 1 193 ));
+DATA(insert (   425    0 2 194 ));
+DATA(insert (   425    0 3 195 ));
+DATA(insert (  1993    0 1 197 ));
+DATA(insert (  1993    0 2 198 ));
+DATA(insert (  1993    0 3 199 ));
 
 
 /* btree */
-DATA(insert (   397 1  382 ));
-DATA(insert (   421 1  357 ));
-DATA(insert (   423 1 1596 ));
-DATA(insert (   424 1 1693 ));
-DATA(insert (   426 1 1078 ));
-DATA(insert (   428 1 1954 ));
-DATA(insert (   429 1  358 ));
-DATA(insert (   432 1  926 ));
-DATA(insert (   434 1 1092 ));
-DATA(insert (  1970 1  354 ));
-DATA(insert (  1972 1  355 ));
-DATA(insert (  1974 1  926 ));
-DATA(insert (  1976 1  350 ));
-DATA(insert (  1978 1  351 ));
-DATA(insert (  1980 1  842 ));
-DATA(insert (  1982 1 1315 ));
-DATA(insert (  1984 1  836 ));
-DATA(insert (  1986 1  359 ));
-DATA(insert (  1988 1 1769 ));
-DATA(insert (  1989 1  356 ));
-DATA(insert (  1991 1  404 ));
-DATA(insert (  1994 1  360 ));
-DATA(insert (  1996 1 1107 ));
-DATA(insert (  1998 1 1314 ));
-DATA(insert (  2000 1 1358 ));
-DATA(insert (  2002 1 1672 ));
-DATA(insert (  2003 1  360 ));
-DATA(insert (  2039 1 2045 ));
-DATA(insert (  2095 1 2166 ));
-DATA(insert (  2096 1 2166 ));
-DATA(insert (  2097 1 2180 ));
-DATA(insert (  2098 1 2187 ));
-DATA(insert (  2099 1  377 ));
-DATA(insert (  2233 1  380 ));
-DATA(insert (  2234 1  381 ));
+DATA(insert (   397    0 1 382 ));
+DATA(insert (   421    0 1 357 ));
+DATA(insert (   423    0 1 1596 ));
+DATA(insert (   424    0 1 1693 ));
+DATA(insert (   426    0 1 1078 ));
+DATA(insert (   428    0 1 1954 ));
+DATA(insert (   429    0 1 358 ));
+DATA(insert (   432    0 1 926 ));
+DATA(insert (   434    0 1 1092 ));
+DATA(insert (  1970    0 1 354 ));
+DATA(insert (  1970  701 1 2194 ));
+DATA(insert (  1972    0 1 355 ));
+DATA(insert (  1972  700 1 2195 ));
+DATA(insert (  1974    0 1 926 ));
+DATA(insert (  1976    0 1 350 ));
+DATA(insert (  1976   23 1 2190 ));
+DATA(insert (  1976   20 1 2192 ));
+DATA(insert (  1978    0 1 351 ));
+DATA(insert (  1978   20 1 2188 ));
+DATA(insert (  1978   21 1 2191 ));
+DATA(insert (  1980    0 1 842 ));
+DATA(insert (  1980   23 1 2189 ));
+DATA(insert (  1980   21 1 2193 ));
+DATA(insert (  1982    0 1 1315 ));
+DATA(insert (  1984    0 1 836 ));
+DATA(insert (  1986    0 1 359 ));
+DATA(insert (  1988    0 1 1769 ));
+DATA(insert (  1989    0 1 356 ));
+DATA(insert (  1991    0 1 404 ));
+DATA(insert (  1994    0 1 360 ));
+DATA(insert (  1996    0 1 1107 ));
+DATA(insert (  1998    0 1 1314 ));
+DATA(insert (  2000    0 1 1358 ));
+DATA(insert (  2002    0 1 1672 ));
+DATA(insert (  2003    0 1 360 ));
+DATA(insert (  2039    0 1 2045 ));
+DATA(insert (  2095    0 1 2166 ));
+DATA(insert (  2096    0 1 2166 ));
+DATA(insert (  2097    0 1 2180 ));
+DATA(insert (  2098    0 1 2187 ));
+DATA(insert (  2099    0 1  377 ));
+DATA(insert (  2233    0 1  380 ));
+DATA(insert (  2234    0 1  381 ));
 
 
 /* hash */
-DATA(insert (   427 1 1080 ));
-DATA(insert (   431  454 ));
-DATA(insert (   433  456 ));
-DATA(insert (   435  450 ));
-DATA(insert (  1971  451 ));
-DATA(insert (  1973  452 ));
-DATA(insert (  1975  456 ));
-DATA(insert (  1977  449 ));
-DATA(insert (  1979  450 ));
-DATA(insert (  1981  949 ));
-DATA(insert (  1983 1 1697 ));
-DATA(insert (  1985  399 ));
-DATA(insert (  1987  455 ));
-DATA(insert (  1990  453 ));
-DATA(insert (  1992  457 ));
-DATA(insert (  1995  400 ));
-DATA(insert (  1997  452 ));
-DATA(insert (  1999  452 ));
-DATA(insert (  2001 1 1696 ));
-DATA(insert (  2004  400 ));
-DATA(insert (  2040  452 ));
-DATA(insert (  2222  454 ));
-DATA(insert (  2223  456 ));
-DATA(insert (  2224  398 ));
-DATA(insert (  2225  450 ));
-DATA(insert (  2226  450 ));
-DATA(insert (  2227  450 ));
-DATA(insert (  2228  450 ));
-DATA(insert (  2229  456 ));
-DATA(insert (  2230  456 ));
-DATA(insert (  2231  456 ));
-DATA(insert (  2232  455 ));
-DATA(insert (  2235  329 ));
+DATA(insert (   427    0 1 1080 ));
+DATA(insert (   431    0 1 454 ));
+DATA(insert (   433    0 1 456 ));
+DATA(insert (   435    0 1 450 ));
+DATA(insert (  1971    0 1 451 ));
+DATA(insert (  1973    0 1 452 ));
+DATA(insert (  1975    0 1 456 ));
+DATA(insert (  1977    0 1 449 ));
+DATA(insert (  1979    0 1 450 ));
+DATA(insert (  1981    0 1 949 ));
+DATA(insert (  1983    0 1 1697 ));
+DATA(insert (  1985    0 1 399 ));
+DATA(insert (  1987    0 1 455 ));
+DATA(insert (  1990    0 1 453 ));
+DATA(insert (  1992    0 1 457 ));
+DATA(insert (  1995    0 1 400 ));
+DATA(insert (  1997    0 1 452 ));
+DATA(insert (  1999    0 1 452 ));
+DATA(insert (  2001    0 1 1696 ));
+DATA(insert (  2004    0 1 400 ));
+DATA(insert (  2040    0 1 452 ));
+DATA(insert (  2222    0 1 454 ));
+DATA(insert (  2223    0 1 456 ));
+DATA(insert (  2224    0 1 398 ));
+DATA(insert (  2225    0 1 450 ));
+DATA(insert (  2226    0 1 450 ));
+DATA(insert (  2227    0 1 450 ));
+DATA(insert (  2228    0 1 450 ));
+DATA(insert (  2229    0 1 456 ));
+DATA(insert (  2230    0 1 456 ));
+DATA(insert (  2231    0 1 456 ));
+DATA(insert (  2232    0 1 455 ));
+DATA(insert (  2235    0 1 329 ));
 
 #endif   /* PG_AMPROC_H */
index af277ad687aec114506435da31a52d136c08e267..0f196de19fc82fa71966a6264f7b1a9a45664717 100644 (file)
  * such an index.
  *
  * Normally opckeytype = InvalidOid (zero), indicating that the data stored
- * in the index is the same as the input data. If opckeytype is nonzero
- * then it indicates that a conversion step is needed to produce the stored
- * index data, which will be of type opckeytype (which might be the same or
- * different from the input data). Performing such a conversion is the
- * responsibility of the index access method --- not all AMs support this.
+ * in the index is the same as the data in the indexed column.  If opckeytype
+ * is nonzero then it indicates that a conversion step is needed to produce
+ * the stored index data, which will be of type opckeytype (which might be
+ * the same or different from the input datatype).  Performing such a
+ * conversion is the responsibility of the index access method --- not all
+ * AMs support this.
  *
  *
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_opclass.h,v 1.57 2003/08/17 19:58:06 tgl Exp $
+ * $Id: pg_opclass.h,v 1.58 2003/11/12 21:15:57 tgl Exp $
  *
  * NOTES
  *   the genbki.sh script reads this file and generates .bki
@@ -56,9 +57,9 @@ CATALOG(pg_opclass)
    NameData    opcname;        /* name of this opclass */
    Oid         opcnamespace;   /* namespace of this opclass */
    int4        opcowner;       /* opclass owner */
-   Oid         opcintype;      /* type of input data for opclass */
+   Oid         opcintype;      /* type of data indexed by opclass */
    bool        opcdefault;     /* T if opclass is default for opcintype */
-   Oid         opckeytype;     /* type of index data, or InvalidOid */
+   Oid         opckeytype;     /* type of data in index, or InvalidOid */
 } FormData_pg_opclass;
 
 /* ----------------
@@ -89,7 +90,6 @@ typedef FormData_pg_opclass *Form_pg_opclass;
 DATA(insert OID =  421 (   403     abstime_ops     PGNSP PGUID  702 t 0 ));
 DATA(insert OID =  397 (   403     array_ops       PGNSP PGUID 2277 t 0 ));
 #define ARRAY_BTREE_OPS_OID 397
-DATA(insert OID =  422 (   402     bigbox_ops      PGNSP PGUID  603 f 0 ));
 DATA(insert OID =  423 (   403     bit_ops         PGNSP PGUID 1560 t 0 ));
 DATA(insert OID =  424 (   403     bool_ops        PGNSP PGUID   16 t 0 ));
 DATA(insert OID =  425 (   402     box_ops         PGNSP PGUID  603 t 0 ));
index 4128d5f164314b7aa0adf042d016fce2bb750d6e..50b363eda34439246fc5fc0ff6bd67b9cb2d031d 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.314 2003/10/21 16:23:16 tgl Exp $
+ * $Id: pg_proc.h,v 1.315 2003/11/12 21:15:57 tgl Exp $
  *
  * NOTES
  *   The script catalog/genbki.sh reads this file and generates .bki
@@ -400,8 +400,6 @@ DATA(insert OID = 194 (  rt_box_inter      PGNSP PGUID 12 f f t f i 2 2278 "603 60
 DESCR("r-tree");
 DATA(insert OID = 195 (  rt_box_size      PGNSP PGUID 12 f f t f i 2 2278 "603 2281"  rt_box_size - _null_ ));
 DESCR("r-tree");
-DATA(insert OID = 196 (  rt_bigbox_size    PGNSP PGUID 12 f f t f i 2 2278 "603 2281"  rt_bigbox_size - _null_ ));
-DESCR("r-tree");
 DATA(insert OID = 197 (  rt_poly_union    PGNSP PGUID 12 f f t f i 2 604 "604 604"  rt_poly_union - _null_ ));
 DESCR("r-tree");
 DATA(insert OID = 198 (  rt_poly_inter    PGNSP PGUID 12 f f t f i 2 2278 "604 604"  rt_poly_inter - _null_ ));
@@ -3075,6 +3073,15 @@ DATA(insert OID = 2185 ( name_pattern_gt PGNSP PGUID 12 f f t f i 2 16 "19 19" n
 DATA(insert OID = 2186 ( name_pattern_ne   PGNSP PGUID 12 f f t f i 2 16 "19 19" name_pattern_ne - _null_ ));
 DATA(insert OID = 2187 ( btname_pattern_cmp PGNSP PGUID 12 f f t f i 2 23 "19 19" btname_pattern_cmp - _null_ ));
 
+DATA(insert OID = 2188 ( btint48cmp         PGNSP PGUID 12 f f t f i 2 23 "23 20" btint48cmp - _null_ ));
+DATA(insert OID = 2189 ( btint84cmp         PGNSP PGUID 12 f f t f i 2 23 "20 23" btint84cmp - _null_ ));
+DATA(insert OID = 2190 ( btint24cmp         PGNSP PGUID 12 f f t f i 2 23 "21 23" btint24cmp - _null_ ));
+DATA(insert OID = 2191 ( btint42cmp         PGNSP PGUID 12 f f t f i 2 23 "23 21" btint42cmp - _null_ ));
+DATA(insert OID = 2192 ( btint28cmp         PGNSP PGUID 12 f f t f i 2 23 "21 20" btint28cmp - _null_ ));
+DATA(insert OID = 2193 ( btint82cmp         PGNSP PGUID 12 f f t f i 2 23 "20 21" btint82cmp - _null_ ));
+DATA(insert OID = 2194 ( btfloat48cmp       PGNSP PGUID 12 f f t f i 2 23 "700 701" btfloat48cmp - _null_ ));
+DATA(insert OID = 2195 ( btfloat84cmp       PGNSP PGUID 12 f f t f i 2 23 "701 700" btfloat84cmp - _null_ ));
+
 
 DATA(insert OID = 2212 (  regprocedurein   PGNSP PGUID 12 f f t f s 1 2202 "2275"  regprocedurein - _null_ ));
 DESCR("I/O");
@@ -3157,7 +3164,6 @@ DATA(insert OID = 2273 (  has_schema_privilege           PGNSP PGUID 12 f f t f s 2 16
 DESCR("current user privilege on schema by schema oid");
 
 
-
 DATA(insert OID = 2290 (  record_in            PGNSP PGUID 12 f f t f i 1 2249 "2275"  record_in - _null_ ));
 DESCR("I/O");
 DATA(insert OID = 2291 (  record_out       PGNSP PGUID 12 f f t f i 1 2275 "2249"  record_out - _null_ ));
index 2312c0562e3cddbed6ba5b1684a7be5cb4d3a122..669ce93e70a51ed9d9d95df2cd42b5bfbde0d497 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: plannodes.h,v 1.69 2003/11/09 21:30:37 tgl Exp $
+ * $Id: plannodes.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -165,6 +165,7 @@ typedef struct IndexScan
    List       *indxqual;       /* list of sublists of index quals */
    List       *indxqualorig;   /* the same in original form */
    List       *indxstrategy;   /* list of sublists of strategy numbers */
+   List       *indxsubtype;    /* list of sublists of strategy subtypes */
    ScanDirection indxorderdir; /* forward or backward or don't care */
 } IndexScan;
 
index 71615b6610f001f45b26a4245ec276cfa8de6b25..602553114777948067b1695f23b65dc83ec84e78 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.228 2003/08/17 19:58:06 tgl Exp $
+ * $Id: builtins.h,v 1.229 2003/11/12 21:15:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -219,6 +219,14 @@ extern Datum btint4cmp(PG_FUNCTION_ARGS);
 extern Datum btint8cmp(PG_FUNCTION_ARGS);
 extern Datum btfloat4cmp(PG_FUNCTION_ARGS);
 extern Datum btfloat8cmp(PG_FUNCTION_ARGS);
+extern Datum btint48cmp(PG_FUNCTION_ARGS);
+extern Datum btint84cmp(PG_FUNCTION_ARGS);
+extern Datum btint24cmp(PG_FUNCTION_ARGS);
+extern Datum btint42cmp(PG_FUNCTION_ARGS);
+extern Datum btint28cmp(PG_FUNCTION_ARGS);
+extern Datum btint82cmp(PG_FUNCTION_ARGS);
+extern Datum btfloat48cmp(PG_FUNCTION_ARGS);
+extern Datum btfloat84cmp(PG_FUNCTION_ARGS);
 extern Datum btoidcmp(PG_FUNCTION_ARGS);
 extern Datum btoidvectorcmp(PG_FUNCTION_ARGS);
 extern Datum btabstimecmp(PG_FUNCTION_ARGS);
index e029c136b85e88ed08c0b58b970c6f3de0001539..8b945885095015d5e26e8c301cbf0057c7ce2785 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: geo_decls.h,v 1.41 2003/08/04 02:40:15 momjian Exp $
+ * $Id: geo_decls.h,v 1.42 2003/11/12 21:15:59 tgl Exp $
  *
  * NOTE
  *   These routines do *not* use the float types from adt/.
@@ -399,7 +399,6 @@ extern Datum circle_area(PG_FUNCTION_ARGS);
 extern Datum rt_box_union(PG_FUNCTION_ARGS);
 extern Datum rt_box_inter(PG_FUNCTION_ARGS);
 extern Datum rt_box_size(PG_FUNCTION_ARGS);
-extern Datum rt_bigbox_size(PG_FUNCTION_ARGS);
 extern Datum rt_poly_size(PG_FUNCTION_ARGS);
 extern Datum rt_poly_union(PG_FUNCTION_ARGS);
 extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
index 36146f23d11fc9f234287e9aa2a0e2dbd5858f81..2f017db844ae1828b7c5d5c93a7bae90e7a4cb22 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: lsyscache.h,v 1.83 2003/11/09 21:30:38 tgl Exp $
+ * $Id: lsyscache.h,v 1.84 2003/11/12 21:15:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,10 +26,11 @@ typedef enum IOFuncSelector
 
 extern bool op_in_opclass(Oid opno, Oid opclass);
 extern void get_op_opclass_properties(Oid opno, Oid opclass,
-                                     int *strategy, bool *recheck);
-extern Oid get_opclass_member(Oid opclass, int16 strategy);
+                                     int *strategy, Oid *subtype,
+                                     bool *recheck);
+extern Oid get_opclass_member(Oid opclass, Oid subtype, int16 strategy);
 extern Oid get_op_hash_function(Oid opno);
-extern Oid get_opclass_proc(Oid opclass, int16 procnum);
+extern Oid get_opclass_proc(Oid opclass, Oid subtype, int16 procnum);
 extern char *get_attname(Oid relid, AttrNumber attnum);
 extern char *get_relid_attribute_name(Oid relid, AttrNumber attnum);
 extern AttrNumber get_attnum(Oid relid, const char *attname);
index f08d6c0f1f8b38e59d85ab921e31b775aafe297c..eb24cf839ffed8b0354d27e14f02dc16e30dd035 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: rel.h,v 1.69 2003/11/09 21:30:38 tgl Exp $
+ * $Id: rel.h,v 1.70 2003/11/12 21:15:59 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -139,8 +139,8 @@ typedef struct RelationData
    /*
     * index access support info (used only for an index relation)
     *
-    * Note: only operators and support procs for the index's own datatype
-    * are cached, not any cross-type operators.  The arrays are indexed by
+    * Note: only default operators and support procs for each opclass are
+    * cached, namely those with subtype zero.  The arrays are indexed by
     * strategy or support number, which is a sufficient identifier given
     * that restriction.
     */
index 464ab8d7e8c96ad3432a70609f64a219718ba312..46d2657d015fc796dbf595c4cabc3990bceaedbe 100644 (file)
@@ -47,7 +47,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
 -- in the regression test (we check them using the sequoia 2000
 -- benchmark).
 --
-CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
+CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
 -- there's no easy way to check that this command actually is using
 -- the index, unfortunately.  (EXPLAIN would work, but its output
 -- changes too often for me to want to put an EXPLAIN in the test...)
index 0bdecf5ed1b22c069bb89550f94f1e330be9c1d8..21628b6e69b8a087c1bba50adbde81abd2e731be 100644 (file)
@@ -129,6 +129,14 @@ WHERE  amopclaid != 0 AND
 ------+-----------
 (0 rows)
 
+SELECT ctid, amopsubtype 
+FROM   pg_catalog.pg_amop fk 
+WHERE  amopsubtype != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
+ ctid | amopsubtype 
+------+-------------
+(0 rows)
+
 SELECT ctid, amopopr 
 FROM   pg_catalog.pg_amop fk 
 WHERE  amopopr != 0 AND 
@@ -145,6 +153,14 @@ WHERE  amopclaid != 0 AND
 ------+-----------
 (0 rows)
 
+SELECT ctid, amprocsubtype 
+FROM   pg_catalog.pg_amproc fk 
+WHERE  amprocsubtype != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
+ ctid | amprocsubtype 
+------+---------------
+(0 rows)
+
 SELECT ctid, amproc 
 FROM   pg_catalog.pg_amproc fk 
 WHERE  amproc != 0 AND 
index 985e06595e74c1731dcd525a9908642ee8297b1e..4e2c76de5c2fb7041f40862219ad22a5851007cf 100644 (file)
@@ -685,30 +685,61 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
 -----------+---------+-----+--------
 (0 rows)
 
--- Detect missing pg_amop entries: should have as many strategy functions
--- as AM expects for each opclass for the AM
-SELECT p1.oid, p1.amname, p2.oid, p2.opcname
-FROM pg_am AS p1, pg_opclass AS p2
-WHERE p2.opcamid = p1.oid AND
-    p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
-                        WHERE p3.amopclaid = p2.oid);
- oid | amname | oid | opcname 
------+--------+-----+---------
+-- Detect missing pg_amop entries: should have as many strategy operators
+-- as AM expects for each opclass for the AM.  When nondefault subtypes are
+-- present, enforce condition separately for each subtype.
+SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
+FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
+WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
+                        WHERE p4.amopclaid = p2.oid AND
+                              p4.amopsubtype = p3.amopsubtype);
+ oid | amname | oid | opcname | amopsubtype 
+-----+--------+-----+---------+-------------
 (0 rows)
 
 -- Check that amopopr points at a reasonable-looking operator, ie a binary
 -- operator yielding boolean.
--- NOTE: for 7.1, add restriction that operator inputs are of same type.
--- We used to have opclasses like "int24_ops" but these were broken.
 SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
 FROM pg_amop AS p1, pg_operator AS p2
 WHERE p1.amopopr = p2.oid AND
-    (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
-     p2.oprleft != p2.oprright);
+    (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
  amopclaid | amopopr | oid | oprname 
 -----------+---------+-----+---------
 (0 rows)
 
+-- Make a list of all the distinct operator names being used in particular
+-- strategy slots.  This is a bit hokey, since the list might need to change
+-- in future releases, but it's an effective way of spotting mistakes such as
+-- swapping two operators within a class.
+SELECT DISTINCT opcamid, amopstrategy, oprname
+FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
+                LEFT JOIN pg_operator p3 ON amopopr = p3.oid
+ORDER BY 1, 2, 3;
+ opcamid | amopstrategy | oprname 
+---------+--------------+---------
+     402 |            1 | <<
+     402 |            2 | &<
+     402 |            3 | &&
+     402 |            4 | &>
+     402 |            5 | >>
+     402 |            6 | ~=
+     402 |            7 | ~
+     402 |            8 | @
+     403 |            1 | <
+     403 |            1 | ~<~
+     403 |            2 | <=
+     403 |            2 | ~<=~
+     403 |            3 | =
+     403 |            3 | ~=~
+     403 |            4 | >=
+     403 |            4 | ~>=~
+     403 |            5 | >
+     403 |            5 | ~>~
+     405 |            1 | =
+     405 |            1 | ~=~
+(20 rows)
+
 -- Check that all operators linked to by opclass entries have selectivity
 -- estimators.  This is not absolutely required, but it seems a reasonable
 -- thing to insist on for all standard datatypes.
@@ -721,11 +752,31 @@ WHERE p1.amopopr = p2.oid AND
 (0 rows)
 
 -- Check that operator input types match the opclass
+-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
+-- When amopsubtype is zero (default), oprright must equal oprleft;
+-- when amopsubtype is not zero, oprright must equal amopsubtype.
+SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
+FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
+WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
+    NOT binary_coercible(p3.opcintype, p2.oprleft);
+ amopclaid | amopopr | oid | oprname | opcname 
+-----------+---------+-----+---------+---------
+(0 rows)
+
 SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
 FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
 WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
-    (NOT binary_coercible(p3.opcintype, p2.oprleft) OR
-     p2.oprleft != p2.oprright);
+    p1.amopsubtype = 0 AND
+    p2.oprleft != p2.oprright;
+ amopclaid | amopopr | oid | oprname | opcname 
+-----------+---------+-----+---------+---------
+(0 rows)
+
+SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
+FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
+WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
+    p1.amopsubtype != 0 AND
+    p1.amopsubtype != p2.oprright;
  amopclaid | amopopr | oid | oprname | opcname 
 -----------+---------+-----+---------+---------
 (0 rows)
@@ -749,14 +800,16 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
 (0 rows)
 
 -- Detect missing pg_amproc entries: should have as many support functions
--- as AM expects for each opclass for the AM
-SELECT p1.oid, p1.amname, p2.oid, p2.opcname
-FROM pg_am AS p1, pg_opclass AS p2
-WHERE p2.opcamid = p1.oid AND
-    p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
-                     WHERE p3.amopclaid = p2.oid);
- oid | amname | oid | opcname 
------+--------+-----+---------
+-- as AM expects for each opclass for the AM.  When nondefault subtypes are
+-- present, enforce condition separately for each subtype.
+SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
+FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
+WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
+                     WHERE p4.amopclaid = p2.oid AND
+                           p4.amprocsubtype = p3.amprocsubtype);
+ oid | amname | oid | opcname | amprocsubtype 
+-----+--------+-----+---------+---------------
 (0 rows)
 
 -- Unfortunately, we can't check the amproc link very well because the
@@ -782,13 +835,15 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
 (0 rows)
 
 -- For btree, though, we can do better since we know the support routines
--- must be of the form cmp(input, input) returns int4.
+-- must be of the form cmp(input, input) returns int4 in the default case
+-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
 SELECT p1.amopclaid, p1.amprocnum,
    p2.oid, p2.proname,
    p3.opcname
 FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
 WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
     AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
+    amprocsubtype = 0 AND
     (opckeytype != 0
      OR amprocnum != 1
      OR proretset
@@ -800,6 +855,24 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
 -----------+-----------+-----+---------+---------
 (0 rows)
 
+SELECT p1.amopclaid, p1.amprocnum,
+   p2.oid, p2.proname,
+   p3.opcname
+FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
+WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
+    AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
+    amprocsubtype != 0 AND
+    (opckeytype != 0
+     OR amprocnum != 1
+     OR proretset
+     OR prorettype != 23
+     OR pronargs != 2
+     OR NOT binary_coercible(opcintype, proargtypes[0])
+     OR proargtypes[1] != amprocsubtype);
+ amopclaid | amprocnum | oid | proname | opcname 
+-----------+-----------+-----+---------+---------
+(0 rows)
+
 -- For hash we can also do a little better: the support routines must be
 -- of the form hash(something) returns int4.  Ideally we'd check that the
 -- opcintype is binary-coercible to the function's input, but there are
index 8400a3bb3334ad8b096a57c0eb5a85a6e4a63496..d904bacd66bc7cbe974ee7d0e739fab09edf3481 100644 (file)
@@ -68,7 +68,7 @@ CREATE INDEX onek2_stu1_prtl ON onek2 USING btree(stringu1 name_ops)
 -- in the regression test (we check them using the sequoia 2000
 -- benchmark).
 --
-CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base bigbox_ops);
+CREATE INDEX rect2ind ON fast_emp4000 USING rtree (home_base);
 
 -- there's no easy way to check that this command actually is using
 -- the index, unfortunately.  (EXPLAIN would work, but its output
index 5e8323bc11b0db227181159f3b60523b67a0bfe3..d822aaf4e5546267774a8e68ffeb2e0c453133ab 100644 (file)
@@ -65,6 +65,10 @@ SELECT   ctid, amopclaid
 FROM   pg_catalog.pg_amop fk 
 WHERE  amopclaid != 0 AND 
    NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
+SELECT ctid, amopsubtype 
+FROM   pg_catalog.pg_amop fk 
+WHERE  amopsubtype != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amopsubtype);
 SELECT ctid, amopopr 
 FROM   pg_catalog.pg_amop fk 
 WHERE  amopopr != 0 AND 
@@ -73,6 +77,10 @@ SELECT   ctid, amopclaid
 FROM   pg_catalog.pg_amproc fk 
 WHERE  amopclaid != 0 AND 
    NOT EXISTS(SELECT 1 FROM pg_catalog.pg_opclass pk WHERE pk.oid = fk.amopclaid);
+SELECT ctid, amprocsubtype 
+FROM   pg_catalog.pg_amproc fk 
+WHERE  amprocsubtype != 0 AND 
+   NOT EXISTS(SELECT 1 FROM pg_catalog.pg_type pk WHERE pk.oid = fk.amprocsubtype);
 SELECT ctid, amproc 
 FROM   pg_catalog.pg_amproc fk 
 WHERE  amproc != 0 AND 
index 9cba48b4296d515f8710b9f34bb613c11edf691b..448f3ff0c5b74463029aae2648b238144464540e 100644 (file)
@@ -574,25 +574,34 @@ FROM pg_amop AS p1, pg_am AS p2, pg_opclass AS p3
 WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
     p1.amopstrategy > p2.amstrategies;
 
--- Detect missing pg_amop entries: should have as many strategy functions
--- as AM expects for each opclass for the AM
+-- Detect missing pg_amop entries: should have as many strategy operators
+-- as AM expects for each opclass for the AM.  When nondefault subtypes are
+-- present, enforce condition separately for each subtype.
 
-SELECT p1.oid, p1.amname, p2.oid, p2.opcname
-FROM pg_am AS p1, pg_opclass AS p2
-WHERE p2.opcamid = p1.oid AND
-    p1.amstrategies != (SELECT count(*) FROM pg_amop AS p3
-                        WHERE p3.amopclaid = p2.oid);
+SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amopsubtype
+FROM pg_am AS p1, pg_opclass AS p2, pg_amop AS p3
+WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amstrategies != (SELECT count(*) FROM pg_amop AS p4
+                        WHERE p4.amopclaid = p2.oid AND
+                              p4.amopsubtype = p3.amopsubtype);
 
 -- Check that amopopr points at a reasonable-looking operator, ie a binary
 -- operator yielding boolean.
--- NOTE: for 7.1, add restriction that operator inputs are of same type.
--- We used to have opclasses like "int24_ops" but these were broken.
 
 SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname
 FROM pg_amop AS p1, pg_operator AS p2
 WHERE p1.amopopr = p2.oid AND
-    (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype OR
-     p2.oprleft != p2.oprright);
+    (p2.oprkind != 'b' OR p2.oprresult != 'bool'::regtype);
+
+-- Make a list of all the distinct operator names being used in particular
+-- strategy slots.  This is a bit hokey, since the list might need to change
+-- in future releases, but it's an effective way of spotting mistakes such as
+-- swapping two operators within a class.
+
+SELECT DISTINCT opcamid, amopstrategy, oprname
+FROM pg_amop p1 LEFT JOIN pg_opclass p2 ON amopclaid = p2.oid
+                LEFT JOIN pg_operator p3 ON amopopr = p3.oid
+ORDER BY 1, 2, 3;
 
 -- Check that all operators linked to by opclass entries have selectivity
 -- estimators.  This is not absolutely required, but it seems a reasonable
@@ -604,12 +613,26 @@ WHERE p1.amopopr = p2.oid AND
     (p2.oprrest = 0 OR p2.oprjoin = 0);
 
 -- Check that operator input types match the opclass
+-- For 7.5, we require that oprleft match opcintype (possibly by coercion).
+-- When amopsubtype is zero (default), oprright must equal oprleft;
+-- when amopsubtype is not zero, oprright must equal amopsubtype.
+
+SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
+FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
+WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
+    NOT binary_coercible(p3.opcintype, p2.oprleft);
 
 SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
 FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
 WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
-    (NOT binary_coercible(p3.opcintype, p2.oprleft) OR
-     p2.oprleft != p2.oprright);
+    p1.amopsubtype = 0 AND
+    p2.oprleft != p2.oprright;
+
+SELECT p1.amopclaid, p1.amopopr, p2.oid, p2.oprname, p3.opcname
+FROM pg_amop AS p1, pg_operator AS p2, pg_opclass AS p3
+WHERE p1.amopopr = p2.oid AND p1.amopclaid = p3.oid AND
+    p1.amopsubtype != 0 AND
+    p1.amopsubtype != p2.oprright;
 
 -- **************** pg_amproc ****************
 
@@ -627,13 +650,15 @@ WHERE p1.amopclaid = p3.oid AND p3.opcamid = p2.oid AND
     p1.amprocnum > p2.amsupport;
 
 -- Detect missing pg_amproc entries: should have as many support functions
--- as AM expects for each opclass for the AM
+-- as AM expects for each opclass for the AM.  When nondefault subtypes are
+-- present, enforce condition separately for each subtype.
 
-SELECT p1.oid, p1.amname, p2.oid, p2.opcname
-FROM pg_am AS p1, pg_opclass AS p2
-WHERE p2.opcamid = p1.oid AND
-    p1.amsupport != (SELECT count(*) FROM pg_amproc AS p3
-                     WHERE p3.amopclaid = p2.oid);
+SELECT p1.oid, p1.amname, p2.oid, p2.opcname, p3.amprocsubtype
+FROM pg_am AS p1, pg_opclass AS p2, pg_amproc AS p3
+WHERE p2.opcamid = p1.oid AND p3.amopclaid = p2.oid AND
+    p1.amsupport != (SELECT count(*) FROM pg_amproc AS p4
+                     WHERE p4.amopclaid = p2.oid AND
+                           p4.amprocsubtype = p3.amprocsubtype);
 
 -- Unfortunately, we can't check the amproc link very well because the
 -- signature of the function may be different for different support routines
@@ -656,7 +681,8 @@ WHERE p1.amopclaid = p3.oid AND p4.amopclaid = p6.oid AND
     (p2.proretset OR p5.proretset OR p2.pronargs != p5.pronargs);
 
 -- For btree, though, we can do better since we know the support routines
--- must be of the form cmp(input, input) returns int4.
+-- must be of the form cmp(input, input) returns int4 in the default case
+-- (subtype = 0), and cmp(input, subtype) returns int4 when subtype != 0.
 
 SELECT p1.amopclaid, p1.amprocnum,
    p2.oid, p2.proname,
@@ -664,6 +690,7 @@ SELECT p1.amopclaid, p1.amprocnum,
 FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
 WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
     AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
+    amprocsubtype = 0 AND
     (opckeytype != 0
      OR amprocnum != 1
      OR proretset
@@ -672,6 +699,21 @@ WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
      OR NOT binary_coercible(opcintype, proargtypes[0])
      OR proargtypes[0] != proargtypes[1]);
 
+SELECT p1.amopclaid, p1.amprocnum,
+   p2.oid, p2.proname,
+   p3.opcname
+FROM pg_amproc AS p1, pg_proc AS p2, pg_opclass AS p3
+WHERE p3.opcamid = (SELECT oid FROM pg_am WHERE amname = 'btree')
+    AND p1.amopclaid = p3.oid AND p1.amproc = p2.oid AND
+    amprocsubtype != 0 AND
+    (opckeytype != 0
+     OR amprocnum != 1
+     OR proretset
+     OR prorettype != 23
+     OR pronargs != 2
+     OR NOT binary_coercible(opcintype, proargtypes[0])
+     OR proargtypes[1] != amprocsubtype);
+
 -- For hash we can also do a little better: the support routines must be
 -- of the form hash(something) returns int4.  Ideally we'd check that the
 -- opcintype is binary-coercible to the function's input, but there are