OSDN Git Service

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