OSDN Git Service

pg_class has a relnamespace column. You can create and access tables
[pg-rex/syncrep.git] / src / backend / tcop / utility.c
index 9ee7267..84f3325 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.100 2000/11/07 02:17:50 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.140 2002/03/26 19:16:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,8 @@
 
 #include "access/heapam.h"
 #include "catalog/catalog.h"
+#include "catalog/namespace.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"
 
 /*
  * Error-checking support for DROP commands
  */
 
-struct kindstrings {
-       char kind;
-       char *indef_article;
-       char *name;
-       char *command;
+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", "???", "???" }
+       {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(charrelname, char wrongkind, char rightkind)
+DropErrorMsg(char *relname, char wrongkind, char rightkind)
 {
        struct kindstrings *rentry;
        struct kindstrings *wentry;
@@ -91,9 +95,10 @@ DropErrorMsg(char* relname, char wrongkind, char rightkind)
 }
 
 static void
-CheckDropPermissions(char *name, char rightkind)
+CheckDropPermissions(RangeVar *rel, char rightkind)
 {
        struct kindstrings *rentry;
+       Oid                     relOid;
        HeapTuple       tuple;
        Form_pg_class classform;
 
@@ -102,42 +107,86 @@ CheckDropPermissions(char *name, char rightkind)
                        break;
        Assert(rentry->kind != '\0');
 
-       tuple = SearchSysCacheTuple(RELNAME,
-                                                               PointerGetDatum(name),
-                                                               0, 0, 0);
+       relOid = RangeVarGetRelid(rel, true);
+       if (!OidIsValid(relOid))
+               elog(ERROR, "%s \"%s\" does not exist", rentry->name, rel->relname);
+       tuple = SearchSysCache(RELOID,
+                                                  ObjectIdGetDatum(relOid),
+                                                  0, 0, 0);
        if (!HeapTupleIsValid(tuple))
-               elog(ERROR, "%s \"%s\" does not exist", rentry->name, name);
+               elog(ERROR, "%s \"%s\" does not exist", rentry->name, rel->relname);
 
        classform = (Form_pg_class) GETSTRUCT(tuple);
 
        if (classform->relkind != rightkind)
-               DropErrorMsg(name, classform->relkind, rightkind);
+               DropErrorMsg(rel->relname, classform->relkind, rightkind);
 
-       if (!pg_ownercheck(GetUserId(), name, RELNAME))
+       if (!pg_class_ownercheck(relOid, GetUserId()))
                elog(ERROR, "you do not own %s \"%s\"",
-                        rentry->name, name);
+                        rentry->name, rel->relname);
 
-       if (!allowSystemTableMods && IsSystemRelationName(name))
+       if (!allowSystemTableMods && IsSystemRelationName(rel->relname) &&
+               !is_temp_relname(rel->relname))
                elog(ERROR, "%s \"%s\" is a system %s",
-                        rentry->name, name, rentry->name);
+                        rentry->name, rel->relname, rentry->name);
+
+       ReleaseSysCache(tuple);
+}
+
+static void
+CheckOwnership(RangeVar *rel, bool noCatalogs)
+{
+       Oid                     relOid;
+       HeapTuple       tuple;
+
+       relOid = RangeVarGetRelid(rel, false);
+       tuple = SearchSysCache(RELOID,
+                                                  ObjectIdGetDatum(relOid),
+                                                  0, 0, 0);
+       if (!HeapTupleIsValid(tuple))
+               elog(ERROR, "Relation \"%s\" does not exist", rel->relname);
+
+       if (!pg_class_ownercheck(relOid, GetUserId()))
+               elog(ERROR, "%s: %s", rel->relname,
+                        aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+
+       if (noCatalogs)
+       {
+               if (!allowSystemTableMods && IsSystemRelationName(rel->relname))
+                       elog(ERROR, "relation \"%s\" is a system catalog",
+                                rel->relname);
+       }
+
+       ReleaseSysCache(tuple);
 }
 
 
-/* ----------------
+/*
+ * ProcessUtility
  *             general utility function invoker
- * ----------------
+ *
+ *     parsetree: the parse tree for the utility statement
+ *     dest: where to send results
+ *     completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
+ *             in which to store a command completion status string.
+ *
+ * completionTag is only set nonempty if we want to return a nondefault
+ * status (currently, only used for MOVE/FETCH).
+ *
+ * completionTag may be NULL if caller doesn't want a status string.
  */
 void
 ProcessUtility(Node *parsetree,
-                          CommandDest dest)
+                          CommandDest dest,
+                          char *completionTag)
 {
-       char       *commandTag = NULL;
        char       *relname;
-       char       *relationName;
+
+       if (completionTag)
+               completionTag[0] = '\0';
 
        switch (nodeTag(parsetree))
        {
-
                        /*
                         * ******************************** transactions ********************************
                         *
@@ -149,17 +198,14 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->command)
                                {
                                        case BEGIN_TRANS:
-                                               set_ps_display(commandTag = "BEGIN");
                                                BeginTransactionBlock();
                                                break;
 
                                        case COMMIT:
-                                               set_ps_display(commandTag = "COMMIT");
                                                EndTransactionBlock();
                                                break;
 
                                        case ROLLBACK:
-                                               set_ps_display(commandTag = "ROLLBACK");
                                                UserAbortTransactionBlock();
                                                break;
                                }
@@ -174,8 +220,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLOSE");
-
                                PerformPortalClose(stmt->portalname, dest);
                        }
                        break;
@@ -187,8 +231,6 @@ ProcessUtility(Node *parsetree,
                                bool            forward;
                                int                     count;
 
-                               set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
-
                                SetQuerySnapshot();
 
                                forward = (bool) (stmt->direction == FORWARD);
@@ -198,88 +240,92 @@ ProcessUtility(Node *parsetree,
                                 */
 
                                count = stmt->howMany;
-                               PerformPortalFetch(portalName, forward, count, commandTag,
-                                                                  (stmt->ismove) ? None : dest);               /* /dev/null for MOVE */
+                               PerformPortalFetch(portalName, forward, count,
+                                                                  (stmt->ismove) ? None : dest,
+                                                                  completionTag);
                        }
                        break;
 
                        /*
-                        * ******************************** relation and attribute
-                        * manipulation ********************************
-                        *
+                        * relation and attribute manipulation
                         */
+               case T_CreateSchemaStmt:
+                       {
+                               CreateSchemaStmt  *stmt = (CreateSchemaStmt *) parsetree;
+
+                               CreateSchemaCommand(stmt);
+                       }
+                       break;
+
                case T_CreateStmt:
-                       set_ps_display(commandTag = "CREATE");
+                       {
+                               Oid                     relOid;
 
-                       DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
+                               relOid = DefineRelation((CreateStmt *) parsetree,
+                                                                               RELKIND_RELATION);
 
-                       /*
-                        * Let AlterTableCreateToastTable decide if this
-                        * one needs a secondary relation too.
-                        */
-                       CommandCounterIncrement();
-                       AlterTableCreateToastTable(((CreateStmt *)parsetree)->relname,
-                                                                               true);
+                               /*
+                                * Let AlterTableCreateToastTable decide if this one needs a
+                                * secondary relation too.
+                                */
+                               CommandCounterIncrement();
+                               AlterTableCreateToastTable(relOid, true);
+                       }
                        break;
 
                case T_DropStmt:
                        {
                                DropStmt   *stmt = (DropStmt *) parsetree;
-                               List       *args = stmt->names;
                                List       *arg;
 
-                               set_ps_display(commandTag = "DROP");
-
-                               foreach(arg, args)
+                               foreach(arg, stmt->objects)
                                {
-                                       relname = strVal(lfirst(arg));
+                                       RangeVar   *rel = (RangeVar *) lfirst(arg);
+
+                                       relname = rel->relname;
 
-                                       switch(stmt->removeType)
+                                       switch (stmt->removeType)
                                        {
                                                case DROP_TABLE:
-                                                       CheckDropPermissions(relname, RELKIND_RELATION);
+                                                       CheckDropPermissions(rel, RELKIND_RELATION);
                                                        RemoveRelation(relname);
                                                        break;
 
                                                case DROP_SEQUENCE:
-                                                       CheckDropPermissions(relname, RELKIND_SEQUENCE);
+                                                       CheckDropPermissions(rel, RELKIND_SEQUENCE);
                                                        RemoveRelation(relname);
                                                        break;
 
                                                case DROP_VIEW:
-                                                       CheckDropPermissions(relname, RELKIND_VIEW);
+                                                       CheckDropPermissions(rel, RELKIND_VIEW);
                                                        RemoveView(relname);
                                                        break;
 
                                                case DROP_INDEX:
-                                                       CheckDropPermissions(relname, RELKIND_INDEX);
-                                                       RemoveIndex(relname);
+                                                       CheckDropPermissions(rel, RELKIND_INDEX);
+                                                       RemoveIndex(rel);
                                                        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);
-                                                       }
+                                                       /* RemoveRewriteRule checks permissions */
+                                                       RemoveRewriteRule(relname);
                                                        break;
 
-                                               case DROP_TYPE_P:
+                                               case DROP_TYPE:
                                                        /* RemoveType does its own permissions checks */
                                                        RemoveType(relname);
                                                        break;
+
+                                               case DROP_DOMAIN:
+                                                       /* RemoveDomain does its own permissions checks */
+                                                       RemoveDomain(relname, stmt->behavior);
+                                                       break;
                                        }
 
                                        /*
-                                        * Make sure subsequent loop iterations will see results
-                                        * of this one; needed if removing multiple rules for
-                                        * same table, for example.
+                                        * Make sure subsequent loop iterations will see
+                                        * results of this one; needed if removing multiple
+                                        * rules for same table, for example.
                                         */
                                        CommandCounterIncrement();
                                }
@@ -288,42 +334,19 @@ ProcessUtility(Node *parsetree,
 
                case T_TruncateStmt:
                        {
-                               Relation        rel;
-
-                               set_ps_display(commandTag = "TRUNCATE");
-
-                               relname = ((TruncateStmt *) parsetree)->relName;
-                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                       elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
-                                                relname);
-
-                               /* Grab exclusive lock in preparation for truncate... */
-                               rel = heap_openr(relname, AccessExclusiveLock);
-                               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 sequence",
-                                                relname);
-                               heap_close(rel, NoLock);
-
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "you do not own class \"%s\"", relname);
+                               relname = ((TruncateStmt *) parsetree)->relation->relname;
                                TruncateRelation(relname);
                        }
                        break;
 
                case T_CommentStmt:
                        {
-                               CommentStmt *statement;
+                               CommentStmt *stmt;
 
-                               statement = ((CommentStmt *) parsetree);
+                               stmt = ((CommentStmt *) parsetree);
 
-                               set_ps_display(commandTag = "COMMENT");
-
-                               CommentObject(statement->objtype, statement->objname,
-                                                         statement->objproperty, statement->objlist,
-                                                         statement->comment);
+                               CommentObject(stmt->objtype, stmt->objschema, stmt->objname,
+                                                         stmt->objproperty, stmt->objlist, stmt->comment);
                        }
                        break;
 
@@ -331,12 +354,10 @@ ProcessUtility(Node *parsetree,
                        {
                                CopyStmt   *stmt = (CopyStmt *) parsetree;
 
-                               set_ps_display(commandTag = "COPY");
-
                                if (stmt->direction != FROM)
                                        SetQuerySnapshot();
 
-                               DoCopy(stmt->relname,
+                               DoCopy(stmt->relation->relname,
                                           stmt->binary,
                                           stmt->oids,
                                           (bool) (stmt->direction == FROM),
@@ -359,14 +380,8 @@ ProcessUtility(Node *parsetree,
                        {
                                RenameStmt *stmt = (RenameStmt *) parsetree;
 
-                               set_ps_display(commandTag = "ALTER");
-
-                               relname = stmt->relname;
-                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                       elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
-                                                relname);
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "permission denied");
+                               relname = stmt->relation->relname;
+                               CheckOwnership(stmt->relation, true);
 
                                /* ----------------
                                 *      XXX using len == 3 to tell the difference
@@ -379,26 +394,24 @@ 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 */
+                                       renamerel(stmt->relation,       /* old relation */
                                                          stmt->newname);       /* new name */
                                }
                                else
                                {
-                                       /* ----------------
-                                        *              rename attribute
-                                        * ----------------
+                                       /*
+                                        * rename attribute
                                         */
                                        renameatt(relname,      /* relname */
                                                          stmt->column,         /* old att name */
                                                          stmt->newname,        /* new att name */
-                                                         stmt->inh);           /* recursive? */
+                                                         interpretInhOption(stmt->relation->inhOpt));          /* recursive? */
                                }
                        }
                        break;
@@ -409,8 +422,6 @@ ProcessUtility(Node *parsetree,
                        {
                                AlterTableStmt *stmt = (AlterTableStmt *) parsetree;
 
-                               set_ps_display(commandTag = "ALTER");
-
                                /*
                                 * Some or all of these functions are recursive to cover
                                 * inherited things, so permission checks are done there.
@@ -418,25 +429,48 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->subtype)
                                {
                                        case 'A':       /* ADD COLUMN */
-                                               AlterTableAddColumn(stmt->relname, stmt->inh, (ColumnDef *) stmt->def);
+                                               AlterTableAddColumn(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
+                                                                                       (ColumnDef *) stmt->def);
+                                               break;
+                                       case 'T':       /* ALTER COLUMN DEFAULT */
+                                               AlterTableAlterColumnDefault(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
+                                                                                                        stmt->name,
+                                                                                                        stmt->def);
                                                break;
-                                       case 'T':       /* ALTER COLUMN */
-                                               AlterTableAlterColumn(stmt->relname, stmt->inh, stmt->name, stmt->def);
+                                       case 'S':       /* ALTER COLUMN STATISTICS */
+                                       case 'M':   /* ALTER COLUMN STORAGE */
+                                               AlterTableAlterColumnFlags(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
+                                                                                                               stmt->name,
+                                                                                                               stmt->def,
+                                                                                                       &(stmt->subtype));
                                                break;
-                                       case 'D':       /* ALTER DROP */
-                                               AlterTableDropColumn(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
+                                       case 'D':       /* DROP COLUMN */
+                                               AlterTableDropColumn(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
+                                                                                        stmt->name,
+                                                                                        stmt->behavior);
                                                break;
                                        case 'C':       /* ADD CONSTRAINT */
-                                               AlterTableAddConstraint(stmt->relname, stmt->inh, stmt->def);
+                                               AlterTableAddConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
+                                                                                               (List *) stmt->def);
                                                break;
                                        case 'X':       /* DROP CONSTRAINT */
-                                               AlterTableDropConstraint(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
+                                               AlterTableDropConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
+                                                                                                stmt->name,
+                                                                                                stmt->behavior);
                                                break;
                                        case 'E':       /* CREATE TOAST TABLE */
-                                               AlterTableCreateToastTable(stmt->relname, false);
+                                               AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false),
+                                                                                                  false);
                                                break;
                                        case 'U':       /* ALTER OWNER */
-                                               AlterTableOwner(stmt->relname, stmt->name);
+                                               AlterTableOwner(stmt->relation,
+                                                                               stmt->name);
                                                break;
                                        default:        /* oops */
                                                elog(ERROR, "T_AlterTableStmt: unknown subtype");
@@ -446,13 +480,11 @@ ProcessUtility(Node *parsetree,
                        break;
 
 
-               case T_ChangeACLStmt:
+               case T_GrantStmt:
                        {
-                               ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
+                               GrantStmt  *stmt = (GrantStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CHANGE");
-
-                               ExecuteChangeACLStmt(stmt);
+                               ExecuteGrantStmt(stmt);
                        }
                        break;
 
@@ -465,8 +497,6 @@ ProcessUtility(Node *parsetree,
                        {
                                DefineStmt *stmt = (DefineStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
                                switch (stmt->defType)
                                {
                                        case OPERATOR:
@@ -488,29 +518,24 @@ ProcessUtility(Node *parsetree,
                        {
                                ViewStmt   *stmt = (ViewStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
-                               DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
+                               DefineView(stmt->view->relname, stmt->query);   /* retrieve parsetree */
                        }
                        break;
 
                case T_ProcedureStmt:   /* CREATE FUNCTION */
-                       set_ps_display(commandTag = "CREATE");
-
-                       CreateFunction((ProcedureStmt *) parsetree, dest);      /* everything */
+                       CreateFunction((ProcedureStmt *) parsetree);
                        break;
 
                case T_IndexStmt:               /* CREATE INDEX */
                        {
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
+                               CheckOwnership(stmt->relation, true);
 
-                               DefineIndex(stmt->relname,              /* relation name */
-                                                       stmt->idxname,          /* index name */
-                                                       stmt->accessMethod, /* am name */
-                                                       stmt->indexParams,      /* parameters */
-                                                       stmt->withClause,
+                               DefineIndex(stmt->relation,                             /* relation */
+                                                       stmt->idxname,                          /* index name */
+                                                       stmt->accessMethod,             /* am name */
+                                                       stmt->indexParams,                      /* parameters */
                                                        stmt->unique,
                                                        stmt->primary,
                                                        (Expr *) stmt->whereClause,
@@ -519,45 +544,18 @@ ProcessUtility(Node *parsetree,
                        break;
 
                case T_RuleStmt:                /* CREATE RULE */
-                       {
-                               RuleStmt   *stmt = (RuleStmt *) parsetree;
-                               int                     aclcheck_result;
-
-                               relname = stmt->object->relname;
-                               aclcheck_result = pg_aclcheck(relname, GetUserId(), ACL_RU);
-                               if (aclcheck_result != ACLCHECK_OK)
-                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
-                               set_ps_display(commandTag = "CREATE");
-
-                               DefineQueryRewrite(stmt);
-                       }
+                       DefineQueryRewrite((RuleStmt *) parsetree);
                        break;
 
                case T_CreateSeqStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        DefineSequence((CreateSeqStmt *) parsetree);
                        break;
 
-               case T_ExtendStmt:
-                       {
-                               ExtendStmt *stmt = (ExtendStmt *) parsetree;
-
-                               set_ps_display(commandTag = "EXTEND");
-
-                               ExtendIndex(stmt->idxname,              /* index name */
-                                                       (Expr *) stmt->whereClause, /* where */
-                                                       stmt->rangetable);
-                       }
-                       break;
-
                case T_RemoveAggrStmt:
                        {
                                RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
                                char       *typename = (char *) NULL;
 
-                               set_ps_display(commandTag = "DROP");
-
                                if (stmt->aggtype != NULL)
                                        typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
 
@@ -569,8 +567,6 @@ ProcessUtility(Node *parsetree,
                        {
                                RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
 
-                               set_ps_display(commandTag = "DROP");
-
                                RemoveFunction(stmt->funcname, stmt->args);
                        }
                        break;
@@ -583,8 +579,6 @@ ProcessUtility(Node *parsetree,
                                char       *typename1 = (char *) NULL;
                                char       *typename2 = (char *) NULL;
 
-                               set_ps_display(commandTag = "DROP");
-
                                if (typenode1 != NULL)
                                        typename1 = TypeNameToInternalName(typenode1);
                                if (typenode2 != NULL)
@@ -594,26 +588,24 @@ ProcessUtility(Node *parsetree,
                        }
                        break;
 
-               case T_VersionStmt:
-                       elog(ERROR, "CREATE VERSION is not currently implemented");
-                       break;
-
                case T_CreatedbStmt:
                        {
                                CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE DATABASE");
-
-                               createdb(stmt->dbname, stmt->dbpath, stmt->encoding);
+                               createdb(stmt->dbname, stmt->dbowner,
+                                                stmt->dbpath, stmt->dbtemplate,
+                                                stmt->encoding);
                        }
                        break;
 
+               case T_AlterDatabaseSetStmt:
+                       AlterDatabaseSet((AlterDatabaseSetStmt *)parsetree);
+                       break;
+
                case T_DropdbStmt:
                        {
                                DropdbStmt *stmt = (DropdbStmt *) parsetree;
 
-                               set_ps_display(commandTag = "DROP DATABASE");
-
                                dropdb(stmt->dbname);
                        }
                        break;
@@ -623,9 +615,7 @@ ProcessUtility(Node *parsetree,
                        {
                                NotifyStmt *stmt = (NotifyStmt *) parsetree;
 
-                               set_ps_display(commandTag = "NOTIFY");
-
-                               Async_Notify(stmt->relname);
+                               Async_Notify(stmt->relation->relname);
                        }
                        break;
 
@@ -633,9 +623,7 @@ ProcessUtility(Node *parsetree,
                        {
                                ListenStmt *stmt = (ListenStmt *) parsetree;
 
-                               set_ps_display(commandTag = "LISTEN");
-
-                               Async_Listen(stmt->relname, MyProcPid);
+                               Async_Listen(stmt->relation->relname, MyProcPid);
                        }
                        break;
 
@@ -643,22 +631,14 @@ ProcessUtility(Node *parsetree,
                        {
                                UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
 
-                               set_ps_display(commandTag = "UNLISTEN");
-
-                               Async_Unlisten(stmt->relname, MyProcPid);
+                               Async_Unlisten(stmt->relation->relname, MyProcPid);
                        }
                        break;
 
-                       /*
-                        * ******************************** dynamic loader ********************************
-                        *
-                        */
                case T_LoadStmt:
                        {
                                LoadStmt   *stmt = (LoadStmt *) parsetree;
 
-                               set_ps_display(commandTag = "LOAD");
-
                                closeAllVfds(); /* probably not necessary... */
                                load_file(stmt->filename);
                        }
@@ -668,56 +648,36 @@ ProcessUtility(Node *parsetree,
                        {
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLUSTER");
+                               CheckOwnership(stmt->relation, true);
 
-                               cluster(stmt->relname, stmt->indexname);
+                               cluster(stmt->relation, stmt->indexname);
                        }
                        break;
 
                case T_VacuumStmt:
-                       set_ps_display(commandTag = "VACUUM");
-
-                       vacuum(((VacuumStmt *) parsetree)->vacrel,
-                                  ((VacuumStmt *) parsetree)->verbose,
-                                  ((VacuumStmt *) parsetree)->analyze,
-                                  ((VacuumStmt *) parsetree)->va_spec);
+                       vacuum((VacuumStmt *) parsetree);
                        break;
 
                case T_ExplainStmt:
-                       {
-                               ExplainStmt *stmt = (ExplainStmt *) parsetree;
-
-                               set_ps_display(commandTag = "EXPLAIN");
-
-                               ExplainQuery(stmt->query, stmt->verbose, dest);
-                       }
+                       ExplainQuery((ExplainStmt *) parsetree, dest);
                        break;
 
 #ifdef NOT_USED
 
-                       /*
-                        * ******************************** Tioga-related statements *******************************
-                        */
                case T_RecipeStmt:
                        {
                                RecipeStmt *stmt = (RecipeStmt *) parsetree;
 
-                               set_ps_display(commandTag = "EXECUTE RECIPE");
-
                                beginRecipe(stmt);
                        }
                        break;
 #endif
 
-                       /*
-                        * ******************************** set variable statements *******************************
-                        */
                case T_VariableSetStmt:
                        {
                                VariableSetStmt *n = (VariableSetStmt *) parsetree;
 
-                               SetPGVariable(n->name, n->value);
-                               set_ps_display(commandTag = "SET VARIABLE");
+                               SetPGVariable(n->name, n->args);
                        }
                        break;
 
@@ -726,7 +686,6 @@ ProcessUtility(Node *parsetree,
                                VariableShowStmt *n = (VariableShowStmt *) parsetree;
 
                                GetPGVariable(n->name);
-                               set_ps_display(commandTag = "SHOW VARIABLE");
                        }
                        break;
 
@@ -735,96 +694,75 @@ ProcessUtility(Node *parsetree,
                                VariableResetStmt *n = (VariableResetStmt *) parsetree;
 
                                ResetPGVariable(n->name);
-                               set_ps_display(commandTag = "RESET VARIABLE");
                        }
                        break;
 
-                       /*
-                        * ******************************** TRIGGER statements *******************************
-                        */
                case T_CreateTrigStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        CreateTrigger((CreateTrigStmt *) parsetree);
                        break;
 
                case T_DropTrigStmt:
-                       set_ps_display(commandTag = "DROP");
-
                        DropTrigger((DropTrigStmt *) parsetree);
                        break;
 
-                       /*
-                        * ************* PROCEDURAL LANGUAGE statements *****************
-                        */
                case T_CreatePLangStmt:
-                       set_ps_display(commandTag = "CREATE");
-
                        CreateProceduralLanguage((CreatePLangStmt *) parsetree);
                        break;
 
                case T_DropPLangStmt:
-                       set_ps_display(commandTag = "DROP");
-
                        DropProceduralLanguage((DropPLangStmt *) parsetree);
                        break;
 
                        /*
+                        * ******************************** DOMAIN statements ****
+                        */
+               case T_CreateDomainStmt:
+                       DefineDomain((CreateDomainStmt *) parsetree);
+                       break;
+
+                       /*
                         * ******************************** USER statements ****
-                        *
                         */
                case T_CreateUserStmt:
-                       set_ps_display(commandTag = "CREATE USER");
-
                        CreateUser((CreateUserStmt *) parsetree);
                        break;
 
                case T_AlterUserStmt:
-                       set_ps_display(commandTag = "ALTER USER");
-
                        AlterUser((AlterUserStmt *) parsetree);
                        break;
 
-               case T_DropUserStmt:
-                       set_ps_display(commandTag = "DROP USER");
+               case T_AlterUserSetStmt:
+                       AlterUserSet((AlterUserSetStmt *) parsetree);
+                       break;
 
+               case T_DropUserStmt:
                        DropUser((DropUserStmt *) parsetree);
                        break;
 
                case T_LockStmt:
-                       set_ps_display(commandTag = "LOCK TABLE");
-
                        LockTableCommand((LockStmt *) parsetree);
                        break;
 
                case T_ConstraintsSetStmt:
-                       set_ps_display(commandTag = "SET CONSTRAINTS");
-
                        DeferredTriggerSetState((ConstraintsSetStmt *) parsetree);
                        break;
 
                case T_CreateGroupStmt:
-                       set_ps_display(commandTag = "CREATE GROUP");
-
                        CreateGroup((CreateGroupStmt *) parsetree);
                        break;
 
                case T_AlterGroupStmt:
-                       set_ps_display(commandTag = "ALTER GROUP");
-
                        AlterGroup((AlterGroupStmt *) parsetree, "ALTER GROUP");
                        break;
 
                case T_DropGroupStmt:
-                       set_ps_display(commandTag = "DROP GROUP");
-
                        DropGroup((DropGroupStmt *) parsetree);
                        break;
 
                case T_CheckPointStmt:
                        {
-                               set_ps_display(commandTag = "CHECKPOINT");
-
+                               if (!superuser())
+                                       elog(ERROR, "permission denied");
                                CreateCheckPoint(false);
                        }
                        break;
@@ -833,40 +771,25 @@ ProcessUtility(Node *parsetree,
                        {
                                ReindexStmt *stmt = (ReindexStmt *) parsetree;
 
-                               set_ps_display(commandTag = "REINDEX");
-
                                switch (stmt->reindexType)
                                {
                                        case INDEX:
-                                               relname = (char *) stmt->name;
+                                               relname = (char *) stmt->relation->relname;
                                                if (IsSystemRelationName(relname))
                                                {
-                                                       if (!allowSystemTableMods && IsSystemRelationName(relname))
+                                                       if (!allowSystemTableMods)
                                                                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);
                                                }
-                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                                               ReindexIndex(relname, stmt->force);
+                                               CheckOwnership(stmt->relation, false);
+                                               ReindexIndex(stmt->relation, 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);
-                                               }
-                                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                                               ReindexTable(relname, stmt->force);
+                                               CheckOwnership(stmt->relation, false);
+                                               ReindexTable(stmt->relation, stmt->force);
                                                break;
                                        case DATABASE:
                                                relname = (char *) stmt->name;
@@ -881,19 +804,9 @@ ProcessUtility(Node *parsetree,
                        }
                        break;
 
-                       /*
-                        * ******************************** default ********************************
-                        *
-                        */
                default:
                        elog(ERROR, "ProcessUtility: command #%d unsupported",
                                 nodeTag(parsetree));
                        break;
        }
-
-       /* ----------------
-        *      tell fe/be or whatever that we're done.
-        * ----------------
-        */
-       EndCommand(commandTag, dest);
 }