OSDN Git Service

DROP IF EXISTS for ROLE/USER/GROUP
authorAndrew Dunstan <andrew@dunslane.net>
Sat, 4 Feb 2006 19:06:47 +0000 (19:06 +0000)
committerAndrew Dunstan <andrew@dunslane.net>
Sat, 4 Feb 2006 19:06:47 +0000 (19:06 +0000)
doc/src/sgml/ref/drop_group.sgml
doc/src/sgml/ref/drop_role.sgml
doc/src/sgml/ref/drop_user.sgml
src/backend/commands/user.c
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/include/nodes/parsenodes.h
src/test/regress/expected/drop_if_exists.out
src/test/regress/sql/drop_if_exists.sql

index 1decf95..e19c0a1 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/drop_group.sgml,v 1.11 2005/07/26 23:24:02 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/drop_group.sgml,v 1.12 2006/02/04 19:06:46 adunstan Exp $
 PostgreSQL documentation
 -->
 
@@ -20,7 +20,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-DROP GROUP <replaceable class="PARAMETER">name</replaceable> [, ...]
+DROP GROUP [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...]
 </synopsis>
  </refsynopsisdiv>
 
index dc8a089..d2364da 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/drop_role.sgml,v 1.1 2005/07/26 23:24:02 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/drop_role.sgml,v 1.2 2006/02/04 19:06:46 adunstan Exp $
 PostgreSQL documentation
 -->
 
@@ -20,7 +20,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-DROP ROLE <replaceable class="PARAMETER">name</replaceable> [, ...]
+DROP ROLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...]
 </synopsis>
  </refsynopsisdiv>
 
@@ -54,6 +54,17 @@ DROP ROLE <replaceable class="PARAMETER">name</replaceable> [, ...]
 
   <variablelist>
    <varlistentry>
+    <term><literal>IF EXISTS</literal></term>
+    <listitem>
+     <para>
+      Do not throw an error if the role does not exist. A notice is issued 
+      in this case.
+     </para>
+    </listitem>
+   </varlistentry>
+
+  <variablelist>
+   <varlistentry>
     <term><replaceable class="PARAMETER">name</replaceable></term>
     <listitem>
      <para>
index 419a7ed..7ed3573 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$PostgreSQL: pgsql/doc/src/sgml/ref/drop_user.sgml,v 1.21 2005/07/26 23:24:02 tgl Exp $
+$PostgreSQL: pgsql/doc/src/sgml/ref/drop_user.sgml,v 1.22 2006/02/04 19:06:46 adunstan Exp $
 PostgreSQL documentation
 -->
 
@@ -20,7 +20,7 @@ PostgreSQL documentation
 
  <refsynopsisdiv>
 <synopsis>
-DROP USER <replaceable class="PARAMETER">name</replaceable> [, ...]
+DROP USER [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable> [, ...]
 </synopsis>
  </refsynopsisdiv>
 
index 0ffcc21..b3aa2ed 100644 (file)
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.167 2005/12/23 16:46:39 petere Exp $
+ * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.168 2006/02/04 19:06:46 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -840,9 +840,22 @@ DropRole(DropRoleStmt *stmt)
                                                           PointerGetDatum(role),
                                                           0, 0, 0);
                if (!HeapTupleIsValid(tuple))
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_UNDEFINED_OBJECT),
-                                        errmsg("role \"%s\" does not exist", role)));
+               {
+                       if (!stmt->missing_ok)
+                       {
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_UNDEFINED_OBJECT),
+                                                errmsg("role \"%s\" does not exist", role)));
+                       }
+                       else
+                       {
+                               ereport(NOTICE,
+                                               (errmsg("role \"%s\" does not exist, skipping", 
+                                                               role)));
+                       }
+
+                       continue;
+               }
 
                roleid = HeapTupleGetOid(tuple);
 
index 19b9879..6578bf3 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.325 2006/01/31 21:39:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.326 2006/02/04 19:06:46 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -2518,6 +2518,7 @@ _copyDropRoleStmt(DropRoleStmt *from)
        DropRoleStmt *newnode = makeNode(DropRoleStmt);
 
        COPY_NODE_FIELD(roles);
+       COPY_SCALAR_FIELD(missing_ok);
 
        return newnode;
 }
index e7a9ced..a9fdc95 100644 (file)
@@ -18,7 +18,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.261 2006/01/31 21:39:23 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.262 2006/02/04 19:06:46 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1398,6 +1398,7 @@ static bool
 _equalDropRoleStmt(DropRoleStmt *a, DropRoleStmt *b)
 {
        COMPARE_NODE_FIELD(roles);
+       COMPARE_SCALAR_FIELD(missing_ok);
 
        return true;
 }
index bda5c93..8c21c42 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.525 2006/01/31 22:40:03 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.526 2006/02/04 19:06:46 adunstan Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -824,9 +824,17 @@ DropRoleStmt:
                        DROP ROLE name_list
                                {
                                        DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->missing_ok = FALSE;
                                        n->roles = $3;
                                        $$ = (Node *)n;
                                }
+                       | DROP ROLE IF_P EXISTS name_list
+                               {
+                                       DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->missing_ok = TRUE;
+                                       n->roles = $5;
+                                       $$ = (Node *)n;
+                               }
                        ;
 
 /*****************************************************************************
@@ -842,9 +850,17 @@ DropUserStmt:
                        DROP USER name_list
                                {
                                        DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->missing_ok = FALSE;
                                        n->roles = $3;
                                        $$ = (Node *)n;
                                }
+                       | DROP USER IF_P EXISTS name_list
+                               {
+                                       DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->roles = $5;
+                                       n->missing_ok = TRUE;
+                                       $$ = (Node *)n;
+                               }
                        ;
 
 
@@ -900,9 +916,17 @@ DropGroupStmt:
                        DROP GROUP_P name_list
                                {
                                        DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->missing_ok = FALSE;
                                        n->roles = $3;
                                        $$ = (Node *)n;
                                }
+                       | DROP GROUP_P IF_P EXISTS name_list
+                               {
+                                       DropRoleStmt *n = makeNode(DropRoleStmt);
+                                       n->missing_ok = TRUE;
+                                       n->roles = $5;
+                                       $$ = (Node *)n;
+                               }
                ;
 
 
index e738ec2..0efe47f 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.299 2006/01/21 02:16:20 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/nodes/parsenodes.h,v 1.300 2006/02/04 19:06:46 adunstan Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1193,6 +1193,7 @@ typedef struct DropRoleStmt
 {
        NodeTag         type;
        List       *roles;                      /* List of roles to remove */
+       bool            missing_ok;             /* skip error if a role is missing? */
 } DropRoleStmt;
 
 /* ----------------------
index 10feb3f..092c904 100644 (file)
@@ -65,3 +65,27 @@ ERROR:  type "test_domain_exists" does not exist
 DROP TABLE IF EXISTS test_exists;
 DROP TABLE test_exists;
 ERROR:  table "test_exists" does not exist
+---
+--- role/user/group
+---
+CREATE USER tu1;
+CREATE ROLE tr1;
+CREATE GROUP tg1;
+DROP USER tu2;
+ERROR:  role "tu2" does not exist
+DROP USER IF EXISTS tu1, tu2;
+NOTICE:  role "tu2" does not exist, skipping
+DROP USER tu1;
+ERROR:  role "tu1" does not exist
+DROP ROLE tr2;
+ERROR:  role "tr2" does not exist
+DROP ROLE IF EXISTS tr1, tr2;
+NOTICE:  role "tr2" does not exist, skipping
+DROP ROLE tr1;
+ERROR:  role "tr1" does not exist
+DROP GROUP tg2;
+ERROR:  role "tg2" does not exist
+DROP GROUP IF EXISTS tg1, tg2;
+NOTICE:  role "tg2" does not exist, skipping
+DROP GROUP tg1;
+ERROR:  role "tg1" does not exist
index 7addeda..ae7543f 100644 (file)
@@ -89,3 +89,30 @@ DROP TABLE IF EXISTS test_exists;
 
 DROP TABLE test_exists;
 
+
+---
+--- role/user/group
+---
+
+CREATE USER tu1;
+CREATE ROLE tr1;
+CREATE GROUP tg1;
+
+DROP USER tu2;
+
+DROP USER IF EXISTS tu1, tu2;
+
+DROP USER tu1;
+
+DROP ROLE tr2;
+
+DROP ROLE IF EXISTS tr1, tr2;
+
+DROP ROLE tr1;
+
+DROP GROUP tg2;
+
+DROP GROUP IF EXISTS tg1, tg2;
+
+DROP GROUP tg1;
+