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

📄 pg_constraint.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
 * * name1, name2, and label are used the same way as for makeObjectName(), * except that the label can't be NULL; digits will be appended to the label * if needed to create a name that is unique within the specified namespace. * * 'others' can be a list of string names already chosen within the current * command (but not yet reflected into the catalogs); we will not choose * a duplicate of one of these either. * * Note: it is theoretically possible to get a collision anyway, if someone * else chooses the same name concurrently.  This is fairly unlikely to be * a problem in practice, especially if one is holding an exclusive lock on * the relation identified by name1. * * Returns a palloc'd string. */char *ChooseConstraintName(const char *name1, const char *name2,					 const char *label, Oid namespace,					 List *others){	int			pass = 0;	char	   *conname = NULL;	char		modlabel[NAMEDATALEN];	Relation	conDesc;	SysScanDesc conscan;	ScanKeyData skey[2];	bool		found;	ListCell   *l;	conDesc = heap_open(ConstraintRelationId, AccessShareLock);	/* try the unmodified label first */	StrNCpy(modlabel, label, sizeof(modlabel));	for (;;)	{		conname = makeObjectName(name1, name2, modlabel);		found = false;		foreach(l, others)		{			if (strcmp((char *) lfirst(l), conname) == 0)			{				found = true;				break;			}		}		if (!found)		{			ScanKeyInit(&skey[0],						Anum_pg_constraint_conname,						BTEqualStrategyNumber, F_NAMEEQ,						CStringGetDatum(conname));			ScanKeyInit(&skey[1],						Anum_pg_constraint_connamespace,						BTEqualStrategyNumber, F_OIDEQ,						ObjectIdGetDatum(namespace));			conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,										 SnapshotNow, 2, skey);			found = (HeapTupleIsValid(systable_getnext(conscan)));			systable_endscan(conscan);		}		if (!found)			break;		/* found a conflict, so try a new name component */		pfree(conname);		snprintf(modlabel, sizeof(modlabel), "%s%d", label, ++pass);	}	heap_close(conDesc, AccessShareLock);	return conname;}/* * Delete a single constraint record. */voidRemoveConstraintById(Oid conId){	Relation	conDesc;	ScanKeyData skey[1];	SysScanDesc conscan;	HeapTuple	tup;	Form_pg_constraint con;	conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);	ScanKeyInit(&skey[0],				ObjectIdAttributeNumber,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(conId));	conscan = systable_beginscan(conDesc, ConstraintOidIndexId, true,								 SnapshotNow, 1, skey);	tup = systable_getnext(conscan);	if (!HeapTupleIsValid(tup))		elog(ERROR, "could not find tuple for constraint %u", conId);	con = (Form_pg_constraint) GETSTRUCT(tup);	/*	 * Special processing depending on what the constraint is for.	 */	if (OidIsValid(con->conrelid))	{		Relation	rel;		/*		 * If the constraint is for a relation, open and exclusive-lock the		 * relation it's for.		 */		rel = heap_open(con->conrelid, AccessExclusiveLock);		/*		 * We need to update the relcheck count if it is a check constraint		 * being dropped.  This update will force backends to rebuild relcache		 * entries when we commit.		 */		if (con->contype == CONSTRAINT_CHECK)		{			Relation	pgrel;			HeapTuple	relTup;			Form_pg_class classForm;			pgrel = heap_open(RelationRelationId, RowExclusiveLock);			relTup = SearchSysCacheCopy(RELOID,										ObjectIdGetDatum(con->conrelid),										0, 0, 0);			if (!HeapTupleIsValid(relTup))				elog(ERROR, "cache lookup failed for relation %u",					 con->conrelid);			classForm = (Form_pg_class) GETSTRUCT(relTup);			if (classForm->relchecks == 0)		/* should not happen */				elog(ERROR, "relation \"%s\" has relchecks = 0",					 RelationGetRelationName(rel));			classForm->relchecks--;			simple_heap_update(pgrel, &relTup->t_self, relTup);			CatalogUpdateIndexes(pgrel, relTup);			heap_freetuple(relTup);			heap_close(pgrel, RowExclusiveLock);		}		/* Keep lock on constraint's rel until end of xact */		heap_close(rel, NoLock);	}	else if (OidIsValid(con->contypid))	{		/*		 * XXX for now, do nothing special when dropping a domain constraint		 *		 * Probably there should be some form of locking on the domain type,		 * but we have no such concept at the moment.		 */	}	else		elog(ERROR, "constraint %u is not of a known type", conId);	/* Fry the constraint itself */	simple_heap_delete(conDesc, &tup->t_self);	/* Clean up */	systable_endscan(conscan);	heap_close(conDesc, RowExclusiveLock);}/* * GetConstraintNameForTrigger *		Get the name of the constraint owning a trigger, if any * * Returns a palloc'd string, or NULL if no constraint can be found */char *GetConstraintNameForTrigger(Oid triggerId){	char	   *result;	Oid			constraintId = InvalidOid;	Relation	depRel;	Relation	conRel;	ScanKeyData key[2];	SysScanDesc scan;	HeapTuple	tup;	/*	 * We must grovel through pg_depend to find the owning constraint. Perhaps	 * pg_trigger should have a column for the owning constraint ... but right	 * now this is not performance-critical code.	 */	depRel = heap_open(DependRelationId, AccessShareLock);	ScanKeyInit(&key[0],				Anum_pg_depend_classid,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(TriggerRelationId));	ScanKeyInit(&key[1],				Anum_pg_depend_objid,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(triggerId));	/* assume we can ignore objsubid for a trigger */	scan = systable_beginscan(depRel, DependDependerIndexId, true,							  SnapshotNow, 2, key);	while (HeapTupleIsValid(tup = systable_getnext(scan)))	{		Form_pg_depend foundDep = (Form_pg_depend) GETSTRUCT(tup);		if (foundDep->refclassid == ConstraintRelationId &&			foundDep->deptype == DEPENDENCY_INTERNAL)		{			constraintId = foundDep->refobjid;			break;		}	}	systable_endscan(scan);	heap_close(depRel, AccessShareLock);	if (!OidIsValid(constraintId))		return NULL;			/* no owning constraint found */	conRel = heap_open(ConstraintRelationId, AccessShareLock);	ScanKeyInit(&key[0],				ObjectIdAttributeNumber,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(constraintId));	scan = systable_beginscan(conRel, ConstraintOidIndexId, true,							  SnapshotNow, 1, key);	tup = systable_getnext(scan);	if (HeapTupleIsValid(tup))	{		Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);		result = pstrdup(NameStr(con->conname));	}	else	{		/* This arguably should be an error, but we'll just return NULL */		result = NULL;	}	systable_endscan(scan);	heap_close(conRel, AccessShareLock);	return result;}/* * AlterConstraintNamespaces *		Find any constraints belonging to the specified object, *		and move them to the specified new namespace. * * isType indicates whether the owning object is a type or a relation. */voidAlterConstraintNamespaces(Oid ownerId, Oid oldNspId,						  Oid newNspId, bool isType){	Relation	conRel;	ScanKeyData key[1];	SysScanDesc scan;	HeapTuple	tup;	conRel = heap_open(ConstraintRelationId, RowExclusiveLock);	if (isType)	{		ScanKeyInit(&key[0],					Anum_pg_constraint_contypid,					BTEqualStrategyNumber, F_OIDEQ,					ObjectIdGetDatum(ownerId));		scan = systable_beginscan(conRel, ConstraintTypidIndexId, true,								  SnapshotNow, 1, key);	}	else	{		ScanKeyInit(&key[0],					Anum_pg_constraint_conrelid,					BTEqualStrategyNumber, F_OIDEQ,					ObjectIdGetDatum(ownerId));		scan = systable_beginscan(conRel, ConstraintRelidIndexId, true,								  SnapshotNow, 1, key);	}	while (HeapTupleIsValid((tup = systable_getnext(scan))))	{		Form_pg_constraint conform = (Form_pg_constraint) GETSTRUCT(tup);		if (conform->connamespace == oldNspId)		{			tup = heap_copytuple(tup);			conform = (Form_pg_constraint) GETSTRUCT(tup);			conform->connamespace = newNspId;			simple_heap_update(conRel, &tup->t_self, tup);			CatalogUpdateIndexes(conRel, tup);			/*			 * Note: currently, the constraint will not have its own			 * dependency on the namespace, so we don't need to do			 * changeDependencyFor().			 */		}	}	systable_endscan(scan);	heap_close(conRel, RowExclusiveLock);}

⌨️ 快捷键说明

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