📄 index.c
字号:
* ---------------- */ indexRelation->rd_rel->relowner = GetUserId(); indexRelation->rd_rel->relam = amoid; indexRelation->rd_rel->reltuples = 1; /* XXX */ indexRelation->rd_rel->relkind = RELKIND_INDEX;}/* ---------------------------------------------------------------- * UpdateRelationRelation * ---------------------------------------------------------------- */static OidUpdateRelationRelation(Relation indexRelation, char *temp_relname){ Relation pg_class; HeapTuple tuple; Oid tupleOid; Relation idescs[Num_pg_class_indices]; pg_class = heap_openr(RelationRelationName); /* XXX Natts_pg_class_fixed is a hack - see pg_class.h */ tuple = heap_addheader(Natts_pg_class_fixed, sizeof(*indexRelation->rd_rel), (char *) indexRelation->rd_rel); /* ---------------- * the new tuple must have the same oid as the relcache entry for the * index. sure would be embarassing to do this sort of thing in polite * company. * ---------------- */ tuple->t_data->t_oid = RelationGetRelid(indexRelation); heap_insert(pg_class, tuple); if (temp_relname) create_temp_relation(temp_relname, tuple); /* * During normal processing, we need to make sure that the system * catalog indices are correct. Bootstrap (initdb) time doesn't * require this, because we make sure that the indices are correct * just before exiting. */ if (!IsBootstrapProcessingMode()) { CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs); CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class, tuple); CatalogCloseIndices(Num_pg_class_indices, idescs); } tupleOid = tuple->t_data->t_oid; pfree(tuple); heap_close(pg_class); return tupleOid;}/* ---------------------------------------------------------------- * InitializeAttributeOids * ---------------------------------------------------------------- */static voidInitializeAttributeOids(Relation indexRelation, int numatts, Oid indexoid){ TupleDesc tupleDescriptor; int i; tupleDescriptor = RelationGetDescr(indexRelation); for (i = 0; i < numatts; i += 1) tupleDescriptor->attrs[i]->attrelid = indexoid;}/* ---------------------------------------------------------------- * AppendAttributeTuples * * XXX For now, only change the ATTNUM attribute value * ---------------------------------------------------------------- */static voidAppendAttributeTuples(Relation indexRelation, int numatts){ Relation pg_attribute; HeapTuple init_tuple, cur_tuple = NULL, new_tuple; bool hasind; Relation idescs[Num_pg_attr_indices]; Datum value[Natts_pg_attribute]; char nullv[Natts_pg_attribute]; char replace[Natts_pg_attribute]; TupleDesc indexTupDesc; int i; /* ---------------- * open the attribute relation * XXX ADD INDEXING * ---------------- */ pg_attribute = heap_openr(AttributeRelationName); /* ---------------- * initialize *null, *replace and *value * ---------------- */ MemSet(nullv, ' ', Natts_pg_attribute); MemSet(replace, ' ', Natts_pg_attribute); /* ---------------- * create the first attribute tuple. * XXX For now, only change the ATTNUM attribute value * ---------------- */ replace[Anum_pg_attribute_attnum - 1] = 'r'; replace[Anum_pg_attribute_attcacheoff - 1] = 'r'; value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(1); value[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1); init_tuple = heap_addheader(Natts_pg_attribute, ATTRIBUTE_TUPLE_SIZE, (char *) (indexRelation->rd_att->attrs[0])); hasind = false; if (!IsBootstrapProcessingMode() && pg_attribute->rd_rel->relhasindex) { hasind = true; CatalogOpenIndices(Num_pg_attr_indices, Name_pg_attr_indices, idescs); } /* ---------------- * insert the first attribute tuple. * ---------------- */ cur_tuple = heap_modifytuple(init_tuple, pg_attribute, value, nullv, replace); pfree(init_tuple); heap_insert(pg_attribute, cur_tuple); if (hasind) CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, cur_tuple); /* ---------------- * now we use the information in the index cur_tuple * descriptor to form the remaining attribute tuples. * ---------------- */ indexTupDesc = RelationGetDescr(indexRelation); for (i = 1; i < numatts; i += 1) { /* ---------------- * process the remaining attributes... * ---------------- */ memmove(GETSTRUCT(cur_tuple), (char *) indexTupDesc->attrs[i], ATTRIBUTE_TUPLE_SIZE); value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(i + 1); new_tuple = heap_modifytuple(cur_tuple, pg_attribute, value, nullv, replace); pfree(cur_tuple); heap_insert(pg_attribute, new_tuple); if (hasind) CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, new_tuple); /* ---------------- * ModifyHeapTuple returns a new copy of a cur_tuple * so we free the original and use the copy.. * ---------------- */ cur_tuple = new_tuple; } if (cur_tuple) pfree(cur_tuple); heap_close(pg_attribute); if (hasind) CatalogCloseIndices(Num_pg_attr_indices, idescs);}/* ---------------------------------------------------------------- * UpdateIndexRelation * ---------------------------------------------------------------- */static voidUpdateIndexRelation(Oid indexoid, Oid heapoid, FuncIndexInfo *funcInfo, int natts, AttrNumber *attNums, Oid *classOids, Node *predicate, List *attributeList, bool islossy, bool unique, bool primary){ Form_pg_index indexForm; IndexElem *IndexKey; char *predString; text *predText; int predLen, itupLen; Relation pg_index; HeapTuple tuple; int i; /* ---------------- * allocate an Form_pg_index big enough to hold the * index-predicate (if any) in string form * ---------------- */ if (predicate != NULL) { predString = nodeToString(predicate); predText = (text *) fmgr(F_TEXTIN, predString); pfree(predString); } else predText = (text *) fmgr(F_TEXTIN, ""); predLen = VARSIZE(predText); itupLen = predLen + sizeof(FormData_pg_index); indexForm = (Form_pg_index) palloc(itupLen); memset(indexForm, 0, sizeof(FormData_pg_index)); memmove((char *) &indexForm->indpred, (char *) predText, predLen); /* ---------------- * store the oid information into the index tuple form * ---------------- */ indexForm->indrelid = heapoid; indexForm->indexrelid = indexoid; indexForm->indproc = (PointerIsValid(funcInfo)) ? FIgetProcOid(funcInfo) : InvalidOid; indexForm->indislossy = islossy; indexForm->indisprimary = primary; indexForm->indisunique = unique; indexForm->indhaskeytype = 0; while (attributeList != NIL) { IndexKey = (IndexElem *) lfirst(attributeList); if (IndexKey->typename != NULL) { indexForm->indhaskeytype = 1; break; } attributeList = lnext(attributeList); } MemSet((char *) &indexForm->indkey[0], 0, sizeof indexForm->indkey); MemSet((char *) &indexForm->indclass[0], 0, sizeof indexForm->indclass); /* ---------------- * copy index key and op class information * ---------------- */ for (i = 0; i < natts; i += 1) { indexForm->indkey[i] = attNums[i]; indexForm->indclass[i] = classOids[i]; } /* * If we have a functional index, add all attribute arguments */ if (PointerIsValid(funcInfo)) { for (i = 1; i < FIgetnArgs(funcInfo); i++) indexForm->indkey[i] = attNums[i]; } indexForm->indisclustered = '\0'; /* XXX constant */ /* ---------------- * open the system catalog index relation * ---------------- */ pg_index = heap_openr(IndexRelationName); /* ---------------- * form a tuple to insert into pg_index * ---------------- */ tuple = heap_addheader(Natts_pg_index, itupLen, (char *) indexForm); /* ---------------- * insert the tuple into the pg_index * XXX ADD INDEX TUPLES TOO * ---------------- */ heap_insert(pg_index, tuple); /* ---------------- * close the relation and free the tuple * ---------------- */ heap_close(pg_index); pfree(predText); pfree(indexForm); pfree(tuple);}/* ---------------------------------------------------------------- * UpdateIndexPredicate * ---------------------------------------------------------------- */voidUpdateIndexPredicate(Oid indexoid, Node *oldPred, Node *predicate){ Node *newPred; char *predString; text *predText; Relation pg_index; HeapTuple tuple; HeapTuple newtup; int i; Datum values[Natts_pg_index]; char nulls[Natts_pg_index]; char replace[Natts_pg_index]; /* * Construct newPred as a CNF expression equivalent to the OR of the * original partial-index predicate ("oldPred") and the extension * predicate ("predicate"). * * This should really try to process the result to change things like * "a>2 OR a>1" to simply "a>1", but for now all it does is make sure * that if the extension predicate is NULL (i.e., it is being extended * to be a complete index), then newPred will be NULL - in effect, * changing "a>2 OR TRUE" to "TRUE". --Nels, Jan '93 */ newPred = NULL; if (predicate != NULL) { newPred = (Node *) make_orclause(lcons(make_andclause((List *) predicate), lcons(make_andclause((List *) oldPred), NIL))); newPred = (Node *) cnfify((Expr *) newPred, true); } /* translate the index-predicate to string form */ if (newPred != NULL) { predString = nodeToString(newPred); predText = (text *) fmgr(F_TEXTIN, predString); pfree(predString); } else predText = (text *) fmgr(F_TEXTIN, ""); /* open the index system catalog relation */ pg_index = heap_openr(IndexRelationName); tuple = SearchSysCacheTuple(INDEXRELID, ObjectIdGetDatum(indexoid), 0, 0, 0); Assert(HeapTupleIsValid(tuple)); for (i = 0; i < Natts_pg_index; i++) { nulls[i] = heap_attisnull(tuple, i + 1) ? 'n' : ' '; replace[i] = ' '; values[i] = (Datum) NULL; } replace[Anum_pg_index_indpred - 1] = 'r'; values[Anum_pg_index_indpred - 1] = (Datum) predText; newtup = heap_modifytuple(tuple, pg_index, values, nulls, replace); heap_replace(pg_index, &newtup->t_self, newtup, NULL); pfree(newtup); heap_close(pg_index); pfree(predText);}/* ---------------------------------------------------------------- * InitIndexStrategy * ---------------------------------------------------------------- */voidInitIndexStrategy(int numatts, Relation indexRelation, Oid accessMethodObjectId){ IndexStrategy strategy; RegProcedure *support; uint16 amstrategies; uint16 amsupport; Oid attrelid; Size strsize; extern GlobalMemory CacheCxt; /* ---------------- * get information from the index relation descriptor * ---------------- */ attrelid = indexRelation->rd_att->attrs[0]->attrelid; amstrategies = indexRelation->rd_am->amstrategies; amsupport = indexRelation->rd_am->amsupport; /* ---------------- * get the size of the strategy * ---------------- */ strsize = AttributeNumberGetIndexStrategySize(numatts, amstrategies); /* ---------------- * allocate the new index strategy structure
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -