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

📄 heap.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 4 页
字号:
				/*				 * Unneeded since they should be OK in the constant data				 * anyway				 */				/* attStruct->attstattarget = 0; */				/* attStruct->attcacheoff = -1; */				simple_heap_insert(rel, tup);				CatalogIndexInsert(indstate, tup);				heap_freetuple(tup);			}			dpp++;		}	}	/*	 * clean up	 */	CatalogCloseIndexes(indstate);	heap_close(rel, RowExclusiveLock);}/* -------------------------------- *		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,					Oid new_type_oid,					Oid relowner,					char relkind){	Form_pg_class new_rel_reltup;	HeapTuple	tup;	/*	 * first we update some of the information in our uncataloged relation's	 * relation descriptor.	 */	new_rel_reltup = new_rel_desc->rd_rel;	switch (relkind)	{		case RELKIND_RELATION:		case RELKIND_INDEX:		case RELKIND_TOASTVALUE:			/* The relation is real, but as yet empty */			new_rel_reltup->relpages = 0;			new_rel_reltup->reltuples = 0;			break;		case RELKIND_SEQUENCE:			/* Sequences always have a known size */			new_rel_reltup->relpages = 1;			new_rel_reltup->reltuples = 1;			break;		default:			/* Views, etc, have no disk storage */			new_rel_reltup->relpages = 0;			new_rel_reltup->reltuples = 0;			break;	}	new_rel_reltup->relowner = relowner;	new_rel_reltup->reltype = new_type_oid;	new_rel_reltup->relkind = relkind;	new_rel_desc->rd_att->tdtypeid = new_type_oid;	/* ----------------	 *	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,						 true,						 CLASS_TUPLE_SIZE,						 (void *) new_rel_reltup);	/* force tuple to have the desired OID */	HeapTupleSetOid(tup, new_rel_oid);	/*	 * finally insert the new tuple, update the indexes, and clean up.	 */	simple_heap_insert(pg_class_desc, tup);	CatalogUpdateIndexes(pg_class_desc, tup);	heap_freetuple(tup);}/* -------------------------------- *		AddNewRelationType - * *		define a composite type corresponding to the new relation * -------------------------------- */static OidAddNewRelationType(const char *typeName,				   Oid typeNamespace,				   Oid new_rel_oid,				   char new_rel_kind){	return		TypeCreate(typeName,	/* type name */				   typeNamespace,		/* type namespace */				   new_rel_oid, /* relation oid */				   new_rel_kind,	/* relation kind */				   -1,			/* internal size (varlena) */				   'c',			/* type-type (complex) */				   ',',			/* default array delimiter */				   F_RECORD_IN, /* input procedure */				   F_RECORD_OUT,	/* output procedure */				   F_RECORD_RECV,		/* receive procedure */				   F_RECORD_SEND,		/* send procedure */				   InvalidOid,	/* analyze procedure - default */				   InvalidOid,	/* array element type - irrelevant */				   InvalidOid,	/* domain base type - irrelevant */				   NULL,		/* default value - none */				   NULL,		/* default binary representation */				   false,		/* passed by reference */				   'd',			/* alignment - must be the largest! */				   'x',			/* fully TOASTable */				   -1,			/* typmod */				   0,			/* array dimensions for typBaseType */				   false);		/* Type NOT NULL */}/* -------------------------------- *		heap_create_with_catalog * *		creates a new cataloged relation.  see comments above. * -------------------------------- */Oidheap_create_with_catalog(const char *relname,						 Oid relnamespace,						 Oid reltablespace,						 Oid relid,						 Oid ownerid,						 TupleDesc tupdesc,						 char relkind,						 bool shared_relation,						 bool oidislocal,						 int oidinhcount,						 OnCommitAction oncommit,						 bool allow_system_table_mods){	Relation	pg_class_desc;	Relation	new_rel_desc;	Oid			new_type_oid;	pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);	/*	 * sanity checks	 */	Assert(IsNormalProcessingMode() || IsBootstrapProcessingMode());	CheckAttributeNamesTypes(tupdesc, relkind);	if (get_relname_relid(relname, relnamespace))		ereport(ERROR,				(errcode(ERRCODE_DUPLICATE_TABLE),				 errmsg("relation \"%s\" already exists", relname)));	/*	 * Allocate an OID for the relation, unless we were told what to use.	 *	 * The OID will be the relfilenode as well, so make sure it doesn't	 * collide with either pg_class OIDs or existing physical files.	 */	if (!OidIsValid(relid))		relid = GetNewRelFileNode(reltablespace, shared_relation,								  pg_class_desc);	/*	 * Create the relcache entry (mostly dummy at this point) and the physical	 * disk file.  (If we fail further down, it's the smgr's responsibility to	 * remove the disk file again.)	 */	new_rel_desc = heap_create(relname,							   relnamespace,							   reltablespace,							   relid,							   tupdesc,							   relkind,							   shared_relation,							   allow_system_table_mods);	Assert(relid == RelationGetRelid(new_rel_desc));	/*	 * since defining a relation also defines a complex type, we add a new	 * system type corresponding to the new relation.	 *	 * NOTE: we could get a unique-index failure here, in case the same name	 * has already been used for a type.	 */	new_type_oid = AddNewRelationType(relname,									  relnamespace,									  relid,									  relkind);	/*	 * now create an entry in pg_class for the relation.	 *	 * NOTE: we could get a unique-index failure here, in case someone else is	 * creating the same relation name in parallel but hadn't committed yet	 * when we checked for a duplicate name above.	 */	AddNewRelationTuple(pg_class_desc,						new_rel_desc,						relid,						new_type_oid,						ownerid,						relkind);	/*	 * now add tuples to pg_attribute for the attributes in our new relation.	 */	AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind,						  oidislocal, oidinhcount);	/*	 * make a dependency link to force the relation to be deleted if its	 * namespace is.  Skip this in bootstrap mode, since we don't make	 * dependencies while bootstrapping.	 *	 * Also make a dependency link to its owner.	 */	if (!IsBootstrapProcessingMode())	{		ObjectAddress myself,					referenced;		myself.classId = RelationRelationId;		myself.objectId = relid;		myself.objectSubId = 0;		referenced.classId = NamespaceRelationId;		referenced.objectId = relnamespace;		referenced.objectSubId = 0;		recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);		/*		 * For composite types, the dependency on owner is tracked for the		 * pg_type entry, so don't record it here.  All other relkinds need		 * their ownership tracked.		 */		if (relkind != RELKIND_COMPOSITE_TYPE)			recordDependencyOnOwner(RelationRelationId, relid, ownerid);	}	/*	 * store constraints and defaults passed in the tupdesc, if any.	 *	 * NB: this may do a CommandCounterIncrement and rebuild the relcache	 * entry, so the relation must be valid and self-consistent at this point.	 * In particular, there are not yet constraints and defaults anywhere.	 */	StoreConstraints(new_rel_desc, tupdesc);	/*	 * If there's a special on-commit action, remember it	 */	if (oncommit != ONCOMMIT_NOOP)		register_on_commit_action(relid, oncommit);	/*	 * ok, the relation has been cataloged, so close our relations and return	 * the OID of the newly created relation.	 */	heap_close(new_rel_desc, NoLock);	/* do not unlock till end of xact */	heap_close(pg_class_desc, RowExclusiveLock);	return relid;}/* *		RelationRemoveInheritance * * Formerly, this routine checked for child relations and aborted the * deletion if any were found.	Now we rely on the dependency mechanism * to check for or delete child relations.	By the time we get here, * there are no children and we need only remove any pg_inherits rows * linking this relation to its parent(s). */static voidRelationRemoveInheritance(Oid relid){	Relation	catalogRelation;	SysScanDesc scan;	ScanKeyData key;	HeapTuple	tuple;	catalogRelation = heap_open(InheritsRelationId, RowExclusiveLock);	ScanKeyInit(&key,				Anum_pg_inherits_inhrelid,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(relid));	scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, true,							  SnapshotNow, 1, &key);	while (HeapTupleIsValid(tuple = systable_getnext(scan)))		simple_heap_delete(catalogRelation, &tuple->t_self);	systable_endscan(scan);	heap_close(catalogRelation, RowExclusiveLock);}/* *		DeleteRelationTuple * * Remove pg_class row for the given relid. * * Note: this is shared by relation deletion and index deletion.  It's * not intended for use anyplace else. */voidDeleteRelationTuple(Oid relid){	Relation	pg_class_desc;	HeapTuple	tup;	/* Grab an appropriate lock on the pg_class relation */	pg_class_desc = heap_open(RelationRelationId, RowExclusiveLock);	tup = SearchSysCache(RELOID,						 ObjectIdGetDatum(relid),						 0, 0, 0);	if (!HeapTupleIsValid(tup))		elog(ERROR, "cache lookup failed for relation %u", relid);	/* delete the relation tuple from pg_class, and finish up */	simple_heap_delete(pg_class_desc, &tup->t_self);	ReleaseSysCache(tup);	heap_close(pg_class_desc, RowExclusiveLock);}/* *		DeleteAttributeTuples * * Remove pg_attribute rows for the given relid. * * Note: this is shared by relation deletion and index deletion.  It's * not intended for use anyplace else. */voidDeleteAttributeTuples(Oid relid){	Relation	attrel;	SysScanDesc scan;	ScanKeyData key[1];	HeapTuple	atttup;	/* Grab an appropriate lock on the pg_attribute relation */	attrel = heap_open(AttributeRelationId, RowExclusiveLock);	/* Use the index to scan only attributes of the target relation */	ScanKeyInit(&key[0],				Anum_pg_attribute_attrelid,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(relid));	scan = systable_beginscan(attrel, AttributeRelidNumIndexId, true,							  SnapshotNow, 1, key);	/* Delete all the matching tuples */	while ((atttup = systable_getnext(scan)) != NULL)		simple_heap_delete(attrel, &atttup->t_self);	/* Clean up after the scan */	systable_endscan(scan);	heap_close(attrel, RowExclusiveLock);}/* *		RemoveAttributeById * * This is the guts of ALTER TABLE DROP COLUMN: actually mark the attribute * deleted in pg_attribute.  We also remove pg_statistic entries for it. * (Everything else needed, such as getting rid of any pg_attrdef entry, * is handled by dependency.c.) */voidRemoveAttributeById(Oid relid, AttrNumber attnum){	Relation	rel;	Relation	attr_rel;	HeapTuple	tuple;	Form_pg_attribute attStruct;	char		newattname[NAMEDATALEN];	/*	 * Grab an exclusive lock on the target table, which we will NOT release	 * until end of transaction.  (In the simple case where we are directly	 * dropping this column, AlterTableDropColumn already did this ... but	 * when cascading from a drop of some other object, we may not have any	 * lock.)	 */	rel = relation_open(relid, AccessExclusiveLock);	attr_rel = heap_open(AttributeRelationId, RowExclusiveLock);	tuple = SearchSysCacheCopy(ATTNUM,							   ObjectIdGetDatum(relid),							   Int16GetDatum(attnum),							   0, 0);	if (!HeapTupleIsValid(tuple))		/* shouldn't happen */		elog(ERROR, "cache lookup failed for attribute %d of relation %u",			 attnum, relid);	attStruct = (Form_pg_attribute) GETSTRUCT(tuple);	if (attnum < 0)	{		/* System attribute (probably OID) ... just delete the row */		simple_heap_delete(attr_rel, &tuple->t_self);	}	else	{		/* Dropping user attributes is lots harder */		/* Mark the attribute as dropped */		attStruct->attisdropped = true;		/*		 * Set the type OID to invalid.  A dropped attribute's type link		 * cannot be relied on (once the attribute is dropped, the type might		 * be too). Fortunately we do not need the type row --- the only		 * really essential information is the type's typlen and typalign,		 * which are preserved in the attribute's attlen and attalign.  We set		 * atttypid to zero here as a means of catching code that incorrectly		 * expects it to be valid.		 */		attStruct->atttypid = InvalidOid;		/* Remove any NOT NULL constraint the column may have */		attStruct->attnotnull = false;		/* We don't want to keep stats for it anymore */		attStruct->attstattarget = 0;		/*		 * Change the column name to something that isn't likely to conflict		 */		snprintf(newattname, sizeof(newattname),				 "........pg.dropped.%d........", attnum);		namestrcpy(&(attStruct->attname), newattname);		simple_heap_update(attr_rel, &tuple->t_self, tuple);		/* keep the system catalog indexes current */		CatalogUpdateIndexes(attr_rel, tuple);	}	/*	 * Because updating the pg_attribute row will trigger a relcache flush for	 * the target relation, we need not do anything else to notify other	 * backends of the change.	 */	heap_close(attr_rel, RowExclusiveLock);	if (attnum > 0)		RemoveStatistics(relid, attnum);	relation_close(rel, NoLock);}/* *		RemoveAttrDefault * * If the specified relation/attribute has a default, remove it. * (If no default, raise error if complain is true, else return quietly.) */voidRemoveAttrDefault(Oid relid, AttrNumber attnum,				  DropBehavior behavior, bool complain){	Relation	attrdef_rel;	ScanKeyData scankeys[2];	SysScanDesc scan;	HeapTuple	tuple;	bool		found = false;	attrdef_rel = heap_open(AttrDefaultRelationId, RowExclusiveLock);	ScanKeyInit(&scankeys[0],				Anum_pg_attrdef_adrelid,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(relid));	ScanKeyInit(&scankeys[1],				Anum_pg_attrdef_adnum,				BTEqualStrategyNumber, F_INT2EQ,				Int16GetDatum(attnum));	scan = systable_beginscan(attrdef_rel, AttrDefaultIndexId, true,							  SnapshotNow, 2, scankeys);	/* There should be at most one matching tuple, but we loop anyway */	while (HeapTupleIsValid(tuple = systable_getnext(scan)))	{		ObjectAddress object;		object.classId = AttrDefaultRelationId;		object.objectId = HeapTupleGetOid(tuple);

⌨️ 快捷键说明

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