diff options
author | Peter Eisentraut | 2012-01-05 17:48:55 +0000 |
---|---|---|
committer | Peter Eisentraut | 2012-01-05 17:48:55 +0000 |
commit | 104e7dac28c56dcaf9b778dff60a5daefc3a0661 (patch) | |
tree | 5152172e545132186865eeb9ddf5903170011c94 | |
parent | 2abefd9a92f3c02ad4f6030ac1578bbf314db368 (diff) |
Improve ALTER DOMAIN / DROP CONSTRAINT with nonexistent constraint
ALTER DOMAIN / DROP CONSTRAINT on a nonexistent constraint name did
not report any error. Now it reports an error. The IF EXISTS option
was added to get the usual behavior of ignoring nonexistent objects to
drop.
-rw-r--r-- | doc/src/sgml/ref/alter_domain.sgml | 6 | ||||
-rw-r--r-- | src/backend/commands/typecmds.c | 17 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 1 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 12 | ||||
-rw-r--r-- | src/backend/tcop/utility.c | 3 | ||||
-rw-r--r-- | src/include/commands/typecmds.h | 2 | ||||
-rw-r--r-- | src/include/nodes/parsenodes.h | 1 | ||||
-rw-r--r-- | src/test/regress/expected/domain.out | 4 | ||||
-rw-r--r-- | src/test/regress/sql/domain.sql | 3 |
10 files changed, 45 insertions, 5 deletions
diff --git a/doc/src/sgml/ref/alter_domain.sgml b/doc/src/sgml/ref/alter_domain.sgml index 29504ccd7c..2511a125d3 100644 --- a/doc/src/sgml/ref/alter_domain.sgml +++ b/doc/src/sgml/ref/alter_domain.sgml @@ -30,7 +30,7 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> ADD <replaceable class="PARAMETER">domain_constraint</replaceable> [ NOT VALID ] ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> - DROP CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ] + DROP CONSTRAINT [ IF EXISTS ] <replaceable class="PARAMETER">constraint_name</replaceable> [ RESTRICT | CASCADE ] ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> VALIDATE CONSTRAINT <replaceable class="PARAMETER">constraint_name</replaceable> ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> @@ -92,10 +92,12 @@ ALTER DOMAIN <replaceable class="PARAMETER">name</replaceable> </varlistentry> <varlistentry> - <term>DROP CONSTRAINT</term> + <term>DROP CONSTRAINT [ IF EXISTS ]</term> <listitem> <para> This form drops constraints on a domain. + If <literal>IF EXISTS</literal> is specified and the constraint + does not exist, no error is thrown. In this case a notice is issued instead. </para> </listitem> </varlistentry> diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c index 4bbbaf36c9..0f8af31fee 100644 --- a/src/backend/commands/typecmds.c +++ b/src/backend/commands/typecmds.c @@ -2264,7 +2264,7 @@ AlterDomainNotNull(List *names, bool notNull) */ void AlterDomainDropConstraint(List *names, const char *constrName, - DropBehavior behavior) + DropBehavior behavior, bool missing_ok) { TypeName *typename; Oid domainoid; @@ -2274,6 +2274,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, SysScanDesc conscan; ScanKeyData key[1]; HeapTuple contup; + bool found = false; /* Make a TypeName so we can use standard type lookup machinery */ typename = makeTypeNameFromNameList(names); @@ -2317,6 +2318,7 @@ AlterDomainDropConstraint(List *names, const char *constrName, conobj.objectSubId = 0; performDeletion(&conobj, behavior); + found = true; } } /* Clean up after the scan */ @@ -2324,6 +2326,19 @@ AlterDomainDropConstraint(List *names, const char *constrName, heap_close(conrel, RowExclusiveLock); heap_close(rel, NoLock); + + if (!found) + { + if (!missing_ok) + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_OBJECT), + errmsg("constraint \"%s\" of domain \"%s\" does not exist", + constrName, TypeNameToString(typename)))); + else + ereport(NOTICE, + (errmsg("constraint \"%s\" of domain \"%s\" does not exist, skipping", + constrName, TypeNameToString(typename)))); + } } /* diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index c9d3e2ee51..756e3a689b 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -2568,6 +2568,7 @@ _copyAlterDomainStmt(const AlterDomainStmt *from) COPY_STRING_FIELD(name); COPY_NODE_FIELD(def); COPY_SCALAR_FIELD(behavior); + COPY_SCALAR_FIELD(missing_ok); return newnode; } diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index efe2c96fea..9eff42f707 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -1034,6 +1034,7 @@ _equalAlterDomainStmt(const AlterDomainStmt *a, const AlterDomainStmt *b) COMPARE_STRING_FIELD(name); COMPARE_NODE_FIELD(def); COMPARE_SCALAR_FIELD(behavior); + COMPARE_SCALAR_FIELD(missing_ok); return true; } diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 29df0c16b3..87d7305c76 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -7616,6 +7616,18 @@ AlterDomainStmt: n->typeName = $3; n->name = $6; n->behavior = $7; + n->missing_ok = false; + $$ = (Node *)n; + } + /* ALTER DOMAIN <domain> DROP CONSTRAINT IF EXISTS <name> [RESTRICT|CASCADE] */ + | ALTER DOMAIN_P any_name DROP CONSTRAINT IF_P EXISTS name opt_drop_behavior + { + AlterDomainStmt *n = makeNode(AlterDomainStmt); + n->subtype = 'X'; + n->typeName = $3; + n->name = $8; + n->behavior = $9; + n->missing_ok = true; $$ = (Node *)n; } /* ALTER DOMAIN <domain> VALIDATE CONSTRAINT <name> */ diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c index 923da6a3f3..704bbe9ced 100644 --- a/src/backend/tcop/utility.c +++ b/src/backend/tcop/utility.c @@ -768,7 +768,8 @@ standard_ProcessUtility(Node *parsetree, case 'X': /* DROP CONSTRAINT */ AlterDomainDropConstraint(stmt->typeName, stmt->name, - stmt->behavior); + stmt->behavior, + stmt->missing_ok); break; case 'V': /* VALIDATE CONSTRAINT */ AlterDomainValidateConstraint(stmt->typeName, diff --git a/src/include/commands/typecmds.h b/src/include/commands/typecmds.h index 11d05b894f..3748bd56af 100644 --- a/src/include/commands/typecmds.h +++ b/src/include/commands/typecmds.h @@ -33,7 +33,7 @@ extern void AlterDomainNotNull(List *names, bool notNull); extern void AlterDomainAddConstraint(List *names, Node *constr); extern void AlterDomainValidateConstraint(List *names, char *constrName); extern void AlterDomainDropConstraint(List *names, const char *constrName, - DropBehavior behavior); + DropBehavior behavior, bool missing_ok); extern List *GetDomainConstraints(Oid typeOid); diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index bee0e1883f..0be3fb1174 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -1264,6 +1264,7 @@ typedef struct AlterDomainStmt char *name; /* column or constraint name to act on */ Node *def; /* definition of default or constraint */ DropBehavior behavior; /* RESTRICT or CASCADE for DROP cases */ + bool missing_ok; /* skip error if missing? */ } AlterDomainStmt; diff --git a/src/test/regress/expected/domain.out b/src/test/regress/expected/domain.out index 3e44e3b533..4f47374b5d 100644 --- a/src/test/regress/expected/domain.out +++ b/src/test/regress/expected/domain.out @@ -358,6 +358,10 @@ alter domain con drop constraint t; insert into domcontest values (-5); --fails ERROR: value for domain con violates check constraint "con_check" insert into domcontest values (42); +alter domain con drop constraint nonexistent; +ERROR: constraint "nonexistent" of domain "con" does not exist +alter domain con drop constraint if exists nonexistent; +NOTICE: constraint "nonexistent" of domain "con" does not exist, skipping -- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID create domain things AS INT; CREATE TABLE thethings (stuff things); diff --git a/src/test/regress/sql/domain.sql b/src/test/regress/sql/domain.sql index 1fd39008e6..ad049b7ba5 100644 --- a/src/test/regress/sql/domain.sql +++ b/src/test/regress/sql/domain.sql @@ -259,6 +259,9 @@ alter domain con drop constraint t; insert into domcontest values (-5); --fails insert into domcontest values (42); +alter domain con drop constraint nonexistent; +alter domain con drop constraint if exists nonexistent; + -- Test ALTER DOMAIN .. CONSTRAINT .. NOT VALID create domain things AS INT; CREATE TABLE thethings (stuff things); |