aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands/typecmds.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2007-05-11 20:18:21 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2007-05-11 20:18:21 +0000
commit4a898fbb206f5fb93b4701f6f71d67715e6a1498 (patch)
treead9d0e52ab4282e609eaacfb7a9588cf276614eb /src/backend/commands/typecmds.c
parentff5ff47b5dd6d48aa5f0dd27007e1a17f9566bb5 (diff)
downloadpostgresql-4a898fbb206f5fb93b4701f6f71d67715e6a1498.tar.gz
postgresql-4a898fbb206f5fb93b4701f6f71d67715e6a1498.zip
Fix my oversight in enabling domains-of-domains: ALTER DOMAIN ADD CONSTRAINT
needs to check the new constraint against columns of derived domains too. Also, make it error out if the domain to be modified is used within any composite-type columns. Eventually we should support that case, but it seems a bit painful, and not suitable for a back-patch. For the moment just let the user know we can't do it. Backpatch to 8.2, which is the only released version that allows nested domains. Possibly the other part should be back-patched further.
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);