]> granicus.if.org Git - postgresql/blobdiff - src/backend/tcop/utility.c
From: t-ishii@sra.co.jp
[postgresql] / src / backend / tcop / utility.c
index fc5b09b4a1e4ee4a0b15fd6723ce8031bb69fe54..94f44a73857076f37e053e089bb0a073693a4b39 100644 (file)
@@ -1,20 +1,19 @@
 /*-------------------------------------------------------------------------
  *
  * utility.c--
- *    Contains functions which control the execution of the POSTGRES utility
- *    commands.  At one time acted as an interface between the Lisp and C
- *    systems.
+ *       Contains functions which control the execution of the POSTGRES utility
+ *       commands.  At one time acted as an interface between the Lisp and C
+ *       systems.
  *
  * Copyright (c) 1994, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *    $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.17 1997/05/22 00:15:36 scrappy Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.44 1998/07/26 04:30:48 scrappy Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
-#include "parser/dbcommands.h"
 #include "access/xact.h"
 #include "access/heapam.h"
 #include "catalog/catalog.h"
 #include "commands/command.h"
 #include "commands/copy.h"
 #include "commands/creatinh.h"
+#include "commands/dbcommands.h"
 #include "commands/sequence.h"
 #include "commands/defrem.h"
-#include "commands/purge.h"
 #include "commands/rename.h"
 #include "commands/view.h"
 #include "commands/version.h"
 #include "commands/vacuum.h"
 #include "commands/recipe.h"
 #include "commands/explain.h"
+#include "commands/trigger.h"
+#include "commands/proclang.h"
+#include "commands/variable.h"
 
 #include "nodes/parsenodes.h"
 #include "../backend/parser/parse.h"
@@ -44,9 +46,9 @@
 #include "rewrite/rewriteDefine.h"
 #include "tcop/tcopdebug.h"
 #include "tcop/dest.h"
-#include "tcop/variable.h"
 #include "tcop/utility.h"
-#include "fmgr.h"       /* For load_file() */
+#include "fmgr.h"                              /* For load_file() */
+#include "storage/fd.h"
 
 #ifndef NO_SECURITY
 #include "miscadmin.h"
 #include "utils/syscache.h"
 #endif
 
+void           DefineUser(CreateUserStmt *stmt);
+void           AlterUser(AlterUserStmt *stmt);
+void           RemoveUser(char *username);
+
+extern const char **ps_status; /* from postgres.c */
 
 /* ----------------
- *      CHECK_IF_ABORTED() is used to avoid doing unnecessary
- *      processing within an aborted transaction block.
+ *             CHECK_IF_ABORTED() is used to avoid doing unnecessary
+ *             processing within an aborted transaction block.
  * ----------------
  */
+ /* we have to use IF because of the 'break' */
 #define CHECK_IF_ABORTED() \
-    if (IsAbortedTransactionBlockState()) { \
-        elog(NOTICE, "(transaction aborted): %s", \
-             "queries ignored until END"); \
-        commandTag = "*ABORT STATE*"; \
-        break; \
-    } \
-    
+if (1) \
+{ \
+       if (IsAbortedTransactionBlockState()) \
+       { \
+               elog(NOTICE, "(transaction aborted): %s", \
+                        "all queries ignored until end of transaction block"); \
+               commandTag = "*ABORT STATE*"; \
+               break; \
+       } \
+} else
+
 /* ----------------
- *      general utility function invoker
+ *             general utility function invoker
  * ----------------
  */
 void
 ProcessUtility(Node *parsetree,
-               CommandDest dest)
+                          CommandDest dest)
 {
-    char *commandTag = NULL;
-    char *relname;
-    char *relationName;
-    char *userName;
-    
-    userName = GetPgUserName();
-    
-    switch (nodeTag(parsetree)) {
-        /* ********************************
-         *      transactions
-         * ********************************
-         */
-    case T_TransactionStmt:
-        {
-            TransactionStmt *stmt = (TransactionStmt *)parsetree;
-            switch (stmt->command) {
-            case BEGIN_TRANS:
-                commandTag = "BEGIN";
-                CHECK_IF_ABORTED();
-                BeginTransactionBlock();
-                break;
-                
-            case END_TRANS:
-                commandTag = "END";
-                EndTransactionBlock();
-                break;
-                
-            case ABORT_TRANS:
-                commandTag = "ABORT";
-                UserAbortTransactionBlock();
-                break;
-            }
-        }
-        break;
-      
-        /* ********************************
-         *      portal manipulation
-         * ********************************
-         */
-    case T_ClosePortalStmt:
-        {
-            ClosePortalStmt *stmt = (ClosePortalStmt *)parsetree;
-
-            commandTag = "CLOSE";
-            CHECK_IF_ABORTED();
-        
-            PerformPortalClose(stmt->portalname, dest);
-        }
-        break;
-      
-    case T_FetchStmt:
-        {
-            FetchStmt *stmt = (FetchStmt *)parsetree;
-            char *portalName = stmt->portalname;
-            bool forward;
-            int count;
-
-            commandTag = "FETCH";
-            CHECK_IF_ABORTED();
-
-            forward = (bool)(stmt->direction == FORWARD);
-
-            /* parser ensures that count is >= 0 and 
-               'fetch ALL' -> 0 */
-               
-            count = stmt->howMany;
-            PerformPortalFetch(portalName, forward, count, commandTag, dest);
-        }
-        break;
-      
-        /* ********************************
-         *      relation and attribute manipulation
-         * ********************************
-         */
-    case T_CreateStmt:
-        commandTag = "CREATE";
-        CHECK_IF_ABORTED();
-      
-        DefineRelation((CreateStmt *)parsetree);
-        break;
-      
-    case T_DestroyStmt:
-        {
-            DestroyStmt *stmt = (DestroyStmt *)parsetree;
-            List *arg;
-            List *args = stmt->relNames;
-            Relation rel;
-
-            commandTag = "DROP";
-            CHECK_IF_ABORTED();
-
-            foreach (arg, args) {
-                relname = strVal(lfirst(arg));
-                if (IsSystemRelationName(relname))
-                    elog(WARN, "class \"%-.*s\" is a system catalog",
-                         NAMEDATALEN, relname);
-                rel = heap_openr (relname);
-                if ( RelationIsValid (rel) )
-                {
-                    if ( stmt->sequence && 
-                               rel->rd_rel->relkind != RELKIND_SEQUENCE )
-                       elog (WARN, "Use DROP TABLE to drop table '%s'",
-                               relname);
-                    if ( !(stmt->sequence) && 
-                               rel->rd_rel->relkind == RELKIND_SEQUENCE )
-                       elog (WARN, "Use DROP SEQUENCE to drop sequence '%s'",
-                               relname);
-                    heap_close (rel);
-                }
-#ifndef NO_SECURITY
-                if (!pg_ownercheck(userName, relname, RELNAME))
-                    elog(WARN, "you do not own class \"%-.*s\"",
-                         NAMEDATALEN, relname);
-#endif
-            }
-            foreach (arg, args) {
-                relname = strVal(lfirst(arg));
-                RemoveRelation(relname);
-            }
-        }
-        break;
-      
-    case T_PurgeStmt:
-        {
-            PurgeStmt *stmt = (PurgeStmt *)parsetree;
-
-            commandTag = "PURGE";
-            CHECK_IF_ABORTED();
-            
-            RelationPurge(stmt->relname,
-                          stmt->beforeDate, /* absolute time string */
-                          stmt->afterDate); /* relative time string */
-        }
-        break;
-      
-    case T_CopyStmt:
-        {
-            CopyStmt *stmt = (CopyStmt *)parsetree;
-
-           commandTag = "COPY";
-           CHECK_IF_ABORTED();
-           
-           /* Free up file descriptors - going to do a read... */
-           closeOneVfd();
-
-           DoCopy(stmt->relname, 
-                   stmt->binary, 
-                   stmt->oids, 
-                   (bool)(stmt->direction == FROM), 
-                   (bool)(stmt->filename == NULL), 
-                      /* null filename means copy to/from stdout/stdin,
-                         rather than to/from a file.
-                         */
-                   stmt->filename, 
-                   stmt->delimiter);
-       }
-       break;
-      
-    case T_AddAttrStmt:
-       {
-           AddAttrStmt *stmt = (AddAttrStmt *)parsetree;
-
-           commandTag = "ADD";
-           CHECK_IF_ABORTED();
-       
-           /* owner checking done in PerformAddAttribute (now recursive) */
-           PerformAddAttribute(stmt->relname,
-                               userName,
-                               stmt->inh,
-                               stmt->colDef);
-       }
-       break;
-      
-       /*
-        * schema
-        */
-    case T_RenameStmt:
-       {
-           RenameStmt *stmt = (RenameStmt *)parsetree;
-
-           commandTag = "RENAME";
-           CHECK_IF_ABORTED();
-       
-           relname = stmt->relname;
-           if (IsSystemRelationName(relname))
-               elog(WARN, "class \"%s\" is a system catalog",
-                    relname);
-#ifndef NO_SECURITY
-           if (!pg_ownercheck(userName, relname, RELNAME))
-               elog(WARN, "you do not own class \"%s\"",
-                    relname);
-#endif
-           
-           /* ----------------
-            *  XXX using len == 3 to tell the difference
-            *      between "rename rel to newrel" and
-            *      "rename att in rel to newatt" will not
-            *      work soon because "rename type/operator/rule"
-            *      stuff is being added. - cim 10/24/90
-            * ----------------
-            * [another piece of amuzing but useless anecdote -- ay]
-            */
-           if (stmt->column == NULL) {
-               /* ----------------
-                *      rename relation
-                *
-                *      Note: we also rename the "type" tuple
-                *      corresponding to the relation.
-                * ----------------
-                */
-               renamerel(relname, /* old name */
-                         stmt->newname); /* new name */
-               TypeRename(relname, /* old name */
-                          stmt->newname); /* new name */
-           } else {
-               /* ----------------
-                *      rename attribute
-                * ----------------
-                */
-               renameatt(relname, /* relname */
-                         stmt->column, /* old att name */
-                         stmt->newname, /* new att name */
-                         userName,
-                         stmt->inh); /* recursive? */
-           }
-       }
-       break;
-      
-    case T_ChangeACLStmt:
-       {
-           ChangeACLStmt *stmt = (ChangeACLStmt *)parsetree;
-           List *i;
-           AclItem *aip;
-           unsigned modechg;
-
-           commandTag = "CHANGE";
-           CHECK_IF_ABORTED();
-           
-           aip = stmt->aclitem;
-           modechg = stmt->modechg;
-#ifndef NO_SECURITY
-           foreach (i, stmt->relNames) {
-               relname = strVal(lfirst(i));
-               if (!pg_ownercheck(userName, relname, RELNAME))
-                   elog(WARN, "you do not own class \"%-.*s\"",
-                        NAMEDATALEN, relname);
-           }
-#endif
-           foreach (i, stmt->relNames) {
-               relname = strVal(lfirst(i));
-               ChangeAcl(relname, aip, modechg);
-           }
+       char       *commandTag = NULL;
+       char       *relname;
+       char       *relationName;
+       char       *userName;
 
-       }
-       break;
-      
-       /* ********************************
-        *      object creation / destruction
-        * ********************************
-        */
-    case T_DefineStmt:
-       {
-           DefineStmt *stmt = (DefineStmt *)parsetree;
-
-           commandTag = "CREATE";
-           CHECK_IF_ABORTED();
-
-           switch(stmt->defType) {
-           case OPERATOR:
-               DefineOperator(stmt->defname, /* operator name */
-                              stmt->definition); /* rest */
-               break;
-           case P_TYPE:
-               {
-                   DefineType (stmt->defname, stmt->definition);
-               }
-               break;
-           case AGGREGATE:
-               DefineAggregate(stmt->defname, /*aggregate name */
-                               stmt->definition); /* rest */
-               break;
-           }
-       }
-       break;
-      
-    case T_ViewStmt:           /* CREATE VIEW */
-       {
-           ViewStmt *stmt = (ViewStmt *)parsetree;
+       userName = GetPgUserName();
 
-           commandTag = "CREATE";
-           CHECK_IF_ABORTED();
-           DefineView (stmt->viewname, stmt->query); /* retrieve parsetree */
-       }
-       break;
-      
-    case T_ProcedureStmt:      /* CREATE FUNCTION */
-       commandTag = "CREATE";
-       CHECK_IF_ABORTED();
-       CreateFunction((ProcedureStmt *)parsetree, dest); /* everything */
-       break;
-      
-    case T_IndexStmt:           /* CREATE INDEX */
-       {
-           IndexStmt *stmt = (IndexStmt *)parsetree;
-
-           commandTag = "CREATE";
-           CHECK_IF_ABORTED();
-           /* XXX no support for ARCHIVE indices, yet */
-           DefineIndex(stmt->relname, /* relation name */
-                       stmt->idxname, /* index name */
-                       stmt->accessMethod, /* am name */
-                       stmt->indexParams, /* parameters */
-                       stmt->withClause,
-                       stmt->unique,
-                       (Expr*)stmt->whereClause,
-                       stmt->rangetable);
-       }
-       break;
-      
-    case T_RuleStmt:            /* CREATE RULE */
+       switch (nodeTag(parsetree))
        {
-           RuleStmt *stmt = (RuleStmt *)parsetree;
-           int aclcheck_result;
 
+                       /*
+                        * ******************************** transactions ********************************
+                        *
+                        */
+               case T_TransactionStmt:
+                       {
+                               TransactionStmt *stmt = (TransactionStmt *) parsetree;
+
+                               switch (stmt->command)
+                               {
+                                       case BEGIN_TRANS:
+                                               *ps_status = commandTag = "BEGIN";
+                                               CHECK_IF_ABORTED();
+                                               BeginTransactionBlock();
+                                               break;
+
+                                       case END_TRANS:
+                                               *ps_status = commandTag = "END";
+                                               EndTransactionBlock();
+                                               break;
+
+                                       case ABORT_TRANS:
+                                               *ps_status = commandTag = "ABORT";
+                                               UserAbortTransactionBlock();
+                                               break;
+                               }
+                       }
+                       break;
+
+                       /*
+                        * ******************************** portal manipulation ********************************
+                        *
+                        */
+               case T_ClosePortalStmt:
+                       {
+                               ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
+
+                               *ps_status = commandTag = "CLOSE";
+                               CHECK_IF_ABORTED();
+
+                               PerformPortalClose(stmt->portalname, dest);
+                       }
+                       break;
+
+               case T_FetchStmt:
+                       {
+                               FetchStmt  *stmt = (FetchStmt *) parsetree;
+                               char       *portalName = stmt->portalname;
+                               bool            forward;
+                               int                     count;
+
+                               *ps_status = commandTag = (stmt->ismove) ? "MOVE" : "FETCH";
+                               CHECK_IF_ABORTED();
+
+                               forward = (bool) (stmt->direction == FORWARD);
+
+                               /*
+                                * parser ensures that count is >= 0 and 'fetch ALL' -> 0
+                                */
+
+                               count = stmt->howMany;
+                               PerformPortalFetch(portalName, forward, count, commandTag,
+                                                                  (stmt->ismove) ? None : dest);               /* /dev/null for MOVE */
+                       }
+                       break;
+
+                       /*
+                        * ******************************** relation and attribute
+                        * manipulation ********************************
+                        *
+                        */
+               case T_CreateStmt:
+                       *ps_status = commandTag = "CREATE";
+                       CHECK_IF_ABORTED();
+
+                       DefineRelation((CreateStmt *) parsetree);
+                       break;
+
+               case T_DestroyStmt:
+                       {
+                               DestroyStmt *stmt = (DestroyStmt *) parsetree;
+                               List       *arg;
+                               List       *args = stmt->relNames;
+                               Relation        rel;
+
+                               *ps_status = commandTag = "DROP";
+                               CHECK_IF_ABORTED();
+
+                               foreach(arg, args)
+                               {
+                                       relname = strVal(lfirst(arg));
+                                       if (IsSystemRelationName(relname))
+                                               elog(ERROR, "class \"%s\" is a system catalog",
+                                                        relname);
+                                       rel = heap_openr(relname);
+                                       if (RelationIsValid(rel))
+                                       {
+                                               if (stmt->sequence &&
+                                                       rel->rd_rel->relkind != RELKIND_SEQUENCE)
+                                                       elog(ERROR, "Use DROP TABLE to drop table '%s'",
+                                                                relname);
+                                               if (!(stmt->sequence) &&
+                                                       rel->rd_rel->relkind == RELKIND_SEQUENCE)
+                                                       elog(ERROR, "Use DROP SEQUENCE to drop sequence '%s'",
+                                                                relname);
+                                               heap_close(rel);
+                                       }
 #ifndef NO_SECURITY
-           relname = stmt->object->relname;
-           aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
-           if(aclcheck_result != ACLCHECK_OK)
-               elog(WARN, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]); 
+                                       if (!pg_ownercheck(userName, relname, RELNAME))
+                                               elog(ERROR, "you do not own class \"%s\"",
+                                                        relname);
 #endif
-           commandTag = "CREATE";
-           CHECK_IF_ABORTED();
-           DefineQueryRewrite(stmt);
-       }
-       break;
-
-    case T_CreateSeqStmt:
-        commandTag = "CREATE";
-        CHECK_IF_ABORTED();
-      
-        DefineSequence((CreateSeqStmt *)parsetree);
-        break;
-      
-    case T_ExtendStmt:
-       {
-           ExtendStmt *stmt = (ExtendStmt *)parsetree;
-
-           commandTag = "EXTEND";
-           CHECK_IF_ABORTED();
-       
-           ExtendIndex(stmt->idxname, /* index name */
-                       (Expr*)stmt->whereClause, /* where */
-                       stmt->rangetable);
-       }
-       break;
-      
-    case T_RemoveStmt:
-       {
-           RemoveStmt *stmt = (RemoveStmt *)parsetree;
-
-           commandTag = "DROP";
-           CHECK_IF_ABORTED();
-       
-           switch(stmt->removeType) {
-           case INDEX:
-               relname = stmt->name;
-               if (IsSystemRelationName(relname))
-                   elog(WARN, "class \"%s\" is a system catalog index",
-                        relname);
+                               }
+                               foreach(arg, args)
+                               {
+                                       relname = strVal(lfirst(arg));
+                                       RemoveRelation(relname);
+                               }
+                       }
+                       break;
+
+               case T_CopyStmt:
+                       {
+                               CopyStmt   *stmt = (CopyStmt *) parsetree;
+
+                               *ps_status = commandTag = "COPY";
+                               CHECK_IF_ABORTED();
+
+                               DoCopy(stmt->relname,
+                                          stmt->binary,
+                                          stmt->oids,
+                                          (bool) (stmt->direction == FROM),
+                                          (bool) (stmt->filename == NULL),
+
+                               /*
+                                * null filename means copy to/from stdout/stdin, rather
+                                * than to/from a file.
+                                */
+                                          stmt->filename,
+                                          stmt->delimiter);
+                       }
+                       break;
+
+               case T_AddAttrStmt:
+                       {
+                               AddAttrStmt *stmt = (AddAttrStmt *) parsetree;
+
+                               *ps_status = commandTag = "ADD";
+                               CHECK_IF_ABORTED();
+
+                               /*
+                                * owner checking done in PerformAddAttribute (now
+                                * recursive)
+                                */
+                               PerformAddAttribute(stmt->relname,
+                                                                       userName,
+                                                                       stmt->inh,
+                                                                       (ColumnDef *) stmt->colDef);
+                       }
+                       break;
+
+                       /*
+                        * schema
+                        */
+               case T_RenameStmt:
+                       {
+                               RenameStmt *stmt = (RenameStmt *) parsetree;
+
+                               *ps_status = commandTag = "RENAME";
+                               CHECK_IF_ABORTED();
+
+                               relname = stmt->relname;
+                               if (IsSystemRelationName(relname))
+                                       elog(ERROR, "class \"%s\" is a system catalog",
+                                                relname);
 #ifndef NO_SECURITY
-               if (!pg_ownercheck(userName, relname, RELNAME))
-                   elog(WARN, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+                               if (!pg_ownercheck(userName, relname, RELNAME))
+                                       elog(ERROR, "you do not own class \"%s\"",
+                                                relname);
 #endif
-               RemoveIndex(relname);
-               break;
-           case RULE:
-               {
-                   char *rulename = stmt->name;
-                   int aclcheck_result;
+
+                               /* ----------------
+                                *      XXX using len == 3 to tell the difference
+                                *              between "rename rel to newrel" and
+                                *              "rename att in rel to newatt" will not
+                                *              work soon because "rename type/operator/rule"
+                                *              stuff is being added. - cim 10/24/90
+                                * ----------------
+                                * [another piece of amuzing but useless anecdote -- ay]
+                                */
+                               if (stmt->column == NULL)
+                               {
+                                       /* ----------------
+                                        *              rename relation
+                                        *
+                                        *              Note: we also rename the "type" tuple
+                                        *              corresponding to the relation.
+                                        * ----------------
+                                        */
+                                       renamerel(relname,      /* old name */
+                                                         stmt->newname);       /* new name */
+                                       TypeRename(relname, /* old name */
+                                                          stmt->newname);      /* new name */
+                               }
+                               else
+                               {
+                                       /* ----------------
+                                        *              rename attribute
+                                        * ----------------
+                                        */
+                                       renameatt(relname,      /* relname */
+                                                         stmt->column,         /* old att name */
+                                                         stmt->newname,        /* new att name */
+                                                         userName,
+                                                         stmt->inh);           /* recursive? */
+                               }
+                       }
+                       break;
+
+               case T_ChangeACLStmt:
+                       {
+                               ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
+                               List       *i;
+                               AclItem    *aip;
+                               unsigned        modechg;
+
+                               *ps_status = commandTag = "CHANGE";
+                               CHECK_IF_ABORTED();
+
+                               aip = stmt->aclitem;
+
+                               modechg = stmt->modechg;
 #ifndef NO_SECURITY
-               
-                   relationName = RewriteGetRuleEventRel(rulename);
-                   aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
-                   if(aclcheck_result != ACLCHECK_OK) {
-                       elog(WARN, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
-                   }
+                               foreach(i, stmt->relNames)
+                               {
+                                       relname = strVal(lfirst(i));
+                                       if (!pg_ownercheck(userName, relname, RELNAME))
+                                               elog(ERROR, "you do not own class \"%s\"",
+                                                        relname);
+                               }
 #endif
-                   RemoveRewriteRule(rulename);
-               }
-               break;
-           case P_TYPE:
+                               foreach(i, stmt->relNames)
+                               {
+                                       relname = strVal(lfirst(i));
+                                       ChangeAcl(relname, aip, modechg);
+                               }
+
+                       }
+                       break;
+
+                       /*
+                        * ******************************** object creation /
+                        * destruction ********************************
+                        *
+                        */
+               case T_DefineStmt:
+                       {
+                               DefineStmt *stmt = (DefineStmt *) parsetree;
+
+                               *ps_status = commandTag = "CREATE";
+                               CHECK_IF_ABORTED();
+
+                               switch (stmt->defType)
+                               {
+                                       case OPERATOR:
+                                               DefineOperator(stmt->defname,   /* operator name */
+                                                                          stmt->definition);           /* rest */
+                                               break;
+                                       case TYPE_P:
+                                                       DefineType(stmt->defname, stmt->definition);
+                                               break;
+                                       case AGGREGATE:
+                                               DefineAggregate(stmt->defname,  /* aggregate name */
+                                                                               stmt->definition);              /* rest */
+                                               break;
+                               }
+                       }
+                       break;
+
+               case T_ViewStmt:                /* CREATE VIEW */
+                       {
+                               ViewStmt   *stmt = (ViewStmt *) parsetree;
+
+                               *ps_status = commandTag = "CREATE";
+                               CHECK_IF_ABORTED();
+                               DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
+                       }
+                       break;
+
+               case T_ProcedureStmt:   /* CREATE FUNCTION */
+                       *ps_status = commandTag = "CREATE";
+                       CHECK_IF_ABORTED();
+                       CreateFunction((ProcedureStmt *) parsetree, dest);      /* everything */
+                       break;
+
+               case T_IndexStmt:               /* CREATE INDEX */
+                       {
+                               IndexStmt  *stmt = (IndexStmt *) parsetree;
+
+                               *ps_status = commandTag = "CREATE";
+                               CHECK_IF_ABORTED();
+                               DefineIndex(stmt->relname,              /* relation name */
+                                                       stmt->idxname,          /* index name */
+                                                       stmt->accessMethod, /* am name */
+                                                       stmt->indexParams,      /* parameters */
+                                                       stmt->withClause,
+                                                       stmt->unique,
+                                                       (Expr *) stmt->whereClause,
+                                                       stmt->rangetable);
+                       }
+                       break;
+
+               case T_RuleStmt:                /* CREATE RULE */
+                       {
+                               RuleStmt   *stmt = (RuleStmt *) parsetree;
+                               int                     aclcheck_result;
+
 #ifndef NO_SECURITY
-               /* XXX moved to remove.c */
+                               relname = stmt->object->relname;
+                               aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
+                               if (aclcheck_result != ACLCHECK_OK)
+                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
 #endif
-               RemoveType(stmt->name);
-               break;
-           case VIEW:
-               {
-                   char *viewName = stmt->name;
-                   char *ruleName;
-                   extern char *RewriteGetRuleEventRel();
-
+                               *ps_status = commandTag = "CREATE";
+                               CHECK_IF_ABORTED();
+                               DefineQueryRewrite(stmt);
+                       }
+                       break;
+
+               case T_CreateSeqStmt:
+                       *ps_status = commandTag = "CREATE";
+                       CHECK_IF_ABORTED();
+
+                       DefineSequence((CreateSeqStmt *) parsetree);
+                       break;
+
+               case T_ExtendStmt:
+                       {
+                               ExtendStmt *stmt = (ExtendStmt *) parsetree;
+
+                               *ps_status = commandTag = "EXTEND";
+                               CHECK_IF_ABORTED();
+
+                               ExtendIndex(stmt->idxname,              /* index name */
+                                                       (Expr *) stmt->whereClause, /* where */
+                                                       stmt->rangetable);
+                       }
+                       break;
+
+               case T_RemoveStmt:
+                       {
+                               RemoveStmt *stmt = (RemoveStmt *) parsetree;
+
+                               *ps_status = commandTag = "DROP";
+                               CHECK_IF_ABORTED();
+
+                               switch (stmt->removeType)
+                               {
+                                       case INDEX:
+                                               relname = stmt->name;
+                                               if (IsSystemRelationName(relname))
+                                                       elog(ERROR, "class \"%s\" is a system catalog index",
+                                                                relname);
 #ifndef NO_SECURITY
-               
-                   ruleName = MakeRetrieveViewRuleName(viewName);
-                   relationName = RewriteGetRuleEventRel(ruleName);
-                   if (!pg_ownercheck(userName, relationName, RELNAME))
-                       elog(WARN, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
-                   pfree(ruleName);
+                                               if (!pg_ownercheck(userName, relname, RELNAME))
+                                                       elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
 #endif
-                   RemoveView(viewName);
-               }
-               break;
-           }
-           break;
-       }
-       break;
+                                               RemoveIndex(relname);
+                                               break;
+                                       case RULE:
+                                               {
+                                                       char       *rulename = stmt->name;
+                                                       int                     aclcheck_result;
 
-    case T_RemoveAggrStmt:
-       {
-           RemoveAggrStmt *stmt = (RemoveAggrStmt *)parsetree;
-           commandTag = "DROP";
-           CHECK_IF_ABORTED();
-           RemoveAggregate(stmt->aggname, stmt->aggtype);
-       }
-       break;
-      
-    case T_RemoveFuncStmt:
-       {
-           RemoveFuncStmt *stmt = (RemoveFuncStmt *)parsetree;
-           commandTag = "DROP";
-           CHECK_IF_ABORTED();
-           RemoveFunction(stmt->funcname,
-                          length(stmt->args),
-                          stmt->args);
-       }
-       break;
-      
-    case T_RemoveOperStmt:
-       {
-           RemoveOperStmt *stmt = (RemoveOperStmt *)parsetree;
-           char* type1 = (char*) NULL; 
-           char *type2 = (char*) NULL;
-               
-           commandTag = "DROP";
-           CHECK_IF_ABORTED();
-
-           if (lfirst(stmt->args)!=NULL)
-               type1 = strVal(lfirst(stmt->args));
-           if (lsecond(stmt->args)!=NULL)
-               type2 = strVal(lsecond(stmt->args));
-           RemoveOperator(stmt->opname, type1, type2);
-       }
-       break;
-      
-    case T_VersionStmt:
-       {
-           elog(WARN, "CREATE VERSION is not currently implemented");
-       }
-       break;
-      
-    case T_CreatedbStmt:
-       {
-           CreatedbStmt *stmt = (CreatedbStmt *)parsetree;
-
-           commandTag = "CREATEDB";
-           CHECK_IF_ABORTED();
-           createdb(stmt->dbname);
-       }
-       break;
-      
-    case T_DestroydbStmt:
-       {
-           DestroydbStmt *stmt = (DestroydbStmt *)parsetree;
-
-           commandTag = "DESTROYDB";
-           CHECK_IF_ABORTED();
-           destroydb(stmt->dbname);
-       }
-       break;
-      
-       /* Query-level asynchronous notification */
-    case T_NotifyStmt:
-       {
-           NotifyStmt *stmt = (NotifyStmt *)parsetree;
-
-           commandTag = "NOTIFY";
-           CHECK_IF_ABORTED();
-
-           Async_Notify(stmt->relname);
-       }
-       break;
-      
-    case T_ListenStmt:
-       {
-           ListenStmt *stmt = (ListenStmt *)parsetree;
-
-           commandTag = "LISTEN";
-           CHECK_IF_ABORTED();
-
-           Async_Listen(stmt->relname,MasterPid);
-       }
-       break;
-      
-       /* ********************************
-        *      dynamic loader
-        * ********************************
-        */
-    case T_LoadStmt:
-       {
-           LoadStmt *stmt = (LoadStmt *)parsetree;
-           FILE *fp, *fopen();
-           char *filename;
-
-           commandTag = "LOAD";
-           CHECK_IF_ABORTED();
-
-           filename = stmt->filename;
-           closeAllVfds();
-           if ((fp = fopen(filename, "r")) == NULL)
-               elog(WARN, "LOAD: could not open file %s", filename);
-           fclose(fp);
-           load_file(filename);
-       }
-       break;
-
-    case T_ClusterStmt:
-       {
-           ClusterStmt *stmt = (ClusterStmt *)parsetree;
-
-           commandTag = "CLUSTER";
-           CHECK_IF_ABORTED();
+#ifndef NO_SECURITY
 
-           cluster(stmt->relname, stmt->indexname);
-       }
-       break;
-       
-    case T_VacuumStmt:
-       commandTag = "VACUUM";
-       CHECK_IF_ABORTED();
-       vacuum( ((VacuumStmt *) parsetree)->vacrel,
-               ((VacuumStmt *) parsetree)->verbose,
-               ((VacuumStmt *) parsetree)->analyze,
-               ((VacuumStmt *) parsetree)->va_spec);
-       break;
-
-    case T_ExplainStmt:
-       {
-           ExplainStmt *stmt = (ExplainStmt *)parsetree;
+                                                       relationName = RewriteGetRuleEventRel(rulename);
+                                                       aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
+                                                       if (aclcheck_result != ACLCHECK_OK)
+                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
+#endif
+                                                       RemoveRewriteRule(rulename);
+                                               }
+                                               break;
+                                       case TYPE_P:
+#ifndef NO_SECURITY
+                                               /* XXX moved to remove.c */
+#endif
+                                               RemoveType(stmt->name);
+                                               break;
+                                       case VIEW:
+                                               {
+                                                       char       *viewName = stmt->name;
+                                                       char       *ruleName;
 
-           commandTag = "EXPLAIN";
-           CHECK_IF_ABORTED();
+#ifndef NO_SECURITY
 
-           ExplainQuery(stmt->query, stmt->verbose, dest);
-       }
-       break;
-       
-       /* ********************************
-          Tioga-related statements
-          *********************************/
-    case T_RecipeStmt:
-       {
-           RecipeStmt* stmt = (RecipeStmt*)parsetree;
-           commandTag="EXECUTE RECIPE";
-           CHECK_IF_ABORTED();
-           beginRecipe(stmt);
+                                                       ruleName = MakeRetrieveViewRuleName(viewName);
+                                                       relationName = RewriteGetRuleEventRel(ruleName);
+                                                       if (!pg_ownercheck(userName, relationName, RELNAME))
+                                                               elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
+                                                       pfree(ruleName);
+#endif
+                                                       RemoveView(viewName);
+                                               }
+                                               break;
+                               }
+                               break;
+                       }
+                       break;
+
+               case T_RemoveAggrStmt:
+                       {
+                               RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
+
+                               *ps_status = commandTag = "DROP";
+                               CHECK_IF_ABORTED();
+                               RemoveAggregate(stmt->aggname, stmt->aggtype);
+                       }
+                       break;
+
+               case T_RemoveFuncStmt:
+                       {
+                               RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
+
+                               *ps_status = commandTag = "DROP";
+                               CHECK_IF_ABORTED();
+                               RemoveFunction(stmt->funcname,
+                                                          length(stmt->args),
+                                                          stmt->args);
+                       }
+                       break;
+
+               case T_RemoveOperStmt:
+                       {
+                               RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
+                               char       *type1 = (char *) NULL;
+                               char       *type2 = (char *) NULL;
+
+                               *ps_status = commandTag = "DROP";
+                               CHECK_IF_ABORTED();
+
+                               if (lfirst(stmt->args) != NULL)
+                                       type1 = strVal(lfirst(stmt->args));
+                               if (lsecond(stmt->args) != NULL)
+                                       type2 = strVal(lsecond(stmt->args));
+                               RemoveOperator(stmt->opname, type1, type2);
+                       }
+                       break;
+
+               case T_VersionStmt:
+                               elog(ERROR, "CREATE VERSION is not currently implemented");
+                       break;
+
+               case T_CreatedbStmt:
+                       {
+                               CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
+
+                               *ps_status = commandTag = "CREATEDB";
+                               CHECK_IF_ABORTED();
+#ifdef MULTIBYTE
+                               createdb(stmt->dbname, stmt->dbpath, stmt->encoding);
+#else
+                               createdb(stmt->dbname, stmt->dbpath);
+#endif
+                       }
+                       break;
+
+               case T_DestroydbStmt:
+                       {
+                               DestroydbStmt *stmt = (DestroydbStmt *) parsetree;
+
+                               *ps_status = commandTag = "DESTROYDB";
+                               CHECK_IF_ABORTED();
+                               destroydb(stmt->dbname);
+                       }
+                       break;
+
+                       /* Query-level asynchronous notification */
+               case T_NotifyStmt:
+                       {
+                               NotifyStmt *stmt = (NotifyStmt *) parsetree;
+
+                               *ps_status = commandTag = "NOTIFY";
+                               CHECK_IF_ABORTED();
+
+                               Async_Notify(stmt->relname);
+                       }
+                       break;
+
+               case T_ListenStmt:
+                       {
+                               ListenStmt *stmt = (ListenStmt *) parsetree;
+
+                               *ps_status = commandTag = "LISTEN";
+                               CHECK_IF_ABORTED();
+
+                               Async_Listen(stmt->relname, MyProcPid);
+                       }
+                       break;
+
+                       /*
+                        * ******************************** dynamic loader ********************************
+                        *
+                        */
+               case T_LoadStmt:
+                       {
+                               LoadStmt   *stmt = (LoadStmt *) parsetree;
+                               FILE       *fp;
+                               char       *filename;
+
+                               *ps_status = commandTag = "LOAD";
+                               CHECK_IF_ABORTED();
+
+                               filename = stmt->filename;
+                               closeAllVfds();
+                               if ((fp = AllocateFile(filename, "r")) == NULL)
+                                       elog(ERROR, "LOAD: could not open file %s", filename);
+                               FreeFile(fp);
+                               load_file(filename);
+                       }
+                       break;
+
+               case T_ClusterStmt:
+                       {
+                               ClusterStmt *stmt = (ClusterStmt *) parsetree;
+
+                               *ps_status = commandTag = "CLUSTER";
+                               CHECK_IF_ABORTED();
+
+                               cluster(stmt->relname, stmt->indexname);
+                       }
+                       break;
+
+               case T_VacuumStmt:
+                       *ps_status = commandTag = "VACUUM";
+                       CHECK_IF_ABORTED();
+                       vacuum(((VacuumStmt *) parsetree)->vacrel,
+                                  ((VacuumStmt *) parsetree)->verbose,
+                                  ((VacuumStmt *) parsetree)->analyze,
+                                  ((VacuumStmt *) parsetree)->va_spec);
+                       break;
+
+               case T_ExplainStmt:
+                       {
+                               ExplainStmt *stmt = (ExplainStmt *) parsetree;
+
+                               *ps_status = commandTag = "EXPLAIN";
+                               CHECK_IF_ABORTED();
+
+                               ExplainQuery(stmt->query, stmt->verbose, dest);
+                       }
+                       break;
+
+                       /*
+                        * ******************************** Tioga-related statements *******************************
+                        */
+               case T_RecipeStmt:
+                       {
+                               RecipeStmt *stmt = (RecipeStmt *) parsetree;
+
+                               *ps_status = commandTag = "EXECUTE RECIPE";
+                               CHECK_IF_ABORTED();
+                               beginRecipe(stmt);
+                       }
+                       break;
+
+                       /*
+                        * ******************************** set variable statements *******************************
+                        */
+               case T_VariableSetStmt:
+                       {
+                               VariableSetStmt *n = (VariableSetStmt *) parsetree;
+
+                               SetPGVariable(n->name, n->value);
+                               *ps_status = commandTag = "SET VARIABLE";
+                       }
+                       break;
+
+               case T_VariableShowStmt:
+                       {
+                               VariableShowStmt *n = (VariableShowStmt *) parsetree;
+
+                               GetPGVariable(n->name);
+                               *ps_status = commandTag = "SHOW VARIABLE";
+                       }
+                       break;
+
+               case T_VariableResetStmt:
+                       {
+                               VariableResetStmt *n = (VariableResetStmt *) parsetree;
+
+                               ResetPGVariable(n->name);
+                               *ps_status = commandTag = "RESET VARIABLE";
+                       }
+                       break;
+
+                       /*
+                        * ******************************** TRIGGER statements *******************************
+                        */
+               case T_CreateTrigStmt:
+                       *ps_status = commandTag = "CREATE";
+                       CHECK_IF_ABORTED();
+
+                       CreateTrigger((CreateTrigStmt *) parsetree);
+                       break;
+
+               case T_DropTrigStmt:
+                       *ps_status = commandTag = "DROP";
+                       CHECK_IF_ABORTED();
+
+                       DropTrigger((DropTrigStmt *) parsetree);
+                       break;
+
+                       /*
+                        * ************* PROCEDURAL LANGUAGE statements *****************
+                        */
+               case T_CreatePLangStmt:
+                       *ps_status = commandTag = "CREATE";
+                       CHECK_IF_ABORTED();
+
+                       CreateProceduralLanguage((CreatePLangStmt *) parsetree);
+                       break;
+
+               case T_DropPLangStmt:
+                       *ps_status = commandTag = "DROP";
+                       CHECK_IF_ABORTED();
+
+                       DropProceduralLanguage((DropPLangStmt *) parsetree);
+                       break;
+
+                       /*
+                        * ******************************** USER statements ****
+                        *
+                        */
+               case T_CreateUserStmt:
+                       *ps_status = commandTag = "CREATE USER";
+                       CHECK_IF_ABORTED();
+
+                       DefineUser((CreateUserStmt *) parsetree);
+                       break;
+
+               case T_AlterUserStmt:
+                       *ps_status = commandTag = "ALTER USER";
+                       CHECK_IF_ABORTED();
+
+                       AlterUser((AlterUserStmt *) parsetree);
+                       break;
+
+               case T_DropUserStmt:
+                       *ps_status = commandTag = "DROP USER";
+                       CHECK_IF_ABORTED();
+
+                       RemoveUser(((DropUserStmt *) parsetree)->user);
+                       break;
+
+
+                       /*
+                        * ******************************** default ********************************
+                        *
+                        */
+               default:
+                       elog(ERROR, "ProcessUtility: command #%d unsupported",
+                                nodeTag(parsetree));
+                       break;
        }
-       break;
 
-       /* ********************************
-        * set variable statements
-        *********************************/
-    case T_VariableSetStmt:
-       {
-           VariableSetStmt *n = (VariableSetStmt *) parsetree;
-           SetPGVariable(n->name, n->value);
-           commandTag = "SET VARIABLE";
-       }
-       break;
-      
-    case T_VariableShowStmt:
-       {
-           VariableShowStmt *n = (VariableShowStmt *) parsetree;
-           GetPGVariable(n->name);
-           commandTag = "SHOW VARIABLE";
-       }
-       break;
-      
-    case T_VariableResetStmt:
-       {
-           VariableResetStmt *n = (VariableResetStmt *) parsetree;
-           ResetPGVariable(n->name);
-           commandTag = "RESET VARIABLE";
-       }
-       break;
-      
-       /* ********************************
-        *      default
-        * ********************************
+       /* ----------------
+        *      tell fe/be or whatever that we're done.
+        * ----------------
         */
-    default:
-       elog(WARN, "ProcessUtility: command #%d unsupported",
-            nodeTag(parsetree));
-       break;
-    }
-    
-    /* ----------------
-     * tell fe/be or whatever that we're done.
-     * ----------------
-     */
-    EndCommand(commandTag, dest);
+       EndCommand(commandTag, dest);
 }
-