]> granicus.if.org Git - postgresql/blobdiff - src/backend/tcop/utility.c
Accept an INTERVAL argument for SET TIME ZONE per SQL99.
[postgresql] / src / backend / tcop / utility.c
index 409aca70adaf0b4e51fdab57d965322208726393..66ccb65278440f6a7defaa34f3b25c86f6c5cac6 100644 (file)
@@ -5,12 +5,12 @@
  *       commands.  At one time acted as an interface between the Lisp and C
  *       systems.
  *
- * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
+ * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.91 2000/07/05 12:45:26 wieck Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.121 2001/10/18 17:30:15 thomas Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 
 #include "access/heapam.h"
 #include "catalog/catalog.h"
+#include "catalog/pg_shadow.h"
 #include "commands/async.h"
 #include "commands/cluster.h"
 #include "commands/command.h"
 #include "commands/view.h"
 #include "miscadmin.h"
 #include "parser/parse.h"
+#include "parser/parse_clause.h"
+#include "parser/parse_expr.h"
 #include "rewrite/rewriteDefine.h"
 #include "rewrite/rewriteRemove.h"
 #include "tcop/utility.h"
 #include "utils/acl.h"
 #include "utils/ps_status.h"
 #include "utils/syscache.h"
+#include "utils/temprel.h"
+#include "access/xlog.h"
 
-
-/* ----------------
- *             CHECK_IF_ABORTED() is used to avoid doing unnecessary
- *             processing within an aborted transaction block.
- * ----------------
+/*
+ * Error-checking support for DROP commands
  */
- /* we have to use IF because of the 'break' */
-#define CHECK_IF_ABORTED() \
-if (1) \
-{ \
-       if (IsAbortedTransactionBlockState()) \
-       { \
-               elog(NOTICE, "current transaction is aborted, " \
-                        "queries ignored until end of transaction block"); \
-               commandTag = "*ABORT STATE*"; \
-               break; \
-       } \
-} else
+
+struct kindstrings
+{
+       char            kind;
+       char       *indef_article;
+       char       *name;
+       char       *command;
+};
+
+static struct kindstrings kindstringarray[] = {
+       {RELKIND_RELATION, "a", "table", "TABLE"},
+       {RELKIND_SEQUENCE, "a", "sequence", "SEQUENCE"},
+       {RELKIND_VIEW, "a", "view", "VIEW"},
+       {RELKIND_INDEX, "an", "index", "INDEX"},
+       {'\0', "a", "???", "???"}
+};
+
+
+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;
+       /* wrongkind could be something we don't have in our table... */
+       if (wentry->kind != '\0')
+               elog(ERROR, "\"%s\" is not %s %s. Use DROP %s to remove %s %s",
+                        relname, rentry->indef_article, rentry->name,
+                        wentry->command, wentry->indef_article, wentry->name);
+       else
+               elog(ERROR, "\"%s\" is not %s %s",
+                        relname, rentry->indef_article, rentry->name);
+}
+
+static void
+CheckDropPermissions(char *name, char rightkind)
+{
+       struct kindstrings *rentry;
+       HeapTuple       tuple;
+       Form_pg_class classform;
+
+       for (rentry = kindstringarray; rentry->kind != '\0'; rentry++)
+               if (rentry->kind == rightkind)
+                       break;
+       Assert(rentry->kind != '\0');
+
+       tuple = SearchSysCache(RELNAME,
+                                                  PointerGetDatum(name),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "%s \"%s\" does not exist", rentry->name, name);
+
+       classform = (Form_pg_class) GETSTRUCT(tuple);
+
+       if (classform->relkind != rightkind)
+               DropErrorMsg(name, classform->relkind, rightkind);
+
+       if (!pg_ownercheck(GetUserId(), name, RELNAME))
+               elog(ERROR, "you do not own %s \"%s\"",
+                        rentry->name, name);
+
+       if (!allowSystemTableMods && IsSystemRelationName(name) &&
+               !is_temp_relname(name))
+               elog(ERROR, "%s \"%s\" is a system %s",
+                        rentry->name, name, rentry->name);
+
+       ReleaseSysCache(tuple);
+}
+
 
 /* ----------------
  *             general utility function invoker
@@ -74,9 +141,6 @@ ProcessUtility(Node *parsetree,
        char       *commandTag = NULL;
        char       *relname;
        char       *relationName;
-       char       *userName;
-
-       userName = GetPgUserName();
 
        switch (nodeTag(parsetree))
        {
@@ -93,7 +157,6 @@ ProcessUtility(Node *parsetree,
                                {
                                        case BEGIN_TRANS:
                                                set_ps_display(commandTag = "BEGIN");
-                                               CHECK_IF_ABORTED();
                                                BeginTransactionBlock();
                                                break;
 
@@ -119,7 +182,6 @@ ProcessUtility(Node *parsetree,
                                ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
 
                                set_ps_display(commandTag = "CLOSE");
-                               CHECK_IF_ABORTED();
 
                                PerformPortalClose(stmt->portalname, dest);
                        }
@@ -133,7 +195,6 @@ ProcessUtility(Node *parsetree,
                                int                     count;
 
                                set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
-                               CHECK_IF_ABORTED();
 
                                SetQuerySnapshot();
 
@@ -156,60 +217,78 @@ ProcessUtility(Node *parsetree,
                         */
                case T_CreateStmt:
                        set_ps_display(commandTag = "CREATE");
-                       CHECK_IF_ABORTED();
 
                        DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
 
                        /*
-                        * Let AlterTableCreateToastTable decide if this
-                        * one needs a secondary relation too.
-                        *
+                        * Let AlterTableCreateToastTable decide if this one needs a
+                        * secondary relation too.
                         */
                        CommandCounterIncrement();
-                       AlterTableCreateToastTable(((CreateStmt *)parsetree)->relname,
-                                                                               true);
+                       AlterTableCreateToastTable(((CreateStmt *) parsetree)->relname,
+                                                                          true);
                        break;
 
                case T_DropStmt:
                        {
                                DropStmt   *stmt = (DropStmt *) parsetree;
-                               List       *args = stmt->relNames;
+                               List       *args = stmt->names;
                                List       *arg;
 
                                set_ps_display(commandTag = "DROP");
-                               CHECK_IF_ABORTED();
 
-                               /* 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);
-#ifndef NO_SECURITY
-                                       if (!pg_ownercheck(userName, relname, RELNAME))
-                                               elog(ERROR, "you do not own class \"%s\"",
-                                                        relname);
-#endif
-                               }
-                               /* OK, terminate 'em all */
                                foreach(arg, args)
                                {
                                        relname = strVal(lfirst(arg));
-                                       RemoveRelation(relname);
+
+                                       switch (stmt->removeType)
+                                       {
+                                               case DROP_TABLE:
+                                                       CheckDropPermissions(relname, RELKIND_RELATION);
+                                                       RemoveRelation(relname);
+                                                       break;
+
+                                               case DROP_SEQUENCE:
+                                                       CheckDropPermissions(relname, RELKIND_SEQUENCE);
+                                                       RemoveRelation(relname);
+                                                       break;
+
+                                               case DROP_VIEW:
+                                                       CheckDropPermissions(relname, RELKIND_VIEW);
+                                                       RemoveView(relname);
+                                                       break;
+
+                                               case DROP_INDEX:
+                                                       CheckDropPermissions(relname, RELKIND_INDEX);
+                                                       RemoveIndex(relname);
+                                                       break;
+
+                                               case DROP_RULE:
+                                                       {
+                                                               char       *rulename = relname;
+                                                               int                     aclcheck_result;
+
+                                                               relationName = RewriteGetRuleEventRel(rulename);
+                                                               aclcheck_result = pg_aclcheck(relationName, GetUserId(), ACL_RULE);
+                                                               if (aclcheck_result != ACLCHECK_OK)
+                                                                       elog(ERROR, "%s: %s", relationName,
+                                                                                aclcheck_error_strings[aclcheck_result]);
+                                                               RemoveRewriteRule(rulename);
+                                                       }
+                                                       break;
+
+                                               case DROP_TYPE_P:
+                                                       /* RemoveType does its own permissions checks */
+                                                       RemoveType(relname);
+                                                       break;
+                                       }
+
+                                       /*
+                                        * Make sure subsequent loop iterations will see
+                                        * results of this one; needed if removing multiple
+                                        * rules for same table, for example.
+                                        */
+                                       CommandCounterIncrement();
                                }
                        }
                        break;
@@ -219,7 +298,6 @@ ProcessUtility(Node *parsetree,
                                Relation        rel;
 
                                set_ps_display(commandTag = "TRUNCATE");
-                               CHECK_IF_ABORTED();
 
                                relname = ((TruncateStmt *) parsetree)->relName;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
@@ -231,39 +309,36 @@ ProcessUtility(Node *parsetree,
                                if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
                                        elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
                                                 relname);
+                               if (rel->rd_rel->relkind == RELKIND_VIEW)
+                                       elog(ERROR, "TRUNCATE cannot be used on views. '%s' is a view",
+                                                relname);
                                heap_close(rel, NoLock);
 
-#ifndef NO_SECURITY
-                               if (!pg_ownercheck(userName, relname, RELNAME))
+                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                        elog(ERROR, "you do not own class \"%s\"", relname);
-#endif
                                TruncateRelation(relname);
                        }
                        break;
 
                case T_CommentStmt:
                        {
-
                                CommentStmt *statement;
 
                                statement = ((CommentStmt *) parsetree);
 
                                set_ps_display(commandTag = "COMMENT");
-                               CHECK_IF_ABORTED();
+
                                CommentObject(statement->objtype, statement->objname,
                                                          statement->objproperty, statement->objlist,
                                                          statement->comment);
                        }
                        break;
 
-
-
                case T_CopyStmt:
                        {
                                CopyStmt   *stmt = (CopyStmt *) parsetree;
 
                                set_ps_display(commandTag = "COPY");
-                               CHECK_IF_ABORTED();
 
                                if (stmt->direction != FROM)
                                        SetQuerySnapshot();
@@ -292,16 +367,13 @@ ProcessUtility(Node *parsetree,
                                RenameStmt *stmt = (RenameStmt *) parsetree;
 
                                set_ps_display(commandTag = "ALTER");
-                               CHECK_IF_ABORTED();
 
                                relname = stmt->relname;
                                if (!allowSystemTableMods && IsSystemRelationName(relname))
                                        elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
                                                 relname);
-#ifndef NO_SECURITY
-                               if (!pg_ownercheck(userName, relname, RELNAME))
+                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                        elog(ERROR, "permission denied");
-#endif
 
                                /* ----------------
                                 *      XXX using len == 3 to tell the difference
@@ -314,27 +386,26 @@ ProcessUtility(Node *parsetree,
                                 */
                                if (stmt->column == NULL)
                                {
-                                       /* ----------------
-                                        *              rename relation
+
+                                       /*
+                                        * rename relation
                                         *
-                                        *              Note: we also rename the "type" tuple
-                                        *              corresponding to the relation.
-                                        * ----------------
+                                        * Note: we also rename the "type" tuple corresponding to
+                                        * the relation.
                                         */
                                        renamerel(relname,      /* old name */
                                                          stmt->newname);       /* new name */
                                }
                                else
                                {
-                                       /* ----------------
-                                        *              rename attribute
-                                        * ----------------
+
+                                       /*
+                                        * rename attribute
                                         */
                                        renameatt(relname,      /* relname */
                                                          stmt->column,         /* old att name */
                                                          stmt->newname,        /* new att name */
-                                                         userName,
-                                                         stmt->inh);           /* recursive? */
+                                                         interpretInhOption(stmt->inhOpt));            /* recursive? */
                                }
                        }
                        break;
@@ -346,7 +417,6 @@ ProcessUtility(Node *parsetree,
                                AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
 
                                set_ps_display(commandTag = "ALTER");
-                               CHECK_IF_ABORTED();
 
                                /*
                                 * Some or all of these functions are recursive to cover
@@ -355,22 +425,46 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->subtype)
                                {
                                        case 'A':       /* ADD COLUMN */
-                                               AlterTableAddColumn(stmt->relname, stmt->inh, (ColumnDef *) stmt->def);
+                                               AlterTableAddColumn(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                       (ColumnDef *) stmt->def);
+                                               break;
+                                       case 'T':       /* ALTER COLUMN DEFAULT */
+                                               AlterTableAlterColumnDefault(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                                        stmt->name,
+                                                                                                        stmt->def);
                                                break;
-                                       case 'T':       /* ALTER COLUMN */
-                                               AlterTableAlterColumn(stmt->relname, stmt->inh, stmt->name, stmt->def);
+                                       case 'S':       /* ALTER COLUMN STATISTICS */
+                                               AlterTableAlterColumnStatistics(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                                               stmt->name,
+                                                                                                               stmt->def);
                                                break;
-                                       case 'D':       /* ALTER DROP */
-                                               AlterTableDropColumn(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
+                                       case 'D':       /* DROP COLUMN */
+                                               AlterTableDropColumn(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                        stmt->name,
+                                                                                        stmt->behavior);
                                                break;
                                        case 'C':       /* ADD CONSTRAINT */
-                                               AlterTableAddConstraint(stmt->relname, stmt->inh, stmt->def);
+                                               AlterTableAddConstraint(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                               (List *) stmt->def);
                                                break;
                                        case 'X':       /* DROP CONSTRAINT */
-                                               AlterTableDropConstraint(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
+                                               AlterTableDropConstraint(stmt->relname,
+                                                                               interpretInhOption(stmt->inhOpt),
+                                                                                                stmt->name,
+                                                                                                stmt->behavior);
                                                break;
                                        case 'E':       /* CREATE TOAST TABLE */
-                                               AlterTableCreateToastTable(stmt->relname, false);
+                                               AlterTableCreateToastTable(stmt->relname,
+                                                                                                  false);
+                                               break;
+                                       case 'U':       /* ALTER OWNER */
+                                               AlterTableOwner(stmt->relname,
+                                                                               stmt->name);
                                                break;
                                        default:        /* oops */
                                                elog(ERROR, "T_AlterTableStmt: unknown subtype");
@@ -380,37 +474,13 @@ ProcessUtility(Node *parsetree,
                        break;
 
 
-               case T_ChangeACLStmt:
+               case T_GrantStmt:
                        {
-                               ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
-                               List       *i;
-                               AclItem    *aip;
-                               unsigned        modechg;
+                               GrantStmt *stmt = (GrantStmt *) parsetree;
+                               commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
+                               set_ps_display(commandTag);
 
-                               set_ps_display(commandTag = "CHANGE");
-                               CHECK_IF_ABORTED();
-
-                               aip = stmt->aclitem;
-
-                               modechg = stmt->modechg;
-                               foreach(i, stmt->relNames)
-                               {
-                                       Relation        rel;
-
-                                       relname = strVal(lfirst(i));
-                                       rel = heap_openr(relname, AccessExclusiveLock);
-                                       if (rel && rel->rd_rel->relkind == RELKIND_INDEX)
-                                               elog(ERROR, "\"%s\" is an index relation",
-                                                        relname);
-                                       /* close rel, but keep lock until end of xact */
-                                       heap_close(rel, NoLock);
-#ifndef NO_SECURITY
-                                       if (!pg_ownercheck(userName, relname, RELNAME))
-                                               elog(ERROR, "you do not own class \"%s\"",
-                                                        relname);
-#endif
-                                       ChangeAcl(relname, aip, modechg);
-                               }
+                               ExecuteGrantStmt(stmt);
                        }
                        break;
 
@@ -424,7 +494,6 @@ ProcessUtility(Node *parsetree,
                                DefineStmt *stmt = (DefineStmt *) parsetree;
 
                                set_ps_display(commandTag = "CREATE");
-                               CHECK_IF_ABORTED();
 
                                switch (stmt->defType)
                                {
@@ -448,15 +517,15 @@ ProcessUtility(Node *parsetree,
                                ViewStmt   *stmt = (ViewStmt *) parsetree;
 
                                set_ps_display(commandTag = "CREATE");
-                               CHECK_IF_ABORTED();
+
                                DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
                        }
                        break;
 
                case T_ProcedureStmt:   /* CREATE FUNCTION */
                        set_ps_display(commandTag = "CREATE");
-                       CHECK_IF_ABORTED();
-                       CreateFunction((ProcedureStmt *) parsetree, dest);      /* everything */
+
+                       CreateFunction((ProcedureStmt *) parsetree);
                        break;
 
                case T_IndexStmt:               /* CREATE INDEX */
@@ -464,12 +533,11 @@ ProcessUtility(Node *parsetree,
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
                                set_ps_display(commandTag = "CREATE");
-                               CHECK_IF_ABORTED();
+
                                DefineIndex(stmt->relname,              /* relation name */
                                                        stmt->idxname,          /* index name */
                                                        stmt->accessMethod, /* am name */
                                                        stmt->indexParams,      /* parameters */
-                                                       stmt->withClause,
                                                        stmt->unique,
                                                        stmt->primary,
                                                        (Expr *) stmt->whereClause,
@@ -482,107 +550,33 @@ ProcessUtility(Node *parsetree,
                                RuleStmt   *stmt = (RuleStmt *) parsetree;
                                int                     aclcheck_result;
 
-#ifndef NO_SECURITY
                                relname = stmt->object->relname;
-                               aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
+                               aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RULE);
                                if (aclcheck_result != ACLCHECK_OK)
                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
-#endif
                                set_ps_display(commandTag = "CREATE");
-                               CHECK_IF_ABORTED();
+
                                DefineQueryRewrite(stmt);
                        }
                        break;
 
                case T_CreateSeqStmt:
                        set_ps_display(commandTag = "CREATE");
-                       CHECK_IF_ABORTED();
 
                        DefineSequence((CreateSeqStmt *) parsetree);
                        break;
 
-               case T_ExtendStmt:
-                       {
-                               ExtendStmt *stmt = (ExtendStmt *) parsetree;
-
-                               set_ps_display(commandTag = "EXTEND");
-                               CHECK_IF_ABORTED();
-
-                               ExtendIndex(stmt->idxname,              /* index name */
-                                                       (Expr *) stmt->whereClause, /* where */
-                                                       stmt->rangetable);
-                       }
-                       break;
-
-               case T_RemoveStmt:
-                       {
-                               RemoveStmt *stmt = (RemoveStmt *) parsetree;
-
-                               set_ps_display(commandTag = "DROP");
-                               CHECK_IF_ABORTED();
-
-                               switch (stmt->removeType)
-                               {
-                                       case INDEX:
-                                               relname = stmt->name;
-                                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                                       elog(ERROR, "class \"%s\" is a system catalog index",
-                                                                relname);
-#ifndef NO_SECURITY
-                                               if (!pg_ownercheck(userName, relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-#endif
-                                               RemoveIndex(relname);
-                                               break;
-                                       case RULE:
-                                               {
-                                                       char       *rulename = stmt->name;
-                                                       int                     aclcheck_result;
-
-#ifndef NO_SECURITY
-
-                                                       relationName = RewriteGetRuleEventRel(rulename);
-                                                       aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
-                                                       if (aclcheck_result != ACLCHECK_OK)
-                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
-#endif
-                                                       RemoveRewriteRule(rulename);
-                                               }
-                                               break;
-                                       case TYPE_P:
-#ifndef NO_SECURITY
-                                               /* XXX moved to remove.c */
-#endif
-                                               RemoveType(stmt->name);
-                                               break;
-                                       case VIEW:
-                                               {
-                                                       char       *viewName = stmt->name;
-                                                       char       *ruleName;
-
-#ifndef NO_SECURITY
-
-                                                       ruleName = MakeRetrieveViewRuleName(viewName);
-                                                       relationName = RewriteGetRuleEventRel(ruleName);
-                                                       if (!pg_ownercheck(userName, relationName, RELNAME))
-                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                                                       pfree(ruleName);
-#endif
-                                                       RemoveView(viewName);
-                                               }
-                                               break;
-                               }
-                               break;
-                       }
-                       break;
-
                case T_RemoveAggrStmt:
                        {
                                RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
+                               char       *typename = (char *) NULL;
 
                                set_ps_display(commandTag = "DROP");
-                               CHECK_IF_ABORTED();
-                               RemoveAggregate(stmt->aggname, stmt->aggtype);
+
+                               if (stmt->aggtype != NULL)
+                                       typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
+
+                               RemoveAggregate(stmt->aggname, typename);
                        }
                        break;
 
@@ -591,27 +585,27 @@ ProcessUtility(Node *parsetree,
                                RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
 
                                set_ps_display(commandTag = "DROP");
-                               CHECK_IF_ABORTED();
-                               RemoveFunction(stmt->funcname,
-                                                          length(stmt->args),
-                                                          stmt->args);
+
+                               RemoveFunction(stmt->funcname, stmt->args);
                        }
                        break;
 
                case T_RemoveOperStmt:
                        {
                                RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
-                               char       *type1 = (char *) NULL;
-                               char       *type2 = (char *) NULL;
+                               TypeName   *typenode1 = (TypeName *) lfirst(stmt->args);
+                               TypeName   *typenode2 = (TypeName *) lsecond(stmt->args);
+                               char       *typename1 = (char *) NULL;
+                               char       *typename2 = (char *) NULL;
 
                                set_ps_display(commandTag = "DROP");
-                               CHECK_IF_ABORTED();
 
-                               if (lfirst(stmt->args) != NULL)
-                                       type1 = strVal(lfirst(stmt->args));
-                               if (lsecond(stmt->args) != NULL)
-                                       type2 = strVal(lsecond(stmt->args));
-                               RemoveOperator(stmt->opname, type1, type2);
+                               if (typenode1 != NULL)
+                                       typename1 = TypeNameToInternalName(typenode1);
+                               if (typenode2 != NULL)
+                                       typename2 = TypeNameToInternalName(typenode2);
+
+                               RemoveOperator(stmt->opname, typename1, typename2);
                        }
                        break;
 
@@ -624,8 +618,9 @@ ProcessUtility(Node *parsetree,
                                CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
 
                                set_ps_display(commandTag = "CREATE DATABASE");
-                               CHECK_IF_ABORTED();
-                               createdb(stmt->dbname, stmt->dbpath, stmt->encoding);
+
+                               createdb(stmt->dbname, stmt->dbpath,
+                                                stmt->dbtemplate, stmt->encoding);
                        }
                        break;
 
@@ -634,7 +629,7 @@ ProcessUtility(Node *parsetree,
                                DropdbStmt *stmt = (DropdbStmt *) parsetree;
 
                                set_ps_display(commandTag = "DROP DATABASE");
-                               CHECK_IF_ABORTED();
+
                                dropdb(stmt->dbname);
                        }
                        break;
@@ -645,7 +640,6 @@ ProcessUtility(Node *parsetree,
                                NotifyStmt *stmt = (NotifyStmt *) parsetree;
 
                                set_ps_display(commandTag = "NOTIFY");
-                               CHECK_IF_ABORTED();
 
                                Async_Notify(stmt->relname);
                        }
@@ -656,7 +650,6 @@ ProcessUtility(Node *parsetree,
                                ListenStmt *stmt = (ListenStmt *) parsetree;
 
                                set_ps_display(commandTag = "LISTEN");
-                               CHECK_IF_ABORTED();
 
                                Async_Listen(stmt->relname, MyProcPid);
                        }
@@ -667,7 +660,6 @@ ProcessUtility(Node *parsetree,
                                UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
 
                                set_ps_display(commandTag = "UNLISTEN");
-                               CHECK_IF_ABORTED();
 
                                Async_Unlisten(stmt->relname, MyProcPid);
                        }
@@ -682,7 +674,6 @@ ProcessUtility(Node *parsetree,
                                LoadStmt   *stmt = (LoadStmt *) parsetree;
 
                                set_ps_display(commandTag = "LOAD");
-                               CHECK_IF_ABORTED();
 
                                closeAllVfds(); /* probably not necessary... */
                                load_file(stmt->filename);
@@ -694,19 +685,26 @@ ProcessUtility(Node *parsetree,
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
                                set_ps_display(commandTag = "CLUSTER");
-                               CHECK_IF_ABORTED();
 
-                               cluster(stmt->relname, stmt->indexname);
+                               relname = stmt->relname;
+                               if (IsSystemRelationName(relname))
+                                       elog(ERROR, "CLUSTER: relation \"%s\" is a system catalog",
+                                                relname);
+                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
+                                       elog(ERROR, "permission denied");
+
+                               cluster(relname, stmt->indexname);
                        }
                        break;
 
                case T_VacuumStmt:
-                       set_ps_display(commandTag = "VACUUM");
-                       CHECK_IF_ABORTED();
-                       vacuum(((VacuumStmt *) parsetree)->vacrel,
-                                  ((VacuumStmt *) parsetree)->verbose,
-                                  ((VacuumStmt *) parsetree)->analyze,
-                                  ((VacuumStmt *) parsetree)->va_spec);
+                       if (((VacuumStmt *) parsetree)->vacuum)
+                               commandTag = "VACUUM";
+                       else
+                               commandTag = "ANALYZE";
+                       set_ps_display(commandTag);
+
+                       vacuum((VacuumStmt *) parsetree);
                        break;
 
                case T_ExplainStmt:
@@ -714,9 +712,8 @@ ProcessUtility(Node *parsetree,
                                ExplainStmt *stmt = (ExplainStmt *) parsetree;
 
                                set_ps_display(commandTag = "EXPLAIN");
-                               CHECK_IF_ABORTED();
 
-                               ExplainQuery(stmt->query, stmt->verbose, dest);
+                               ExplainQuery(stmt->query, stmt->verbose, stmt->analyze, dest);
                        }
                        break;
 
@@ -730,7 +727,7 @@ ProcessUtility(Node *parsetree,
                                RecipeStmt *stmt = (RecipeStmt *) parsetree;
 
                                set_ps_display(commandTag = "EXECUTE RECIPE");
-                               CHECK_IF_ABORTED();
+
                                beginRecipe(stmt);
                        }
                        break;
@@ -743,7 +740,7 @@ ProcessUtility(Node *parsetree,
                        {
                                VariableSetStmt *n = (VariableSetStmt *) parsetree;
 
-                               SetPGVariable(n->name, n->value);
+                               SetPGVariable(n->name, n->args);
                                set_ps_display(commandTag = "SET VARIABLE");
                        }
                        break;
@@ -771,14 +768,12 @@ ProcessUtility(Node *parsetree,
                         */
                case T_CreateTrigStmt:
                        set_ps_display(commandTag = "CREATE");
-                       CHECK_IF_ABORTED();
 
                        CreateTrigger((CreateTrigStmt *) parsetree);
                        break;
 
                case T_DropTrigStmt:
                        set_ps_display(commandTag = "DROP");
-                       CHECK_IF_ABORTED();
 
                        DropTrigger((DropTrigStmt *) parsetree);
                        break;
@@ -788,14 +783,12 @@ ProcessUtility(Node *parsetree,
                         */
                case T_CreatePLangStmt:
                        set_ps_display(commandTag = "CREATE");
-                       CHECK_IF_ABORTED();
 
                        CreateProceduralLanguage((CreatePLangStmt *) parsetree);
                        break;
 
                case T_DropPLangStmt:
                        set_ps_display(commandTag = "DROP");
-                       CHECK_IF_ABORTED();
 
                        DropProceduralLanguage((DropPLangStmt *) parsetree);
                        break;
@@ -806,66 +799,67 @@ ProcessUtility(Node *parsetree,
                         */
                case T_CreateUserStmt:
                        set_ps_display(commandTag = "CREATE USER");
-                       CHECK_IF_ABORTED();
 
                        CreateUser((CreateUserStmt *) parsetree);
                        break;
 
                case T_AlterUserStmt:
                        set_ps_display(commandTag = "ALTER USER");
-                       CHECK_IF_ABORTED();
 
                        AlterUser((AlterUserStmt *) parsetree);
                        break;
 
                case T_DropUserStmt:
                        set_ps_display(commandTag = "DROP USER");
-                       CHECK_IF_ABORTED();
 
                        DropUser((DropUserStmt *) parsetree);
                        break;
 
                case T_LockStmt:
                        set_ps_display(commandTag = "LOCK TABLE");
-                       CHECK_IF_ABORTED();
 
                        LockTableCommand((LockStmt *) parsetree);
                        break;
 
                case T_ConstraintsSetStmt:
                        set_ps_display(commandTag = "SET CONSTRAINTS");
-                       CHECK_IF_ABORTED();
 
                        DeferredTriggerSetState((ConstraintsSetStmt *) parsetree);
                        break;
 
                case T_CreateGroupStmt:
                        set_ps_display(commandTag = "CREATE GROUP");
-                       CHECK_IF_ABORTED();
 
                        CreateGroup((CreateGroupStmt *) parsetree);
                        break;
 
                case T_AlterGroupStmt:
                        set_ps_display(commandTag = "ALTER GROUP");
-                       CHECK_IF_ABORTED();
 
                        AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
                        break;
 
                case T_DropGroupStmt:
                        set_ps_display(commandTag = "DROP GROUP");
-                       CHECK_IF_ABORTED();
 
                        DropGroup((DropGroupStmt *) parsetree);
                        break;
 
+               case T_CheckPointStmt:
+                       {
+                               set_ps_display(commandTag = "CHECKPOINT");
+
+                               if (!superuser())
+                                       elog(ERROR, "permission denied");
+                               CreateCheckPoint(false);
+                       }
+                       break;
+
                case T_ReindexStmt:
                        {
                                ReindexStmt *stmt = (ReindexStmt *) parsetree;
 
                                set_ps_display(commandTag = "REINDEX");
-                               CHECK_IF_ABORTED();
 
                                switch (stmt->reindexType)
                                {
@@ -875,33 +869,19 @@ ProcessUtility(Node *parsetree,
                                                {
                                                        if (!allowSystemTableMods && IsSystemRelationName(relname))
                                                                elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -O -P options",
-                                                                relname);
+                                                                        relname);
                                                        if (!IsIgnoringSystemIndexes())
                                                                elog(ERROR, "\"%s\" is a system index. call REINDEX under standalone postgres with -P -O options",
-                                                                relname);
+                                                                        relname);
                                                }
-#ifndef NO_SECURITY
-                                               if (!pg_ownercheck(userName, relname, RELNAME))
+                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-#endif
                                                ReindexIndex(relname, stmt->force);
                                                break;
                                        case TABLE:
                                                relname = (char *) stmt->name;
-                                               if (IsSystemRelationName(relname))
-                                               {
-                                                       if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                                               elog(ERROR, "\"%s\" is a system table. call REINDEX under standalone postgres with -O -P options",
-                                                                relname);
-                                                       if (!IsIgnoringSystemIndexes())
-                                                               elog(ERROR, "\"%s\" is a system table. call REINDEX under standalone postgres with -P -O options",
-
-                                                                relname);
-                                               }
-#ifndef NO_SECURITY
-                                               if (!pg_ownercheck(userName, relname, RELNAME))
+                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
                                                        elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-#endif
                                                ReindexTable(relname, stmt->force);
                                                break;
                                        case DATABASE:
@@ -927,9 +907,8 @@ ProcessUtility(Node *parsetree,
                        break;
        }
 
-       /* ----------------
-        *      tell fe/be or whatever that we're done.
-        * ----------------
+       /*
+        * tell fe/be or whatever that we're done.
         */
        EndCommand(commandTag, dest);
 }