⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 index.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
	 *	 *	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 + -