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 766512a..84f3325 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.125 2002/02/07 00:27:30 inoue Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.140 2002/03/26 19:16:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -18,6 +18,7 @@
 
 #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"
@@ -44,7 +45,6 @@
 #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"
@@ -95,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;
 
@@ -106,41 +107,83 @@ CheckDropPermissions(char *name, char rightkind)
                        break;
        Assert(rentry->kind != '\0');
 
-       tuple = SearchSysCache(RELNAME,
-                                                  PointerGetDatum(name),
+       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) &&
-               !is_temp_relname(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))
        {
@@ -155,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;
                                }
@@ -180,8 +220,6 @@ ProcessUtility(Node *parsetree,
                        {
                                ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLOSE");
-
                                PerformPortalClose(stmt->portalname, dest);
                        }
                        break;
@@ -193,8 +231,6 @@ ProcessUtility(Node *parsetree,
                                bool            forward;
                                int                     count;
 
-                               set_ps_display(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
-
                                SetQuerySnapshot();
 
                                forward = (bool) (stmt->direction == FORWARD);
@@ -204,82 +240,86 @@ 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)
                                        {
                                                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_RULE);
-                                                               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;
                                        }
 
                                        /*
@@ -294,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 view",
-                                                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;
 
@@ -337,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),
@@ -365,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
@@ -391,7 +400,7 @@ ProcessUtility(Node *parsetree,
                                         * 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
@@ -402,7 +411,7 @@ ProcessUtility(Node *parsetree,
                                        renameatt(relname,      /* relname */
                                                          stmt->column,         /* old att name */
                                                          stmt->newname,        /* new att name */
-                                                         interpretInhOption(stmt->inhOpt));            /* recursive? */
+                                                         interpretInhOption(stmt->relation->inhOpt));          /* recursive? */
                                }
                        }
                        break;
@@ -413,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.
@@ -422,45 +429,47 @@ ProcessUtility(Node *parsetree,
                                switch (stmt->subtype)
                                {
                                        case 'A':       /* ADD COLUMN */
-                                               AlterTableAddColumn(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAddColumn(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
                                                                                        (ColumnDef *) stmt->def);
                                                break;
                                        case 'T':       /* ALTER COLUMN DEFAULT */
-                                               AlterTableAlterColumnDefault(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAlterColumnDefault(stmt->relation->relname,
+                                                                               interpretInhOption((stmt->relation)->inhOpt),
                                                                                                         stmt->name,
                                                                                                         stmt->def);
                                                break;
                                        case 'S':       /* ALTER COLUMN STATISTICS */
-                                               AlterTableAlterColumnStatistics(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                       case 'M':   /* ALTER COLUMN STORAGE */
+                                               AlterTableAlterColumnFlags(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                                stmt->name,
-                                                                                                               stmt->def);
+                                                                                                               stmt->def,
+                                                                                                       &(stmt->subtype));
                                                break;
                                        case 'D':       /* DROP COLUMN */
-                                               AlterTableDropColumn(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableDropColumn(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                         stmt->name,
                                                                                         stmt->behavior);
                                                break;
                                        case 'C':       /* ADD CONSTRAINT */
-                                               AlterTableAddConstraint(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableAddConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                (List *) stmt->def);
                                                break;
                                        case 'X':       /* DROP CONSTRAINT */
-                                               AlterTableDropConstraint(stmt->relname,
-                                                                               interpretInhOption(stmt->inhOpt),
+                                               AlterTableDropConstraint(stmt->relation->relname,
+                                                                               interpretInhOption(stmt->relation->inhOpt),
                                                                                                 stmt->name,
                                                                                                 stmt->behavior);
                                                break;
                                        case 'E':       /* CREATE TOAST TABLE */
-                                               AlterTableCreateToastTable(stmt->relname,
+                                               AlterTableCreateToastTable(RangeVarGetRelid(stmt->relation, false),
                                                                                                   false);
                                                break;
                                        case 'U':       /* ALTER OWNER */
-                                               AlterTableOwner(stmt->relname,
+                                               AlterTableOwner(stmt->relation,
                                                                                stmt->name);
                                                break;
                                        default:        /* oops */
@@ -475,9 +484,6 @@ ProcessUtility(Node *parsetree,
                        {
                                GrantStmt  *stmt = (GrantStmt *) parsetree;
 
-                               commandTag = stmt->is_grant ? "GRANT" : "REVOKE";
-                               set_ps_display(commandTag);
-
                                ExecuteGrantStmt(stmt);
                        }
                        break;
@@ -491,8 +497,6 @@ ProcessUtility(Node *parsetree,
                        {
                                DefineStmt *stmt = (DefineStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
-
                                switch (stmt->defType)
                                {
                                        case OPERATOR:
@@ -514,15 +518,11 @@ 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);
                        break;
 
@@ -530,19 +530,12 @@ ProcessUtility(Node *parsetree,
                        {
                                IndexStmt  *stmt = (IndexStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CREATE");
+                               CheckOwnership(stmt->relation, true);
 
-                               relname = stmt->relname;
-                               if (!allowSystemTableMods && IsSystemRelationName(relname))
-                                       elog(ERROR, "CREATE INDEX: relation \"%s\" is a system catalog",
-                                                relname);
-                               if (!pg_ownercheck(GetUserId(), relname, RELNAME))
-                                       elog(ERROR, "permission denied");
-
-                               DefineIndex(stmt->relname,              /* relation name */
-                                                       stmt->idxname,          /* index name */
-                                                       stmt->accessMethod, /* am name */
-                                                       stmt->indexParams,      /* parameters */
+                               DefineIndex(stmt->relation,                             /* relation */
+                                                       stmt->idxname,                          /* index name */
+                                                       stmt->accessMethod,             /* am name */
+                                                       stmt->indexParams,                      /* parameters */
                                                        stmt->unique,
                                                        stmt->primary,
                                                        (Expr *) stmt->whereClause,
@@ -551,23 +544,10 @@ 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_RULE);
-                               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;
 
@@ -576,8 +556,6 @@ ProcessUtility(Node *parsetree,
                                RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
                                char       *typename = (char *) NULL;
 
-                               set_ps_display(commandTag = "DROP");
-
                                if (stmt->aggtype != NULL)
                                        typename = TypeNameToInternalName((TypeName *) stmt->aggtype);
 
@@ -589,8 +567,6 @@ ProcessUtility(Node *parsetree,
                        {
                                RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
 
-                               set_ps_display(commandTag = "DROP");
-
                                RemoveFunction(stmt->funcname, stmt->args);
                        }
                        break;
@@ -603,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)
@@ -614,27 +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->dbtemplate, 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;
@@ -644,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;
 
@@ -654,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;
 
@@ -664,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);
                        }
@@ -689,64 +648,36 @@ ProcessUtility(Node *parsetree,
                        {
                                ClusterStmt *stmt = (ClusterStmt *) parsetree;
 
-                               set_ps_display(commandTag = "CLUSTER");
-
-                               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");
+                               CheckOwnership(stmt->relation, true);
 
-                               cluster(relname, stmt->indexname);
+                               cluster(stmt->relation, stmt->indexname);
                        }
                        break;
 
                case T_VacuumStmt:
-                       if (((VacuumStmt *) parsetree)->vacuum)
-                               commandTag = "VACUUM";
-                       else
-                               commandTag = "ANALYZE";
-                       set_ps_display(commandTag);
-
                        vacuum((VacuumStmt *) parsetree);
                        break;
 
                case T_ExplainStmt:
-                       {
-                               ExplainStmt *stmt = (ExplainStmt *) parsetree;
-
-                               set_ps_display(commandTag = "EXPLAIN");
-
-                               ExplainQuery(stmt->query, stmt->verbose, stmt->analyze, 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->args);
-                               set_ps_display(commandTag = "SET VARIABLE");
                        }
                        break;
 
@@ -755,7 +686,6 @@ ProcessUtility(Node *parsetree,
                                VariableShowStmt *n = (VariableShowStmt *) parsetree;
 
                                GetPGVariable(n->name);
-                               set_ps_display(commandTag = "SHOW VARIABLE");
                        }
                        break;
 
@@ -764,96 +694,73 @@ 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);
@@ -864,12 +771,10 @@ 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)
@@ -879,15 +784,12 @@ ProcessUtility(Node *parsetree,
                                                                elog(ERROR, "\"%s\" is a system index. 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]);
-                                               ReindexIndex(relname, stmt->force);
+                                               CheckOwnership(stmt->relation, false);
+                                               ReindexIndex(stmt->relation, stmt->force);
                                                break;
                                        case TABLE:
-                                               relname = (char *) stmt->name;
-                                               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;
@@ -902,18 +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);
 }