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

📄 index.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
/*------------------------------------------------------------------------- * * index.c *	  code to create and destroy POSTGRES index relations * * Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/catalog/index.c,v 1.81.2.1 1999/08/02 05:56:54 scrappy Exp $ * * * INTERFACE ROUTINES *		index_create()			- Create a cataloged index relation *		index_destroy()			- Removes index relation from catalogs * * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/genam.h"#include "access/heapam.h"#include "access/istrat.h"#include "bootstrap/bootstrap.h"#include "catalog/catname.h"#include "catalog/heap.h"#include "catalog/index.h"#include "catalog/indexing.h"#include "catalog/pg_index.h"#include "catalog/pg_proc.h"#include "catalog/pg_type.h"#include "executor/executor.h"#include "miscadmin.h"#include "optimizer/clauses.h"#include "optimizer/prep.h"#include "parser/parse_func.h"#include "storage/smgr.h"#include "utils/builtins.h"#include "utils/relcache.h"#include "utils/syscache.h"#include "utils/temprel.h"/* * macros used in guessing how many tuples are on a page. */#define AVG_ATTR_SIZE 8#define NTUPLES_PER_PAGE(natts) \	((BLCKSZ - MAXALIGN(sizeof (PageHeaderData))) / \	((natts) * AVG_ATTR_SIZE + MAXALIGN(sizeof(HeapTupleHeaderData))))/* non-export function prototypes */static Oid GetHeapRelationOid(char *heapRelationName, char *indexRelationName,				   bool istemp);static TupleDesc BuildFuncTupleDesc(FuncIndexInfo *funcInfo);static TupleDesc ConstructTupleDescriptor(Oid heapoid, Relation heapRelation,						 List *attributeList,						 int numatts, AttrNumber *attNums);static void ConstructIndexReldesc(Relation indexRelation, Oid amoid);static Oid	UpdateRelationRelation(Relation indexRelation, char *temp_relname);static void InitializeAttributeOids(Relation indexRelation,						int numatts,						Oid indexoid);static void			AppendAttributeTuples(Relation indexRelation, int numatts);static void UpdateIndexRelation(Oid indexoid, Oid heapoid,					FuncIndexInfo *funcInfo, int natts,					AttrNumber *attNums, Oid *classOids, Node *predicate,		   List *attributeList, bool islossy, bool unique, bool primary);static void DefaultBuild(Relation heapRelation, Relation indexRelation,			 int numberOfAttributes, AttrNumber *attributeNumber,			 IndexStrategy indexStrategy, uint16 parameterCount,		Datum *parameter, FuncIndexInfoPtr funcInfo, PredInfo *predInfo);/* ---------------------------------------------------------------- *	  sysatts is a structure containing attribute tuple forms *	  for system attributes (numbered -1, -2, ...).  This really *	  should be generated or eliminated or moved elsewhere. -cim 1/19/91 * * typedef struct FormData_pg_attribute { *		Oid				attrelid; *		NameData		attname; *		Oid				atttypid; *		uint32			attnvals; *		int16			attlen; *		AttrNumber		attnum; *		uint32			attnelems; *		int32			attcacheoff; *		int32			atttypmod; *		bool			attbyval; *		bool			attisset; *		char			attalign; *		bool			attnotnull; *		bool			atthasdef; * } FormData_pg_attribute; * * ---------------------------------------------------------------- */static FormData_pg_attribute sysatts[] = {	{0, {"ctid"}, TIDOID, 0, 6, -1, 0, -1, -1, '\0', '\0', 'i', '\0', '\0'},	{0, {"oid"}, OIDOID, 0, 4, -2, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},	{0, {"xmin"}, XIDOID, 0, 4, -3, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},	{0, {"cmin"}, CIDOID, 0, 4, -4, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},	{0, {"xmax"}, XIDOID, 0, 4, -5, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},	{0, {"cmax"}, CIDOID, 0, 4, -6, 0, -1, -1, '\001', '\0', 'i', '\0', '\0'},};/* ---------------------------------------------------------------- *		GetHeapRelationOid * ---------------------------------------------------------------- */static OidGetHeapRelationOid(char *heapRelationName, char *indexRelationName, bool istemp){	Oid			indoid;	Oid			heapoid;	indoid = RelnameFindRelid(indexRelationName);	if ((!istemp && OidIsValid(indoid)) ||		(istemp && get_temp_rel_by_name(indexRelationName) != NULL))		elog(ERROR, "Cannot create index: '%s' already exists",			 indexRelationName);	heapoid = RelnameFindRelid(heapRelationName);	if (!OidIsValid(heapoid))		elog(ERROR, "Cannot create index on '%s': relation does not exist",			 heapRelationName);	return heapoid;}static TupleDescBuildFuncTupleDesc(FuncIndexInfo *funcInfo){	HeapTuple	tuple;	TupleDesc	funcTupDesc;	Oid			retType;	char	   *funcname;	int4		nargs;	Oid		   *argtypes;	/*	 * Allocate and zero a tuple descriptor.	 */	funcTupDesc = CreateTemplateTupleDesc(1);	funcTupDesc->attrs[0] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);	MemSet(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE);	/*	 * Lookup the function for the return type.	 */	funcname = FIgetname(funcInfo);	nargs = FIgetnArgs(funcInfo);	argtypes = FIgetArglist(funcInfo);	tuple = SearchSysCacheTuple(PRONAME,								PointerGetDatum(funcname),								Int32GetDatum(nargs),								PointerGetDatum(argtypes),								0);	if (!HeapTupleIsValid(tuple))		func_error("BuildFuncTupleDesc", funcname, nargs, argtypes, NULL);	retType = ((Form_pg_proc) GETSTRUCT(tuple))->prorettype;	/*	 * Look up the return type in pg_type for the type length.	 */	tuple = SearchSysCacheTuple(TYPOID,								ObjectIdGetDatum(retType),								0, 0, 0);	if (!HeapTupleIsValid(tuple))		elog(ERROR, "Function %s return type does not exist", FIgetname(funcInfo));	/*	 * Assign some of the attributes values. Leave the rest as 0.	 */	funcTupDesc->attrs[0]->attlen = ((Form_pg_type) GETSTRUCT(tuple))->typlen;	funcTupDesc->attrs[0]->atttypid = retType;	funcTupDesc->attrs[0]->attnum = 1;	funcTupDesc->attrs[0]->attbyval = ((Form_pg_type) GETSTRUCT(tuple))->typbyval;	funcTupDesc->attrs[0]->attcacheoff = -1;	funcTupDesc->attrs[0]->atttypmod = -1;	funcTupDesc->attrs[0]->attalign = ((Form_pg_type) GETSTRUCT(tuple))->typalign;	/*	 * make the attributes name the same as the functions	 */	namestrcpy(&funcTupDesc->attrs[0]->attname, funcname);	return funcTupDesc;}/* ---------------------------------------------------------------- *		ConstructTupleDescriptor * ---------------------------------------------------------------- */static TupleDescConstructTupleDescriptor(Oid heapoid,						 Relation heapRelation,						 List *attributeList,						 int numatts,						 AttrNumber *attNums){	TupleDesc	heapTupDesc;	TupleDesc	indexTupDesc;	IndexElem  *IndexKey;	TypeName   *IndexKeyType;	AttrNumber	atnum;			/* attributeNumber[attributeOffset] */	AttrNumber	atind;	int			natts;			/* Form_pg_class->relnatts */	char	   *from;			/* used to simplify memcpy below */	char	   *to;				/* used to simplify memcpy below */	int			i;	/* ----------------	 *	allocate the new tuple descriptor	 * ----------------	 */	natts = RelationGetForm(heapRelation)->relnatts;	indexTupDesc = CreateTemplateTupleDesc(numatts);	/* ----------------	 *	 * ----------------	 */	/* ----------------	 *	  for each attribute we are indexing, obtain its attribute	 *	  tuple form from either the static table of system attribute	 *	  tuple forms or the relation tuple descriptor	 * ----------------	 */	for (i = 0; i < numatts; i += 1)	{		/* ----------------		 *	 get the attribute number and make sure it's valid		 * ----------------		 */		atnum = attNums[i];		if (atnum > natts)			elog(ERROR, "Cannot create index: attribute %d does not exist",				 atnum);		if (attributeList)		{			IndexKey = (IndexElem *) lfirst(attributeList);			IndexKeyType = IndexKey->typename;			attributeList = lnext(attributeList);		}		else			IndexKeyType = NULL;		indexTupDesc->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);		/* ----------------		 *	 determine which tuple descriptor to copy		 * ----------------		 */		if (!AttrNumberIsForUserDefinedAttr(atnum))		{			/* ----------------			 *	  here we are indexing on a system attribute (-1...-12)			 *	  so we convert atnum into a usable index 0...11 so we can			 *	  use it to dereference the array sysatts[] which stores			 *	  tuple descriptor information for system attributes.			 * ----------------			 */			if (atnum <= FirstLowInvalidHeapAttributeNumber || atnum >= 0)				elog(ERROR, "Cannot create index on system attribute: attribute number out of range (%d)", atnum);			atind = (-atnum) - 1;			from = (char *) (&sysatts[atind]);		}		else		{			/* ----------------			 *	  here we are indexing on a normal attribute (1...n)			 * ----------------			 */			heapTupDesc = RelationGetDescr(heapRelation);			atind = AttrNumberGetAttrOffset(atnum);			from = (char *) (heapTupDesc->attrs[atind]);		}		/* ----------------		 *	 now that we've determined the "from", let's copy		 *	 the tuple desc data...		 * ----------------		 */		to = (char *) (indexTupDesc->attrs[i]);		memcpy(to, from, ATTRIBUTE_TUPLE_SIZE);		((Form_pg_attribute) to)->attnum = i + 1;		((Form_pg_attribute) to)->attnotnull = false;		((Form_pg_attribute) to)->atthasdef = false;		((Form_pg_attribute) to)->attcacheoff = -1;		((Form_pg_attribute) to)->atttypmod = -1;		((Form_pg_attribute) to)->attalign = 'i';		/*		 * if the keytype is defined, we need to change the tuple form's		 * atttypid & attlen field to match that of the key's type		 */		if (IndexKeyType != NULL)		{			HeapTuple	tup;			tup = SearchSysCacheTuple(TYPNAME,									  PointerGetDatum(IndexKeyType->name),									  0, 0, 0);			if (!HeapTupleIsValid(tup))				elog(ERROR, "create index: type '%s' undefined",					 IndexKeyType->name);			((Form_pg_attribute) to)->atttypid = tup->t_data->t_oid;			((Form_pg_attribute) to)->attbyval =				((Form_pg_type) GETSTRUCT(tup))->typbyval;			((Form_pg_attribute) to)->attlen =				((Form_pg_type) GETSTRUCT(tup))->typlen;			((Form_pg_attribute) to)->attalign =				((Form_pg_type) GETSTRUCT(tup))->typalign;			((Form_pg_attribute) to)->atttypmod = IndexKeyType->typmod;		}		/* ----------------		 *	  now we have to drop in the proper relation descriptor		 *	  into the copied tuple form's attrelid and we should be		 *	  all set.		 * ----------------		 */		((Form_pg_attribute) to)->attrelid = heapoid;	}	return indexTupDesc;}/* ---------------------------------------------------------------- * AccessMethodObjectIdGetForm *		Returns the formated access method tuple given its object identifier. * * XXX ADD INDEXING * * Note: *		Assumes object identifier is valid. * ---------------------------------------------------------------- */Form_pg_amAccessMethodObjectIdGetForm(Oid accessMethodObjectId){	Relation	pg_am_desc;	HeapScanDesc pg_am_scan;	HeapTuple	pg_am_tuple;	ScanKeyData key;	Form_pg_am	aform;	/* ----------------	 *	form a scan key for the pg_am relation	 * ----------------	 */	ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,						   F_OIDEQ,						   ObjectIdGetDatum(accessMethodObjectId));	/* ----------------	 *	fetch the desired access method tuple	 * ----------------	 */	pg_am_desc = heap_openr(AccessMethodRelationName);	pg_am_scan = heap_beginscan(pg_am_desc, 0, SnapshotNow, 1, &key);	pg_am_tuple = heap_getnext(pg_am_scan, 0);	/* ----------------	 *	return NULL if not found	 * ----------------	 */	if (!HeapTupleIsValid(pg_am_tuple))	{		heap_endscan(pg_am_scan);		heap_close(pg_am_desc);		return NULL;	}	/* ----------------	 *	if found am tuple, then copy the form and return the copy	 * ----------------	 */	aform = (Form_pg_am) palloc(sizeof *aform);	memcpy(aform, GETSTRUCT(pg_am_tuple), sizeof *aform);	heap_endscan(pg_am_scan);	heap_close(pg_am_desc);	return aform;}/* ---------------------------------------------------------------- *		ConstructIndexReldesc * ---------------------------------------------------------------- */static voidConstructIndexReldesc(Relation indexRelation, Oid amoid){	extern GlobalMemory CacheCxt;	MemoryContext oldcxt;	/* ----------------	 *	  here we make certain to allocate the access method	 *	  tuple within the cache context lest it vanish when the	 *	  context changes	 * ----------------	 */	if (!CacheCxt)		CacheCxt = CreateGlobalMemory("Cache");	oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);	indexRelation->rd_am = AccessMethodObjectIdGetForm(amoid);	MemoryContextSwitchTo(oldcxt);	/* ----------------	 *	 XXX missing the initialization of some other fields

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -