mirror of https://github.com/postgres/postgres
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.REL8_0_STABLE
parent
723825afeb
commit
c1d62bfd00
@ -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 |
@ -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 |
@ -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) */ |
@ -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 |
@ -1,61 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* istrat.h |
||||
* POSTGRES index strategy definitions. |
||||
* |
||||
* |
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* $Id: istrat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $ |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#ifndef ISTRAT_H |
||||
#define ISTRAT_H |
||||
|
||||
#include "utils/rel.h" |
||||
|
||||
/*
|
||||
* StrategyNumberIsValid |
||||
* True iff the strategy number is valid. |
||||
*/ |
||||
#define StrategyNumberIsValid(strategyNumber) \ |
||||
((bool) ((strategyNumber) != InvalidStrategy)) |
||||
|
||||
/*
|
||||
* StrategyNumberIsInBounds |
||||
* True iff strategy number is within given bounds. |
||||
* |
||||
* Note: |
||||
* Assumes StrategyNumber is an unsigned type. |
||||
* Assumes the bounded interval to be (0,max]. |
||||
*/ |
||||
#define StrategyNumberIsInBounds(strategyNumber, maxStrategyNumber) \ |
||||
((bool)(InvalidStrategy < (strategyNumber) && \
|
||||
(strategyNumber) <= (maxStrategyNumber))) |
||||
|
||||
/*
|
||||
* StrategyMapIsValid |
||||
* True iff the index strategy mapping is valid. |
||||
*/ |
||||
#define StrategyMapIsValid(map) PointerIsValid(map) |
||||
|
||||
/*
|
||||
* IndexStrategyIsValid |
||||
* True iff the index strategy is valid. |
||||
*/ |
||||
#define IndexStrategyIsValid(s) PointerIsValid(s) |
||||
|
||||
extern ScanKey StrategyMapGetScanKeyEntry(StrategyMap map, |
||||
StrategyNumber strategyNumber); |
||||
extern StrategyMap IndexStrategyGetStrategyMap(IndexStrategy indexStrategy, |
||||
StrategyNumber maxStrategyNum, AttrNumber attrNum); |
||||
|
||||
extern Size AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber, |
||||
StrategyNumber maxStrategyNumber); |
||||
extern StrategyNumber RelationGetStrategy(Relation relation, |
||||
AttrNumber attributeNumber, StrategyEvaluation evaluation, |
||||
RegProcedure procedure); |
||||
|
||||
#endif /* ISTRAT_H */ |
@ -1,90 +0,0 @@ |
||||
/*-------------------------------------------------------------------------
|
||||
* |
||||
* strat.h |
||||
* index strategy type definitions |
||||
* (separated out from original istrat.h to avoid circular refs) |
||||
* |
||||
* |
||||
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group |
||||
* Portions Copyright (c) 1994, Regents of the University of California |
||||
* |
||||
* $Id: strat.h,v 1.27 2003/08/04 02:40:10 momjian Exp $ |
||||
* |
||||
*------------------------------------------------------------------------- |
||||
*/ |
||||
#ifndef STRAT_H |
||||
#define STRAT_H |
||||
|
||||
#include "access/skey.h" |
||||
|
||||
|
||||
typedef uint16 StrategyNumber; |
||||
|
||||
#define InvalidStrategy 0 |
||||
|
||||
typedef struct StrategyTransformMapData |
||||
{ |
||||
StrategyNumber strategy[1]; /* VARIABLE LENGTH ARRAY */ |
||||
} StrategyTransformMapData; /* VARIABLE LENGTH STRUCTURE */ |
||||
|
||||
typedef StrategyTransformMapData *StrategyTransformMap; |
||||
|
||||
typedef struct StrategyOperatorData |
||||
{ |
||||
StrategyNumber strategy; |
||||
bits16 flags; /* scan qualification flags, see skey.h */ |
||||
} StrategyOperatorData; |
||||
|
||||
typedef StrategyOperatorData *StrategyOperator; |
||||
|
||||
typedef struct StrategyTermData |
||||
{ /* conjunctive term */ |
||||
uint16 degree; |
||||
StrategyOperatorData operatorData[1]; /* VARIABLE LENGTH ARRAY */ |
||||
} StrategyTermData; /* VARIABLE LENGTH STRUCTURE */ |
||||
|
||||
typedef StrategyTermData *StrategyTerm; |
||||
|
||||
typedef struct StrategyExpressionData |
||||
{ /* disjunctive normal form */ |
||||
StrategyTerm term[1]; /* VARIABLE LENGTH ARRAY */ |
||||
} StrategyExpressionData; /* VARIABLE LENGTH STRUCTURE */ |
||||
|
||||
typedef StrategyExpressionData *StrategyExpression; |
||||
|
||||
typedef struct StrategyEvaluationData |
||||
{ |
||||
StrategyNumber maxStrategy; |
||||
/* each of these must point to an array of maxStrategy elements: */ |
||||
StrategyTransformMap negateTransform; |
||||
StrategyTransformMap commuteTransform; |
||||
StrategyTransformMap negateCommuteTransform; |
||||
StrategyExpression *expression; |
||||
} StrategyEvaluationData; |
||||
|
||||
typedef StrategyEvaluationData *StrategyEvaluation; |
||||
|
||||
/*
|
||||
* StrategyTransformMapIsValid |
||||
* Returns true iff strategy transformation map is valid. |
||||
*/ |
||||
#define StrategyTransformMapIsValid(transform) PointerIsValid(transform) |
||||
|
||||
|
||||
#define AMStrategies(foo) (foo) |
||||
|
||||
typedef struct StrategyMapData |
||||
{ |
||||
ScanKeyData entry[1]; /* VARIABLE LENGTH ARRAY */ |
||||
} StrategyMapData; /* VARIABLE LENGTH STRUCTURE */ |
||||
|
||||
typedef StrategyMapData *StrategyMap; |
||||
|
||||
typedef struct IndexStrategyData |
||||
{ |
||||
StrategyMapData strategyMapData[1]; /* VARIABLE LENGTH ARRAY */ |
||||
} IndexStrategyData; /* VARIABLE LENGTH STRUCTURE */ |
||||
|
||||
typedef IndexStrategyData *IndexStrategy; |
||||
|
||||
#endif /* STRAT_H */ |
Loading…
Reference in new issue