Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend')
-rw-r--r--src/backend/nodes/copyfuncs.c20
-rw-r--r--src/backend/nodes/equalfuncs.c19
-rw-r--r--src/backend/parser/gram.y28
-rw-r--r--src/backend/tcop/utility.c207
4 files changed, 151 insertions, 123 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index e768d0bd796..3d740533ff0 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -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;
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index d5b2ff4607e..372f22499d5 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -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;
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index a596bd6aba1..fbda2758035 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -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; }
;
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 6c0b2be5ea9..d63a5c6b7e2 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -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 $
*
*-------------------------------------------------------------------------
*/
@@ -46,6 +46,71 @@
#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;