📄 index.c
字号:
* * the index strategy has to be allocated in the same * context as the relation descriptor cache or else * it will be lost at the end of the transaction. * ---------------- */ if (!CacheCxt) CacheCxt = CreateGlobalMemory("Cache"); strategy = (IndexStrategy) MemoryContextAlloc((MemoryContext) CacheCxt, strsize); if (amsupport > 0) { strsize = numatts * (amsupport * sizeof(RegProcedure)); support = (RegProcedure *) MemoryContextAlloc((MemoryContext) CacheCxt, strsize); } else support = (RegProcedure *) NULL; /* ---------------- * fill in the index strategy structure with information * from the catalogs. Note: we use heap override mode * in order to be allowed to see the correct information in the * catalogs, even though our transaction has not yet committed. * ---------------- */ setheapoverride(true); IndexSupportInitialize(strategy, support, attrelid, accessMethodObjectId, amstrategies, amsupport, numatts); setheapoverride(false); /* ---------------- * store the strategy information in the index reldesc * ---------------- */ RelationSetIndexSupport(indexRelation, strategy, support);}/* ---------------------------------------------------------------- * index_create * ---------------------------------------------------------------- */voidindex_create(char *heapRelationName, char *indexRelationName, FuncIndexInfo *funcInfo, List *attributeList, Oid accessMethodObjectId, int numatts, AttrNumber *attNums, Oid *classObjectId, uint16 parameterCount, Datum *parameter, Node *predicate, bool islossy, bool unique, bool primary){ Relation heapRelation; Relation indexRelation; TupleDesc indexTupDesc; Oid heapoid; Oid indexoid; PredInfo *predInfo; bool istemp = (get_temp_rel_by_name(heapRelationName) != NULL); char *temp_relname = NULL; /* ---------------- * check parameters * ---------------- */ if (numatts < 1) elog(ERROR, "must index at least one attribute"); /* ---------------- * get heap relation oid and open the heap relation * XXX ADD INDEXING * ---------------- */ heapoid = GetHeapRelationOid(heapRelationName, indexRelationName, istemp); heapRelation = heap_open(heapoid); /* * Only SELECT ... FOR UPDATE are allowed */ LockRelation(heapRelation, ShareLock); /* ---------------- * construct new tuple descriptor * ---------------- */ if (PointerIsValid(funcInfo)) indexTupDesc = BuildFuncTupleDesc(funcInfo); else indexTupDesc = ConstructTupleDescriptor(heapoid, heapRelation, attributeList, numatts, attNums); /* invalidate cache so possible non-temp index is masked by temp */ if (istemp) { Oid relid = RelnameFindRelid(indexRelationName); if (relid != InvalidOid) RelationForgetRelation(relid); } /* save user relation name because heap_create changes it */ if (istemp) { temp_relname = pstrdup(indexRelationName); /* save original value */ indexRelationName = palloc(NAMEDATALEN); strcpy(indexRelationName, temp_relname); /* heap_create will * change this */ } /* ---------------- * create the index relation * ---------------- */ indexRelation = heap_create(indexRelationName, indexTupDesc, false, istemp); /* ---------------- * construct the index relation descriptor * * XXX should have a proper way to create cataloged relations * ---------------- */ ConstructIndexReldesc(indexRelation, accessMethodObjectId); /* ---------------- * add index to catalogs * (append RELATION tuple) * ---------------- */ indexoid = UpdateRelationRelation(indexRelation, temp_relname); /* ---------------- * Now get the index procedure (only relevant for functional indices). * ---------------- */ if (PointerIsValid(funcInfo)) { HeapTuple proc_tup; proc_tup = SearchSysCacheTuple(PRONAME, PointerGetDatum(FIgetname(funcInfo)), Int32GetDatum(FIgetnArgs(funcInfo)), PointerGetDatum(FIgetArglist(funcInfo)), 0); if (!HeapTupleIsValid(proc_tup)) { func_error("index_create", FIgetname(funcInfo), FIgetnArgs(funcInfo), FIgetArglist(funcInfo), NULL); } FIgetProcOid(funcInfo) = proc_tup->t_data->t_oid; } /* ---------------- * now update the object id's of all the attribute * tuple forms in the index relation's tuple descriptor * ---------------- */ InitializeAttributeOids(indexRelation, numatts, indexoid); /* ---------------- * append ATTRIBUTE tuples * ---------------- */ AppendAttributeTuples(indexRelation, numatts); /* ---------------- * update pg_index * (append INDEX tuple) * * Note that this stows away a representation of "predicate". * (Or, could define a rule to maintain the predicate) --Nels, Feb '92 * ---------------- */ UpdateIndexRelation(indexoid, heapoid, funcInfo, numatts, attNums, classObjectId, predicate, attributeList, islossy, unique, primary); predInfo = (PredInfo *) palloc(sizeof(PredInfo)); predInfo->pred = predicate; predInfo->oldPred = NULL; /* ---------------- * initialize the index strategy * ---------------- */ InitIndexStrategy(numatts, indexRelation, accessMethodObjectId); /* * If this is bootstrap (initdb) time, then we don't actually fill in * the index yet. We'll be creating more indices and classes later, * so we delay filling them in until just before we're done with * bootstrapping. Otherwise, we call the routine that constructs the * index. The heap and index relations are closed by index_build(). */ if (IsBootstrapProcessingMode()) { index_register(heapRelationName, indexRelationName, numatts, attNums, parameterCount, parameter, funcInfo, predInfo); } else { heapRelation = heap_openr(heapRelationName); index_build(heapRelation, indexRelation, numatts, attNums, parameterCount, parameter, funcInfo, predInfo); }}/* ---------------------------------------------------------------- * * index_destroy * * ---------------------------------------------------------------- */voidindex_destroy(Oid indexId){ Relation userindexRelation; Relation indexRelation; Relation relationRelation; Relation attributeRelation; HeapTuple tuple; int16 attnum; Assert(OidIsValid(indexId)); /* Open now to obtain lock by referencing table? bjm */ userindexRelation = index_open(indexId); /* ---------------- * fix RELATION relation * ---------------- */ relationRelation = heap_openr(RelationRelationName); tuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(indexId), 0, 0, 0); Assert(HeapTupleIsValid(tuple)); heap_delete(relationRelation, &tuple->t_self, NULL); pfree(tuple); heap_close(relationRelation); /* ---------------- * fix ATTRIBUTE relation * ---------------- */ attributeRelation = heap_openr(AttributeRelationName); attnum = 1; /* indexes start at 1 */ while (HeapTupleIsValid(tuple = SearchSysCacheTupleCopy(ATTNUM, ObjectIdGetDatum(indexId), Int16GetDatum(attnum), 0, 0))) { heap_delete(attributeRelation, &tuple->t_self, NULL); pfree(tuple); attnum++; } heap_close(attributeRelation); /* does something only if it is a temp index */ remove_temp_relation(indexId); /* ---------------- * fix INDEX relation * ---------------- */ tuple = SearchSysCacheTupleCopy(INDEXRELID, ObjectIdGetDatum(indexId), 0, 0, 0); Assert(HeapTupleIsValid(tuple)); indexRelation = heap_openr(IndexRelationName); heap_delete(indexRelation, &tuple->t_self, NULL); pfree(tuple); heap_close(indexRelation); /* * flush cache and physically remove the file */ ReleaseRelationBuffers(userindexRelation); if (smgrunlink(DEFAULT_SMGR, userindexRelation) != SM_SUCCESS) elog(ERROR, "amdestroyr: unlink: %m"); index_close(userindexRelation); RelationForgetRelation(RelationGetRelid(userindexRelation));}/* ---------------------------------------------------------------- * index_build support * ---------------------------------------------------------------- *//* ---------------- * FormIndexDatum * ---------------- */voidFormIndexDatum(int numberOfAttributes, AttrNumber *attributeNumber, HeapTuple heapTuple, TupleDesc heapDescriptor, Datum *datum, char *nullv, FuncIndexInfoPtr fInfo){ AttrNumber i; int offset; bool isNull; /* ---------------- * for each attribute we need from the heap tuple, * get the attribute and stick it into the datum and * null arrays. * ---------------- */ for (i = 1; i <= numberOfAttributes; i++) { offset = AttrNumberGetAttrOffset(i); datum[offset] = PointerGetDatum(GetIndexValue(heapTuple, heapDescriptor, offset, attributeNumber, fInfo, &isNull)); nullv[offset] = (isNull) ? 'n' : ' '; }}/* ---------------- * UpdateStats * ---------------- */voidUpdateStats(Oid relid, long reltuples, bool hasindex){ Relation whichRel; Relation pg_class; HeapTuple tuple; HeapTuple newtup; long relpages; int i; Form_pg_class rd_rel; Relation idescs[Num_pg_class_indices]; Datum values[Natts_pg_class]; char nulls[Natts_pg_class]; char replace[Natts_pg_class]; HeapScanDesc pg_class_scan = NULL; /* ---------------- * This routine handles updates for both the heap and index relation * statistics. In order to guarantee that we're able to *see* the index * relation tuple, we bump the command counter id here. The index * relation tuple was created in the current transaction. * ---------------- */ CommandCounterIncrement(); /* ---------------- * CommandCounterIncrement() flushes invalid cache entries, including * those for the heap and index relations for which we're updating * statistics. Now that the cache is flushed, it's safe to open the * relation again. We need the relation open in order to figure out * how many blocks it contains. * ---------------- */ whichRel = RelationIdGetRelation(relid); if (!RelationIsValid(whichRel)) elog(ERROR, "UpdateStats: cannot open relation id %u", relid); /* ---------------- * Find the RELATION relation tuple for the given relation. * ---------------- */ pg_class = heap_openr(RelationRelationName); if (!RelationIsValid(pg_class)) elog(ERROR, "UpdateStats: could not open RELATION relation"); if (!IsBootstrapProcessingMode()) { tuple = SearchSysCacheTupleCopy(RELOID, ObjectIdGetDatum(relid), 0, 0, 0); } else { ScanKeyData key[1]; ScanKeyEntryInitialize(&key[0], 0, ObjectIdAttributeNumber, F_OIDEQ, ObjectIdGetDatum(relid)); pg_class_scan = heap_beginscan(pg_class, 0, SnapshotNow, 1, key); tuple = heap_getnext(pg_class_scan, 0); } if (!HeapTupleIsValid(tuple)) { if (IsBootstrapProcessingMode()) heap_endscan(pg_class_scan); heap_close(pg_class); elog(ERROR, "UpdateStats: cannot scan RELATION relation"); } /* ---------------- * Figure values to insert.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -