OSDN Git Service

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