summaryrefslogtreecommitdiff
path: root/src/backend/access/rtree
diff options
context:
space:
mode:
authorTom Lane2003-11-09 21:30:38 +0000
committerTom Lane2003-11-09 21:30:38 +0000
commitc1d62bfd00f4d1ea0647e12947ca1de9fea39b33 (patch)
tree1afdccb5267627182cab94b347730657107ad6eb /src/backend/access/rtree
parent723825afebb6de7212fa18882bcc78212d5c1743 (diff)
Add operator strategy and comparison-value datatype fields to ScanKey.
Remove the 'strategy map' code, which was a large amount of mechanism that no longer had any use except reverse-mapping from procedure OID to strategy number. Passing the strategy number to the index AM in the first place is simpler and faster. This is a preliminary step in planned support for cross-datatype index operations. I'm committing it now since the ScanKeyEntryInitialize() API change touches quite a lot of files, and I want to commit those changes before the tree drifts under me.
Diffstat (limited to 'src/backend/access/rtree')
-rw-r--r--src/backend/access/rtree/rtscan.c26
-rw-r--r--src/backend/access/rtree/rtstrat.c201
2 files changed, 24 insertions, 203 deletions
diff --git a/src/backend/access/rtree/rtscan.c b/src/backend/access/rtree/rtscan.c
index f3329448d93..263fff4bf26 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 f7253a48e14..7d9097c8ea4 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];
}