summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Eisentraut2012-01-05 17:48:55 +0000
committerPeter Eisentraut2012-01-05 17:48:55 +0000
commit104e7dac28c56dcaf9b778dff60a5daefc3a0661 (patch)
tree5152172e545132186865eeb9ddf5903170011c94
parent2abefd9a92f3c02ad4f6030ac1578bbf314db368 (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.sgml6
-rw-r--r--src/backend/commands/typecmds.c17
-rw-r--r--src/backend/nodes/copyfuncs.c1
-rw-r--r--src/backend/nodes/equalfuncs.c1
-rw-r--r--src/backend/parser/gram.y12
-rw-r--r--src/backend/tcop/utility.c3
-rw-r--r--src/include/commands/typecmds.h2
-rw-r--r--src/include/nodes/parsenodes.h1
-rw-r--r--src/test/regress/expected/domain.out4
-rw-r--r--src/test/regress/sql/domain.sql3
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);