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

📄 heap.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* ----------------	 *	first we add the user attributes..	 * ----------------	 */	dpp = tupdesc->attrs;	for (i = 0; i < natts; i++)	{		(*dpp)->attrelid = new_rel_oid;		(*dpp)->attdisbursion = 0;		tup = heap_addheader(Natts_pg_attribute,							 ATTRIBUTE_TUPLE_SIZE,							 (char *) *dpp);		heap_insert(rel, tup);		if (hasindex)			CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);		pfree(tup);		dpp++;	}	/* ----------------	 *	next we add the system attributes..	 * ----------------	 */	dpp = HeapAtt;	for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)	{		(*dpp)->attrelid = new_rel_oid;		/* (*dpp)->attdisbursion = 0;	   unneeded */		tup = heap_addheader(Natts_pg_attribute,							 ATTRIBUTE_TUPLE_SIZE,							 (char *) *dpp);		heap_insert(rel, tup);		if (hasindex)			CatalogIndexInsert(idescs, Num_pg_attr_indices, rel, tup);		pfree(tup);		dpp++;	}	heap_close(rel);	/*	 * close pg_attribute indices	 */	if (hasindex)		CatalogCloseIndices(Num_pg_attr_indices, idescs);}/* -------------------------------- *		AddNewRelationTuple * *		this registers the new relation in the catalogs by *		adding a tuple to pg_class. * -------------------------------- */static voidAddNewRelationTuple(Relation pg_class_desc,					Relation new_rel_desc,					Oid new_rel_oid,					unsigned natts,					char relkind,					char *temp_relname){	Form_pg_class new_rel_reltup;	HeapTuple	tup;	Relation	idescs[Num_pg_class_indices];	bool		isBootstrap;	/* ----------------	 *	first we munge some of the information in our	 *	uncataloged relation's relation descriptor.	 * ----------------	 */	new_rel_reltup = new_rel_desc->rd_rel;	/* CHECK should get new_rel_oid first via an insert then use XXX */	/* ----------------	 * Here we insert bogus estimates of the size of the new relation.	 * In reality, of course, the new relation has 0 tuples and pages,	 * and if we were tracking these statistics accurately then we'd	 * set the fields that way.  But at present the stats will be updated	 * only by VACUUM or CREATE INDEX, and the user might insert a lot of	 * tuples before he gets around to doing either of those.  So, instead	 * of saying the relation is empty, we insert guesstimates.  The point	 * is to keep the optimizer from making really stupid choices on	 * never-yet-vacuumed tables; so the estimates need only be large	 * enough to discourage the optimizer from using nested-loop plans.	 * With this hack, nested-loop plans will be preferred only after	 * the table has been proven to be small by VACUUM or CREATE INDEX.	 * Maintaining the stats on-the-fly would solve the problem more cleanly,	 * but the overhead of that would likely cost more than it'd save.	 * (NOTE: CREATE INDEX inserts the same bogus estimates if it finds the	 * relation has 0 rows and pages. See index.c.)	 * ----------------	 */	new_rel_reltup->relpages = 10;		/* bogus estimates */	new_rel_reltup->reltuples = 1000;	new_rel_reltup->relowner = GetUserId();	new_rel_reltup->relkind = relkind;	new_rel_reltup->relnatts = natts;	/* ----------------	 *	now form a tuple to add to pg_class	 *	XXX Natts_pg_class_fixed is a hack - see pg_class.h	 * ----------------	 */	tup = heap_addheader(Natts_pg_class_fixed,						 CLASS_TUPLE_SIZE,						 (char *) new_rel_reltup);	tup->t_data->t_oid = new_rel_oid;	/* ----------------	 *	finally insert the new tuple and free it.	 *	 *	Note: I have no idea why we do a	 *			SetProcessingMode(BootstrapProcessing);	 *		  here -cim 6/14/90	 * ----------------	 */	isBootstrap = IsBootstrapProcessingMode() ? true : false;	SetProcessingMode(BootstrapProcessing);	heap_insert(pg_class_desc, tup);	if (temp_relname)		create_temp_relation(temp_relname, tup);	if (!isBootstrap)	{		/*		 * First, open the catalog indices and insert index tuples for the		 * new relation.		 */		CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, idescs);		CatalogIndexInsert(idescs, Num_pg_class_indices, pg_class_desc, tup);		CatalogCloseIndices(Num_pg_class_indices, idescs);		/* now restore processing mode */		SetProcessingMode(NormalProcessing);	}	pfree(tup);}/* -------------------------------- *		AddNewRelationType - * *		define a complex type corresponding to the new relation * -------------------------------- */static voidAddNewRelationType(char *typeName, Oid new_rel_oid){	Oid			new_type_oid;	/*	 * The sizes are set to oid size because it makes implementing sets	 * MUCH easier, and no one (we hope) uses these fields to figure out	 * how much space to allocate for the type. An oid is the type used	 * for a set definition.  When a user requests a set, what they	 * actually get is the oid of a tuple in the pg_proc catalog, so the	 * size of the "set" is the size of an oid. Similarly, byval being	 * true makes sets much easier, and it isn't used by anything else.	 * Note the assumption that OIDs are the same size as int4s.	 */	new_type_oid = TypeCreate(typeName, /* type name */							  new_rel_oid,		/* relation oid */							  typeLen(typeidType(OIDOID)),		/* internal size */							  typeLen(typeidType(OIDOID)),		/* external size */							  'c',		/* type-type (catalog) */							  ',',		/* default array delimiter */							  "int4in", /* input procedure */							  "int4out",		/* output procedure */							  "int4in", /* receive procedure */							  "int4out",		/* send procedure */							  NULL,		/* array element type - irrelevent */							  "-",		/* default type value */							  (bool) 1, /* passed by value */							  'i');		/* default alignment */}/* -------------------------------- *		heap_create_with_catalog * *		creates a new cataloged relation.  see comments above. * -------------------------------- */Oidheap_create_with_catalog(char *relname,						 TupleDesc tupdesc,						 char relkind,						 bool istemp){	Relation	pg_class_desc;	Relation	new_rel_desc;	Oid			new_rel_oid;	int			natts = tupdesc->natts;	char	   *temp_relname = NULL;	/* ----------------	 *	sanity checks	 * ----------------	 */	Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());	if (natts == 0 || natts > MaxHeapAttributeNumber)		elog(ERROR, "Number of attributes is out of range"			 "\n\tFrom 1 to %d attributes may be specified",			 MaxHeapAttributeNumber);	CheckAttributeNames(tupdesc);	/* temp tables can mask non-temp tables */	if ((!istemp && RelnameFindRelid(relname)) ||		(istemp && get_temp_rel_by_name(relname) != NULL))		elog(ERROR, "Relation '%s' already exists", relname);	/* invalidate cache so non-temp table is masked by temp */	if (istemp)	{		Oid			relid = RelnameFindRelid(relname);		if (relid != InvalidOid)			RelationForgetRelation(relid);	}	/* save user relation name because heap_create changes it */	if (istemp)	{		temp_relname = pstrdup(relname);		/* save original value */		relname = palloc(NAMEDATALEN);		strcpy(relname, temp_relname);	/* heap_create will change this */	}	/* ----------------	 *	ok, relation does not already exist so now we	 *	create an uncataloged relation and pull its relation oid	 *	from the newly formed relation descriptor.	 *	 *	Note: The call to heap_create() does all the "real" work	 *	of creating the disk file for the relation.	 *	This changes relname for noname and temp tables.	 * ----------------	 */	new_rel_desc = heap_create(relname, tupdesc, false, istemp);	new_rel_oid = new_rel_desc->rd_att->attrs[0]->attrelid;	/* ----------------	 *	since defining a relation also defines a complex type,	 *	we add a new system type corresponding to the new relation.	 * ----------------	 */	AddNewRelationType(relname, new_rel_oid);	/* ----------------	 *	now add tuples to pg_attribute for the attributes in	 *	our new relation.	 * ----------------	 */	AddNewAttributeTuples(new_rel_oid, tupdesc);	/* ----------------	 *	now update the information in pg_class.	 * ----------------	 */	pg_class_desc = heap_openr(RelationRelationName);	AddNewRelationTuple(pg_class_desc,						new_rel_desc,						new_rel_oid,						natts,						relkind,						temp_relname);	StoreConstraints(new_rel_desc);	if (istemp)	{		pfree(relname);		pfree(temp_relname);	}	/* ----------------	 *	ok, the relation has been cataloged, so close our relations	 *	and return the oid of the newly created relation.	 *	 *	SOMEDAY: fill the STATISTIC relation properly.	 * ----------------	 */	heap_close(new_rel_desc);	heap_close(pg_class_desc);	return new_rel_oid;}/* ---------------------------------------------------------------- *		heap_destroy_with_catalog	- removes all record of named relation from catalogs * *		1)	open relation, check for existence, etc. *		2)	remove inheritance information *		3)	remove indexes *		4)	remove pg_class tuple *		5)	remove pg_attribute tuples *		6)	remove pg_type tuples *		7)	RemoveConstraints () *		8)	unlink relation * * old comments *		Except for vital relations, removes relation from *		relation catalog, and related attributes from *		attribute catalog (needed?).  (Anything else?) * *		get proper relation from relation catalog (if not arg) *		check if relation is vital (strcmp()/reltype?) *		scan attribute catalog deleting attributes of reldesc *				(necessary?) *		delete relation from relation catalog *		(How are the tuples of the relation discarded?) * *		XXX Must fix to work with indexes. *		There may be a better order for doing things. *		Problems with destroying a deleted database--cannot create *		a struct reldesc without having an open file descriptor. * ---------------------------------------------------------------- *//* -------------------------------- *		RelationRemoveInheritance * *		Note: for now, we cause an exception if relation is a *		superclass.  Someday, we may want to allow this and merge *		the type info into subclass procedures....	this seems like *		lots of work. * -------------------------------- */static voidRelationRemoveInheritance(Relation relation){	Relation	catalogRelation;	HeapTuple	tuple;	HeapScanDesc scan;	ScanKeyData entry;	bool		found = false;	/* ----------------	 *	open pg_inherits	 * ----------------	 */	catalogRelation = heap_openr(InheritsRelationName);	/* ----------------	 *	form a scan key for the subclasses of this class	 *	and begin scanning	 * ----------------	 */	ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_inherits_inhparent,						   F_OIDEQ,						   ObjectIdGetDatum(RelationGetRelid(relation)));	scan = heap_beginscan(catalogRelation,						  false,						  SnapshotNow,						  1,						  &entry);	/* ----------------	 *	if any subclasses exist, then we disallow the deletion.	 * ----------------	 */	tuple = heap_getnext(scan, 0);	if (HeapTupleIsValid(tuple))	{		heap_endscan(scan);		heap_close(catalogRelation);		elog(ERROR, "Relation '%u' inherits '%s'",			 ((Form_pg_inherits) GETSTRUCT(tuple))->inhrel,			 RelationGetRelationName(relation));	}	/* ----------------	 *	If we get here, it means the relation has no subclasses	 *	so we can trash it.  First we remove dead INHERITS tuples.	 * ----------------	 */	entry.sk_attno = Anum_pg_inherits_inhrel;	scan = heap_beginscan(catalogRelation,						  false,						  SnapshotNow,						  1,						  &entry);	while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))	{		heap_delete(catalogRelation, &tuple->t_self, NULL);		found = true;	}	heap_endscan(scan);	heap_close(catalogRelation);	/* ----------------	 *	now remove dead IPL tuples	 * ----------------	 */	catalogRelation = heap_openr(InheritancePrecidenceListRelationName);	entry.sk_attno = Anum_pg_ipl_iplrel;	scan = heap_beginscan(catalogRelation,						  false,						  SnapshotNow,						  1,						  &entry);	while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))		heap_delete(catalogRelation, &tuple->t_self, NULL);	heap_endscan(scan);	heap_close(catalogRelation);}/* -------------------------------- *		RelationRemoveIndexes * * -------------------------------- */static voidRelationRemoveIndexes(Relation relation){	Relation	indexRelation;	HeapTuple	tuple;	HeapScanDesc scan;	ScanKeyData entry;	indexRelation = heap_openr(IndexRelationName);	ScanKeyEntryInitialize(&entry, 0x0, Anum_pg_index_indrelid,						   F_OIDEQ,						   ObjectIdGetDatum(RelationGetRelid(relation)));	scan = heap_beginscan(indexRelation,						  false,						  SnapshotNow,						  1,						  &entry);	while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))		index_destroy(((Form_pg_index) GETSTRUCT(tuple))->indexrelid);	heap_endscan(scan);	heap_close(indexRelation);}/* -------------------------------- *		DeleteRelationTuple * * -------------------------------- */static voidDeleteRelationTuple(Relation rel){	Relation	pg_class_desc;	HeapTuple	tup;	/* ----------------	 *	open pg_class	 * ----------------	 */	pg_class_desc = heap_openr(RelationRelationName);	tup = SearchSysCacheTupleCopy(RELOID,					   ObjectIdGetDatum(rel->rd_att->attrs[0]->attrelid),								  0, 0, 0);	if (!HeapTupleIsValid(tup))	{		heap_close(pg_class_desc);		elog(ERROR, "Relation '%s' does not exist",			 &rel->rd_rel->relname);	}	/* ----------------	 *	delete the relation tuple from pg_class, and finish up.	 * ----------------	 */	heap_delete(pg_class_desc, &tup->t_self, NULL);	pfree(tup);	heap_close(pg_class_desc);}/* -------------------------------- *		DeleteAttributeTuples * * -------------------------------- */static voidDeleteAttributeTuples(Relation rel){	Relation	pg_attribute_desc;	HeapTuple	tup;	int2		attnum;	/* ----------------	 *	open pg_attribute	 * ----------------	 */	pg_attribute_desc = heap_openr(AttributeRelationName);	/* -----------------	 * Get a write lock _before_ getting the read lock in the scan	 * ----------------	 */	LockRelation(pg_attribute_desc, AccessExclusiveLock);	for (attnum = FirstLowInvalidHeapAttributeNumber + 1;		 attnum <= rel->rd_att->natts;		 attnum++)	{		if (HeapTupleIsValid(tup = SearchSysCacheTupleCopy(ATTNUM,								 ObjectIdGetDatum(RelationGetRelid(rel)),												   Int16GetDatum(attnum),														   0, 0)))		{			heap_delete(pg_attribute_desc, &tup->t_self, NULL);			pfree(tup);		}	}	/* ----------------	 * Release the write lock	 * ----------------	 */	UnlockRelation(pg_attribute_desc, AccessExclusiveLock);	heap_close(pg_attribute_desc);}/* -------------------------------- *		DeleteTypeTuple * *		If the user attempts to destroy a relation and there *		exists attributes in other relations of type *		"relation we are deleting", then we have to do something *		special.  presently we disallow the destroy. * -------------------------------- */static voidDeleteTypeTuple(Relation rel){	Relation	pg_type_desc;	HeapScanDesc pg_type_scan;	Relation	pg_attribute_desc;	HeapScanDesc pg_attribute_scan;	ScanKeyData key;	ScanKeyData attkey;	HeapTuple	tup;	HeapTuple	atttup;	Oid			typoid;	/* ----------------	 *	open pg_type	 * ----------------	 */	pg_type_desc = heap_openr(TypeRelationName);

⌨️ 快捷键说明

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