aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/index/istrat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/index/istrat.c')
-rw-r--r--src/backend/access/index/istrat.c1095
1 files changed, 568 insertions, 527 deletions
diff --git a/src/backend/access/index/istrat.c b/src/backend/access/index/istrat.c
index 5c143f0aa5f..35158c22170 100644
--- a/src/backend/access/index/istrat.c
+++ b/src/backend/access/index/istrat.c
@@ -1,689 +1,730 @@
/*-------------------------------------------------------------------------
*
* istrat.c--
- * index scan strategy manipulation code and index strategy manipulation
- * operator code.
+ * index scan strategy manipulation code and index strategy manipulation
+ * operator code.
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.9 1997/08/22 16:48:14 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/access/index/Attic/istrat.c,v 1.10 1997/09/07 04:38:32 momjian Exp $
*
*-------------------------------------------------------------------------
*/
#include <postgres.h>
-
+
#include <catalog/pg_proc.h>
#include <catalog/pg_operator.h>
#include <catalog/catname.h>
#include <catalog/pg_index.h>
#include <catalog/pg_amop.h>
#include <catalog/pg_amproc.h>
-#include <utils/memutils.h> /* could have been access/itup.h */
+#include <utils/memutils.h> /* could have been access/itup.h */
#include <access/heapam.h>
#include <access/istrat.h>
#include <fmgr.h>
-#ifndef NO_ASSERT_CHECKING
-static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
-static bool StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy);
-static ScanKey StrategyMapGetScanKeyEntry(StrategyMap map,
- StrategyNumber strategyNumber);
-static bool StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy);
-static bool StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy);
+#ifndef NO_ASSERT_CHECKING
+static bool StrategyEvaluationIsValid(StrategyEvaluation evaluation);
+static bool
+StrategyExpressionIsValid(StrategyExpression expression,
+ StrategyNumber maxStrategy);
+static ScanKey
+StrategyMapGetScanKeyEntry(StrategyMap map,
+ StrategyNumber strategyNumber);
+static bool
+StrategyOperatorIsValid(StrategyOperator operator,
+ StrategyNumber maxStrategy);
+static bool
+StrategyTermIsValid(StrategyTerm term,
+ StrategyNumber maxStrategy);
+
#endif
/* ----------------------------------------------------------------
- * misc strategy support routines
+ * misc strategy support routines
* ----------------------------------------------------------------
*/
-
-/*
- * StrategyNumberIsValid
- * StrategyNumberIsInBounds
- * StrategyMapIsValid
- * StrategyTransformMapIsValid
- * IndexStrategyIsValid
+
+/*
+ * StrategyNumberIsValid
+ * StrategyNumberIsInBounds
+ * StrategyMapIsValid
+ * StrategyTransformMapIsValid
+ * IndexStrategyIsValid
*
- * ... are now macros in istrat.h -cim 4/27/91
+ * ... are now macros in istrat.h -cim 4/27/91
*/
-
+
/*
* StrategyMapGetScanKeyEntry --
- * Returns a scan key entry of a index strategy mapping member.
+ * 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.
+ * Assumes that the index strategy mapping is valid.
+ * Assumes that the index strategy number is valid.
+ * Bounds checking should be done outside this routine.
*/
-static ScanKey
+static ScanKey
StrategyMapGetScanKeyEntry(StrategyMap map,
- StrategyNumber strategyNumber)
+ StrategyNumber strategyNumber)
{
- Assert(StrategyMapIsValid(map));
- Assert(StrategyNumberIsValid(strategyNumber));
- return (&map->entry[strategyNumber - 1]);
+ Assert(StrategyMapIsValid(map));
+ Assert(StrategyNumberIsValid(strategyNumber));
+ return (&map->entry[strategyNumber - 1]);
}
/*
* IndexStrategyGetStrategyMap --
- * Returns an index strategy mapping of an index strategy.
+ * 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.
+ * 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)
+ StrategyNumber maxStrategyNum,
+ AttrNumber attrNum)
{
- Assert(IndexStrategyIsValid(indexStrategy));
- Assert(StrategyNumberIsValid(maxStrategyNum));
- Assert(AttributeNumberIsValid(attrNum));
-
- maxStrategyNum = AMStrategies(maxStrategyNum); /* XXX */
- return
- &indexStrategy->strategyMapData[maxStrategyNum * (attrNum - 1)];
+ 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.
+ * Computes the size of an index strategy.
*/
Size
AttributeNumberGetIndexStrategySize(AttrNumber maxAttributeNumber,
- StrategyNumber maxStrategyNumber)
+ StrategyNumber maxStrategyNumber)
{
- maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
- return
- maxAttributeNumber * maxStrategyNumber * sizeof (ScanKeyData);
+ maxStrategyNumber = AMStrategies(maxStrategyNumber); /* XXX */
+ return
+ maxAttributeNumber * maxStrategyNumber * sizeof(ScanKeyData);
}
-#ifndef NO_ASSERT_CHECKING
-/*
+#ifndef NO_ASSERT_CHECKING
+/*
* StrategyTransformMapIsValid is now a macro in istrat.h -cim 4/27/91
*/
/* ----------------
- * StrategyOperatorIsValid
+ * StrategyOperatorIsValid
* ----------------
*/
-static bool
+static bool
StrategyOperatorIsValid(StrategyOperator operator,
- StrategyNumber maxStrategy)
+ StrategyNumber maxStrategy)
{
- return (bool)
+ return (bool)
(PointerIsValid(operator) &&
StrategyNumberIsInBounds(operator->strategy, maxStrategy) &&
!(operator->flags & ~(SK_NEGATE | SK_COMMUTE)));
}
/* ----------------
- * StrategyTermIsValid
+ * StrategyTermIsValid
* ----------------
*/
-static bool
+static bool
StrategyTermIsValid(StrategyTerm term,
- StrategyNumber maxStrategy)
+ 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;
+ 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;
+
+ return true;
}
/* ----------------
- * StrategyExpressionIsValid
+ * StrategyExpressionIsValid
* ----------------
*/
-static bool
+static bool
StrategyExpressionIsValid(StrategyExpression expression,
- StrategyNumber maxStrategy)
+ 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));
+ 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
+ * StrategyEvaluationIsValid
* ----------------
*/
-static bool
+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;
+ Index index;
+
+ if (!PointerIsValid(evaluation) ||
+ !StrategyNumberIsValid(evaluation->maxStrategy) ||
+ !StrategyTransformMapIsValid(evaluation->negateTransform) ||
+ !StrategyTransformMapIsValid(evaluation->commuteTransform) ||
+ !StrategyTransformMapIsValid(evaluation->negateCommuteTransform))
+ {
+
+ return false;
}
- }
- return true;
+
+ for (index = 0; index < evaluation->maxStrategy; index += 1)
+ {
+ if (!StrategyExpressionIsValid(evaluation->expression[index],
+ evaluation->maxStrategy))
+ {
+
+ return false;
+ }
+ }
+ return true;
}
+
#endif
/* ----------------
- * StrategyTermEvaluate
+ * StrategyTermEvaluate
* ----------------
*/
-static bool
+static bool
StrategyTermEvaluate(StrategyTerm term,
- StrategyMap map,
- Datum left,
- Datum right)
+ StrategyMap map,
+ Datum left,
+ Datum right)
{
- Index index;
- long tmpres = 0;
- bool result = 0;
- StrategyOperator operator;
- ScanKey entry;
-
- for (index = 0, operator = &term->operatorData[0];
- index < term->degree; index += 1, operator += 1) {
-
- entry = &map->entry[operator->strategy - 1];
-
- Assert(RegProcedureIsValid(entry->sk_procedure));
-
- switch (operator->flags ^ entry->sk_flags) {
- case 0x0:
- tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- left, right);
- break;
-
- case SK_NEGATE:
- tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- left, right);
- break;
-
- case SK_COMMUTE:
- tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- right, left);
- break;
-
- case SK_NEGATE | SK_COMMUTE:
- tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
- right, left);
- break;
-
- default:
- elog(FATAL, "StrategyTermEvaluate: impossible case %d",
- operator->flags ^ entry->sk_flags);
+ Index index;
+ long tmpres = 0;
+ bool result = 0;
+ StrategyOperator operator;
+ ScanKey entry;
+
+ for (index = 0, operator = &term->operatorData[0];
+ index < term->degree; index += 1, operator += 1)
+ {
+
+ entry = &map->entry[operator->strategy - 1];
+
+ Assert(RegProcedureIsValid(entry->sk_procedure));
+
+ switch (operator->flags ^ entry->sk_flags)
+ {
+ case 0x0:
+ tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ left, right);
+ break;
+
+ case SK_NEGATE:
+ tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ left, right);
+ break;
+
+ case SK_COMMUTE:
+ tmpres = (long) FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ right, left);
+ break;
+
+ case SK_NEGATE | SK_COMMUTE:
+ tmpres = (long) !FMGR_PTR2(entry->sk_func, entry->sk_procedure,
+ right, left);
+ break;
+
+ default:
+ elog(FATAL, "StrategyTermEvaluate: impossible case %d",
+ operator->flags ^ entry->sk_flags);
+ }
+
+ result = (bool) tmpres;
+ if (!result)
+ return result;
}
-
- result = (bool) tmpres;
- if (!result)
- return result;
- }
-
- return result;
+
+ return result;
}
/* ----------------
- * RelationGetStrategy
+ * RelationGetStrategy
* ----------------
*/
StrategyNumber
RelationGetStrategy(Relation relation,
- AttrNumber attributeNumber,
- StrategyEvaluation evaluation,
- RegProcedure procedure)
+ 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(AttributeNumberIsValid(attributeNumber));
- Assert( (attributeNumber >= 1) && (attributeNumber < 1 + 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;
+ 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(AttributeNumberIsValid(attributeNumber));
+ Assert((attributeNumber >= 1) && (attributeNumber < 1 + 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(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags);
- }
-
-
- if (! StrategyNumberIsInBounds(strategy, evaluation->maxStrategy)) {
- if (! StrategyNumberIsValid(strategy)) {
- elog(WARN, "RelationGetStrategy: corrupted evaluation");
+
+ 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(FATAL, "RelationGetStrategy: impossible case %d", entry->sk_flags);
}
- }
-
- return strategy;
+
+
+ if (!StrategyNumberIsInBounds(strategy, evaluation->maxStrategy))
+ {
+ if (!StrategyNumberIsValid(strategy))
+ {
+ elog(WARN, "RelationGetStrategy: corrupted evaluation");
+ }
+ }
+
+ return strategy;
}
/* ----------------
- * RelationInvokeStrategy
+ * RelationInvokeStrategy
* ----------------
*/
-bool /* XXX someday, this may return Datum */
+bool /* XXX someday, this may return Datum */
RelationInvokeStrategy(Relation relation,
- StrategyEvaluation evaluation,
- AttrNumber attributeNumber,
- StrategyNumber strategy,
- Datum left,
- Datum right)
+ 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);
+ 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->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->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->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);
+
+ 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);
+ }
}
- }
-
- 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;
+
+ 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 (index == (*termP)->degree) {
- return
- StrategyTermEvaluate(*termP, strategyMap, left, right);
- }
-
- termP += 1;
}
- }
-
- elog(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d",
- strategy);
- /* not reached, just to make compiler happy */
- return FALSE;
+ 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(WARN, "RelationInvokeStrategy: cannot evaluate strategy %d",
+ strategy);
+
+ /* not reached, just to make compiler happy */
+ return FALSE;
}
/* ----------------
- * OperatorRelationFillScanKeyEntry
+ * OperatorRelationFillScanKeyEntry
* ----------------
*/
static void
OperatorRelationFillScanKeyEntry(Relation operatorRelation,
- Oid operatorObjectId,
- ScanKey entry)
+ Oid operatorObjectId,
+ ScanKey entry)
{
- HeapScanDesc scan;
- ScanKeyData scanKeyData;
- HeapTuple tuple;
-
- ScanKeyEntryInitialize(&scanKeyData, 0,
- ObjectIdAttributeNumber,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(operatorObjectId));
-
- scan = heap_beginscan(operatorRelation, false, NowTimeQual,
- 1, &scanKeyData);
-
- tuple = heap_getnext(scan, false, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple)) {
- elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu",
- (uint32) operatorObjectId);
- }
-
- entry->sk_flags = 0;
- entry->sk_procedure =
- ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode;
- fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs);
-
- if (! RegProcedureIsValid(entry->sk_procedure)) {
- elog(WARN,
- "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu",
- (uint32) operatorObjectId);
- }
-
- heap_endscan(scan);
+ HeapScanDesc scan;
+ ScanKeyData scanKeyData;
+ HeapTuple tuple;
+
+ ScanKeyEntryInitialize(&scanKeyData, 0,
+ ObjectIdAttributeNumber,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(operatorObjectId));
+
+ scan = heap_beginscan(operatorRelation, false, NowTimeQual,
+ 1, &scanKeyData);
+
+ tuple = heap_getnext(scan, false, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ {
+ elog(WARN, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu",
+ (uint32) operatorObjectId);
+ }
+
+ entry->sk_flags = 0;
+ entry->sk_procedure =
+ ((OperatorTupleForm) GETSTRUCT(tuple))->oprcode;
+ fmgr_info(entry->sk_procedure, &entry->sk_func, &entry->sk_nargs);
+
+ if (!RegProcedureIsValid(entry->sk_procedure))
+ {
+ elog(WARN,
+ "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu",
+ (uint32) operatorObjectId);
+ }
+
+ heap_endscan(scan);
}
/*
* IndexSupportInitialize --
- * Initializes an index strategy and associated support procedures.
+ * Initializes an index strategy and associated support procedures.
*/
void
IndexSupportInitialize(IndexStrategy indexStrategy,
- RegProcedure *indexSupport,
- Oid indexObjectId,
- Oid accessMethodObjectId,
- StrategyNumber maxStrategyNumber,
- StrategyNumber maxSupportNumber,
- AttrNumber maxAttributeNumber)
+ RegProcedure * indexSupport,
+ Oid indexObjectId,
+ Oid accessMethodObjectId,
+ StrategyNumber maxStrategyNumber,
+ StrategyNumber maxSupportNumber,
+ AttrNumber maxAttributeNumber)
{
- Relation relation;
- Relation operatorRelation;
- HeapScanDesc scan;
- HeapTuple tuple;
- ScanKeyData entry[2];
- StrategyMap map;
- AttrNumber attributeNumber;
- int attributeIndex;
- Oid operatorClassObjectId[ MaxIndexAttributeNumber ];
-
- maxStrategyNumber = AMStrategies(maxStrategyNumber);
-
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(indexObjectId));
-
- relation = heap_openr(IndexRelationName);
- scan = heap_beginscan(relation, false, NowTimeQual, 1, entry);
- tuple = heap_getnext(scan, 0, (Buffer *)NULL);
- if (! HeapTupleIsValid(tuple))
- elog(WARN, "IndexSupportInitialize: corrupted catalogs");
-
- /*
- * XXX note that the following assumes the INDEX tuple is well formed and
- * that the key[] and class[] are 0 terminated.
- */
- for (attributeIndex=0; attributeIndex<maxAttributeNumber; attributeIndex++)
+ Relation relation;
+ Relation operatorRelation;
+ HeapScanDesc scan;
+ HeapTuple tuple;
+ ScanKeyData entry[2];
+ StrategyMap map;
+ AttrNumber attributeNumber;
+ int attributeIndex;
+ Oid operatorClassObjectId[MaxIndexAttributeNumber];
+
+ maxStrategyNumber = AMStrategies(maxStrategyNumber);
+
+ ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(indexObjectId));
+
+ relation = heap_openr(IndexRelationName);
+ scan = heap_beginscan(relation, false, NowTimeQual, 1, entry);
+ tuple = heap_getnext(scan, 0, (Buffer *) NULL);
+ if (!HeapTupleIsValid(tuple))
+ elog(WARN, "IndexSupportInitialize: corrupted catalogs");
+
+ /*
+ * XXX note that the following assumes the INDEX tuple is well formed
+ * and that the key[] and class[] are 0 terminated.
+ */
+ for (attributeIndex = 0; attributeIndex < maxAttributeNumber; attributeIndex++)
{
- IndexTupleForm iform;
-
- iform = (IndexTupleForm) GETSTRUCT(tuple);
-
- if (!OidIsValid(iform->indkey[attributeIndex])) {
- if (attributeIndex == 0) {
- elog(WARN, "IndexSupportInitialize: no pg_index tuple");
+ IndexTupleForm iform;
+
+ iform = (IndexTupleForm) GETSTRUCT(tuple);
+
+ if (!OidIsValid(iform->indkey[attributeIndex]))
+ {
+ if (attributeIndex == 0)
+ {
+ elog(WARN, "IndexSupportInitialize: no pg_index tuple");
+ }
+ break;
}
- break;
- }
-
- operatorClassObjectId[attributeIndex]
- = iform->indclass[attributeIndex];
+
+ operatorClassObjectId[attributeIndex]
+ = iform->indclass[attributeIndex];
}
-
- heap_endscan(scan);
- heap_close(relation);
-
- /* if support routines exist for this access method, load them */
- if (maxSupportNumber > 0) {
-
- ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
- ObjectIdEqualRegProcedure, 0);
-
-/* relation = heap_openr(Name_pg_amproc); */
- relation = heap_openr(AccessMethodProcedureRelationName);
-
-
+
+ heap_endscan(scan);
+ heap_close(relation);
+
+ /* if support routines exist for this access method, load them */
+ if (maxSupportNumber > 0)
+ {
+
+ ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amproc_amid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(accessMethodObjectId));
+
+ ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid,
+ ObjectIdEqualRegProcedure, 0);
+
+/* relation = heap_openr(Name_pg_amproc); */
+ relation = heap_openr(AccessMethodProcedureRelationName);
+
+
+ for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
+ attributeNumber--)
+ {
+
+ int16 support;
+ Form_pg_amproc form;
+ RegProcedure *loc;
+
+ loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
+
+ for (support = maxSupportNumber; --support >= 0;)
+ {
+ loc[support] = InvalidOid;
+ }
+
+ entry[1].sk_argument =
+ ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+
+ scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
+
+ while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
+ HeapTupleIsValid(tuple))
+ {
+
+ form = (Form_pg_amproc) GETSTRUCT(tuple);
+ loc[(form->amprocnum - 1)] = form->amproc;
+ }
+
+ heap_endscan(scan);
+ }
+ heap_close(relation);
+ }
+
+ ScanKeyEntryInitialize(&entry[0], 0,
+ Anum_pg_amop_amopid,
+ ObjectIdEqualRegProcedure,
+ ObjectIdGetDatum(accessMethodObjectId));
+
+ ScanKeyEntryInitialize(&entry[1], 0,
+ Anum_pg_amop_amopclaid,
+ ObjectIdEqualRegProcedure, 0);
+
+ relation = heap_openr(AccessMethodOperatorRelationName);
+ operatorRelation = heap_openr(OperatorRelationName);
+
for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
- attributeNumber--) {
-
- int16 support;
- Form_pg_amproc form;
- RegProcedure *loc;
-
- loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)];
-
- for (support = maxSupportNumber; --support >= 0; ) {
- loc[support] = InvalidOid;
- }
-
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
-
- scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
-
- while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
- HeapTupleIsValid(tuple)) {
-
- form = (Form_pg_amproc) GETSTRUCT(tuple);
- loc[(form->amprocnum - 1)] = form->amproc;
- }
-
- heap_endscan(scan);
+ attributeNumber--)
+ {
+
+ StrategyNumber strategy;
+
+ entry[1].sk_argument =
+ ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
+
+ map = IndexStrategyGetStrategyMap(indexStrategy,
+ maxStrategyNumber,
+ attributeNumber);
+
+ for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
+ ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
+
+ scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
+
+ while (tuple = heap_getnext(scan, 0, (Buffer *) NULL),
+ HeapTupleIsValid(tuple))
+ {
+ Form_pg_amop form;
+
+ form = (Form_pg_amop) GETSTRUCT(tuple);
+
+ OperatorRelationFillScanKeyEntry(operatorRelation,
+ form->amopopr,
+ StrategyMapGetScanKeyEntry(map, form->amopstrategy));
+ }
+
+ heap_endscan(scan);
}
+
+ heap_close(operatorRelation);
heap_close(relation);
- }
-
- ScanKeyEntryInitialize(&entry[0], 0,
- Anum_pg_amop_amopid,
- ObjectIdEqualRegProcedure,
- ObjectIdGetDatum(accessMethodObjectId));
-
- ScanKeyEntryInitialize(&entry[1], 0,
- Anum_pg_amop_amopclaid,
- ObjectIdEqualRegProcedure, 0);
-
- relation = heap_openr(AccessMethodOperatorRelationName);
- operatorRelation = heap_openr(OperatorRelationName);
-
- for (attributeNumber = maxAttributeNumber; attributeNumber > 0;
- attributeNumber--) {
-
- StrategyNumber strategy;
-
- entry[1].sk_argument =
- ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]);
-
- map = IndexStrategyGetStrategyMap(indexStrategy,
- maxStrategyNumber,
- attributeNumber);
-
- for (strategy = 1; strategy <= maxStrategyNumber; strategy++)
- ScanKeyEntrySetIllegal(StrategyMapGetScanKeyEntry(map, strategy));
-
- scan = heap_beginscan(relation, false, NowTimeQual, 2, entry);
-
- while (tuple = heap_getnext(scan, 0, (Buffer *)NULL),
- HeapTupleIsValid(tuple)) {
- Form_pg_amop form;
-
- form = (Form_pg_amop) GETSTRUCT(tuple);
-
- OperatorRelationFillScanKeyEntry(operatorRelation,
- form->amopopr,
- StrategyMapGetScanKeyEntry(map, form->amopstrategy));
- }
-
- heap_endscan(scan);
- }
-
- heap_close(operatorRelation);
- heap_close(relation);
}
/* ----------------
- * IndexStrategyDisplay
+ * IndexStrategyDisplay
* ----------------
*/
#ifdef ISTRATDEBUG
int
IndexStrategyDisplay(IndexStrategy indexStrategy,
- StrategyNumber numberOfStrategies,
- int numberOfAttributes)
+ 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);
+ 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) */
-
+#endif /* defined(ISTRATDEBUG) */