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

📄 pg_constraint.c

📁 PostgreSQL 8.1.4的源码 适用于Linux下的开源数据库系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * pg_constraint.c *	  routines to support manipulation of the pg_constraint relation * * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * * IDENTIFICATION *	  $PostgreSQL: pgsql/src/backend/catalog/pg_constraint.c,v 1.27.2.1 2005/11/22 18:23:06 momjian Exp $ * *------------------------------------------------------------------------- */#include "postgres.h"#include "access/heapam.h"#include "access/genam.h"#include "catalog/catalog.h"#include "catalog/dependency.h"#include "catalog/indexing.h"#include "catalog/pg_constraint.h"#include "catalog/pg_depend.h"#include "catalog/pg_trigger.h"#include "catalog/pg_type.h"#include "commands/defrem.h"#include "miscadmin.h"#include "utils/array.h"#include "utils/builtins.h"#include "utils/fmgroids.h"#include "utils/lsyscache.h"#include "utils/syscache.h"/* * CreateConstraintEntry *	Create a constraint table entry. * * Subsidiary records (such as triggers or indexes to implement the * constraint) are *not* created here.	But we do make dependency links * from the constraint to the things it depends on. */OidCreateConstraintEntry(const char *constraintName,					  Oid constraintNamespace,					  char constraintType,					  bool isDeferrable,					  bool isDeferred,					  Oid relId,					  const int16 *constraintKey,					  int constraintNKeys,					  Oid domainId,					  Oid foreignRelId,					  const int16 *foreignKey,					  int foreignNKeys,					  char foreignUpdateType,					  char foreignDeleteType,					  char foreignMatchType,					  Oid indexRelId,					  Node *conExpr,					  const char *conBin,					  const char *conSrc){	Relation	conDesc;	Oid			conOid;	HeapTuple	tup;	char		nulls[Natts_pg_constraint];	Datum		values[Natts_pg_constraint];	ArrayType  *conkeyArray;	ArrayType  *confkeyArray;	NameData	cname;	int			i;	ObjectAddress conobject;	conDesc = heap_open(ConstraintRelationId, RowExclusiveLock);	Assert(constraintName);	namestrcpy(&cname, constraintName);	/*	 * Convert C arrays into Postgres arrays.	 */	if (constraintNKeys > 0)	{		Datum	   *conkey;		conkey = (Datum *) palloc(constraintNKeys * sizeof(Datum));		for (i = 0; i < constraintNKeys; i++)			conkey[i] = Int16GetDatum(constraintKey[i]);		conkeyArray = construct_array(conkey, constraintNKeys,									  INT2OID, 2, true, 's');	}	else		conkeyArray = NULL;	if (foreignNKeys > 0)	{		Datum	   *confkey;		confkey = (Datum *) palloc(foreignNKeys * sizeof(Datum));		for (i = 0; i < foreignNKeys; i++)			confkey[i] = Int16GetDatum(foreignKey[i]);		confkeyArray = construct_array(confkey, foreignNKeys,									   INT2OID, 2, true, 's');	}	else		confkeyArray = NULL;	/* initialize nulls and values */	for (i = 0; i < Natts_pg_constraint; i++)	{		nulls[i] = ' ';		values[i] = (Datum) NULL;	}	values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname);	values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace);	values[Anum_pg_constraint_contype - 1] = CharGetDatum(constraintType);	values[Anum_pg_constraint_condeferrable - 1] = BoolGetDatum(isDeferrable);	values[Anum_pg_constraint_condeferred - 1] = BoolGetDatum(isDeferred);	values[Anum_pg_constraint_conrelid - 1] = ObjectIdGetDatum(relId);	values[Anum_pg_constraint_contypid - 1] = ObjectIdGetDatum(domainId);	values[Anum_pg_constraint_confrelid - 1] = ObjectIdGetDatum(foreignRelId);	values[Anum_pg_constraint_confupdtype - 1] = CharGetDatum(foreignUpdateType);	values[Anum_pg_constraint_confdeltype - 1] = CharGetDatum(foreignDeleteType);	values[Anum_pg_constraint_confmatchtype - 1] = CharGetDatum(foreignMatchType);	if (conkeyArray)		values[Anum_pg_constraint_conkey - 1] = PointerGetDatum(conkeyArray);	else		nulls[Anum_pg_constraint_conkey - 1] = 'n';	if (confkeyArray)		values[Anum_pg_constraint_confkey - 1] = PointerGetDatum(confkeyArray);	else		nulls[Anum_pg_constraint_confkey - 1] = 'n';	/*	 * initialize the binary form of the check constraint.	 */	if (conBin)		values[Anum_pg_constraint_conbin - 1] = DirectFunctionCall1(textin,													CStringGetDatum(conBin));	else		nulls[Anum_pg_constraint_conbin - 1] = 'n';	/*	 * initialize the text form of the check constraint	 */	if (conSrc)		values[Anum_pg_constraint_consrc - 1] = DirectFunctionCall1(textin,													CStringGetDatum(conSrc));	else		nulls[Anum_pg_constraint_consrc - 1] = 'n';	tup = heap_formtuple(RelationGetDescr(conDesc), values, nulls);	conOid = simple_heap_insert(conDesc, tup);	/* update catalog indexes */	CatalogUpdateIndexes(conDesc, tup);	conobject.classId = ConstraintRelationId;	conobject.objectId = conOid;	conobject.objectSubId = 0;	heap_close(conDesc, RowExclusiveLock);	if (OidIsValid(relId))	{		/*		 * Register auto dependency from constraint to owning relation, or to		 * specific column(s) if any are mentioned.		 */		ObjectAddress relobject;		relobject.classId = RelationRelationId;		relobject.objectId = relId;		if (constraintNKeys > 0)		{			for (i = 0; i < constraintNKeys; i++)			{				relobject.objectSubId = constraintKey[i];				recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);			}		}		else		{			relobject.objectSubId = 0;			recordDependencyOn(&conobject, &relobject, DEPENDENCY_AUTO);		}	}	if (OidIsValid(domainId))	{		/*		 * Register auto dependency from constraint to owning domain		 */		ObjectAddress domobject;		domobject.classId = TypeRelationId;		domobject.objectId = domainId;		domobject.objectSubId = 0;		recordDependencyOn(&conobject, &domobject, DEPENDENCY_AUTO);	}	if (OidIsValid(foreignRelId))	{		/*		 * Register normal dependency from constraint to foreign relation, or		 * to specific column(s) if any are mentioned.		 */		ObjectAddress relobject;		relobject.classId = RelationRelationId;		relobject.objectId = foreignRelId;		if (foreignNKeys > 0)		{			for (i = 0; i < foreignNKeys; i++)			{				relobject.objectSubId = foreignKey[i];				recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);			}		}		else		{			relobject.objectSubId = 0;			recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);		}	}	if (OidIsValid(indexRelId))	{		/*		 * Register normal dependency on the unique index that supports a		 * foreign-key constraint.		 */		ObjectAddress relobject;		relobject.classId = RelationRelationId;		relobject.objectId = indexRelId;		relobject.objectSubId = 0;		recordDependencyOn(&conobject, &relobject, DEPENDENCY_NORMAL);	}	if (conExpr != NULL)	{		/*		 * Register dependencies from constraint to objects mentioned in CHECK		 * expression.		 */		recordDependencyOnSingleRelExpr(&conobject, conExpr, relId,										DEPENDENCY_NORMAL,										DEPENDENCY_NORMAL);	}	return conOid;}/* * Test whether given name is currently used as a constraint name * for the given object (relation or domain). * * This is used to decide whether to accept a user-specified constraint name. * It is deliberately not the same test as ChooseConstraintName uses to decide * whether an auto-generated name is OK: here, we will allow it unless there * is an identical constraint name in use *on the same object*. * * NB: Caller should hold exclusive lock on the given object, else * this test can be fooled by concurrent additions. */boolConstraintNameIsUsed(ConstraintCategory conCat, Oid objId,					 Oid objNamespace, const char *conname){	bool		found;	Relation	conDesc;	SysScanDesc conscan;	ScanKeyData skey[2];	HeapTuple	tup;	conDesc = heap_open(ConstraintRelationId, AccessShareLock);	found = false;	ScanKeyInit(&skey[0],				Anum_pg_constraint_conname,				BTEqualStrategyNumber, F_NAMEEQ,				CStringGetDatum(conname));	ScanKeyInit(&skey[1],				Anum_pg_constraint_connamespace,				BTEqualStrategyNumber, F_OIDEQ,				ObjectIdGetDatum(objNamespace));	conscan = systable_beginscan(conDesc, ConstraintNameNspIndexId, true,								 SnapshotNow, 2, skey);	while (HeapTupleIsValid(tup = systable_getnext(conscan)))	{		Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);		if (conCat == CONSTRAINT_RELATION && con->conrelid == objId)		{			found = true;			break;		}		else if (conCat == CONSTRAINT_DOMAIN && con->contypid == objId)		{			found = true;			break;		}	}	systable_endscan(conscan);	heap_close(conDesc, AccessShareLock);	return found;}/* * Select a nonconflicting name for a new constraint. * * The objective here is to choose a name that is unique within the * specified namespace.  Postgres does not require this, but the SQL * spec does, and some apps depend on it.  Therefore we avoid choosing * default names that so conflict.

⌨️ 快捷键说明

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