]> granicus.if.org Git - postgresql/commitdiff
Improve ALTER DOMAIN / DROP CONSTRAINT with nonexistent constraint
authorPeter Eisentraut <peter_e@gmx.net>
Thu, 5 Jan 2012 17:48:55 +0000 (19:48 +0200)
committerPeter Eisentraut <peter_e@gmx.net>
Thu, 5 Jan 2012 17:48:55 +0000 (19:48 +0200)
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.

doc/src/sgml/ref/alter_domain.sgml
src/backend/commands/typecmds.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/commands/typecmds.h
src/include/nodes/parsenodes.h
src/test/regress/expected/domain.out
src/test/regress/sql/domain.sql

index 29504ccd7cb155658b5147a3d62cb9ab284d9d32..2511a125d389d2f7e4d4876d387427064466291b 100644 (file)
@@ -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>
index 4bbbaf36c93dbcad27fc565e59fb4e06dab44ad7..0f8af31feeff0953bbd7783b2e53fc7e6ac4b8a4 100644 (file)
@@ -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))));
+       }
 }
 
 /*
index c9d3e2ee51797dbe4cbf7c771a9c9a8c3a62f9b2..756e3a689b8cc95fc46853accfa2984ea26c2399 100644 (file)
@@ -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;
 }
index efe2c96fea2b0c8629a13cb77028ae8565a72e44..9eff42f707ead7895727a2543c5639bc253958f6 100644 (file)
@@ -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;
 }
index 29df0c16b3a4c8c3d37fbe09836ba31522120e7f..87d7305c76265ad9ec3aeee0e5ce6c4f82911440 100644 (file)
@@ -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> */
index 923da6a3f3039d0ccd11951aeaf9ce43ba43d60b..704bbe9cedfb7146e9beb1c0630b1576c5eab990 100644 (file)
@@ -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,
index 11d05b894fbe09a4427d745c011f01ca06c7e779..3748bd56af12560508702a2ec01ebe3691c8c2c8 100644 (file)
@@ -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);
 
index bee0e1883f43380353ad7725a599920eeb239dce..0be3fb117464f566112847760b03f515bf8b05dc 100644 (file)
@@ -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;
 
 
index 3e44e3b53316b5f4d4aa1df7d0a3a0df63c91a3a..4f47374b5d36a00405c4f5d5a43d4ae8e7cc2b7a 100644 (file)
@@ -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);
index 1fd39008e684dfcb75929f4a9175f99e1920cac2..ad049b7ba54360caef81a5cb92d4bd14ccb9939d 100644 (file)
@@ -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);