📄 istrat.c
字号:
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, "RelationInvokeStrategy: cannot evaluate strategy %d", strategy); /* not reached, just to make compiler happy */ return FALSE;}/* ---------------- * OperatorRelationFillScanKeyEntry * ---------------- */static voidOperatorRelationFillScanKeyEntry(Relation operatorRelation, Oid operatorObjectId, ScanKey entry){ HeapTuple tuple; HeapScanDesc scan = NULL; if (!IsBootstrapProcessingMode()) { tuple = SearchSysCacheTuple(OPROID, ObjectIdGetDatum(operatorObjectId), 0, 0, 0); } else { ScanKeyData scanKeyData; ScanKeyEntryInitialize(&scanKeyData, 0, ObjectIdAttributeNumber, F_OIDEQ, ObjectIdGetDatum(operatorObjectId)); scan = heap_beginscan(operatorRelation, false, SnapshotNow, 1, &scanKeyData); tuple = heap_getnext(scan, 0); } if (!HeapTupleIsValid(tuple)) { if (IsBootstrapProcessingMode()) heap_endscan(scan); elog(ERROR, "OperatorObjectIdFillScanKeyEntry: unknown operator %lu", (uint32) operatorObjectId); } entry->sk_flags = 0; entry->sk_procedure = ((Form_pg_operator) GETSTRUCT(tuple))->oprcode; fmgr_info(entry->sk_procedure, &entry->sk_func); entry->sk_nargs = entry->sk_func.fn_nargs; if (IsBootstrapProcessingMode()) heap_endscan(scan); if (!RegProcedureIsValid(entry->sk_procedure)) { elog(ERROR, "OperatorObjectIdFillScanKeyEntry: no procedure for operator %lu", (uint32) operatorObjectId); }}/* * IndexSupportInitialize * Initializes an index strategy and associated support procedures. */voidIndexSupportInitialize(IndexStrategy indexStrategy, RegProcedure *indexSupport, Oid indexObjectId, Oid accessMethodObjectId, StrategyNumber maxStrategyNumber, StrategyNumber maxSupportNumber, AttrNumber maxAttributeNumber){ Relation relation = NULL; HeapScanDesc scan = NULL; ScanKeyData entry[2]; Relation operatorRelation; HeapTuple tuple; StrategyMap map; AttrNumber attributeNumber; int attributeIndex; Oid operatorClassObjectId[MaxIndexAttributeNumber]; if (!IsBootstrapProcessingMode()) { tuple = SearchSysCacheTuple(INDEXRELID, ObjectIdGetDatum(indexObjectId), 0, 0, 0); } else { ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_index_indexrelid, F_OIDEQ, ObjectIdGetDatum(indexObjectId)); relation = heap_openr(IndexRelationName); scan = heap_beginscan(relation, false, SnapshotNow, 1, entry); tuple = heap_getnext(scan, 0); } if (!HeapTupleIsValid(tuple)) elog(ERROR, "IndexSupportInitialize: corrupted catalogs"); maxStrategyNumber = AMStrategies(maxStrategyNumber); /* * 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++) { Form_pg_index iform; iform = (Form_pg_index) GETSTRUCT(tuple); if (!OidIsValid(iform->indkey[attributeIndex])) { if (attributeIndex == InvalidAttrNumber) elog(ERROR, "IndexSupportInitialize: no pg_index tuple"); break; } operatorClassObjectId[attributeIndex] = iform->indclass[attributeIndex]; } if (IsBootstrapProcessingMode()) { 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, F_OIDEQ, ObjectIdGetDatum(accessMethodObjectId)); ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amproc_amopclaid, F_OIDEQ, 0); relation = heap_openr(AccessMethodProcedureRelationName); for (attributeNumber = 1; attributeNumber <= maxAttributeNumber; attributeNumber++) { int16 support; Form_pg_amproc aform; RegProcedure *loc; loc = &indexSupport[((attributeNumber - 1) * maxSupportNumber)]; for (support = 0; support < maxSupportNumber; ++support) loc[support] = InvalidOid; entry[1].sk_argument = ObjectIdGetDatum(operatorClassObjectId[attributeNumber - 1]); scan = heap_beginscan(relation, false, SnapshotNow, 2, entry); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { aform = (Form_pg_amproc) GETSTRUCT(tuple); loc[(aform->amprocnum - 1)] = aform->amproc; } heap_endscan(scan); } heap_close(relation); } ScanKeyEntryInitialize(&entry[0], 0, Anum_pg_amop_amopid, F_OIDEQ, ObjectIdGetDatum(accessMethodObjectId)); ScanKeyEntryInitialize(&entry[1], 0, Anum_pg_amop_amopclaid, F_OIDEQ, 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, SnapshotNow, 2, entry); while (HeapTupleIsValid(tuple = heap_getnext(scan, 0))) { Form_pg_amop aform; aform = (Form_pg_amop) GETSTRUCT(tuple); OperatorRelationFillScanKeyEntry(operatorRelation, aform->amopopr, StrategyMapGetScanKeyEntry(map, aform->amopstrategy)); } heap_endscan(scan); } heap_close(operatorRelation); heap_close(relation);}/* ---------------- * IndexStrategyDisplay * ---------------- */#ifdef ISTRATDEBUGintIndexStrategyDisplay(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) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -