aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-11-12 21:15:59 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-11-12 21:15:59 +0000
commitfa5c8a055a02e44f446e4593e397c33a572c4d67 (patch)
tree9c0a7ded5a88c082c28dbe2b431660813abd72b8 /src/backend
parent49f98fa833407b4e4252e42522e640ec8a0d08b2 (diff)
downloadpostgresql-fa5c8a055a02e44f446e4593e397c33a572c4d67.tar.gz
postgresql-fa5c8a055a02e44f446e4593e397c33a572c4d67.zip
Cross-data-type comparisons are now indexable by btrees, pursuant to my
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.
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/access/common/scankey.c42
-rw-r--r--src/backend/access/gist/gistget.c43
-rw-r--r--src/backend/access/gist/gistscan.c5
-rw-r--r--src/backend/access/heap/tuptoaster.c54
-rw-r--r--src/backend/access/nbtree/nbtcompare.c86
-rw-r--r--src/backend/access/nbtree/nbtinsert.c15
-rw-r--r--src/backend/access/nbtree/nbtree.c29
-rw-r--r--src/backend/access/nbtree/nbtsearch.c261
-rw-r--r--src/backend/access/nbtree/nbtsort.c49
-rw-r--r--src/backend/access/nbtree/nbtutils.c307
-rw-r--r--src/backend/access/rtree/rtproc.c16
-rw-r--r--src/backend/access/rtree/rtscan.c10
-rw-r--r--src/backend/catalog/aclchk.c26
-rw-r--r--src/backend/catalog/dependency.c120
-rw-r--r--src/backend/catalog/heap.c75
-rw-r--r--src/backend/catalog/index.c18
-rw-r--r--src/backend/catalog/pg_constraint.c42
-rw-r--r--src/backend/catalog/pg_conversion.c11
-rw-r--r--src/backend/catalog/pg_depend.c35
-rw-r--r--src/backend/catalog/pg_largeobject.c19
-rw-r--r--src/backend/commands/async.c19
-rw-r--r--src/backend/commands/cluster.c11
-rw-r--r--src/backend/commands/comment.c84
-rw-r--r--src/backend/commands/dbcommands.c59
-rw-r--r--src/backend/commands/functioncmds.c10
-rw-r--r--src/backend/commands/indexcmds.c8
-rw-r--r--src/backend/commands/opclasscmds.c289
-rw-r--r--src/backend/commands/tablecmds.c18
-rw-r--r--src/backend/commands/trigger.c83
-rw-r--r--src/backend/commands/typecmds.c34
-rw-r--r--src/backend/commands/user.c10
-rw-r--r--src/backend/commands/vacuum.c19
-rw-r--r--src/backend/executor/nodeIndexscan.c18
-rw-r--r--src/backend/nodes/copyfuncs.c13
-rw-r--r--src/backend/nodes/outfuncs.c12
-rw-r--r--src/backend/optimizer/path/indxpath.c132
-rw-r--r--src/backend/optimizer/plan/createplan.c54
-rw-r--r--src/backend/optimizer/util/plancat.c11
-rw-r--r--src/backend/parser/parse_func.c10
-rw-r--r--src/backend/rewrite/rewriteRemove.c11
-rw-r--r--src/backend/storage/large_object/inv_api.c42
-rw-r--r--src/backend/utils/adt/float.c22
-rw-r--r--src/backend/utils/adt/regproc.c34
-rw-r--r--src/backend/utils/adt/ruleutils.c18
-rw-r--r--src/backend/utils/adt/selfuncs.c11
-rw-r--r--src/backend/utils/cache/catcache.c6
-rw-r--r--src/backend/utils/cache/lsyscache.c25
-rw-r--r--src/backend/utils/cache/relcache.c172
-rw-r--r--src/backend/utils/cache/syscache.c10
-rw-r--r--src/backend/utils/cache/typcache.c15
-rw-r--r--src/backend/utils/init/postinit.c11
-rw-r--r--src/backend/utils/sort/tuplesort.c23
52 files changed, 1504 insertions, 1053 deletions
diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c
index 93741cbb849..2fa02b7d91f 100644
--- a/src/backend/access/common/scankey.c
+++ b/src/backend/access/common/scankey.c
@@ -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);
}
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index 24168c99269..5db69a6b40a 100644
--- a/src/backend/access/gist/gistget.c
+++ b/src/backend/access/gist/gistget.c
@@ -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;
}
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 960d1c2f25b..9b9d1f60341 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -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++)
{
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 0bfe3c01b8f..f643906da1f 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -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;
}
diff --git a/src/backend/access/nbtree/nbtcompare.c b/src/backend/access/nbtree/nbtcompare.c
index 79756513abf..bd698858305 100644
--- a/src/backend/access/nbtree/nbtcompare.c
+++ b/src/backend/access/nbtree/nbtcompare.c
@@ -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
*
@@ -98,6 +98,90 @@ btint8cmp(PG_FUNCTION_ARGS)
}
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)
{
Oid a = PG_GETARG_OID(0);
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 98f3abb511f..719b1e1f0ed 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -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 */
diff --git a/src/backend/access/nbtree/nbtree.c b/src/backend/access/nbtree/nbtree.c
index 3979f79c358..f920d2497ee 100644
--- a/src/backend/access/nbtree/nbtree.c
+++ b/src/backend/access/nbtree/nbtree.c
@@ -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
*/
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index 432a1ab0c2a..87178d12424 100644
--- a/src/backend/access/nbtree/nbtsearch.c
+++ b/src/backend/access/nbtree/nbtsearch.c
@@ -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
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index a56665be5c4..ed920eafd33 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -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)
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 54cd7c8cd01..2c9fd741ff3 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -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 </<= bound, and if there's an = key then
- * 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 </<= bound, and if there's an = key then
+ * 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. */
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
index 790f6bc7b69..985993fb687 100644
--- a/src/backend/access/rtree/rtproc.c
+++ b/src/backend/access/rtree/rtproc.c
@@ -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)
{
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
index 263fff4bf26..5026bd78a70 100644
--- a/src/backend/access/rtree/rtscan.c
+++ b/src/backend/access/rtree/rtscan.c
@@ -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);
}
}
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index a1b697bee85..7534750c99e 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -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);
diff --git a/src/backend/catalog/dependency.c b/src/backend/catalog/dependency.c
index b0e17652c74..d64f027ef64 100644
--- a/src/backend/catalog/dependency.c
+++ b/src/backend/catalog/dependency.c
@@ -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);
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 75445334ec7..a0962f487dd 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -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);
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 67f970c55d7..72f76b01b06 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -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);
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 0fa665a568d..2cb71f6bfcc 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -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);
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index 709f50f2a5d..7f7811c88df 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -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);
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 21eeb3e6543..2bdb5b12d8d 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -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);
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 96f73056cf2..022ca67d10e 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -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);
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 2cda1f94a97..560a134aa86 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -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 */
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 780a60f7966..4d5bc491c71 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -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)
{
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index fbce38ca577..62765a96e0a 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -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);
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 5ac51bc84d3..320f1fc0ded 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -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);
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 9e1e0746f55..7e3c7410a10 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -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);
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index dbbbc376e00..2f83e22a276 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -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;
}
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 599d2eb8259..e251f8577da 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -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"
@@ -38,9 +40,24 @@
#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);
}
@@ -385,25 +396,158 @@ DefineOpClass(CreateOpClassStmt *stmt)
}
/*
+ * 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);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index df441ca476c..feb9720a847 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -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);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 80225f8f25f..4788d90e587 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -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);
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 17b4df92179..896f1047070 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -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);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 4fad67f43a3..869cd847927 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -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);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index a4d6de2282c..c1c5d64ea2f 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -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);
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 54114ad9245..98158a00c9c 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -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 */
}
/*
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index c02270fa2e7..6cf8450567a 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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;
diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c
index b2fa96bd5d2..cb875bd6769 100644
--- a/src/backend/nodes/outfuncs.c
+++ b/src/backend/nodes/outfuncs.c
@@ -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);
}
diff --git a/src/backend/optimizer/path/indxpath.c b/src/backend/optimizer/path/indxpath.c
index 563bd17f41d..9c57f12ca62 100644
--- a/src/backend/optimizer/path/indxpath.c
+++ b/src/backend/optimizer/path/indxpath.c
@@ -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);
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index 37478d7de0a..a5efcb339e0 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -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;
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 8e621dd063a..8c42b431aa3 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -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)
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 95b5dc37cc6..1068f036d1b 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -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);
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 53f94137e16..0c36b127a1e 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -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);
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 33e40109d3e..f777fb33b95 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -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);
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index 9f0fa0de32d..1493a58de74 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -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));
+}
+
/*
* ===================
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 211549afeaf..ee8a00912a2 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -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,
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index fe749cc9b12..70d5626948a 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -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);
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 978c0201466..3c4b780c56c 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -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);
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 640629c3a04..36125c2374a 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -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,
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index bed4fcdbce6..20c10802bc4 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -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);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 88c8cbb1418..ac5e53a91ae 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -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)))
{
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 9b250eef62e..eb2f6eb1af7 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -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 */
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 9b7620b0f0a..12d295c5a59 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -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);
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 21e2efdda75..54175189df5 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -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);
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index 9b3c0bb4075..a6accb5db4d 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -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;
}