diff -c -r pgsql.orig/doc/src/sgml/ref/drop_table.sgml pgsql.work/doc/src/sgml/ref/drop_table.sgml *** pgsql.orig/doc/src/sgml/ref/drop_table.sgml Tue Oct 17 12:53:38 2000 --- pgsql.work/doc/src/sgml/ref/drop_table.sgml Wed Oct 18 11:00:28 2000 *************** *** 39,45 **** name ! The name of an existing table or view to drop. --- 39,45 ---- name ! The name of an existing table to drop. *************** *** 68,78 **** ! ERROR Relation "name" Does Not Exist! ! If the specified table or view does not exist in the database. --- 68,78 ---- ! ERROR: table "name" is nonexistent ! If the specified table does not exist in the database. *************** *** 89,96 **** Description ! DROP TABLE removes tables and views from the database. ! Only its owner may destroy a table or view. A table may be emptied of rows, but not destroyed, by using DELETE. --- 89,96 ---- Description ! DROP TABLE removes tables from the database. ! Only its owner may destroy a table. A table may be emptied of rows, but not destroyed, by using DELETE. diff -c -r pgsql.orig/doc/src/sgml/ref/drop_view.sgml pgsql.work/doc/src/sgml/ref/drop_view.sgml *** pgsql.orig/doc/src/sgml/ref/drop_view.sgml Tue Oct 17 12:53:38 2000 --- pgsql.work/doc/src/sgml/ref/drop_view.sgml Wed Oct 18 11:00:25 2000 *************** *** 23,29 **** 1999-07-20 ! DROP VIEW name --- 23,29 ---- 1999-07-20 ! DROP VIEW name [, ...] *************** *** 70,76 **** ! ERROR: RewriteGetRuleEventRel: rule "_RETname" not found --- 70,76 ---- ! ERROR: view name is nonexistent diff -c -r pgsql.orig/src/backend/nodes/copyfuncs.c pgsql.work/src/backend/nodes/copyfuncs.c *** pgsql.orig/src/backend/nodes/copyfuncs.c Tue Oct 17 12:53:42 2000 --- pgsql.work/src/backend/nodes/copyfuncs.c Wed Oct 18 09:46:40 2000 *************** *** 1949,1956 **** { DropStmt *newnode = makeNode(DropStmt); ! Node_Copy(from, newnode, relNames); ! newnode->sequence = from->sequence; return newnode; } --- 1949,1956 ---- { DropStmt *newnode = makeNode(DropStmt); ! Node_Copy(from, newnode, names); ! newnode->removeType = from->removeType; return newnode; } *************** *** 2071,2087 **** 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) { --- 2071,2076 ---- *************** *** 2781,2789 **** break; case T_RemoveOperStmt: retval = _copyRemoveOperStmt(from); - break; - case T_RemoveStmt: - retval = _copyRemoveStmt(from); break; case T_RenameStmt: retval = _copyRenameStmt(from); --- 2770,2775 ---- diff -c -r pgsql.orig/src/backend/nodes/equalfuncs.c pgsql.work/src/backend/nodes/equalfuncs.c *** pgsql.orig/src/backend/nodes/equalfuncs.c Tue Oct 17 12:53:42 2000 --- pgsql.work/src/backend/nodes/equalfuncs.c Wed Oct 18 09:47:26 2000 *************** *** 850,858 **** static bool _equalDropStmt(DropStmt *a, DropStmt *b) { ! if (!equal(a->relNames, b->relNames)) return false; ! if (a->sequence != b->sequence) return false; return true; --- 850,858 ---- static bool _equalDropStmt(DropStmt *a, DropStmt *b) { ! if (!equal(a->names, b->names)) return false; ! if (a->removeType != b->removeType) return false; return true; *************** *** 989,1004 **** 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) --- 989,994 ---- *************** *** 1958,1966 **** break; case T_RemoveOperStmt: retval = _equalRemoveOperStmt(a, b); - break; - case T_RemoveStmt: - retval = _equalRemoveStmt(a, b); break; case T_RenameStmt: retval = _equalRenameStmt(a, b); --- 1948,1953 ---- diff -c -r pgsql.orig/src/backend/parser/gram.y pgsql.work/src/backend/parser/gram.y *** pgsql.orig/src/backend/parser/gram.y Tue Oct 17 12:53:43 2000 --- pgsql.work/src/backend/parser/gram.y Wed Oct 18 09:42:44 2000 *************** *** 1942,1956 **** DropStmt: DROP TABLE relation_name_list { DropStmt *n = makeNode(DropStmt); ! n->relNames = $3; ! n->sequence = FALSE; $$ = (Node *)n; } | DROP SEQUENCE relation_name_list { DropStmt *n = makeNode(DropStmt); ! n->relNames = $3; ! n->sequence = TRUE; $$ = (Node *)n; } ; --- 1942,1963 ---- DropStmt: DROP TABLE relation_name_list { DropStmt *n = makeNode(DropStmt); ! n->names = $3; ! n->removeType = DROP_TABLE; $$ = (Node *)n; } | DROP SEQUENCE relation_name_list { DropStmt *n = makeNode(DropStmt); ! 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,2574 **** RemoveStmt: DROP remove_type name { ! RemoveStmt *n = makeNode(RemoveStmt); n->removeType = $2; ! n->name = $3; $$ = (Node *)n; } ; ! remove_type: TYPE_P { $$ = TYPE_P; } ! | INDEX { $$ = INDEX; } ! | RULE { $$ = RULE; } ! | VIEW { $$ = VIEW; } ; --- 2565,2580 ---- RemoveStmt: DROP remove_type name { ! DropStmt *n = makeNode(DropStmt); n->removeType = $2; ! n->names = makeList1(makeString($3)); $$ = (Node *)n; } ; ! remove_type: TYPE_P { $$ = DROP_TYPE_P; } ! | INDEX { $$ = DROP_INDEX; } ! | RULE { $$ = DROP_RULE; } ; diff -c -r pgsql.orig/src/backend/tcop/utility.c pgsql.work/src/backend/tcop/utility.c *** pgsql.orig/src/backend/tcop/utility.c Tue Oct 17 12:53:44 2000 --- pgsql.work/src/backend/tcop/utility.c Wed Oct 18 10:12:48 2000 *************** *** 46,51 **** --- 46,116 ---- #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,189 **** case T_DropStmt: { DropStmt *stmt = (DropStmt *) parsetree; ! List *args = stmt->relNames; List *arg; ! set_ps_display(commandTag = "DROP"); ! ! /* check as much as we can before we start dropping ... */ ! foreach(arg, args) ! { ! Relation rel; 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); } } break; --- 214,289 ---- case T_DropStmt: { DropStmt *stmt = (DropStmt *) parsetree; ! List *args = stmt->names; List *arg; ! foreach(arg, args) { relname = strVal(lfirst(arg)); if (!allowSystemTableMods && IsSystemRelationName(relname)) elog(ERROR, "class \"%s\" is a system catalog", 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; *************** *** 449,505 **** ExtendIndex(stmt->idxname, /* index name */ (Expr *) stmt->whereClause, /* where */ stmt->rangetable); - } - 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; --- 549,554 ---- diff -c -r pgsql.orig/src/include/nodes/parsenodes.h pgsql.work/src/include/nodes/parsenodes.h *** pgsql.orig/src/include/nodes/parsenodes.h Tue Oct 17 12:53:51 2000 --- pgsql.work/src/include/nodes/parsenodes.h Wed Oct 18 09:32:43 2000 *************** *** 389,403 **** List *definition; /* a list of DefElem */ } DefineStmt; /* ---------------------- ! * Drop Table Statement * ---------------------- */ typedef struct DropStmt { NodeTag type; ! List *relNames; /* relations to be dropped */ ! bool sequence; } DropStmt; /* ---------------------- --- 389,412 ---- List *definition; /* a list of DefElem */ } DefineStmt; + /* ---------------------- ! * 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 *names; ! int removeType; } DropStmt; /* ---------------------- *************** *** 526,542 **** char *opname; /* operator to drop */ List *args; /* types of the arguments */ } 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 --- 535,540 ---- diff -c -r pgsql.orig/src/test/regress/GNUmakefile pgsql.work/src/test/regress/GNUmakefile *** pgsql.orig/src/test/regress/GNUmakefile Tue Oct 17 12:54:01 2000 --- pgsql.work/src/test/regress/GNUmakefile Tue Oct 17 14:24:57 2000 *************** *** 130,138 **** --- 130,140 ---- 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,156 **** --- 150,160 ---- 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" diff -c -r pgsql.orig/src/test/regress/expected/errors.out pgsql.work/src/test/regress/expected/errors.out *** pgsql.orig/src/test/regress/expected/errors.out Tue Oct 17 12:54:01 2000 --- pgsql.work/src/test/regress/expected/errors.out Wed Oct 18 10:19:58 2000 *************** *** 52,58 **** ERROR: parser: parse error at or near ";" -- no such relation drop table nonesuch; ! ERROR: Relation 'nonesuch' does not exist -- -- RENAME --- 52,58 ---- ERROR: parser: parse error at or near ";" -- no such relation drop table nonesuch; ! ERROR: table "nonesuch" is nonexistent -- -- RENAME *************** *** 122,128 **** ERROR: parser: parse error at or near "314159" -- no such index drop index nonesuch; ! ERROR: index "nonesuch" nonexistent -- -- REMOVE AGGREGATE --- 122,128 ---- ERROR: parser: parse error at or near "314159" -- no such index drop index nonesuch; ! ERROR: index "nonesuch" is nonexistent -- -- REMOVE AGGREGATE diff -c -r pgsql.orig/src/test/regress/expected/foreign_key.out pgsql.work/src/test/regress/expected/foreign_key.out *** pgsql.orig/src/test/regress/expected/foreign_key.out Tue Oct 17 12:54:01 2000 --- pgsql.work/src/test/regress/expected/foreign_key.out Wed Oct 18 10:20:39 2000 *************** *** 699,705 **** 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 DROP TABLE FKTABLE_FAIL2; ! ERROR: Relation 'fktable_fail2' does not exist DROP TABLE PKTABLE; --- 699,705 ---- 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: table "fktable_fail1" is nonexistent DROP TABLE FKTABLE_FAIL2; ! ERROR: table "fktable_fail2" is nonexistent DROP TABLE PKTABLE; diff -c -r pgsql.orig/src/test/regress/expected/inet.out pgsql.work/src/test/regress/expected/inet.out *** pgsql.orig/src/test/regress/expected/inet.out Tue Oct 17 12:54:01 2000 --- pgsql.work/src/test/regress/expected/inet.out Wed Oct 18 10:19:10 2000 *************** *** 3,9 **** -- -- prepare the table... DROP TABLE INET_TBL; ! ERROR: Relation 'inet_tbl' does not exist 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'); --- 3,9 ---- -- -- prepare the table... DROP TABLE INET_TBL; ! 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');