aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/commands/typecmds.c')
-rw-r--r--src/backend/commands/typecmds.c43
1 files changed, 37 insertions, 6 deletions
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 53cca73a9dd..462419e7fe5 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.97 2006/10/04 00:29:51 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/typecmds.c,v 1.97.2.1 2007/05/11 20:18:10 tgl Exp $
*
* DESCRIPTION
* The "DefineFoo" routines take the parse tree and pick out the
@@ -1600,6 +1600,10 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
* the domain type. We have opened each rel and acquired the specified lock
* type on it.
*
+ * We support nested domains by including attributes that are of derived
+ * domain types. Current callers do not need to distinguish between attributes
+ * that are of exactly the given domain and those that are of derived domains.
+ *
* XXX this is completely broken because there is no way to lock the domain
* to prevent columns from being added or dropped while our command runs.
* We can partially protect against column drops by locking relations as we
@@ -1609,9 +1613,11 @@ AlterDomainAddConstraint(List *names, Node *newConstraint)
* trivial risk of deadlock. We can minimize but not eliminate the deadlock
* risk by using the weakest suitable lock (ShareLock for most callers).
*
- * XXX to support domains over domains, we'd need to make this smarter,
- * or make its callers smarter, so that we could find columns of derived
- * domains. Arrays of domains would be a problem too.
+ * XXX the API for this is not sufficient to support checking domain values
+ * that are inside composite types or arrays. Currently we just error out
+ * if a composite type containing the target domain is stored anywhere.
+ * There are not currently arrays of domains; if there were, we could take
+ * the same approach, but it'd be nicer to fix it properly.
*
* Generally used for retrieving a list of tests when adding
* new constraints to a domain.
@@ -1653,7 +1659,23 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
Form_pg_attribute pg_att;
int ptr;
- /* Ignore dependees that aren't user columns of relations */
+ /* Check for directly dependent types --- must be domains */
+ if (pg_depend->classid == TypeRelationId)
+ {
+ Assert(get_typtype(pg_depend->objid) == 'd');
+ /*
+ * Recursively add dependent columns to the output list. This
+ * is a bit inefficient since we may fail to combine RelToCheck
+ * entries when attributes of the same rel have different derived
+ * domain types, but it's probably not worth improving.
+ */
+ result = list_concat(result,
+ get_rels_with_domain(pg_depend->objid,
+ lockmode));
+ continue;
+ }
+
+ /* Else, ignore dependees that aren't user columns of relations */
/* (we assume system columns are never of domain types) */
if (pg_depend->classid != RelationRelationId ||
pg_depend->objsubid <= 0)
@@ -1679,7 +1701,16 @@ get_rels_with_domain(Oid domainOid, LOCKMODE lockmode)
/* Acquire requested lock on relation */
rel = relation_open(pg_depend->objid, lockmode);
- /* It could be a view or composite type; if so ignore it */
+ /*
+ * Check to see if rowtype is stored anyplace as a composite-type
+ * column; if so we have to fail, for now anyway.
+ */
+ if (OidIsValid(rel->rd_rel->reltype))
+ find_composite_type_dependencies(rel->rd_rel->reltype,
+ NULL,
+ format_type_be(domainOid));
+
+ /* Otherwise we can ignore views, composite types, etc */
if (rel->rd_rel->relkind != RELKIND_RELATION)
{
relation_close(rel, lockmode);