OSDN Git Service

Fixed everything in and surrounding createdb and dropdb to make it more
[pg-rex/syncrep.git] / src / backend / tcop / utility.c
1 /*-------------------------------------------------------------------------
2  *
3  * utility.c
4  *        Contains functions which control the execution of the POSTGRES utility
5  *        commands.  At one time acted as an interface between the Lisp and C
6  *        systems.
7  *
8  * Copyright (c) 1994, Regents of the University of California
9  *
10  *
11  * IDENTIFICATION
12  *        $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.77 2000/01/13 18:26:10 petere Exp $
13  *
14  *-------------------------------------------------------------------------
15  */
16 #include "postgres.h"
17
18 #include "access/heapam.h"
19 #include "catalog/catalog.h"
20 #include "catalog/pg_type.h"
21 #include "commands/async.h"
22 #include "commands/cluster.h"
23 #include "commands/command.h"
24 #include "commands/comment.h"
25 #include "commands/copy.h"
26 #include "commands/creatinh.h"
27 #include "commands/dbcommands.h"
28 #include "commands/defrem.h"
29 #include "commands/explain.h"
30 #include "commands/proclang.h"
31 #include "commands/rename.h"
32 #include "commands/sequence.h"
33 #include "commands/trigger.h"
34 #include "commands/user.h"
35 #include "commands/vacuum.h"
36 #include "commands/variable.h"
37 #include "commands/view.h"
38 #include "miscadmin.h"
39 #include "parser/parse.h"
40 #include "rewrite/rewriteDefine.h"
41 #include "rewrite/rewriteRemove.h"
42 #include "tcop/utility.h"
43 #include "utils/acl.h"
44 #include "utils/ps_status.h"
45 #include "utils/syscache.h"
46
47
48 /* ----------------
49  *              CHECK_IF_ABORTED() is used to avoid doing unnecessary
50  *              processing within an aborted transaction block.
51  * ----------------
52  */
53  /* we have to use IF because of the 'break' */
54 #define CHECK_IF_ABORTED() \
55 if (1) \
56 { \
57         if (IsAbortedTransactionBlockState()) \
58         { \
59                 elog(NOTICE, "(transaction aborted): %s", \
60                          "all queries ignored until end of transaction block"); \
61                 commandTag = "*ABORT STATE*"; \
62                 break; \
63         } \
64 } else
65
66 /* ----------------
67  *              general utility function invoker
68  * ----------------
69  */
70 void
71 ProcessUtility(Node *parsetree,
72                            CommandDest dest)
73 {
74         char       *commandTag = NULL;
75         char       *relname;
76         char       *relationName;
77         char       *userName;
78
79         userName = GetPgUserName();
80
81         switch (nodeTag(parsetree))
82         {
83
84                         /*
85                          * ******************************** transactions ********************************
86                          *
87                          */
88                 case T_TransactionStmt:
89                         {
90                                 TransactionStmt *stmt = (TransactionStmt *) parsetree;
91
92                                 switch (stmt->command)
93                                 {
94                                         case BEGIN_TRANS:
95                                                 PS_SET_STATUS(commandTag = "BEGIN");
96                                                 CHECK_IF_ABORTED();
97                                                 BeginTransactionBlock();
98                                                 break;
99
100                                         case END_TRANS:
101                                                 PS_SET_STATUS(commandTag = "END");
102                                                 EndTransactionBlock();
103                                                 break;
104
105                                         case ABORT_TRANS:
106                                                 PS_SET_STATUS(commandTag = "ABORT");
107                                                 UserAbortTransactionBlock();
108                                                 break;
109                                 }
110                         }
111                         break;
112
113                         /*
114                          * ******************************** portal manipulation ********************************
115                          *
116                          */
117                 case T_ClosePortalStmt:
118                         {
119                                 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
120
121                                 PS_SET_STATUS(commandTag = "CLOSE");
122                                 CHECK_IF_ABORTED();
123
124                                 PerformPortalClose(stmt->portalname, dest);
125                         }
126                         break;
127
128                 case T_FetchStmt:
129                         {
130                                 FetchStmt  *stmt = (FetchStmt *) parsetree;
131                                 char       *portalName = stmt->portalname;
132                                 bool            forward;
133                                 int                     count;
134
135                                 PS_SET_STATUS(commandTag = (stmt->ismove) ? "MOVE" : "FETCH");
136                                 CHECK_IF_ABORTED();
137
138                                 forward = (bool) (stmt->direction == FORWARD);
139
140                                 /*
141                                  * parser ensures that count is >= 0 and 'fetch ALL' -> 0
142                                  */
143
144                                 count = stmt->howMany;
145                                 PerformPortalFetch(portalName, forward, count, commandTag,
146                                                                    (stmt->ismove) ? None : dest);               /* /dev/null for MOVE */
147                         }
148                         break;
149
150                         /*
151                          * ******************************** relation and attribute
152                          * manipulation ********************************
153                          *
154                          */
155                 case T_CreateStmt:
156                         PS_SET_STATUS(commandTag = "CREATE");
157                         CHECK_IF_ABORTED();
158
159                         DefineRelation((CreateStmt *) parsetree, RELKIND_RELATION);
160                         break;
161
162                 case T_DropStmt:
163                         {
164                                 DropStmt *stmt = (DropStmt *) parsetree;
165                                 List       *args = stmt->relNames;
166                                 List       *arg;
167
168                                 PS_SET_STATUS(commandTag = "DROP");
169                                 CHECK_IF_ABORTED();
170
171                                 /* check as much as we can before we start dropping ... */
172                                 foreach(arg, args)
173                                 {
174                                         Relation        rel;
175
176                                         relname = strVal(lfirst(arg));
177                                         if (!allowSystemTableMods && IsSystemRelationName(relname))
178                                                 elog(ERROR, "class \"%s\" is a system catalog",
179                                                          relname);
180                                         rel = heap_openr(relname, AccessExclusiveLock);
181                                         if (stmt->sequence &&
182                                                 rel->rd_rel->relkind != RELKIND_SEQUENCE)
183                                                 elog(ERROR, "Use DROP TABLE to drop table '%s'",
184                                                          relname);
185                                         if (!(stmt->sequence) &&
186                                                 rel->rd_rel->relkind == RELKIND_SEQUENCE)
187                                                 elog(ERROR, "Use DROP SEQUENCE to drop sequence '%s'",
188                                                          relname);
189                                         /* close rel, but keep lock until end of xact */
190                                         heap_close(rel, NoLock);
191 #ifndef NO_SECURITY
192                                         if (!pg_ownercheck(userName, relname, RELNAME))
193                                                 elog(ERROR, "you do not own class \"%s\"",
194                                                          relname);
195 #endif
196                                 }
197                                 /* OK, terminate 'em all */
198                                 foreach(arg, args)
199                                 {
200                                         relname = strVal(lfirst(arg));
201                                         RemoveRelation(relname);
202                                 }
203                         }
204                         break;
205
206                 case T_TruncateStmt:
207                         {
208                                 Relation        rel;
209
210                                 PS_SET_STATUS(commandTag = "TRUNCATE");
211                                 CHECK_IF_ABORTED();
212
213                                 relname = ((TruncateStmt *) parsetree)->relName;                        
214                                 if (!allowSystemTableMods && IsSystemRelationName(relname))
215                                         elog(ERROR, "TRUNCATE cannot be used on system tables. '%s' is a system table",
216                                                  relname);
217
218                                 /* Grab exclusive lock in preparation for truncate... */
219                                 rel = heap_openr(relname, AccessExclusiveLock);
220                             if (rel->rd_rel->relkind == RELKIND_SEQUENCE)
221                                         elog(ERROR, "TRUNCATE cannot be used on sequences. '%s' is a sequence",
222                                                  relname);
223                             heap_close(rel, NoLock);
224
225 #ifndef NO_SECURITY
226                                 if (!pg_ownercheck(userName, relname, RELNAME))
227                                         elog(ERROR, "you do not own class \"%s\"", relname);
228 #endif
229                                 TruncateRelation(relname);
230                         }
231                         break;
232
233         case T_CommentStmt:
234           {
235             
236             CommentStmt *statement;
237             
238             statement = ((CommentStmt *) parsetree);
239             
240             PS_SET_STATUS(commandTag = "COMMENT");
241             CHECK_IF_ABORTED();
242             CommentObject(statement->objtype, statement->objname,
243                           statement->objproperty, statement->objlist,
244                           statement->comment);
245           }
246           break;
247             
248
249
250                 case T_CopyStmt:
251                         {
252                                 CopyStmt   *stmt = (CopyStmt *) parsetree;
253
254                                 PS_SET_STATUS(commandTag = "COPY");
255                                 CHECK_IF_ABORTED();
256
257                                 DoCopy(stmt->relname,
258                                            stmt->binary,
259                                            stmt->oids,
260                                            (bool) (stmt->direction == FROM),
261                                            (bool) (stmt->filename == NULL),
262
263                                 /*
264                                  * null filename means copy to/from stdout/stdin, rather
265                                  * than to/from a file.
266                                  */
267                                            stmt->filename,
268                                            stmt->delimiter,
269                        stmt->null_print,
270                                 /*
271                                  * specify 022 umask while writing files with COPY.
272                                  */
273                                            0022);
274                         }
275                         break;
276
277                 case T_AddAttrStmt:
278                         {
279                                 AddAttrStmt *stmt = (AddAttrStmt *) parsetree;
280
281                                 PS_SET_STATUS(commandTag = "ADD");
282                                 CHECK_IF_ABORTED();
283
284                                 /*
285                                  * owner checking done in PerformAddAttribute (now
286                                  * recursive)
287                                  */
288                                 PerformAddAttribute(stmt->relname,
289                                                                         userName,
290                                                                         stmt->inh,
291                                                                         (ColumnDef *) stmt->colDef);
292                         }
293                         break;
294
295                         /*
296                          * schema
297                          */
298                 case T_RenameStmt:
299                         {
300                                 RenameStmt *stmt = (RenameStmt *) parsetree;
301
302                                 PS_SET_STATUS(commandTag = "RENAME");
303                                 CHECK_IF_ABORTED();
304
305                                 relname = stmt->relname;
306                                 if (!allowSystemTableMods && IsSystemRelationName(relname))
307                                         elog(ERROR, "class \"%s\" is a system catalog",
308                                                  relname);
309 #ifndef NO_SECURITY
310                                 if (!pg_ownercheck(userName, relname, RELNAME))
311                                         elog(ERROR, "you do not own class \"%s\"",
312                                                  relname);
313 #endif
314
315                                 /* ----------------
316                                  *      XXX using len == 3 to tell the difference
317                                  *              between "rename rel to newrel" and
318                                  *              "rename att in rel to newatt" will not
319                                  *              work soon because "rename type/operator/rule"
320                                  *              stuff is being added. - cim 10/24/90
321                                  * ----------------
322                                  * [another piece of amuzing but useless anecdote -- ay]
323                                  */
324                                 if (stmt->column == NULL)
325                                 {
326                                         /* ----------------
327                                          *              rename relation
328                                          *
329                                          *              Note: we also rename the "type" tuple
330                                          *              corresponding to the relation.
331                                          * ----------------
332                                          */
333                                         renamerel(relname,      /* old name */
334                                                           stmt->newname);       /* new name */
335                                         TypeRename(relname, /* old name */
336                                                            stmt->newname);      /* new name */
337                                 }
338                                 else
339                                 {
340                                         /* ----------------
341                                          *              rename attribute
342                                          * ----------------
343                                          */
344                                         renameatt(relname,      /* relname */
345                                                           stmt->column,         /* old att name */
346                                                           stmt->newname,        /* new att name */
347                                                           userName,
348                                                           stmt->inh);           /* recursive? */
349                                 }
350                         }
351                         break;
352
353                 case T_ChangeACLStmt:
354                         {
355                                 ChangeACLStmt *stmt = (ChangeACLStmt *) parsetree;
356                                 List       *i;
357                                 AclItem    *aip;
358                                 unsigned        modechg;
359
360                                 PS_SET_STATUS(commandTag = "CHANGE");
361                                 CHECK_IF_ABORTED();
362
363                                 aip = stmt->aclitem;
364
365                                 modechg = stmt->modechg;
366 #ifndef NO_SECURITY
367                                 foreach(i, stmt->relNames)
368                                 {
369                                         relname = strVal(lfirst(i));
370                                         if (!pg_ownercheck(userName, relname, RELNAME))
371                                                 elog(ERROR, "you do not own class \"%s\"",
372                                                          relname);
373                                 }
374 #endif
375                                 foreach(i, stmt->relNames)
376                                 {
377                                         relname = strVal(lfirst(i));
378                                         ChangeAcl(relname, aip, modechg);
379                                 }
380
381                         }
382                         break;
383
384                         /*
385                          * ******************************** object creation /
386                          * destruction ********************************
387                          *
388                          */
389                 case T_DefineStmt:
390                         {
391                                 DefineStmt *stmt = (DefineStmt *) parsetree;
392
393                                 PS_SET_STATUS(commandTag = "CREATE");
394                                 CHECK_IF_ABORTED();
395
396                                 switch (stmt->defType)
397                                 {
398                                         case OPERATOR:
399                                                 DefineOperator(stmt->defname,   /* operator name */
400                                                                            stmt->definition);           /* rest */
401                                                 break;
402                                         case TYPE_P:
403                                                 DefineType(stmt->defname, stmt->definition);
404                                                 break;
405                                         case AGGREGATE:
406                                                 DefineAggregate(stmt->defname,  /* aggregate name */
407                                                                                 stmt->definition);              /* rest */
408                                                 break;
409                                 }
410                         }
411                         break;
412
413                 case T_ViewStmt:                /* CREATE VIEW */
414                         {
415                                 ViewStmt   *stmt = (ViewStmt *) parsetree;
416
417                                 PS_SET_STATUS(commandTag = "CREATE");
418                                 CHECK_IF_ABORTED();
419                                 DefineView(stmt->viewname, stmt->query);                /* retrieve parsetree */
420                         }
421                         break;
422
423                 case T_ProcedureStmt:   /* CREATE FUNCTION */
424                         PS_SET_STATUS(commandTag = "CREATE");
425                         CHECK_IF_ABORTED();
426                         CreateFunction((ProcedureStmt *) parsetree, dest);      /* everything */
427                         break;
428
429                 case T_IndexStmt:               /* CREATE INDEX */
430                         {
431                                 IndexStmt  *stmt = (IndexStmt *) parsetree;
432
433                                 PS_SET_STATUS(commandTag = "CREATE");
434                                 CHECK_IF_ABORTED();
435                                 DefineIndex(stmt->relname,              /* relation name */
436                                                         stmt->idxname,          /* index name */
437                                                         stmt->accessMethod, /* am name */
438                                                         stmt->indexParams,      /* parameters */
439                                                         stmt->withClause,
440                                                         stmt->unique,
441                                                         stmt->primary,
442                                                         (Expr *) stmt->whereClause,
443                                                         stmt->rangetable);
444                         }
445                         break;
446
447                 case T_RuleStmt:                /* CREATE RULE */
448                         {
449                                 RuleStmt   *stmt = (RuleStmt *) parsetree;
450                                 int                     aclcheck_result;
451
452 #ifndef NO_SECURITY
453                                 relname = stmt->object->relname;
454                                 aclcheck_result = pg_aclcheck(relname, userName, ACL_RU);
455                                 if (aclcheck_result != ACLCHECK_OK)
456                                         elog(ERROR, "%s: %s", relname, aclcheck_error_strings[aclcheck_result]);
457 #endif
458                                 PS_SET_STATUS(commandTag = "CREATE");
459                                 CHECK_IF_ABORTED();
460                                 DefineQueryRewrite(stmt);
461                         }
462                         break;
463
464                 case T_CreateSeqStmt:
465                         PS_SET_STATUS(commandTag = "CREATE");
466                         CHECK_IF_ABORTED();
467
468                         DefineSequence((CreateSeqStmt *) parsetree);
469                         break;
470
471                 case T_ExtendStmt:
472                         {
473                                 ExtendStmt *stmt = (ExtendStmt *) parsetree;
474
475                                 PS_SET_STATUS(commandTag = "EXTEND");
476                                 CHECK_IF_ABORTED();
477
478                                 ExtendIndex(stmt->idxname,              /* index name */
479                                                         (Expr *) stmt->whereClause, /* where */
480                                                         stmt->rangetable);
481                         }
482                         break;
483
484                 case T_RemoveStmt:
485                         {
486                                 RemoveStmt *stmt = (RemoveStmt *) parsetree;
487
488                                 PS_SET_STATUS(commandTag = "DROP");
489                                 CHECK_IF_ABORTED();
490
491                                 switch (stmt->removeType)
492                                 {
493                                         case INDEX:
494                                                 relname = stmt->name;
495                                                 if (!allowSystemTableMods && IsSystemRelationName(relname))
496                                                         elog(ERROR, "class \"%s\" is a system catalog index",
497                                                                  relname);
498 #ifndef NO_SECURITY
499                                                 if (!pg_ownercheck(userName, relname, RELNAME))
500                                                         elog(ERROR, "%s: %s", relname, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
501 #endif
502                                                 RemoveIndex(relname);
503                                                 break;
504                                         case RULE:
505                                                 {
506                                                         char       *rulename = stmt->name;
507                                                         int                     aclcheck_result;
508
509 #ifndef NO_SECURITY
510
511                                                         relationName = RewriteGetRuleEventRel(rulename);
512                                                         aclcheck_result = pg_aclcheck(relationName, userName, ACL_RU);
513                                                         if (aclcheck_result != ACLCHECK_OK)
514                                                                 elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[aclcheck_result]);
515 #endif
516                                                         RemoveRewriteRule(rulename);
517                                                 }
518                                                 break;
519                                         case TYPE_P:
520 #ifndef NO_SECURITY
521                                                 /* XXX moved to remove.c */
522 #endif
523                                                 RemoveType(stmt->name);
524                                                 break;
525                                         case VIEW:
526                                                 {
527                                                         char       *viewName = stmt->name;
528                                                         char       *ruleName;
529
530 #ifndef NO_SECURITY
531
532                                                         ruleName = MakeRetrieveViewRuleName(viewName);
533                                                         relationName = RewriteGetRuleEventRel(ruleName);
534                                                         if (!pg_ownercheck(userName, relationName, RELNAME))
535                                                                 elog(ERROR, "%s: %s", relationName, aclcheck_error_strings[ACLCHECK_NOT_OWNER]);
536                                                         pfree(ruleName);
537 #endif
538                                                         RemoveView(viewName);
539                                                 }
540                                                 break;
541                                 }
542                                 break;
543                         }
544                         break;
545
546                 case T_RemoveAggrStmt:
547                         {
548                                 RemoveAggrStmt *stmt = (RemoveAggrStmt *) parsetree;
549
550                                 PS_SET_STATUS(commandTag = "DROP");
551                                 CHECK_IF_ABORTED();
552                                 RemoveAggregate(stmt->aggname, stmt->aggtype);
553                         }
554                         break;
555
556                 case T_RemoveFuncStmt:
557                         {
558                                 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
559
560                                 PS_SET_STATUS(commandTag = "DROP");
561                                 CHECK_IF_ABORTED();
562                                 RemoveFunction(stmt->funcname,
563                                                            length(stmt->args),
564                                                            stmt->args);
565                         }
566                         break;
567
568                 case T_RemoveOperStmt:
569                         {
570                                 RemoveOperStmt *stmt = (RemoveOperStmt *) parsetree;
571                                 char       *type1 = (char *) NULL;
572                                 char       *type2 = (char *) NULL;
573
574                                 PS_SET_STATUS(commandTag = "DROP");
575                                 CHECK_IF_ABORTED();
576
577                                 if (lfirst(stmt->args) != NULL)
578                                         type1 = strVal(lfirst(stmt->args));
579                                 if (lsecond(stmt->args) != NULL)
580                                         type2 = strVal(lsecond(stmt->args));
581                                 RemoveOperator(stmt->opname, type1, type2);
582                         }
583                         break;
584
585                 case T_VersionStmt:
586                         elog(ERROR, "CREATE VERSION is not currently implemented");
587                         break;
588
589                 case T_CreatedbStmt:
590                         {
591                                 CreatedbStmt *stmt = (CreatedbStmt *) parsetree;
592
593                                 PS_SET_STATUS(commandTag = "CREATE DATABASE");
594                                 CHECK_IF_ABORTED();
595                                 createdb(stmt->dbname, stmt->dbpath, stmt->encoding);
596                         }
597                         break;
598
599                 case T_DropdbStmt:
600                         {
601                                 DropdbStmt *stmt = (DropdbStmt *) parsetree;
602
603                                 PS_SET_STATUS(commandTag = "DROP DATABASE");
604                                 CHECK_IF_ABORTED();
605                                 dropdb(stmt->dbname);
606                         }
607                         break;
608
609                         /* Query-level asynchronous notification */
610                 case T_NotifyStmt:
611                         {
612                                 NotifyStmt *stmt = (NotifyStmt *) parsetree;
613
614                                 PS_SET_STATUS(commandTag = "NOTIFY");
615                                 CHECK_IF_ABORTED();
616
617                                 Async_Notify(stmt->relname);
618                         }
619                         break;
620
621                 case T_ListenStmt:
622                         {
623                                 ListenStmt *stmt = (ListenStmt *) parsetree;
624
625                                 PS_SET_STATUS(commandTag = "LISTEN");
626                                 CHECK_IF_ABORTED();
627
628                                 Async_Listen(stmt->relname, MyProcPid);
629                         }
630                         break;
631
632                 case T_UnlistenStmt:
633                         {
634                                 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
635
636                                 PS_SET_STATUS(commandTag = "UNLISTEN");
637                                 CHECK_IF_ABORTED();
638
639                                 Async_Unlisten(stmt->relname, MyProcPid);
640                         }
641                         break;
642
643                         /*
644                          * ******************************** dynamic loader ********************************
645                          *
646                          */
647                 case T_LoadStmt:
648                         {
649                                 LoadStmt   *stmt = (LoadStmt *) parsetree;
650
651                                 PS_SET_STATUS(commandTag = "LOAD");
652                                 CHECK_IF_ABORTED();
653
654                                 closeAllVfds(); /* probably not necessary... */
655                                 load_file(stmt->filename);
656                         }
657                         break;
658
659                 case T_ClusterStmt:
660                         {
661                                 ClusterStmt *stmt = (ClusterStmt *) parsetree;
662
663                                 PS_SET_STATUS(commandTag = "CLUSTER");
664                                 CHECK_IF_ABORTED();
665
666                                 cluster(stmt->relname, stmt->indexname);
667                         }
668                         break;
669
670                 case T_VacuumStmt:
671                         PS_SET_STATUS(commandTag = "VACUUM");
672                         CHECK_IF_ABORTED();
673                         vacuum(((VacuumStmt *) parsetree)->vacrel,
674                                    ((VacuumStmt *) parsetree)->verbose,
675                                    ((VacuumStmt *) parsetree)->analyze,
676                                    ((VacuumStmt *) parsetree)->va_spec);
677                         break;
678
679                 case T_ExplainStmt:
680                         {
681                                 ExplainStmt *stmt = (ExplainStmt *) parsetree;
682
683                                 PS_SET_STATUS(commandTag = "EXPLAIN");
684                                 CHECK_IF_ABORTED();
685
686                                 ExplainQuery(stmt->query, stmt->verbose, dest);
687                         }
688                         break;
689
690 #ifdef NOT_USED
691
692                         /*
693                          * ******************************** Tioga-related statements *******************************
694                          */
695                 case T_RecipeStmt:
696                         {
697                                 RecipeStmt *stmt = (RecipeStmt *) parsetree;
698
699                                 PS_SET_STATUS(commandTag = "EXECUTE RECIPE");
700                                 CHECK_IF_ABORTED();
701                                 beginRecipe(stmt);
702                         }
703                         break;
704 #endif
705
706                         /*
707                          * ******************************** set variable statements *******************************
708                          */
709                 case T_VariableSetStmt:
710                         {
711                                 VariableSetStmt *n = (VariableSetStmt *) parsetree;
712
713                                 SetPGVariable(n->name, n->value);
714                                 PS_SET_STATUS(commandTag = "SET VARIABLE");
715                         }
716                         break;
717
718                 case T_VariableShowStmt:
719                         {
720                                 VariableShowStmt *n = (VariableShowStmt *) parsetree;
721
722                                 GetPGVariable(n->name);
723                                 PS_SET_STATUS(commandTag = "SHOW VARIABLE");
724                         }
725                         break;
726
727                 case T_VariableResetStmt:
728                         {
729                                 VariableResetStmt *n = (VariableResetStmt *) parsetree;
730
731                                 ResetPGVariable(n->name);
732                                 PS_SET_STATUS(commandTag = "RESET VARIABLE");
733                         }
734                         break;
735
736                         /*
737                          * ******************************** TRIGGER statements *******************************
738                          */
739                 case T_CreateTrigStmt:
740                         PS_SET_STATUS(commandTag = "CREATE");
741                         CHECK_IF_ABORTED();
742
743                         CreateTrigger((CreateTrigStmt *) parsetree);
744                         break;
745
746                 case T_DropTrigStmt:
747                         PS_SET_STATUS(commandTag = "DROP");
748                         CHECK_IF_ABORTED();
749
750                         DropTrigger((DropTrigStmt *) parsetree);
751                         break;
752
753                         /*
754                          * ************* PROCEDURAL LANGUAGE statements *****************
755                          */
756                 case T_CreatePLangStmt:
757                         PS_SET_STATUS(commandTag = "CREATE");
758                         CHECK_IF_ABORTED();
759
760                         CreateProceduralLanguage((CreatePLangStmt *) parsetree);
761                         break;
762
763                 case T_DropPLangStmt:
764                         PS_SET_STATUS(commandTag = "DROP");
765                         CHECK_IF_ABORTED();
766
767                         DropProceduralLanguage((DropPLangStmt *) parsetree);
768                         break;
769
770                         /*
771                          * ******************************** USER statements ****
772                          *
773                          */
774                 case T_CreateUserStmt:
775                         PS_SET_STATUS(commandTag = "CREATE USER");
776                         CHECK_IF_ABORTED();
777
778                         DefineUser((CreateUserStmt *) parsetree, dest);
779                         break;
780
781                 case T_AlterUserStmt:
782                         PS_SET_STATUS(commandTag = "ALTER USER");
783                         CHECK_IF_ABORTED();
784
785                         AlterUser((AlterUserStmt *) parsetree, dest);
786                         break;
787
788                 case T_DropUserStmt:
789                         PS_SET_STATUS(commandTag = "DROP USER");
790                         CHECK_IF_ABORTED();
791
792                         RemoveUser(((DropUserStmt *) parsetree)->user, dest);
793                         break;
794
795                 case T_LockStmt:
796                         PS_SET_STATUS(commandTag = "LOCK TABLE");
797                         CHECK_IF_ABORTED();
798
799                         LockTableCommand((LockStmt *) parsetree);
800                         break;
801
802                 case T_ConstraintsSetStmt:
803                         PS_SET_STATUS(commandTag = "SET CONSTRAINTS");
804                         CHECK_IF_ABORTED();
805
806                         DeferredTriggerSetState((ConstraintsSetStmt *) parsetree);
807                         break;
808
809         case T_CreateGroupStmt:
810             PS_SET_STATUS(commandTag = "CREATE GROUP");
811                         CHECK_IF_ABORTED();
812
813             CreateGroup((CreateGroupStmt *) parsetree, dest);
814             break;
815
816         case T_AlterGroupStmt:
817             PS_SET_STATUS(commandTag = "ALTER GROUP");
818                         CHECK_IF_ABORTED();
819
820             AlterGroup((AlterGroupStmt *) parsetree, dest);
821             break;
822
823         case T_DropGroupStmt:
824             PS_SET_STATUS(commandTag = "DROP GROUP");
825                         CHECK_IF_ABORTED();
826
827             DropGroup((DropGroupStmt *) parsetree, dest);
828             break;
829
830                         /*
831                          * ******************************** default ********************************
832                          *
833                          */
834                 default:
835                         elog(ERROR, "ProcessUtility: command #%d unsupported",
836                                  nodeTag(parsetree));
837                         break;
838         }
839
840         /* ----------------
841          *      tell fe/be or whatever that we're done.
842          * ----------------
843          */
844         EndCommand(commandTag, dest);
845 }