OSDN Git Service

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