summaryrefslogtreecommitdiff
path: root/src/backend/access
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access')
-rw-r--r--src/backend/access/common/indexvalid.c9
-rw-r--r--src/backend/access/common/scankey.c77
-rw-r--r--src/backend/access/gist/Makefile4
-rw-r--r--src/backend/access/gist/gistget.c22
-rw-r--r--src/backend/access/gist/gistscan.c14
-rw-r--r--src/backend/access/gist/giststrat.c125
-rw-r--r--src/backend/access/hash/Makefile4
-rw-r--r--src/backend/access/hash/hashstrat.c84
-rw-r--r--src/backend/access/heap/tuptoaster.c51
-rw-r--r--src/backend/access/index/Makefile4
-rw-r--r--src/backend/access/index/istrat.c479
-rw-r--r--src/backend/access/nbtree/Makefile4
-rw-r--r--src/backend/access/nbtree/nbtinsert.c4
-rw-r--r--src/backend/access/nbtree/nbtsearch.c13
-rw-r--r--src/backend/access/nbtree/nbtstrat.c138
-rw-r--r--src/backend/access/nbtree/nbtutils.c148
-rw-r--r--src/backend/access/rtree/rtscan.c26
-rw-r--r--src/backend/access/rtree/rtstrat.c201
18 files changed, 173 insertions, 1234 deletions
diff --git a/src/backend/access/common/indexvalid.c b/src/backend/access/common/indexvalid.c
index 6b31636275..e2ca5a7563 100644
--- a/src/backend/access/common/indexvalid.c
+++ b/src/backend/access/common/indexvalid.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.29 2003/08/04 02:39:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/Attic/indexvalid.c,v 1.30 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -57,12 +57,9 @@ index_keytest(IndexTuple tuple,
if (key->sk_flags & SK_ISNULL)
return false;
- if (key->sk_flags & SK_COMMUTE)
- test = FunctionCall2(&key->sk_func, key->sk_argument, datum);
- else
- test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
+ test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
- if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE))
+ if (!DatumGetBool(test))
return false;
key++;
diff --git a/src/backend/access/common/scankey.c b/src/backend/access/common/scankey.c
index f79b2c7143..93741cbb84 100644
--- a/src/backend/access/common/scankey.c
+++ b/src/backend/access/common/scankey.c
@@ -1,73 +1,46 @@
/*-------------------------------------------------------------------------
*
- * scan.c
- * scan direction and key code
+ * scankey.c
+ * scan key support code
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.22 2003/08/04 02:39:56 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/common/scankey.c,v 1.23 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
-
#include "postgres.h"
#include "access/skey.h"
-/*
- * ScanKeyEntryIsLegal
- * True iff the scan key entry is legal.
- */
-#define ScanKeyEntryIsLegal(entry) \
-( \
- AssertMacro(PointerIsValid(entry)), \
- AttributeNumberIsValid((entry)->sk_attno) \
-)
-
-/*
- * ScanKeyEntrySetIllegal
- * Marks a scan key entry as illegal.
- */
-void
-ScanKeyEntrySetIllegal(ScanKey entry)
-{
-
- Assert(PointerIsValid(entry));
-
- entry->sk_flags = 0; /* just in case... */
- entry->sk_attno = InvalidAttrNumber;
- entry->sk_procedure = 0; /* should be InvalidRegProcedure */
- entry->sk_func.fn_oid = InvalidOid;
- entry->sk_argument = (Datum) 0;
-}
/*
* ScanKeyEntryInitialize
- * Initializes a scan key entry.
+ * Initializes a scan key entry given all the field values.
+ * The target procedure is specified by OID.
*
- * Note:
- * Assumes the scan key entry is valid.
- * Assumes the intialized scan key entry will be legal.
+ * 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
ScanKeyEntryInitialize(ScanKey entry,
- bits16 flags,
+ int flags,
AttrNumber attributeNumber,
+ StrategyNumber strategy,
RegProcedure procedure,
- Datum argument)
+ Datum argument,
+ Oid argtype)
{
- Assert(PointerIsValid(entry));
-
entry->sk_flags = flags;
entry->sk_attno = attributeNumber;
- entry->sk_procedure = procedure;
+ entry->sk_strategy = strategy;
entry->sk_argument = argument;
+ entry->sk_argtype = argtype;
fmgr_info(procedure, &entry->sk_func);
-
- Assert(ScanKeyEntryIsLegal(entry));
}
/*
@@ -75,25 +48,23 @@ ScanKeyEntryInitialize(ScanKey entry,
* Initializes a scan key entry using an already-completed FmgrInfo
* function lookup record.
*
- * mcxt is the memory context holding the scan key; it'll be used for
- * any subsidiary info attached to the scankey's FmgrInfo record.
+ * 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
ScanKeyEntryInitializeWithInfo(ScanKey entry,
- bits16 flags,
+ int flags,
AttrNumber attributeNumber,
+ StrategyNumber strategy,
FmgrInfo *finfo,
- MemoryContext mcxt,
- Datum argument)
+ Datum argument,
+ Oid argtype)
{
- Assert(PointerIsValid(entry));
- Assert(RegProcedureIsValid(finfo->fn_oid));
-
entry->sk_flags = flags;
entry->sk_attno = attributeNumber;
- entry->sk_procedure = finfo->fn_oid;
+ entry->sk_strategy = strategy;
entry->sk_argument = argument;
- fmgr_info_copy(&entry->sk_func, finfo, mcxt);
-
- Assert(ScanKeyEntryIsLegal(entry));
+ entry->sk_argtype = argtype;
+ fmgr_info_copy(&entry->sk_func, finfo, CurrentMemoryContext);
}
diff --git a/src/backend/access/gist/Makefile b/src/backend/access/gist/Makefile
index 7f982d0dfd..f2c7ddf3a7 100644
--- a/src/backend/access/gist/Makefile
+++ b/src/backend/access/gist/Makefile
@@ -4,7 +4,7 @@
# Makefile for access/gist
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.10 2000/08/31 16:09:31 petere Exp $
+# $Header: /cvsroot/pgsql/src/backend/access/gist/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -12,7 +12,7 @@ subdir = src/backend/access/gist
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = gist.o gistget.o gistscan.o giststrat.o
+OBJS = gist.o gistget.o gistscan.o
all: SUBSYS.o
diff --git a/src/backend/access/gist/gistget.c b/src/backend/access/gist/gistget.c
index bfa557bb9c..24168c9926 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.36 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistget.c,v 1.37 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -249,26 +249,16 @@ gistindex_keytest(IndexTuple tuple,
IndexTupleSize(tuple) - sizeof(IndexTupleData),
FALSE, isNull);
- if (key[0].sk_flags & SK_COMMUTE)
- {
- test = FunctionCall3(&key[0].sk_func,
- key[0].sk_argument,
- PointerGetDatum(&de),
- ObjectIdGetDatum(key[0].sk_procedure));
- }
- else
- {
- test = FunctionCall3(&key[0].sk_func,
- PointerGetDatum(&de),
- key[0].sk_argument,
- ObjectIdGetDatum(key[0].sk_procedure));
- }
+ test = FunctionCall3(&key[0].sk_func,
+ PointerGetDatum(&de),
+ key[0].sk_argument,
+ Int32GetDatum(key[0].sk_strategy));
if (de.key != datum && !isAttByVal(giststate, key[0].sk_attno - 1))
if (DatumGetPointer(de.key) != NULL)
pfree(DatumGetPointer(de.key));
- if (DatumGetBool(test) == !!(key[0].sk_flags & SK_NEGATE))
+ if (!DatumGetBool(test))
return false;
scanKeySize--;
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 790048aef3..960d1c2f25 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.47 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/gist/gistscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -106,17 +106,13 @@ gistrescan(PG_FUNCTION_ARGS)
s->numberOfKeys * sizeof(ScanKeyData));
/*
- * Play games here with the scan key to use the Consistent
- * function for all comparisons: 1) the sk_procedure field will
- * now be used to hold the strategy number 2) the sk_func field
- * will point to the Consistent function
+ * 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.
*/
for (i = 0; i < s->numberOfKeys; i++)
{
- s->keyData[i].sk_procedure =
- RelationGetGISTStrategy(s->indexRelation,
- s->keyData[i].sk_attno,
- s->keyData[i].sk_procedure);
s->keyData[i].sk_func = p->giststate->consistentFn[s->keyData[i].sk_attno - 1];
}
}
diff --git a/src/backend/access/gist/giststrat.c b/src/backend/access/gist/giststrat.c
deleted file mode 100644
index fe83b5ac79..0000000000
--- a/src/backend/access/gist/giststrat.c
+++ /dev/null
@@ -1,125 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * giststrat.c
- * strategy map data for GiSTs.
- *
- *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/gist/Attic/giststrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/gist.h"
-#include "access/istrat.h"
-
-
-/*
- * Note: negate, commute, and negatecommute all assume that operators are
- * ordered as follows in the strategy map:
- *
- * contains, contained-by
- *
- * The negate, commute, and negatecommute arrays are used by the planner
- * to plan indexed scans over data that appears in the qualificiation in
- * a boolean negation, or whose operands appear in the wrong order. For
- * example, if the operator "<%" means "contains", and the user says
- *
- * where not rel.box <% "(10,10,20,20)"::box
- *
- * the planner can plan an index scan by noting that GiST indices have
- * an operator in their operator class for negating <%.
- *
- * Similarly, if the user says something like
- *
- * where "(10,10,20,20)"::box <% rel.box
- *
- * the planner can see that the GiST index on rel.box has an operator in
- * its opclass for commuting <%, and plan the scan using that operator.
- * This added complexity in the access methods makes the planner a lot easier
- * to write.
- */
-
-/* if a op b, what operator tells us if (not a op b)? */
-static StrategyNumber GISTNegate[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
-static StrategyNumber GISTCommute[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
-static StrategyNumber GISTNegateCommute[GISTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/*
- * GiSTs do not currently support TermData (see rtree/rtstrat.c for
- * discussion of
- * TermData) -- such logic must be encoded in the user's Consistent function.
- */
-
-static StrategyExpression GISTEvaluationExpressions[GISTNStrategies] = {
- NULL,
- NULL,
- NULL
-};
-
-/*
- * If you were sufficiently attentive to detail, you would go through
- * the ExpressionData pain above for every one of the strategies
- * we defined. I am not. Now we declare the StrategyEvaluationData
- * structure that gets shipped around to help the planner and the access
- * method decide what sort of scan it should do, based on (a) what the
- * user asked for, (b) what operators are defined for a particular opclass,
- * and (c) the reams of information we supplied above.
- *
- * The idea of all of this initialized data is to make life easier on the
- * user when he defines a new operator class to use this access method.
- * By filling in all the data, we let him get away with leaving holes in his
- * operator class, and still let him use the index. The added complexity
- * in the access methods just isn't worth the trouble, though.
- */
-
-static StrategyEvaluationData GISTEvaluationData = {
- GISTNStrategies, /* # of strategies */
- (StrategyTransformMap) GISTNegate, /* how to do (not qual) */
- (StrategyTransformMap) GISTCommute, /* how to swap operands */
- (StrategyTransformMap) GISTNegateCommute, /* how to do both */
- GISTEvaluationExpressions
-};
-
-
-StrategyNumber
-RelationGetGISTStrategy(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
-{
- return RelationGetStrategy(r, attnum, &GISTEvaluationData, proc);
-}
-
-#ifdef NOT_USED
-bool
-RelationInvokeGISTStrategy(Relation r,
- AttrNumber attnum,
- StrategyNumber s,
- Datum left,
- Datum right)
-{
- return (RelationInvokeStrategy(r, &GISTEvaluationData, attnum, s,
- left, right));
-}
-
-#endif
diff --git a/src/backend/access/hash/Makefile b/src/backend/access/hash/Makefile
index 5e4f56a80c..5203db34b1 100644
--- a/src/backend/access/hash/Makefile
+++ b/src/backend/access/hash/Makefile
@@ -4,7 +4,7 @@
# Makefile for access/hash
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.10 2000/08/31 16:09:33 petere Exp $
+# $Header: /cvsroot/pgsql/src/backend/access/hash/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -13,7 +13,7 @@ top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = hash.o hashfunc.o hashinsert.o hashovfl.o hashpage.o hashscan.o \
- hashsearch.o hashstrat.o hashutil.o
+ hashsearch.o hashutil.o
all: SUBSYS.o
diff --git a/src/backend/access/hash/hashstrat.c b/src/backend/access/hash/hashstrat.c
deleted file mode 100644
index d72ad08ee1..0000000000
--- a/src/backend/access/hash/hashstrat.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * hashstrat.c
- * Strategy map entries for the hash indexed access method
- *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/hash/Attic/hashstrat.c,v 1.23 2003/08/04 02:39:57 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/hash.h"
-
-
-/*
- * only one valid strategy for hash tables: equality.
- */
-
-#ifdef NOT_USED
-
-static StrategyNumber HTNegate[HTMaxStrategyNumber] = {
- InvalidStrategy
-};
-
-static StrategyNumber HTCommute[HTMaxStrategyNumber] = {
- HTEqualStrategyNumber
-};
-
-static StrategyNumber HTNegateCommute[HTMaxStrategyNumber] = {
- InvalidStrategy
-};
-
-static StrategyExpression HTEvaluationExpressions[HTMaxStrategyNumber] = {
- NULL
-};
-
-static StrategyEvaluationData HTEvaluationData = {
- HTMaxStrategyNumber,
- (StrategyTransformMap) HTNegate,
- (StrategyTransformMap) HTCommute,
- (StrategyTransformMap) HTNegateCommute,
- HTEvaluationExpressions
-};
-#endif
-
-/* ----------------------------------------------------------------
- * RelationGetHashStrategy
- * ----------------------------------------------------------------
- */
-
-#ifdef NOT_USED
-static StrategyNumber
-_hash_getstrat(Relation rel,
- AttrNumber attno,
- RegProcedure proc)
-{
- StrategyNumber strat;
-
- strat = RelationGetStrategy(rel, attno, &HTEvaluationData, proc);
-
- Assert(StrategyNumberIsValid(strat));
-
- return strat;
-}
-#endif
-
-#ifdef NOT_USED
-static bool
-_hash_invokestrat(Relation rel,
- AttrNumber attno,
- StrategyNumber strat,
- Datum left,
- Datum right)
-{
- return (RelationInvokeStrategy(rel, &HTEvaluationData, attno, strat,
- left, right));
-}
-
-#endif
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 1840e0d1d7..0bfe3c01b8 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.38 2003/08/04 23:59:37 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.39 2003/11/09 21:30:35 tgl Exp $
*
*
* INTERFACE ROUTINES
@@ -31,6 +31,7 @@
#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"
@@ -967,11 +968,11 @@ 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,
- (bits16) 0,
+ ScanKeyEntryInitialize(&toastkey, 0,
(AttrNumber) 1,
- (RegProcedure) F_OIDEQ,
- ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
+ OIDOID);
/*
* Find the chunks by index
@@ -1039,11 +1040,11 @@ toast_fetch_datum(varattrib *attr)
/*
* Setup a scan key to fetch from the index by va_valueid
*/
- ScanKeyEntryInitialize(&toastkey,
- (bits16) 0,
+ ScanKeyEntryInitialize(&toastkey, 0,
(AttrNumber) 1,
- (RegProcedure) F_OIDEQ,
- ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
+ OIDOID);
/*
* Read the chunks by index
@@ -1194,37 +1195,33 @@ 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],
- (bits16) 0,
+ ScanKeyEntryInitialize(&toastkey[0], 0,
(AttrNumber) 1,
- (RegProcedure) F_OIDEQ,
- ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
+ BTEqualStrategyNumber, F_OIDEQ,
+ ObjectIdGetDatum(attr->va_content.va_external.va_valueid),
+ OIDOID);
/*
- * Now dependent on number of chunks:
+ * Use equality condition for one chunk, a range condition otherwise:
*/
-
if (numchunks == 1)
{
- ScanKeyEntryInitialize(&toastkey[1],
- (bits16) 0,
+ ScanKeyEntryInitialize(&toastkey[1], 0,
(AttrNumber) 2,
- (RegProcedure) F_INT4EQ,
- Int32GetDatum(startchunk));
+ BTEqualStrategyNumber, F_INT4EQ,
+ Int32GetDatum(startchunk), INT4OID);
nscankeys = 2;
}
else
{
- ScanKeyEntryInitialize(&toastkey[1],
- (bits16) 0,
+ ScanKeyEntryInitialize(&toastkey[1], 0,
(AttrNumber) 2,
- (RegProcedure) F_INT4GE,
- Int32GetDatum(startchunk));
- ScanKeyEntryInitialize(&toastkey[2],
- (bits16) 0,
+ BTGreaterEqualStrategyNumber, F_INT4GE,
+ Int32GetDatum(startchunk), INT4OID);
+ ScanKeyEntryInitialize(&toastkey[2], 0,
(AttrNumber) 2,
- (RegProcedure) F_INT4LE,
- Int32GetDatum(endchunk));
+ BTLessEqualStrategyNumber, F_INT4LE,
+ Int32GetDatum(endchunk), INT4OID);
nscankeys = 3;
}
diff --git a/src/backend/access/index/Makefile b/src/backend/access/index/Makefile
index dcae193bff..cc3d2ee138 100644
--- a/src/backend/access/index/Makefile
+++ b/src/backend/access/index/Makefile
@@ -4,7 +4,7 @@
# Makefile for access/index
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.10 2000/08/31 16:09:36 petere Exp $
+# $Header: /cvsroot/pgsql/src/backend/access/index/Makefile,v 1.11 2003/11/09 21:30:35 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -12,7 +12,7 @@ subdir = src/backend/access/index
top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
-OBJS = genam.o indexam.o istrat.o
+OBJS = genam.o indexam.o
all: SUBSYS.o
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
deleted file mode 100644
index 1298420d4f..0000000000
--- a/src/backend/access/index/istrat.c
+++ /dev/null
@@ -1,479 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * istrat.c
- * index scan strategy manipulation code and index strategy manipulation
- * operator code.
- *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.60 2003/08/04 02:39:57 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "access/istrat.h"
-
-
-#ifdef USE_ASSERT_CHECKING
-static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
-static bool StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy);
-static bool StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy);
-static bool StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy);
-#endif
-
-
-/* ----------------------------------------------------------------
- * misc strategy support routines
- * ----------------------------------------------------------------
- */
-
-/*
- * StrategyNumberIsValid
- * StrategyNumberIsInBounds
- * StrategyMapIsValid
- * StrategyTransformMapIsValid
- * IndexStrategyIsValid
- *
- * ... are now macros in istrat.h -cim 4/27/91
- */
-
-/*
- * StrategyMapGetScanKeyEntry
- * Returns a scan key entry of a index strategy mapping member.
- *
- * Note:
- * Assumes that the index strategy mapping is valid.
- * Assumes that the index strategy number is valid.
- * Bounds checking should be done outside this routine.
- */
-ScanKey
-StrategyMapGetScanKeyEntry(StrategyMap map,
- StrategyNumber strategyNumber)
-{
- Assert(StrategyMapIsValid(map));
- Assert(StrategyNumberIsValid(strategyNumber));
- return &map->entry[strategyNumber - 1];
-}
-
-/*
- * IndexStrategyGetStrategyMap
- * Returns an index strategy mapping of an index strategy.
- *
- * Note:
- * Assumes that the index strategy is valid.
- * Assumes that the number of index strategies is valid.
- * Bounds checking should be done outside this routine.
- */
-StrategyMap
-IndexStrategyGetStrategyMap(IndexStrategy indexStrategy,
- StrategyNumber maxStrategyNum,
- AttrNumber attrNum)
-{
- Assert(IndexStrategyIsValid(indexStrategy));
- Assert(StrategyNumberIsValid(maxStrategyNum));
- Assert(AttributeNumberIsValid(attrNum));
-
- maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */
- return &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)];
-}
-
-/*
- * AttributeNumberGetIndexStrategySize
- * Computes the size of an index strategy.
- */
-Size
-AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
- StrategyNumber maxStrategyNumber)
-{
- maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
- return maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData);
-}
-
-#ifdef USE_ASSERT_CHECKING
-/*
- * StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91
- */
-
-/* ----------------
- * StrategyOperatorIsValid
- * ----------------
- */
-static bool
-StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy)
-{
- return (bool)
- (PointerIsValid(operator) &&
- StrategyNumberIsInBounds(operator->strategy, maxStrategy) &&
- !(operator->flags & ~(SK_NEGATE | SK_COMMUTE)));
-}
-
-/* ----------------
- * StrategyTermIsValid
- * ----------------
- */
-static bool
-StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy)
-{
- Index index;
-
- if (!PointerIsValid(term) || term->degree == 0)
- return false;
-
- for (index = 0; index < term->degree; index += 1)
- {
- if (!StrategyOperatorIsValid(&term->operatorData[index],
- maxStrategy))
- return false;
- }
-
- return true;
-}
-
-/* ----------------
- * StrategyExpressionIsValid
- * ----------------
- */
-static bool
-StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy)
-{
- StrategyTerm *termP;
-
- if (!PointerIsValid(expression))
- return true;
-
- if (!StrategyTermIsValid(expression->term[0], maxStrategy))
- return false;
-
- termP = &expression->term[1];
- while (StrategyTermIsValid(*termP, maxStrategy))
- termP += 1;
-
- return (bool)
- (!PointerIsValid(*termP));
-}
-
-/* ----------------
- * StrategyEvaluationIsValid
- * ----------------
- */
-static bool
-StrategyEvaluationIsValid(StrategyEvaluation evaluation)
-{
- Index index;
-
- if (!PointerIsValid(evaluation) ||
- !StrategyNumberIsValid(evaluation->maxStrategy) ||
- !StrategyTransformMapIsValid(evaluation->negateTransform) ||
- !StrategyTransformMapIsValid(evaluation->commuteTransform) ||
- !StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
- return false;
-
- for (index = 0; index < evaluation->maxStrategy; index += 1)
- {
- if (!StrategyExpressionIsValid(evaluation->expression[index],
- evaluation->maxStrategy))
- return false;
- }
- return true;
-}
-#endif
-
-#ifdef NOT_USED
-/* ----------------
- * StrategyTermEvaluate
- * ----------------
- */
-static bool
-StrategyTermEvaluate(StrategyTerm term,
- StrategyMap map,
- Datum left,
- Datum right)
-{
- bool result = false;
- Index index;
- StrategyOperator operator;
-
- for (index = 0, operator = &term->operatorData[0];
- index < term->degree; index += 1, operator += 1)
- {
- ScanKey entry;
-
- entry = &map->entry[operator->strategy - 1];
-
- Assert(RegProcedureIsValid(entry->sk_procedure));
-
- switch (operator->flags ^ entry->sk_flags)
- {
- case 0x0:
- result = DatumGetBool(FunctionCall2(&entry->sk_func,
- left, right));
- break;
-
- case SK_NEGATE:
- result = !DatumGetBool(FunctionCall2(&entry->sk_func,
- left, right));
- break;
-
- case SK_COMMUTE:
- result = DatumGetBool(FunctionCall2(&entry->sk_func,
- right, left));
- break;
-
- case SK_NEGATE | SK_COMMUTE:
- result = !DatumGetBool(FunctionCall2(&entry->sk_func,
- right, left));
- break;
-
- default:
- elog(ERROR, "impossible strategy case: %d",
- operator->flags ^ entry->sk_flags);
- }
- if (!result)
- return result;
- }
-
- return result;
-}
-#endif
-
-/* ----------------
- * RelationGetStrategy
- *
- * Identify strategy number that describes given procedure, if there is one.
- * ----------------
- */
-StrategyNumber
-RelationGetStrategy(Relation relation,
- AttrNumber attributeNumber,
- StrategyEvaluation evaluation,
- RegProcedure procedure)
-{
- StrategyNumber strategy;
- StrategyMap strategyMap;
- ScanKey entry;
- Index index;
- int numattrs;
-
- Assert(RelationIsValid(relation));
- numattrs = RelationGetNumberOfAttributes(relation);
-
- Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
- Assert((attributeNumber >= 1) && (attributeNumber <= numattrs));
-
- Assert(StrategyEvaluationIsValid(evaluation));
- Assert(RegProcedureIsValid(procedure));
-
- strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- evaluation->maxStrategy,
- attributeNumber);
-
- /* get a strategy number for the procedure ignoring flags for now */
- for (index = 0; index < evaluation->maxStrategy; index += 1)
- {
- if (strategyMap->entry[index].sk_procedure == procedure)
- break;
- }
-
- if (index == evaluation->maxStrategy)
- return InvalidStrategy;
-
- strategy = 1 + index;
- entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
-
- Assert(!(entry->sk_flags & ~(SK_NEGATE | SK_COMMUTE)));
-
- switch (entry->sk_flags & (SK_NEGATE | SK_COMMUTE))
- {
- case 0x0:
- return strategy;
-
- case SK_NEGATE:
- strategy = evaluation->negateTransform->strategy[strategy - 1];
- break;
-
- case SK_COMMUTE:
- strategy = evaluation->commuteTransform->strategy[strategy - 1];
- break;
-
- case SK_NEGATE | SK_COMMUTE:
- strategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
- break;
-
- default:
- elog(ERROR, "impossible strategy case: %d",
- entry->sk_flags);
- }
-
- if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
- {
- if (!StrategyNumberIsValid(strategy))
- elog(ERROR, "corrupted strategy evaluation");
- }
-
- return strategy;
-}
-
-#ifdef NOT_USED
-/* ----------------
- * RelationInvokeStrategy
- * ----------------
- */
-bool /* XXX someday, this may return Datum */
-RelationInvokeStrategy(Relation relation,
- StrategyEvaluation evaluation,
- AttrNumber attributeNumber,
- StrategyNumber strategy,
- Datum left,
- Datum right)
-{
- StrategyNumber newStrategy;
- StrategyMap strategyMap;
- ScanKey entry;
- StrategyTermData termData;
- int numattrs;
-
- Assert(RelationIsValid(relation));
- Assert(relation->rd_rel->relkind == RELKIND_INDEX); /* XXX use accessor */
- numattrs = RelationGetNumberOfAttributes(relation);
-
- Assert(StrategyEvaluationIsValid(evaluation));
- Assert(AttributeNumberIsValid(attributeNumber));
- Assert((attributeNumber >= 1) && (attributeNumber < 1 + numattrs));
-
- Assert(StrategyNumberIsInBounds(strategy, evaluation->maxStrategy));
-
- termData.degree = 1;
-
- strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- evaluation->maxStrategy,
- attributeNumber);
-
- entry = StrategyMapGetScanKeyEntry(strategyMap, strategy);
-
- if (RegProcedureIsValid(entry->sk_procedure))
- {
- termData.operatorData[0].strategy = strategy;
- termData.operatorData[0].flags = 0x0;
-
- return StrategyTermEvaluate(&termData, strategyMap, left, right);
- }
-
-
- newStrategy = evaluation->negateTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
- {
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure))
- {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_NEGATE;
-
- return StrategyTermEvaluate(&termData, strategyMap, left, right);
- }
- }
-
- newStrategy = evaluation->commuteTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
- {
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure))
- {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_COMMUTE;
-
- return StrategyTermEvaluate(&termData, strategyMap, left, right);
- }
- }
-
- newStrategy = evaluation->negateCommuteTransform->strategy[strategy - 1];
- if (newStrategy != strategy && StrategyNumberIsValid(newStrategy))
- {
- entry = StrategyMapGetScanKeyEntry(strategyMap, newStrategy);
-
- if (RegProcedureIsValid(entry->sk_procedure))
- {
- termData.operatorData[0].strategy = newStrategy;
- termData.operatorData[0].flags = SK_NEGATE | SK_COMMUTE;
-
- return StrategyTermEvaluate(&termData, strategyMap, left, right);
- }
- }
-
- if (PointerIsValid(evaluation->expression[strategy - 1]))
- {
- StrategyTerm *termP;
-
- termP = &evaluation->expression[strategy - 1]->term[0];
- while (PointerIsValid(*termP))
- {
- Index index;
-
- for (index = 0; index < (*termP)->degree; index += 1)
- {
- entry = StrategyMapGetScanKeyEntry(strategyMap,
- (*termP)->operatorData[index].strategy);
-
- if (!RegProcedureIsValid(entry->sk_procedure))
- break;
- }
-
- if (index == (*termP)->degree)
- return StrategyTermEvaluate(*termP, strategyMap, left, right);
-
- termP += 1;
- }
- }
-
- elog(ERROR, "cannot evaluate strategy %d", strategy);
-
- /* not reached, just to make compiler happy */
- return FALSE;
-}
-#endif
-
-/* ----------------
- * IndexStrategyDisplay
- * ----------------
- */
-#ifdef ISTRATDEBUG
-int
-IndexStrategyDisplay(IndexStrategy indexStrategy,
- StrategyNumber numberOfStrategies,
- int numberOfAttributes)
-{
- StrategyMap strategyMap;
- AttrNumber attributeNumber;
- StrategyNumber strategyNumber;
-
- for (attributeNumber = 1; attributeNumber <= numberOfAttributes;
- attributeNumber += 1)
- {
- strategyMap = IndexStrategyGetStrategyMap(indexStrategy,
- numberOfStrategies,
- attributeNumber);
-
- for (strategyNumber = 1;
- strategyNumber <= AMStrategies(numberOfStrategies);
- strategyNumber += 1)
- {
- printf(":att %d\t:str %d\t:opr 0x%x(%d)\n",
- attributeNumber, strategyNumber,
- strategyMap->entry[strategyNumber - 1].sk_procedure,
- strategyMap->entry[strategyNumber - 1].sk_procedure);
- }
- }
-}
-
-#endif /* defined(ISTRATDEBUG) */
diff --git a/src/backend/access/nbtree/Makefile b/src/backend/access/nbtree/Makefile
index cf525f9f1f..487c0a9444 100644
--- a/src/backend/access/nbtree/Makefile
+++ b/src/backend/access/nbtree/Makefile
@@ -4,7 +4,7 @@
# Makefile for access/nbtree
#
# IDENTIFICATION
-# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.12 2003/02/21 00:06:21 tgl Exp $
+# $Header: /cvsroot/pgsql/src/backend/access/nbtree/Makefile,v 1.13 2003/11/09 21:30:35 tgl Exp $
#
#-------------------------------------------------------------------------
@@ -13,7 +13,7 @@ top_builddir = ../../../..
include $(top_builddir)/src/Makefile.global
OBJS = nbtcompare.o nbtinsert.o nbtpage.o nbtree.o nbtsearch.o \
- nbtstrat.o nbtutils.o nbtsort.o nbtxlog.o
+ nbtutils.o nbtsort.o nbtxlog.o
all: SUBSYS.o
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 27c833408d..98f3abb511 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
*
- * btinsert.c
+ * nbtinsert.c
* Item insertion in Lehman and Yao btrees for Postgres.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.106 2003/09/25 06:57:57 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtinsert.c,v 1.107 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
diff --git a/src/backend/access/nbtree/nbtsearch.c b/src/backend/access/nbtree/nbtsearch.c
index d27af61c5c..432a1ab0c2 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.80 2003/08/08 21:41:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtsearch.c,v 1.81 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -488,8 +488,6 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
/* if we didn't find a boundary for the preceding attr, quit */
if (attno > keysCount + 1)
break;
- strat = _bt_getstrat(rel, attno,
- so->keyData[i].sk_procedure);
/*
* Can we use this key as a starting boundary for this attr?
@@ -497,6 +495,7 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
* 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;
@@ -555,13 +554,17 @@ _bt_first(IndexScanDesc scan, ScanDirection dir)
elog(ERROR, "btree doesn't support is(not)null, yet");
return false;
}
+ /*
+ * XXX what if sk_argtype is not same as index?
+ */
procinfo = index_getprocinfo(rel, i + 1, BTORDER_PROC);
ScanKeyEntryInitializeWithInfo(scankeys + i,
so->keyData[j].sk_flags,
i + 1,
+ InvalidStrategy,
procinfo,
- CurrentMemoryContext,
- so->keyData[j].sk_argument);
+ so->keyData[j].sk_argument,
+ so->keyData[j].sk_argtype);
}
if (nKeyIs)
pfree(nKeyIs);
diff --git a/src/backend/access/nbtree/nbtstrat.c b/src/backend/access/nbtree/nbtstrat.c
deleted file mode 100644
index 15544d4757..0000000000
--- a/src/backend/access/nbtree/nbtstrat.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * nbtstrat.c
- * Strategy map entries for the btree indexed access method
- *
- * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/Attic/nbtstrat.c,v 1.18 2003/08/04 02:39:57 momjian Exp $
- *
- *-------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "access/istrat.h"
-#include "access/nbtree.h"
-
-/*
- * Note:
- * StrategyNegate, StrategyCommute, and StrategyNegateCommute
- * assume <, <=, ==, >=, > ordering.
- */
-static StrategyNumber BTNegate[BTMaxStrategyNumber] = {
- BTGreaterEqualStrategyNumber,
- BTGreaterStrategyNumber,
- InvalidStrategy,
- BTLessStrategyNumber,
- BTLessEqualStrategyNumber
-};
-
-static StrategyNumber BTCommute[BTMaxStrategyNumber] = {
- BTGreaterStrategyNumber,
- BTGreaterEqualStrategyNumber,
- InvalidStrategy,
- BTLessEqualStrategyNumber,
- BTLessStrategyNumber
-};
-
-static StrategyNumber BTNegateCommute[BTMaxStrategyNumber] = {
- BTLessEqualStrategyNumber,
- BTLessStrategyNumber,
- InvalidStrategy,
- BTGreaterStrategyNumber,
- BTGreaterEqualStrategyNumber
-};
-
-static uint16 BTLessTermData[] = { /* XXX type clash */
- 2,
- BTLessStrategyNumber,
- SK_NEGATE,
- BTLessStrategyNumber,
- SK_NEGATE | SK_COMMUTE
-};
-
-static uint16 BTLessEqualTermData[] = { /* XXX type clash */
- 2,
- BTLessEqualStrategyNumber,
- 0x0,
- BTLessEqualStrategyNumber,
- SK_COMMUTE
-};
-
-static uint16 BTGreaterEqualTermData[] = { /* XXX type clash */
- 2,
- BTGreaterEqualStrategyNumber,
- 0x0,
- BTGreaterEqualStrategyNumber,
- SK_COMMUTE
-};
-
-static uint16 BTGreaterTermData[] = { /* XXX type clash */
- 2,
- BTGreaterStrategyNumber,
- SK_NEGATE,
- BTGreaterStrategyNumber,
- SK_NEGATE | SK_COMMUTE
-};
-
-static StrategyTerm BTEqualExpressionData[] = {
- (StrategyTerm) BTLessTermData, /* XXX */
- (StrategyTerm) BTLessEqualTermData, /* XXX */
- (StrategyTerm) BTGreaterEqualTermData, /* XXX */
- (StrategyTerm) BTGreaterTermData, /* XXX */
- NULL
-};
-
-static StrategyExpression BTEvaluationExpressions[BTMaxStrategyNumber] = {
- NULL,
- NULL,
- (StrategyExpression) BTEqualExpressionData,
- NULL,
- NULL
-};
-
-static StrategyEvaluationData BTEvaluationData = {
- BTMaxStrategyNumber,
- (StrategyTransformMap) BTNegate,
- (StrategyTransformMap) BTCommute,
- (StrategyTransformMap) BTNegateCommute,
- BTEvaluationExpressions
-};
-
-/* ----------------------------------------------------------------
- * RelationGetBTStrategy
- * ----------------------------------------------------------------
- */
-
-StrategyNumber
-_bt_getstrat(Relation rel,
- AttrNumber attno,
- RegProcedure proc)
-{
- StrategyNumber strat;
-
- strat = RelationGetStrategy(rel, attno, &BTEvaluationData, proc);
-
- Assert(StrategyNumberIsValid(strat));
-
- return strat;
-}
-
-#ifdef NOT_USED
-
-bool
-_bt_invokestrat(Relation rel,
- AttrNumber attno,
- StrategyNumber strat,
- Datum left,
- Datum right)
-{
- return (RelationInvokeStrategy(rel, &BTEvaluationData, attno, strat,
- left, right));
-}
-
-#endif
diff --git a/src/backend/access/nbtree/nbtutils.c b/src/backend/access/nbtree/nbtutils.c
index 44980588a8..54cd7c8cd0 100644
--- a/src/backend/access/nbtree/nbtutils.c
+++ b/src/backend/access/nbtree/nbtutils.c
@@ -1,6 +1,6 @@
/*-------------------------------------------------------------------------
*
- * btutils.c
+ * nbtutils.c
* Utility code for Postgres btree implementation.
*
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.54 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/nbtree/nbtutils.c,v 1.55 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -16,13 +16,10 @@
#include "postgres.h"
#include "access/genam.h"
-#include "access/istrat.h"
#include "access/nbtree.h"
#include "catalog/catalog.h"
#include "executor/execdebug.h"
-
-
-static int _bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map);
+#include "utils/lsyscache.h"
/*
@@ -39,10 +36,6 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
TupleDesc itupdesc;
int natts;
int i;
- FmgrInfo *procinfo;
- Datum arg;
- bool null;
- bits16 flag;
itupdesc = RelationGetDescr(rel);
natts = RelationGetNumberOfAttributes(rel);
@@ -51,15 +44,23 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
for (i = 0; i < natts; i++)
{
+ FmgrInfo *procinfo;
+ Datum arg;
+ bool null;
+
+ /*
+ * We can use the cached 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);
- flag = null ? SK_ISNULL : 0x0;
ScanKeyEntryInitializeWithInfo(&skey[i],
- flag,
+ null ? SK_ISNULL : 0,
(AttrNumber) (i + 1),
+ InvalidStrategy,
procinfo,
- CurrentMemoryContext,
- arg);
+ arg,
+ itupdesc->attrs[i]->atttypid);
}
return skey;
@@ -68,33 +69,42 @@ _bt_mkscankey(Relation rel, IndexTuple itup)
/*
* _bt_mkscankey_nodata
* Build a scan key that contains comparator routines appropriate to
- * the key datatypes, but no comparison data.
+ * the key datatypes, but no comparison data. The comparison data
+ * ultimately used must match the key datatypes.
*
* The result cannot be used with _bt_compare(). Currently this
- * routine is only called by utils/sort/tuplesort.c, which has its
- * own comparison routine.
+ * routine is only called by nbtsort.c and tuplesort.c, which have
+ * their own comparison routines.
*/
ScanKey
_bt_mkscankey_nodata(Relation rel)
{
ScanKey skey;
+ TupleDesc itupdesc;
int natts;
int i;
- FmgrInfo *procinfo;
+ itupdesc = RelationGetDescr(rel);
natts = RelationGetNumberOfAttributes(rel);
skey = (ScanKey) palloc(natts * sizeof(ScanKeyData));
for (i = 0; i < natts; i++)
{
+ FmgrInfo *procinfo;
+
+ /*
+ * We can use the cached 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,
procinfo,
- CurrentMemoryContext,
- (Datum) 0);
+ (Datum) 0,
+ itupdesc->attrs[i]->atttypid);
}
return skey;
@@ -185,17 +195,6 @@ _bt_formitem(IndexTuple itup)
* 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.
- *
- * XXX this routine is one of many places that fail to handle SK_COMMUTE
- * scankeys properly. Currently, the planner is careful never to generate
- * any indexquals that would require SK_COMMUTE to be set. Someday we ought
- * to try to fix this, though it's not real critical as long as indexable
- * operators all have commutators...
- *
- * Note: this routine invokes comparison operators via OidFunctionCallN,
- * ie, without caching function lookups. No point in trying to be smarter,
- * since these comparisons are executed only when the user expresses a
- * hokey qualification, and happen only once per scan anyway.
*----------
*/
void
@@ -208,7 +207,6 @@ _bt_orderkeys(IndexScanDesc scan)
int numberOfKeys = so->numberOfKeys;
ScanKey key;
ScanKey cur;
- StrategyMap map;
Datum test;
int i,
j;
@@ -229,6 +227,32 @@ _bt_orderkeys(IndexScanDesc scan)
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)
{
@@ -243,11 +267,7 @@ _bt_orderkeys(IndexScanDesc scan)
relation->rd_rel->relnatts == 1)
{
/* it's a unique index, do we have an equality qual? */
- map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- BTMaxStrategyNumber,
- 1);
- j = _bt_getstrategynumber(cur->sk_procedure, map);
- if (j == (BTEqualStrategyNumber - 1))
+ if (cur->sk_strategy == BTEqualStrategyNumber)
scan->keys_are_unique = true;
}
so->numberOfRequiredKeys = 1;
@@ -267,9 +287,6 @@ _bt_orderkeys(IndexScanDesc scan)
* any; init[i] is TRUE if we have found such a key for this attr.
*/
attno = 1;
- map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- BTMaxStrategyNumber,
- attno);
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
MemSet(init, 0, sizeof(init));
@@ -324,9 +341,9 @@ _bt_orderkeys(IndexScanDesc scan)
j == (BTEqualStrategyNumber - 1))
continue;
chk = &xform[j];
- test = OidFunctionCall2(chk->sk_procedure,
- eq->sk_argument,
- chk->sk_argument);
+ test = FunctionCall2(&chk->sk_func,
+ eq->sk_argument,
+ chk->sk_argument);
if (!DatumGetBool(test))
so->qual_ok = false;
}
@@ -350,9 +367,9 @@ _bt_orderkeys(IndexScanDesc scan)
ScanKeyData *lt = &xform[BTLessStrategyNumber - 1];
ScanKeyData *le = &xform[BTLessEqualStrategyNumber - 1];
- test = OidFunctionCall2(le->sk_procedure,
- lt->sk_argument,
- le->sk_argument);
+ test = FunctionCall2(&le->sk_func,
+ lt->sk_argument,
+ le->sk_argument);
if (DatumGetBool(test))
init[BTLessEqualStrategyNumber - 1] = false;
else
@@ -366,9 +383,9 @@ _bt_orderkeys(IndexScanDesc scan)
ScanKeyData *gt = &xform[BTGreaterStrategyNumber - 1];
ScanKeyData *ge = &xform[BTGreaterEqualStrategyNumber - 1];
- test = OidFunctionCall2(ge->sk_procedure,
- gt->sk_argument,
- ge->sk_argument);
+ test = FunctionCall2(&ge->sk_func,
+ gt->sk_argument,
+ ge->sk_argument);
if (DatumGetBool(test))
init[BTGreaterEqualStrategyNumber - 1] = false;
else
@@ -404,15 +421,12 @@ _bt_orderkeys(IndexScanDesc scan)
/* Re-initialize for new attno */
attno = cur->sk_attno;
- map = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(relation),
- BTMaxStrategyNumber,
- attno);
MemSet(xform, 0, sizeof(xform)); /* not really necessary */
MemSet(init, 0, sizeof(init));
}
/* figure out which strategy this key's operator corresponds to */
- j = _bt_getstrategynumber(cur->sk_procedure, map);
+ j = cur->sk_strategy - 1;
/* have we seen one of these before? */
if (init[j])
@@ -447,25 +461,6 @@ _bt_orderkeys(IndexScanDesc scan)
}
/*
- * Determine which btree strategy an operator procedure matches.
- *
- * Result is strategy number minus 1.
- */
-static int
-_bt_getstrategynumber(RegProcedure sk_procedure, StrategyMap map)
-{
- int j;
-
- for (j = BTMaxStrategyNumber; --j >= 0;)
- {
- if (sk_procedure == map->entry[j].sk_procedure)
- return j;
- }
- elog(ERROR, "could not identify operator %u", sk_procedure);
- return -1; /* keep compiler quiet */
-}
-
-/*
* Test whether an indextuple satisfies all the scankey conditions.
*
* If the tuple fails to pass the qual, we also determine whether there's
@@ -533,14 +528,9 @@ _bt_checkkeys(IndexScanDesc scan, IndexTuple tuple,
return false;
}
- if (key->sk_flags & SK_COMMUTE)
- test = FunctionCall2(&key->sk_func,
- key->sk_argument, datum);
- else
- test = FunctionCall2(&key->sk_func,
- datum, key->sk_argument);
+ test = FunctionCall2(&key->sk_func, datum, key->sk_argument);
- if (DatumGetBool(test) == !!(key->sk_flags & SK_NEGATE))
+ if (!DatumGetBool(test))
{
/*
* Tuple fails this qual. If it's a required qual, then we
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
index f3329448d9..263fff4bf2 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.47 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtscan.c,v 1.48 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -17,7 +17,7 @@
#include "access/genam.h"
#include "access/rtree.h"
-
+#include "utils/lsyscache.h"
/* routines defined and used here */
@@ -71,7 +71,6 @@ rtrescan(PG_FUNCTION_ARGS)
IndexScanDesc s = (IndexScanDesc) PG_GETARG_POINTER(0);
ScanKey key = (ScanKey) PG_GETARG_POINTER(1);
RTreeScanOpaque p;
- RegProcedure internal_proc;
int i;
/*
@@ -116,14 +115,23 @@ rtrescan(PG_FUNCTION_ARGS)
*/
for (i = 0; i < s->numberOfKeys; i++)
{
- internal_proc = RTMapOperator(s->indexRelation,
- s->keyData[i].sk_attno,
- s->keyData[i].sk_procedure);
+ AttrNumber attno = s->keyData[i].sk_attno;
+ Oid opclass;
+ StrategyNumber int_strategy;
+ Oid int_oper;
+ RegProcedure int_proc;
+
+ 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_proc = get_opcode(int_oper);
ScanKeyEntryInitialize(&(p->s_internalKey[i]),
s->keyData[i].sk_flags,
- s->keyData[i].sk_attno,
- internal_proc,
- s->keyData[i].sk_argument);
+ attno,
+ int_strategy,
+ int_proc,
+ s->keyData[i].sk_argument,
+ s->keyData[i].sk_argtype);
}
}
diff --git a/src/backend/access/rtree/rtstrat.c b/src/backend/access/rtree/rtstrat.c
index f7253a48e1..7d9097c8ea 100644
--- a/src/backend/access/rtree/rtstrat.c
+++ b/src/backend/access/rtree/rtstrat.c
@@ -8,176 +8,18 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.21 2003/08/04 02:39:57 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtstrat.c,v 1.22 2003/11/09 21:30:35 tgl Exp $
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
-#include "access/istrat.h"
#include "access/rtree.h"
-static StrategyNumber RelationGetRTStrategy(Relation r,
- AttrNumber attnum, RegProcedure proc);
/*
- * Note: negate, commute, and negatecommute all assume that operators are
- * ordered as follows in the strategy map:
- *
- * left, left-or-overlap, overlap, right-or-overlap, right, same,
- * contains, contained-by
- *
- * The negate, commute, and negatecommute arrays are used by the planner
- * to plan indexed scans over data that appears in the qualificiation in
- * a boolean negation, or whose operands appear in the wrong order. For
- * example, if the operator "<%" means "contains", and the user says
- *
- * where not rel.box <% "(10,10,20,20)"::box
- *
- * the planner can plan an index scan by noting that rtree indices have
- * an operator in their operator class for negating <%.
- *
- * Similarly, if the user says something like
- *
- * where "(10,10,20,20)"::box <% rel.box
- *
- * the planner can see that the rtree index on rel.box has an operator in
- * its opclass for commuting <%, and plan the scan using that operator.
- * This added complexity in the access methods makes the planner a lot easier
- * to write.
- */
-
-/* if a op b, what operator tells us if (not a op b)? */
-static StrategyNumber RTNegate[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/* if a op_1 b, what is the operator op_2 such that b op_2 a? */
-static StrategyNumber RTCommute[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/* if a op_1 b, what is the operator op_2 such that (b !op_2 a)? */
-static StrategyNumber RTNegateCommute[RTNStrategies] = {
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy,
- InvalidStrategy
-};
-
-/*
- * Now do the TermData arrays. These exist in case the user doesn't give
- * us a full set of operators for a particular operator class. The idea
- * is that by making multiple comparisons using any one of the supplied
- * operators, we can decide whether two n-dimensional polygons are equal.
- * For example, if a contains b and b contains a, we may conclude that
- * a and b are equal.
- *
- * The presence of the TermData arrays in all this is a historical accident.
- * Early in the development of the POSTGRES access methods, it was believed
- * that writing functions was harder than writing arrays. This is wrong;
- * TermData is hard to understand and hard to get right. In general, when
- * someone populates a new operator class, they populate it completely. If
- * Mike Hirohama had forced Cimarron Taylor to populate the strategy map
- * for btree int2_ops completely in 1988, you wouldn't have to deal with
- * all this now. Too bad for you.
- *
- * Since you can't necessarily do this in all cases (for example, you can't
- * do it given only "intersects" or "disjoint"), TermData arrays for some
- * operators don't appear below.
- *
- * Note that if you DO supply all the operators required in a given opclass
- * by inserting them into the pg_opclass system catalog, you can get away
- * without doing all this TermData stuff. Since the rtree code is intended
- * to be a reference for access method implementors, I'm doing TermData
- * correctly here.
- *
- * Note on style: these are all actually of type StrategyTermData, but
- * since those have variable-length data at the end of the struct we can't
- * properly initialize them if we declare them to be what they are.
- */
-
-/* if you only have "contained-by", how do you determine equality? */
-static uint16 RTContainedByTermData[] = {
- 2, /* make two comparisons */
- RTContainedByStrategyNumber, /* use "a contained-by b" */
- 0x0, /* without any magic */
- RTContainedByStrategyNumber, /* then use contained-by, */
- SK_COMMUTE /* swapping a and b */
-};
-
-/* if you only have "contains", how do you determine equality? */
-static uint16 RTContainsTermData[] = {
- 2, /* make two comparisons */
- RTContainsStrategyNumber, /* use "a contains b" */
- 0x0, /* without any magic */
- RTContainsStrategyNumber, /* then use contains again, */
- SK_COMMUTE /* swapping a and b */
-};
-
-/* now put all that together in one place for the planner */
-static StrategyTerm RTEqualExpressionData[] = {
- (StrategyTerm) RTContainedByTermData,
- (StrategyTerm) RTContainsTermData,
- NULL
-};
-
-/*
- * If you were sufficiently attentive to detail, you would go through
- * the ExpressionData pain above for every one of the seven strategies
- * we defined. I am not. Now we declare the StrategyEvaluationData
- * structure that gets shipped around to help the planner and the access
- * method decide what sort of scan it should do, based on (a) what the
- * user asked for, (b) what operators are defined for a particular opclass,
- * and (c) the reams of information we supplied above.
- *
- * The idea of all of this initialized data is to make life easier on the
- * user when he defines a new operator class to use this access method.
- * By filling in all the data, we let him get away with leaving holes in his
- * operator class, and still let him use the index. The added complexity
- * in the access methods just isn't worth the trouble, though.
- */
-
-static StrategyExpression RTEvaluationExpressions[RTNStrategies] = {
- NULL, /* express left */
- NULL, /* express overleft */
- NULL, /* express overlap */
- NULL, /* express overright */
- NULL, /* express right */
- (StrategyExpression) RTEqualExpressionData, /* express same */
- NULL, /* express contains */
- NULL /* express contained-by */
-};
-
-static StrategyEvaluationData RTEvaluationData = {
- RTNStrategies, /* # of strategies */
- (StrategyTransformMap) RTNegate, /* how to do (not qual) */
- (StrategyTransformMap) RTCommute, /* how to swap operands */
- (StrategyTransformMap) RTNegateCommute, /* how to do both */
- RTEvaluationExpressions
-};
-
-/*
- * Okay, now something peculiar to rtrees that doesn't apply to most other
+ * Here's something peculiar to rtrees that doesn't apply to most other
* indexing structures: When we're searching a tree for a given value, we
* can't do the same sorts of comparisons on internal node entries as we
* do at leaves. The reason is that if we're looking for (say) all boxes
@@ -191,7 +33,7 @@ static StrategyEvaluationData RTEvaluationData = {
* left, left-or-overlap, overlap, right-or-overlap, right, same,
* contains, contained-by
*/
-static StrategyNumber RTOperMap[RTNStrategies] = {
+static const StrategyNumber RTOperMap[RTNStrategies] = {
RTOverLeftStrategyNumber,
RTOverLeftStrategyNumber,
RTOverlapStrategyNumber,
@@ -202,39 +44,10 @@ static StrategyNumber RTOperMap[RTNStrategies] = {
RTOverlapStrategyNumber
};
-static StrategyNumber
-RelationGetRTStrategy(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
-{
- return RelationGetStrategy(r, attnum, &RTEvaluationData, proc);
-}
-#ifdef NOT_USED
-bool
-RelationInvokeRTStrategy(Relation r,
- AttrNumber attnum,
- StrategyNumber s,
- Datum left,
- Datum right)
+StrategyNumber
+RTMapToInternalOperator(StrategyNumber strat)
{
- return (RelationInvokeStrategy(r, &RTEvaluationData, attnum, s,
- left, right));
-}
-#endif
-
-RegProcedure
-RTMapOperator(Relation r,
- AttrNumber attnum,
- RegProcedure proc)
-{
- StrategyNumber procstrat;
- StrategyMap strategyMap;
-
- procstrat = RelationGetRTStrategy(r, attnum, proc);
- strategyMap = IndexStrategyGetStrategyMap(RelationGetIndexStrategy(r),
- RTNStrategies,
- attnum);
-
- return strategyMap->entry[RTOperMap[procstrat - 1] - 1].sk_procedure;
+ Assert(strat > 0 && strat <= RTNStrategies);
+ return RTOperMap[strat - 1];
}