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

📄 relcache.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 4 页
字号:
	/* ----------------	 *	end the scan and close the attribute relation	 * ----------------	 */	heap_endscan(pg_attribute_scan);	heap_close(pg_attribute_desc);}static voidbuild_tupdesc_ind(RelationBuildDescInfo buildinfo,				  Relation relation,				  u_int natts){	Relation	attrel;	HeapTuple	atttup;	Form_pg_attribute attp;	TupleConstr *constr = (TupleConstr *) palloc(sizeof(TupleConstr));	AttrDefault *attrdef = NULL;	int			ndef = 0;	int			i;	constr->has_not_null = false;	attrel = heap_openr(AttributeRelationName);	for (i = 1; i <= relation->rd_rel->relnatts; i++)	{		atttup = (HeapTuple) AttributeNumIndexScan(attrel,										  RelationGetRelid(relation), i);		if (!HeapTupleIsValid(atttup))			elog(ERROR, "cannot find attribute %d of relation %s", i,				 relation->rd_rel->relname.data);		attp = (Form_pg_attribute) GETSTRUCT(atttup);		relation->rd_att->attrs[i - 1] =			(Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);		memmove((char *) (relation->rd_att->attrs[i - 1]),				(char *) attp,				ATTRIBUTE_TUPLE_SIZE);		/* Update if this attribute have a constraint */		if (attp->attnotnull)			constr->has_not_null = true;		if (attp->atthasdef)		{			if (attrdef == NULL)				attrdef = (AttrDefault *) palloc(relation->rd_rel->relnatts *												 sizeof(AttrDefault));			attrdef[ndef].adnum = i;			attrdef[ndef].adbin = NULL;			attrdef[ndef].adsrc = NULL;			ndef++;		}	}	heap_close(attrel);	if (constr->has_not_null || ndef > 0 || relation->rd_rel->relchecks)	{		relation->rd_att->constr = constr;		if (ndef > 0)			/* DEFAULTs */		{			if (ndef < relation->rd_rel->relnatts)				constr->defval = (AttrDefault *)					repalloc(attrdef, ndef * sizeof(AttrDefault));			else				constr->defval = attrdef;			constr->num_defval = ndef;			AttrDefaultFetch(relation);		}		else			constr->num_defval = 0;		if (relation->rd_rel->relchecks > 0)	/* CHECKs */		{			constr->num_check = relation->rd_rel->relchecks;			constr->check = (ConstrCheck *) palloc(constr->num_check *												   sizeof(ConstrCheck));			MemSet(constr->check, 0, constr->num_check * sizeof(ConstrCheck));			RelCheckFetch(relation);		}		else			constr->num_check = 0;	}	else	{		pfree(constr);		relation->rd_att->constr = NULL;	}}/* -------------------------------- *		RelationBuildRuleLock * *		Form the relation's rewrite rules from information in *		the pg_rewrite system catalog. * -------------------------------- */static voidRelationBuildRuleLock(Relation relation){	HeapTuple	pg_rewrite_tuple;	Relation	pg_rewrite_desc;	TupleDesc	pg_rewrite_tupdesc;	HeapScanDesc pg_rewrite_scan;	ScanKeyData key;	RuleLock   *rulelock;	int			numlocks;	RewriteRule **rules;	int			maxlocks;	/* ----------------	 *	form an array to hold the rewrite rules (the array is extended if	 *	necessary)	 * ----------------	 */	maxlocks = 4;	rules = (RewriteRule **) palloc(sizeof(RewriteRule *) * maxlocks);	numlocks = 0;	/* ----------------	 *	form a scan key	 * ----------------	 */	ScanKeyEntryInitialize(&key, 0,						   Anum_pg_rewrite_ev_class,						   F_OIDEQ,						   ObjectIdGetDatum(RelationGetRelid(relation)));	/* ----------------	 *	open pg_attribute and begin a scan	 * ----------------	 */	pg_rewrite_desc = heap_openr(RewriteRelationName);	pg_rewrite_scan = heap_beginscan(pg_rewrite_desc, 0, SnapshotNow, 1, &key);	pg_rewrite_tupdesc = RelationGetDescr(pg_rewrite_desc);	/* ----------------	 *	add attribute data to relation->rd_att	 * ----------------	 */	while (HeapTupleIsValid(pg_rewrite_tuple = heap_getnext(pg_rewrite_scan, 0)))	{		bool		isnull;		Datum		ruleaction;		Datum		rule_evqual_string;		RewriteRule *rule;		rule = (RewriteRule *) palloc(sizeof(RewriteRule));		rule->ruleId = pg_rewrite_tuple->t_data->t_oid;		rule->event = (int) heap_getattr(pg_rewrite_tuple,							 Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,										 &isnull) - 48;		rule->attrno = (int) heap_getattr(pg_rewrite_tuple,							 Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,										  &isnull);		rule->isInstead = !!heap_getattr(pg_rewrite_tuple,						  Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,										 &isnull);		ruleaction = heap_getattr(pg_rewrite_tuple,						   Anum_pg_rewrite_ev_action, pg_rewrite_tupdesc,								  &isnull);		rule_evqual_string = heap_getattr(pg_rewrite_tuple,							 Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,										  &isnull);		ruleaction = PointerGetDatum(textout((struct varlena *) DatumGetPointer(ruleaction)));		rule_evqual_string = PointerGetDatum(textout((struct varlena *) DatumGetPointer(rule_evqual_string)));		rule->actions = (List *) stringToNode(DatumGetPointer(ruleaction));		rule->qual = (Node *) stringToNode(DatumGetPointer(rule_evqual_string));		rules[numlocks++] = rule;		if (numlocks == maxlocks)		{			maxlocks *= 2;			rules = (RewriteRule **) repalloc(rules, sizeof(RewriteRule *) * maxlocks);		}	}	/* ----------------	 *	end the scan and close the attribute relation	 * ----------------	 */	heap_endscan(pg_rewrite_scan);	heap_close(pg_rewrite_desc);	/* ----------------	 *	form a RuleLock and insert into relation	 * ----------------	 */	rulelock = (RuleLock *) palloc(sizeof(RuleLock));	rulelock->numLocks = numlocks;	rulelock->rules = rules;	relation->rd_rules = rulelock;	return;}/* -------------------------------- *		RelationBuildDesc * *		To build a relation descriptor, we have to allocate space, *		open the underlying unix file and initialize the following *		fields: * *	File				   rd_fd;		 open file descriptor *	int					   rd_nblocks;	 number of blocks in rel *										 it will be set in ambeginscan() *	uint16				   rd_refcnt;	 reference count *	Form_pg_am			   rd_am;		 AM tuple *	Form_pg_class		   rd_rel;		 RELATION tuple *	Oid					   rd_id;		 relations's object id *	Pointer				   lockInfo;	 ptr. to misc. info. *	TupleDesc			   rd_att;		 tuple desciptor * *		Note: rd_ismem (rel is in-memory only) is currently unused *		by any part of the system.	someday this will indicate that *		the relation lives only in the main-memory buffer pool *		-cim 2/4/91 * -------------------------------- */static RelationRelationBuildDesc(RelationBuildDescInfo buildinfo){	File		fd;	Relation	relation;	u_int		natts;	Oid			relid;	Oid			relam;	Form_pg_class relp;	MemoryContext oldcxt;	HeapTuple	pg_class_tuple;	oldcxt = MemoryContextSwitchTo((MemoryContext) CacheCxt);	/* ----------------	 *	find the tuple in pg_class corresponding to the given relation id	 * ----------------	 */	pg_class_tuple = ScanPgRelation(buildinfo);	/* ----------------	 *	if no such tuple exists, return NULL	 * ----------------	 */	if (!HeapTupleIsValid(pg_class_tuple))	{		MemoryContextSwitchTo(oldcxt);		return NULL;	}	/* ----------------	 *	get information from the pg_class_tuple	 * ----------------	 */	relid = pg_class_tuple->t_data->t_oid;	relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);	natts = relp->relnatts;	/* ----------------	 *	allocate storage for the relation descriptor,	 *	initialize relation->rd_rel and get the access method id.	 * ----------------	 */	relation = AllocateRelationDesc(natts, relp);	relam = relation->rd_rel->relam;	/* ----------------	 *	initialize the relation's relation id (relation->rd_id)	 * ----------------	 */	RelationGetRelid(relation) = relid;	/* ----------------	 *	initialize relation->rd_refcnt	 * ----------------	 */	RelationSetReferenceCount(relation, 1);	/* ----------------	 *	 normal relations are not nailed into the cache	 * ----------------	 */	relation->rd_isnailed = false;	/* ----------------	 *	initialize the access method information (relation->rd_am)	 * ----------------	 */	if (OidIsValid(relam))		relation->rd_am = (Form_pg_am) AccessMethodObjectIdGetForm(relam);	/* ----------------	 *	initialize the tuple descriptor (relation->rd_att).	 *	remember, rd_att is an array of attribute pointers that lives	 *	off the end of the relation descriptor structure so space was	 *	already allocated for it by AllocateRelationDesc.	 * ----------------	 */	RelationBuildTupleDesc(buildinfo, relation, natts);	/* ----------------	 *	initialize rules that affect this relation	 * ----------------	 */	if (relp->relhasrules)		RelationBuildRuleLock(relation);	else		relation->rd_rules = NULL;	/* Triggers */	if (relp->reltriggers > 0)		RelationBuildTriggers(relation);	else		relation->trigdesc = NULL;	/* ----------------	 *	initialize index strategy and support information for this relation	 * ----------------	 */	if (OidIsValid(relam))		IndexedAccessMethodInitialize(relation);	/* ----------------	 *	initialize the relation lock manager information	 * ----------------	 */	RelationInitLockInfo(relation);		/* see lmgr.c */	/* ----------------	 *	open the relation and assign the file descriptor returned	 *	by the storage manager code to rd_fd.	 * ----------------	 */	fd = smgropen(DEFAULT_SMGR, relation);	Assert(fd >= -1);	if (fd == -1)		elog(NOTICE, "RelationIdBuildRelation: smgropen(%s): %m",			 &relp->relname);	relation->rd_fd = fd;	/* ----------------	 *	insert newly created relation into proper relcaches,	 *	restore memory context and return the new reldesc.	 * ----------------	 */	RelationCacheInsert(relation);	/* -------------------	 *	free the memory allocated for pg_class_tuple	 *	and for lock data pointed to by pg_class_tuple	 * -------------------	 */	pfree(pg_class_tuple);	MemoryContextSwitchTo(oldcxt);	return relation;}static voidIndexedAccessMethodInitialize(Relation relation){	IndexStrategy strategy;	RegProcedure *support;	int			natts;	Size		stratSize;	Size		supportSize;	uint16		relamstrategies;	uint16		relamsupport;	natts = relation->rd_rel->relnatts;	relamstrategies = relation->rd_am->amstrategies;	stratSize = AttributeNumberGetIndexStrategySize(natts, relamstrategies);	strategy = (IndexStrategy) palloc(stratSize);	relamsupport = relation->rd_am->amsupport;	if (relamsupport > 0)	{		supportSize = natts * (relamsupport * sizeof(RegProcedure));		support = (RegProcedure *) palloc(supportSize);	}	else		support = (RegProcedure *) NULL;	IndexSupportInitialize(strategy, support,						   relation->rd_att->attrs[0]->attrelid,						   relation->rd_rel->relam,						   relamstrategies, relamsupport, natts);	RelationSetIndexSupport(relation, strategy, support);}/* -------------------------------- *		formrdesc * *		This is a special version of RelationBuildDesc() *		used by RelationInitialize() in initializing the *		relcache.  The system relation descriptors built *		here are all nailed in the descriptor caches, for *		bootstrapping. * -------------------------------- */static voidformrdesc(char *relationName,		  u_int natts,		  FormData_pg_attribute *att){	Relation	relation;	Size		len;	int			i;	/* ----------------	 *	allocate new relation desc	 * ----------------	 */	len = sizeof(RelationData);	relation = (Relation) palloc(len);	MemSet((char *) relation, 0, len);	/* ----------------	 *	don't open the unix file yet..	 * ----------------	 */	relation->rd_fd = -1;	/* ----------------	 *	initialize reference count	 * ----------------	 */	RelationSetReferenceCount(relation, 1);	/* ----------------	 *	initialize relation tuple form	 * ----------------	 */	relation->rd_rel = (Form_pg_class)		palloc((Size) (sizeof(*relation->rd_rel)));	MemSet(relation->rd_rel, 0, sizeof(FormData_pg_class));	namestrcpy(&relation->rd_rel->relname, relationName);	/* ----------------	   initialize attribute tuple form	*/	relation->rd_att = CreateTemplateTupleDesc(natts);	/*	 * For debugging purposes, it's important to distinguish between	 * shared and non-shared relations, even at bootstrap time.  There's	 * code in the buffer manager that traces allocations that has to know	 * about this.	 */	if (IsSystemRelationName(relationName))	{		relation->rd_rel->relowner = 6; /* XXX use sym const */		relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);	}	else	{		relation->rd_rel->relowner = 0;		relation->rd_rel->relisshared = false;	}	relation->rd_rel->relpages = 1;		/* XXX */	relation->rd_rel->reltuples = 1;	/* XXX */	relation->rd_rel->relkind = RELKIND_RELATION;	relation->rd_rel->relnatts = (uint16) natts;	relation->rd_isnailed = true;	/* ----------------	 *	initialize tuple desc info	 * ----------------	 */	for (i = 0; i < natts; i++)	{		relation->rd_att->attrs[i] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);		MemSet((char *) relation->rd_att->attrs[i], 0,			   ATTRIBUTE_TUPLE_SIZE);		memmove((char *) relation->rd_att->attrs[i],				(char *) &att[i],				ATTRIBUTE_TUPLE_SIZE);	}	/* ----------------	 *	initialize relation id	 * ----------------	 */	RelationGetRelid(relation) = relation->rd_att->attrs[0]->attrelid;	/* ----------------	 *	add new reldesc to relcache	 * ----------------	 */	RelationCacheInsert(relation);	RelationInitLockInfo(relation);	/*	 * Determining this requires a scan on pg_class, but to do the scan	 * the rdesc for pg_class must already exist.  Therefore we must do	 * the check (and possible set) after cache insertion.	 */	relation->rd_rel->relhasindex =		CatalogHasIndex(relationName, RelationGetRelid(relation));}/* ---------------------------------------------------------------- *				 Relation Descriptor Lookup Interface * ---------------------------------------------------------------- */

⌨️ 快捷键说明

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