OSDN Git Service

The following patch was sent to the patches list:
authorBruce Momjian <bruce@momjian.us>
Wed, 18 Oct 2000 16:16:18 +0000 (16:16 +0000)
committerBruce Momjian <bruce@momjian.us>
Wed, 18 Oct 2000 16:16:18 +0000 (16:16 +0000)
This patch forces the use of 'DROP VIEW' to destroy views.

It also changes the syntax of DROP VIEW to
DROP VIEW v1, v2, ...
to match the syntax of DROP TABLE.

Some error messages were changed so this patch also includes changes to the
appropriate expected/*.out files.

Doc changes for 'DROP TABLE" and 'DROP VIEW' are included.

--
Mark Hollomon

doc/src/sgml/ref/drop_table.sgml
doc/src/sgml/ref/drop_view.sgml
src/backend/nodes/copyfuncs.c
src/backend/nodes/equalfuncs.c
src/backend/parser/gram.y
src/backend/tcop/utility.c
src/include/nodes/parsenodes.h
src/test/regress/GNUmakefile
src/test/regress/expected/errors.out
src/test/regress/expected/foreign_key.out
src/test/regress/expected/inet.out

index 7e0b85d..5f5a7aa 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v 1.7 2000/07/21 04:37:10 momjian Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_table.sgml,v 1.8 2000/10/18 16:16:03 momjian Exp $
 Postgres documentation
 -->
 
@@ -39,7 +39,7 @@ DROP TABLE <replaceable class="PARAMETER">name</replaceable> [, ...]
       <term><replaceable class="PARAMETER">name</replaceable></term>
       <listitem>
        <para>
-       The name of an existing table or view to drop.
+       The name of an existing table to drop.
        </para>
       </listitem>
      </varlistentry>
@@ -68,11 +68,11 @@ DROP
      </varlistentry>
      <varlistentry>
       <term><computeroutput>
-ERROR Relation "<replaceable class="parameter">name</replaceable>" Does Not Exist!
+ERROR: table "<replaceable class="parameter">name</replaceable>" is nonexistent
        </computeroutput></term>
       <listitem>
        <para>
-       If the specified table or view does not exist in the database.
+       If the specified table does not exist in the database.
        </para>
       </listitem>
      </varlistentry>
@@ -89,8 +89,8 @@ ERROR Relation "<replaceable class="parameter">name</replaceable>" Does Not Exis
    Description
   </title>
   <para>
-   <command>DROP TABLE</command> removes tables and views from the database.
-   Only its owner may destroy a table or view. A table
+   <command>DROP TABLE</command> removes tables from the database.
+   Only its owner may destroy a table. A table
    may be emptied of rows, but not destroyed, by using <command>DELETE</command>.
   </para>
   <para>
index 7d08cbf..636d181 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v 1.6 1999/07/22 15:09:11 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/drop_view.sgml,v 1.7 2000/10/18 16:16:03 momjian Exp $
 Postgres documentation
 -->
 
@@ -23,7 +23,7 @@ Postgres documentation
    <date>1999-07-20</date>
   </refsynopsisdivinfo>
   <synopsis>
-DROP VIEW <replaceable class="PARAMETER">name</replaceable>
+DROP VIEW <replaceable class="PARAMETER">name</replaceable> [, ...]
   </synopsis>
   
   <refsect2 id="R2-SQL-DROPVIEW-1">
@@ -70,7 +70,7 @@ DROP
      </varlistentry>
      <varlistentry>
       <term><computeroutput>
-ERROR: RewriteGetRuleEventRel: rule "_RET<replaceable class="PARAMETER">name</replaceable>" not found
+ERROR: view <replaceable class="parameter">name</replaceable> is nonexistent
        </computeroutput></term>
       <listitem>
        <para>
index e768d0b..3d74053 100644 (file)
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.125 2000/10/07 00:58:16 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.126 2000/10/18 16:16:04 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1949,8 +1949,8 @@ _copyDropStmt(DropStmt *from)
 {
        DropStmt *newnode = makeNode(DropStmt);
        
-       Node_Copy(from, newnode, relNames);
-       newnode->sequence = from->sequence;
+       Node_Copy(from, newnode, names);
+       newnode->removeType = from->removeType;
 
        return newnode;
 }
@@ -2071,17 +2071,6 @@ _copyRemoveOperStmt(RemoveOperStmt *from)
        return newnode;
 }
 
-static RemoveStmt *
-_copyRemoveStmt(RemoveStmt *from)
-{
-       RemoveStmt *newnode = makeNode(RemoveStmt);
-       
-       newnode->removeType = from->removeType;
-       newnode->name = pstrdup(from->name);
-
-       return newnode;
-}
-
 static RenameStmt *
 _copyRenameStmt(RenameStmt *from)
 {
@@ -2782,9 +2771,6 @@ copyObject(void *from)
                case T_RemoveOperStmt:
                        retval = _copyRemoveOperStmt(from);
                        break;
-               case T_RemoveStmt:
-                       retval = _copyRemoveStmt(from);
-                       break;
                case T_RenameStmt:
                        retval = _copyRenameStmt(from);
                        break;
index d5b2ff4..372f224 100644 (file)
@@ -20,7 +20,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.76 2000/10/07 00:58:16 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.77 2000/10/18 16:16:04 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -850,9 +850,9 @@ _equalDefineStmt(DefineStmt *a, DefineStmt *b)
 static bool
 _equalDropStmt(DropStmt *a, DropStmt *b)
 {
-       if (!equal(a->relNames, b->relNames))
+       if (!equal(a->names, b->names))
                return false;
-       if (a->sequence != b->sequence)
+       if (a->removeType != b->removeType)
                return false;
 
        return true;
@@ -989,16 +989,6 @@ _equalRemoveOperStmt(RemoveOperStmt *a, RemoveOperStmt *b)
        return true;
 }
 
-static bool
-_equalRemoveStmt(RemoveStmt *a, RemoveStmt *b)
-{
-       if (a->removeType != b->removeType)
-               return false;
-       if (!equalstr(a->name, b->name))
-               return false;
-
-       return true;
-}
 
 static bool
 _equalRenameStmt(RenameStmt *a, RenameStmt *b)
@@ -1959,9 +1949,6 @@ equal(void *a, void *b)
                case T_RemoveOperStmt:
                        retval = _equalRemoveOperStmt(a, b);
                        break;
-               case T_RemoveStmt:
-                       retval = _equalRemoveStmt(a, b);
-                       break;
                case T_RenameStmt:
                        retval = _equalRenameStmt(a, b);
                        break;
index a596bd6..fbda275 100644 (file)
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.195 2000/10/07 00:58:17 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.196 2000/10/18 16:16:05 momjian Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -1942,15 +1942,22 @@ def_arg:  func_return                                   {  $$ = (Node *)$1; }
 DropStmt:  DROP TABLE relation_name_list
                                {
                                        DropStmt *n = makeNode(DropStmt);
-                                       n->relNames = $3;
-                                       n->sequence = FALSE;
+                                       n->names = $3;
+                                       n->removeType = DROP_TABLE;
                                        $$ = (Node *)n;
                                }
                | DROP SEQUENCE relation_name_list
                                {
                                        DropStmt *n = makeNode(DropStmt);
-                                       n->relNames = $3;
-                                       n->sequence = TRUE;
+                                       n->names = $3;
+                                       n->removeType = DROP_SEQUENCE;
+                                       $$ = (Node *)n;
+                               }
+               | DROP VIEW relation_name_list
+                               {
+                                       DropStmt *n = makeNode(DropStmt);
+                                       n->names = $3;
+                                       n->removeType = DROP_VIEW;
                                        $$ = (Node *)n;
                                }
                ;
@@ -2558,17 +2565,16 @@ func_return:  Typename
 
 RemoveStmt:  DROP remove_type name
                                {
-                                       RemoveStmt *n = makeNode(RemoveStmt);
+                                       DropStmt *n = makeNode(DropStmt);
                                        n->removeType = $2;
-                                       n->name = $3;
+                                       n->names =  makeList1(makeString($3));
                                        $$ = (Node *)n;
                                }
                ;
 
-remove_type:  TYPE_P                                                   {  $$ = TYPE_P; }
-               | INDEX                                                                 {  $$ = INDEX; }
-               | RULE                                                                  {  $$ = RULE; }
-               | VIEW                                                                  {  $$ = VIEW; }
+remove_type:  TYPE_P                                                   {  $$ = DROP_TYPE_P; }
+               | INDEX                                                                 {  $$ = DROP_INDEX; }
+               | RULE                                                                  {  $$ = DROP_RULE; }
                ;
 
 
index 6c0b2be..d63a5c6 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.96 2000/10/16 17:08:07 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.97 2000/10/18 16:16:06 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "utils/syscache.h"
 
 
+/*
+ *
+ */
+
+struct kindstrings {
+       char kind;
+       char *name;
+       char *command;
+};
+
+static struct kindstrings kindstringarray[] = {
+       { RELKIND_RELATION, "table", "TABLE" },
+       { RELKIND_SEQUENCE, "sequence", "SEQUENCE" },
+       { RELKIND_VIEW, "view", "VIEW" },
+       { RELKIND_INDEX, "index", "INDEX" },
+       { '\0', "", "" }
+};
+
+
+static void
+DropErrorMsg(char* relname, char wrongkind, char rightkind)
+{
+       struct kindstrings *rentry;
+       struct kindstrings *wentry;
+
+       for (rentry = kindstringarray; rentry->kind != '\0'; rentry++)
+               if (rentry->kind == rightkind)
+                       break;
+       Assert(rentry->kind != '\0');
+
+       for (wentry = kindstringarray; wentry->kind != '\0'; wentry++)
+               if (wentry->kind == wrongkind)
+                       break;
+       Assert(wentry->kind != '\0');
+       
+       elog(ERROR, "%s is not a %s. Use 'DROP %s' to remove a %s",
+                       relname, rentry->name, wentry->command, wentry->name);
+}
+
+static void
+CheckClassKind(char *name, char rightkind)
+{
+       HeapTuple       tuple;
+       struct kindstrings *rentry;
+       Form_pg_class classform;
+
+       tuple = SearchSysCacheTuple(RELNAME,
+                                                               PointerGetDatum(name),
+                                                               0, 0, 0);
+
+       if (!HeapTupleIsValid(tuple))
+       {
+               for (rentry = kindstringarray; rentry->kind != '\0'; rentry++)
+                       if (rentry->kind == rightkind)
+                               break;
+               Assert(rentry->kind != '\0');
+               elog(ERROR, "%s \"%s\" is nonexistent", rentry->name, name);
+       }
+
+       classform = (Form_pg_class) GETSTRUCT(tuple);
+
+       if (classform->relkind != rightkind)
+               DropErrorMsg(name, classform->relkind, rightkind);
+}
+
 /* ----------------
  *             general utility function invoker
  * ----------------
@@ -149,41 +214,76 @@ ProcessUtility(Node *parsetree,
                case T_DropStmt:
                        {
                                DropStmt   *stmt = (DropStmt *) parsetree;
-                               List       *args = stmt->relNames;
+                               List       *args = stmt->names;
                                List       *arg;
 
-                               set_ps_display(commandTag = "DROP");
-
-                               /* check as much as we can before we start dropping ... */
-                               foreach(arg, args)
-                               {
-                                       Relation        rel;
+                               foreach(arg, args) {
 
                                        relname = strVal(lfirst(arg));
                                        if (!allowSystemTableMods && IsSystemRelationName(relname))
                                                elog(ERROR, "class \"%s\" is a system catalog",
                                                         relname);
-                                       rel = heap_openr(relname, AccessExclusiveLock);
-                                       if (stmt->sequence &&
-                                               rel->rd_rel->relkind != RELKIND_SEQUENCE)
-                                               elog(ERROR, "Use DROP TABLE to drop table '%s'",
-                                                        relname);
-                                       if (!(stmt->sequence) &&
-                                               rel->rd_rel->relkind == RELKIND_SEQUENCE)
-                                               elog(ERROR, "Use DROP SEQUENCE to drop sequence '%s'",
-                                                        relname);
-                                       /* close rel, but keep lock until end of xact */
-                                       heap_close(rel, NoLock);
-                                       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                               elog(ERROR, "you do not own class \"%s\"",
-                                                        relname);
-                               }
-                               /* OK, terminate 'em all */
-                               foreach(arg, args)
-                               {
-                                       relname = strVal(lfirst(arg));
-                                       RemoveRelation(relname);
+
+                                       set_ps_display(commandTag = "DROP");
+
+                                       switch(stmt->removeType)
+                                       {
+                                               case DROP_TABLE:
+                                                       CheckClassKind(relname, RELKIND_RELATION);
+                                                       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+                                                               elog(ERROR, "you do not own table \"%s\"",
+                                                                        relname);
+                                                       RemoveRelation(relname);
+
+                                                       break;
+
+                                               case DROP_SEQUENCE:
+                                                       CheckClassKind(relname, RELKIND_SEQUENCE);
+                                                       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+                                                               elog(ERROR, "you do not own sequence \"%s\"",
+                                                                        relname);
+                                                       RemoveRelation(relname);
+
+                                                       break;
+
+                                               case DROP_VIEW:
+                                                       CheckClassKind(relname, RELKIND_VIEW);
+                                                       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+                                                               elog(ERROR, "you do not own view \"%s\"",
+                                                                        relname);
+                                                       RemoveView(relname);
+
+                                                       break;
+
+                                               case DROP_INDEX:
+                                                       CheckClassKind(relname, RELKIND_INDEX);
+                                                       if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+                                                               elog(ERROR, "%s: %s", relname, 
+                                                                               aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+                                                       RemoveIndex(relname);
+
+                                                       break;
+
+                                               case DROP_RULE:
+                                                       {
+                                                               char       *rulename = relname;
+                                                               int                     aclcheck_result;
+
+                                                               relationName = RewriteGetRuleEventRel(rulename);
+                                                               aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RU);
+                                                               if (aclcheck_result != ACLCHECK_OK)
+                                                                       elog(ERROR, "%s: %s", relationName, 
+                                                                                       aclcheck_error_strings[aclcheck_result]);
+                                                               RemoveRewriteRule(rulename);
+                                                       }
+                                                       break;
+
+                                               case DROP_TYPE_P:
+                                                       RemoveType(relname);
+                                                       break;
+                                       }
                                }
+
                        }
                        break;
 
@@ -452,57 +552,6 @@ ProcessUtility(Node *parsetree,
                        }
                        break;
 
-               case T_RemoveStmt:
-                       {
-                               RemoveStmt *stmt = (RemoveStmt *) parsetree;
-
-                               set_ps_display(commandTag = "DROP");
-
-                               switch (stmt->removeType)
-                               {
-                                       case INDEX:
-                                               relname = stmt->name;
-                                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                                       elog(ERROR, "class \"%s\" is a system catalog index",
-                                                                relname);
-                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                                               RemoveIndex(relname);
-                                               break;
-                                       case RULE:
-                                               {
-                                                       char       *rulename = stmt->name;
-                                                       int                     aclcheck_result;
-
-                                                       relationName = RewriteGetRuleEventRel(rulename);
-                                                       aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RU);
-                                                       if (aclcheck_result != ACLCHECK_OK)
-                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
-                                                       RemoveRewriteRule(rulename);
-                                               }
-                                               break;
-                                       case TYPE_P:
-                                               /* XXX moved to remove.c */
-                                               RemoveType(stmt->name);
-                                               break;
-                                       case VIEW:
-                                               {
-                                                       char       *viewName = stmt->name;
-                                                       char       *ruleName;
-
-                                                       ruleName = MakeRetrieveViewRuleName(viewName);
-                                                       relationName = RewriteGetRuleEventRel(ruleName);
-                                                       if (!pg_ownercheck(GetUserId(), relationName, RELNAME))
-                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                                                       pfree(ruleName);
-                                                       RemoveView(viewName);
-                                               }
-                                               break;
-                               }
-                               break;
-                       }
-                       break;
-
                case T_RemoveAggrStmt:
                        {
                                RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
index b50990f..3913d88 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parsenodes.h,v 1.116 2000/10/07 00:58:21 tgl Exp $
+ * $Id: parsenodes.h,v 1.117 2000/10/18 16:16:10 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -389,15 +389,24 @@ typedef struct DefineStmt
        List       *definition;         /* a list of DefElem */
 } DefineStmt;
 
+
 /* ----------------------
- *             Drop Table Statement
+ *             Drop Table|Sequence|View|Index|Rule|Type Statement
  * ----------------------
  */
+
+#define DROP_TABLE    1
+#define DROP_SEQUENCE 2
+#define DROP_VIEW     3
+#define DROP_INDEX    4
+#define DROP_RULE     5
+#define DROP_TYPE_P   6
+
 typedef struct DropStmt
 {
        NodeTag         type;
-       List       *relNames;           /* relations to be dropped */
-       bool            sequence;
+       List       *names;
+       int                     removeType;
 } DropStmt;
 
 /* ----------------------
@@ -528,17 +537,6 @@ typedef struct RemoveOperStmt
 } RemoveOperStmt;
 
 /* ----------------------
- *             Drop {Type|Index|Rule|View} Statement
- * ----------------------
- */
-typedef struct RemoveStmt
-{
-       NodeTag         type;
-       int                     removeType;             /* P_TYPE|INDEX|RULE|VIEW */
-       char       *name;                       /* name to drop */
-} RemoveStmt;
-
-/* ----------------------
  *             Alter Table Statement
  * ----------------------
  */
index 43d29cd..a721b0a 100644 (file)
@@ -7,7 +7,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.26 2000/10/07 20:23:03 petere Exp $
+#    $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.27 2000/10/18 16:16:14 momjian Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -130,9 +130,11 @@ endif
 runcheck: all
 ifneq ($(PORTNAME), win)
        MULTIBYTE=$(MULTIBYTE);export MULTIBYTE; \
+       MAKE=$(MAKE);export MAKE; \
        $(SHELL) ./run_check.sh $(host_tuple)
 else
        MULTIBYTE=$(MULTIBYTE);export MULTIBYTE; \
+       MAKE=$(MAKE);export MAKE; \
        ./run_check.sh $(host_tuple)
 endif
        @echo "ACTUAL RESULTS OF REGRESSION TEST ARE NOW IN FILES run_check.out"
@@ -148,9 +150,11 @@ endif
 bigcheck: all
 ifneq ($(PORTNAME), win)
        MULTIBYTE=$(MULTIBYTE);export MULTIBYTE; \
+       MAKE=$(MAKE);export MAKE; \
        $(SHELL) ./run_check.sh $(host_tuple) $(EXTRA_TESTS)
 else
        MULTIBYTE=$(MULTIBYTE);export MULTIBYTE; \
+       MAKE=$(MAKE);export MAKE; \
        ./run_check.sh $(host_tuple) $(EXTRA_TESTS)
 endif
        @echo "ACTUAL RESULTS OF REGRESSION TEST ARE NOW IN FILES run_check.out"
index ca030be..81b905b 100644 (file)
@@ -52,7 +52,7 @@ drop table;
 ERROR:  parser: parse error at or near ";"
 -- no such relation 
 drop table nonesuch;
-ERROR:  Relation 'nonesuch' does not exist
+ERROR:  table "nonesuch" is nonexistent
 --
 -- RENAME
  
@@ -122,7 +122,7 @@ drop index 314159;
 ERROR:  parser: parse error at or near "314159"
 -- no such index 
 drop index nonesuch;
-ERROR:  index "nonesuch" nonexistent
+ERROR:  index "nonesuch" is nonexistent
 --
 -- REMOVE AGGREGATE
  
index 105d07a..42ac65a 100644 (file)
@@ -699,7 +699,7 @@ CREATE TABLE FKTABLE_FAIL2 ( ftest1 int, CONSTRAINT fkfail1 FOREIGN KEY (ftest1)
 NOTICE:  CREATE TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
 ERROR:  UNIQUE constraint matching given keys for referenced table "pktable" not found
 DROP TABLE FKTABLE_FAIL1;
-ERROR:  Relation 'fktable_fail1' does not exist
+ERROR:  table "fktable_fail1" is nonexistent
 DROP TABLE FKTABLE_FAIL2;
-ERROR:  Relation 'fktable_fail2' does not exist
+ERROR:  table "fktable_fail2" is nonexistent
 DROP TABLE PKTABLE;
index 6822ae3..4a91fcc 100644 (file)
@@ -3,7 +3,7 @@
 --
 -- prepare the table...
 DROP TABLE INET_TBL;
-ERROR:  Relation 'inet_tbl' does not exist
+ERROR:  table "inet_tbl" is nonexistent
 CREATE TABLE INET_TBL (c cidr, i inet);
 INSERT INTO INET_TBL (c, i) VALUES ('192.168.1', '192.168.1.226/24');
 INSERT INTO INET_TBL (c, i) VALUES ('192.168.1.2/24', '192.168.1.226');