PostgreSQL Source Code  git master
utility.c
Go to the documentation of this file.
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-2020, PostgreSQL Global Development Group
9  * Portions Copyright (c) 1994, Regents of the University of California
10  *
11  *
12  * IDENTIFICATION
13  * src/backend/tcop/utility.c
14  *
15  *-------------------------------------------------------------------------
16  */
17 #include "postgres.h"
18 
19 #include "access/htup_details.h"
20 #include "access/reloptions.h"
21 #include "access/twophase.h"
22 #include "access/xact.h"
23 #include "access/xlog.h"
24 #include "catalog/catalog.h"
25 #include "catalog/namespace.h"
26 #include "catalog/pg_inherits.h"
27 #include "catalog/toasting.h"
28 #include "commands/alter.h"
29 #include "commands/async.h"
30 #include "commands/cluster.h"
31 #include "commands/collationcmds.h"
32 #include "commands/comment.h"
34 #include "commands/copy.h"
35 #include "commands/createas.h"
36 #include "commands/dbcommands.h"
37 #include "commands/defrem.h"
38 #include "commands/discard.h"
39 #include "commands/event_trigger.h"
40 #include "commands/explain.h"
41 #include "commands/extension.h"
42 #include "commands/lockcmds.h"
43 #include "commands/matview.h"
44 #include "commands/policy.h"
45 #include "commands/portalcmds.h"
46 #include "commands/prepare.h"
47 #include "commands/proclang.h"
49 #include "commands/schemacmds.h"
50 #include "commands/seclabel.h"
51 #include "commands/sequence.h"
53 #include "commands/tablecmds.h"
54 #include "commands/tablespace.h"
55 #include "commands/trigger.h"
56 #include "commands/typecmds.h"
57 #include "commands/user.h"
58 #include "commands/vacuum.h"
59 #include "commands/view.h"
60 #include "miscadmin.h"
61 #include "parser/parse_utilcmd.h"
62 #include "postmaster/bgwriter.h"
63 #include "rewrite/rewriteDefine.h"
64 #include "rewrite/rewriteRemove.h"
65 #include "storage/fd.h"
66 #include "tcop/pquery.h"
67 #include "tcop/utility.h"
68 #include "utils/acl.h"
69 #include "utils/guc.h"
70 #include "utils/lsyscache.h"
71 #include "utils/rel.h"
72 #include "utils/syscache.h"
73 
74 /* Hook for plugins to get control in ProcessUtility() */
76 
77 /* local function declarations */
78 static int ClassifyUtilityCommandAsReadOnly(Node *parsetree);
79 static void ProcessUtilitySlow(ParseState *pstate,
80  PlannedStmt *pstmt,
81  const char *queryString,
82  ProcessUtilityContext context,
83  ParamListInfo params,
84  QueryEnvironment *queryEnv,
86  QueryCompletion *qc);
87 static void ExecDropStmt(DropStmt *stmt, bool isTopLevel);
88 
89 /*
90  * CommandIsReadOnly: is an executable query read-only?
91  *
92  * This is a much stricter test than we apply for XactReadOnly mode;
93  * the query must be *in truth* read-only, because the caller wishes
94  * not to do CommandCounterIncrement for it.
95  *
96  * Note: currently no need to support raw or analyzed queries here
97  */
98 bool
100 {
101  Assert(IsA(pstmt, PlannedStmt));
102  switch (pstmt->commandType)
103  {
104  case CMD_SELECT:
105  if (pstmt->rowMarks != NIL)
106  return false; /* SELECT FOR [KEY] UPDATE/SHARE */
107  else if (pstmt->hasModifyingCTE)
108  return false; /* data-modifying CTE */
109  else
110  return true;
111  case CMD_UPDATE:
112  case CMD_INSERT:
113  case CMD_DELETE:
114  return false;
115  case CMD_UTILITY:
116  /* For now, treat all utility commands as read/write */
117  return false;
118  default:
119  elog(WARNING, "unrecognized commandType: %d",
120  (int) pstmt->commandType);
121  break;
122  }
123  return false;
124 }
125 
126 /*
127  * Determine the degree to which a utility command is read only.
128  *
129  * Note the definitions of the relevant flags in src/include/utility/tcop.h.
130  */
131 static int
133 {
134  switch (nodeTag(parsetree))
135  {
138  case T_AlterDatabaseStmt:
140  case T_AlterDomainStmt:
141  case T_AlterEnumStmt:
145  case T_AlterFdwStmt:
147  case T_AlterFunctionStmt:
150  case T_AlterOpFamilyStmt:
151  case T_AlterOperatorStmt:
152  case T_AlterOwnerStmt:
153  case T_AlterPolicyStmt:
155  case T_AlterRoleSetStmt:
156  case T_AlterRoleStmt:
157  case T_AlterSeqStmt:
158  case T_AlterStatsStmt:
164  case T_AlterTableStmt:
165  case T_AlterTypeStmt:
167  case T_CommentStmt:
168  case T_CompositeTypeStmt:
169  case T_CreateAmStmt:
170  case T_CreateCastStmt:
172  case T_CreateDomainStmt:
173  case T_CreateEnumStmt:
176  case T_CreateFdwStmt:
180  case T_CreateOpClassStmt:
182  case T_CreatePLangStmt:
183  case T_CreatePolicyStmt:
185  case T_CreateRangeStmt:
186  case T_CreateRoleStmt:
187  case T_CreateSchemaStmt:
188  case T_CreateSeqStmt:
189  case T_CreateStatsStmt:
190  case T_CreateStmt:
192  case T_CreateTableAsStmt:
195  case T_CreateTrigStmt:
197  case T_CreatedbStmt:
198  case T_DefineStmt:
199  case T_DropOwnedStmt:
200  case T_DropRoleStmt:
201  case T_DropStmt:
205  case T_DropdbStmt:
206  case T_GrantRoleStmt:
207  case T_GrantStmt:
209  case T_IndexStmt:
210  case T_ReassignOwnedStmt:
212  case T_RenameStmt:
213  case T_RuleStmt:
214  case T_SecLabelStmt:
215  case T_TruncateStmt:
216  case T_ViewStmt:
217  {
218  /* DDL is not read-only, and neither is TRUNCATE. */
220  }
221 
222  case T_AlterSystemStmt:
223  {
224  /*
225  * Surprisingly, ALTER SYSTEM meets all our definitions of
226  * read-only: it changes nothing that affects the output of
227  * pg_dump, it doesn't write WAL or imperil the application of
228  * future WAL, and it doesn't depend on any state that needs
229  * to be synchronized with parallel workers.
230  *
231  * So, despite the fact that it writes to a file, it's read
232  * only!
233  */
235  }
236 
237  case T_CallStmt:
238  case T_DoStmt:
239  {
240  /*
241  * Commands inside the DO block or the called procedure might
242  * not be read only, but they'll be checked separately when we
243  * try to execute them. Here we only need to worry about the
244  * DO or CALL command itself.
245  */
247  }
248 
249  case T_CheckPointStmt:
250  {
251  /*
252  * You might think that this should not be permitted in
253  * recovery, but we interpret a CHECKPOINT command during
254  * recovery as a request for a restartpoint instead. We allow
255  * this since it can be a useful way of reducing switchover
256  * time when using various forms of replication.
257  */
259  }
260 
261  case T_ClosePortalStmt:
263  case T_DeallocateStmt:
264  case T_DeclareCursorStmt:
265  case T_DiscardStmt:
266  case T_ExecuteStmt:
267  case T_FetchStmt:
268  case T_LoadStmt:
269  case T_PrepareStmt:
270  case T_UnlistenStmt:
271  case T_VariableSetStmt:
272  {
273  /*
274  * These modify only backend-local state, so they're OK to run
275  * in a read-only transaction or on a standby. However, they
276  * are disallowed in parallel mode, because they either rely
277  * upon or modify backend-local state that might not be
278  * synchronized among cooperating backends.
279  */
281  }
282 
283  case T_ClusterStmt:
284  case T_ReindexStmt:
285  case T_VacuumStmt:
286  {
287  /*
288  * These commands write WAL, so they're not strictly
289  * read-only, and running them in parallel workers isn't
290  * supported.
291  *
292  * However, they don't change the database state in a way that
293  * would affect pg_dump output, so it's fine to run them in a
294  * read-only transaction. (CLUSTER might change the order of
295  * rows on disk, which could affect the ordering of pg_dump
296  * output, but that's not semantically significant.)
297  */
299  }
300 
301  case T_CopyStmt:
302  {
303  CopyStmt *stmt = (CopyStmt *) parsetree;
304 
305  /*
306  * You might think that COPY FROM is not at all read only, but
307  * it's OK to copy into a temporary table, because that
308  * wouldn't change the output of pg_dump. If the target table
309  * turns out to be non-temporary, DoCopy itself will call
310  * PreventCommandIfReadOnly.
311  */
312  if (stmt->is_from)
314  else
316  }
317 
318  case T_ExplainStmt:
319  case T_VariableShowStmt:
320  {
321  /*
322  * These commands don't modify any data and are safe to run in
323  * a parallel worker.
324  */
326  }
327 
328  case T_ListenStmt:
329  case T_NotifyStmt:
330  {
331  /*
332  * NOTIFY requires an XID assignment, so it can't be permitted
333  * on a standby. Perhaps LISTEN could, since without NOTIFY it
334  * would be OK to just do nothing, at least until promotion,
335  * but we currently prohibit it lest the user get the wrong
336  * idea.
337  *
338  * (We do allow T_UnlistenStmt on a standby, though, because
339  * it's a no-op.)
340  */
342  }
343 
344  case T_LockStmt:
345  {
346  LockStmt *stmt = (LockStmt *) parsetree;
347 
348  /*
349  * Only weaker locker modes are allowed during recovery. The
350  * restrictions here must match those in
351  * LockAcquireExtended().
352  */
353  if (stmt->mode > RowExclusiveLock)
355  else
357  }
358 
359  case T_TransactionStmt:
360  {
361  TransactionStmt *stmt = (TransactionStmt *) parsetree;
362 
363  /*
364  * PREPARE, COMMIT PREPARED, and ROLLBACK PREPARED all write
365  * WAL, so they're not read-only in the strict sense; but the
366  * first and third do not change pg_dump output, so they're OK
367  * in a read-only transactions.
368  *
369  * We also consider COMMIT PREPARED to be OK in a read-only
370  * transaction environment, by way of exception.
371  */
372  switch (stmt->kind)
373  {
374  case TRANS_STMT_BEGIN:
375  case TRANS_STMT_START:
376  case TRANS_STMT_COMMIT:
377  case TRANS_STMT_ROLLBACK:
379  case TRANS_STMT_RELEASE:
382 
383  case TRANS_STMT_PREPARE:
387  }
388  elog(ERROR, "unrecognized TransactionStmtKind: %d",
389  (int) stmt->kind);
390  return 0; /* silence stupider compilers */
391  }
392 
393  default:
394  elog(ERROR, "unrecognized node type: %d",
395  (int) nodeTag(parsetree));
396  return 0; /* silence stupider compilers */
397  }
398 }
399 
400 /*
401  * PreventCommandIfReadOnly: throw error if XactReadOnly
402  *
403  * This is useful partly to ensure consistency of the error message wording;
404  * some callers have checked XactReadOnly for themselves.
405  */
406 void
407 PreventCommandIfReadOnly(const char *cmdname)
408 {
409  if (XactReadOnly)
410  ereport(ERROR,
411  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
412  /* translator: %s is name of a SQL command, eg CREATE */
413  errmsg("cannot execute %s in a read-only transaction",
414  cmdname)));
415 }
416 
417 /*
418  * PreventCommandIfParallelMode: throw error if current (sub)transaction is
419  * in parallel mode.
420  *
421  * This is useful partly to ensure consistency of the error message wording;
422  * some callers have checked IsInParallelMode() for themselves.
423  */
424 void
425 PreventCommandIfParallelMode(const char *cmdname)
426 {
427  if (IsInParallelMode())
428  ereport(ERROR,
429  (errcode(ERRCODE_INVALID_TRANSACTION_STATE),
430  /* translator: %s is name of a SQL command, eg CREATE */
431  errmsg("cannot execute %s during a parallel operation",
432  cmdname)));
433 }
434 
435 /*
436  * PreventCommandDuringRecovery: throw error if RecoveryInProgress
437  *
438  * The majority of operations that are unsafe in a Hot Standby
439  * will be rejected by XactReadOnly tests. However there are a few
440  * commands that are allowed in "read-only" xacts but cannot be allowed
441  * in Hot Standby mode. Those commands should call this function.
442  */
443 void
444 PreventCommandDuringRecovery(const char *cmdname)
445 {
446  if (RecoveryInProgress())
447  ereport(ERROR,
448  (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
449  /* translator: %s is name of a SQL command, eg CREATE */
450  errmsg("cannot execute %s during recovery",
451  cmdname)));
452 }
453 
454 /*
455  * CheckRestrictedOperation: throw error for hazardous command if we're
456  * inside a security restriction context.
457  *
458  * This is needed to protect session-local state for which there is not any
459  * better-defined protection mechanism, such as ownership.
460  */
461 static void
462 CheckRestrictedOperation(const char *cmdname)
463 {
465  ereport(ERROR,
466  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
467  /* translator: %s is name of a SQL command, eg PREPARE */
468  errmsg("cannot execute %s within security-restricted operation",
469  cmdname)));
470 }
471 
472 /*
473  * ProcessUtility
474  * general utility function invoker
475  *
476  * pstmt: PlannedStmt wrapper for the utility statement
477  * queryString: original source text of command
478  * context: identifies source of statement (toplevel client command,
479  * non-toplevel client command, subcommand of a larger utility command)
480  * params: parameters to use during execution
481  * queryEnv: environment for parse through execution (e.g., ephemeral named
482  * tables like trigger transition tables). May be NULL.
483  * dest: where to send results
484  * qc: where to store command completion status data. May be NULL,
485  * but if not, then caller must have initialized it.
486  *
487  * Caller MUST supply a queryString; it is not allowed (anymore) to pass NULL.
488  * If you really don't have source text, you can pass a constant string,
489  * perhaps "(query not available)".
490  *
491  * Note for users of ProcessUtility_hook: the same queryString may be passed
492  * to multiple invocations of ProcessUtility when processing a query string
493  * containing multiple semicolon-separated statements. One should use
494  * pstmt->stmt_location and pstmt->stmt_len to identify the substring
495  * containing the current statement. Keep in mind also that some utility
496  * statements (e.g., CREATE SCHEMA) will recurse to ProcessUtility to process
497  * sub-statements, often passing down the same queryString, stmt_location,
498  * and stmt_len that were given for the whole statement.
499  */
500 void
502  const char *queryString,
503  ProcessUtilityContext context,
504  ParamListInfo params,
505  QueryEnvironment *queryEnv,
507  QueryCompletion *qc)
508 {
509  Assert(IsA(pstmt, PlannedStmt));
510  Assert(pstmt->commandType == CMD_UTILITY);
511  Assert(queryString != NULL); /* required as of 8.4 */
512  Assert(qc == NULL || qc->commandTag == CMDTAG_UNKNOWN);
513 
514  /*
515  * We provide a function hook variable that lets loadable plugins get
516  * control when ProcessUtility is called. Such a plugin would normally
517  * call standard_ProcessUtility().
518  */
520  (*ProcessUtility_hook) (pstmt, queryString,
521  context, params, queryEnv,
522  dest, qc);
523  else
524  standard_ProcessUtility(pstmt, queryString,
525  context, params, queryEnv,
526  dest, qc);
527 }
528 
529 /*
530  * standard_ProcessUtility itself deals only with utility commands for
531  * which we do not provide event trigger support. Commands that do have
532  * such support are passed down to ProcessUtilitySlow, which contains the
533  * necessary infrastructure for such triggers.
534  *
535  * This division is not just for performance: it's critical that the
536  * event trigger code not be invoked when doing START TRANSACTION for
537  * example, because we might need to refresh the event trigger cache,
538  * which requires being in a valid transaction.
539  */
540 void
542  const char *queryString,
543  ProcessUtilityContext context,
544  ParamListInfo params,
545  QueryEnvironment *queryEnv,
547  QueryCompletion *qc)
548 {
549  Node *parsetree = pstmt->utilityStmt;
550  bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
551  bool isAtomicContext = (!(context == PROCESS_UTILITY_TOPLEVEL || context == PROCESS_UTILITY_QUERY_NONATOMIC) || IsTransactionBlock());
552  ParseState *pstate;
553  int readonly_flags;
554 
555  /* This can recurse, so check for excessive recursion */
557 
558  /* Prohibit read/write commands in read-only states. */
559  readonly_flags = ClassifyUtilityCommandAsReadOnly(parsetree);
560  if (readonly_flags != COMMAND_IS_STRICTLY_READ_ONLY &&
562  {
563  CommandTag commandtag = CreateCommandTag(parsetree);
564 
565  if ((readonly_flags & COMMAND_OK_IN_READ_ONLY_TXN) == 0)
567  if ((readonly_flags & COMMAND_OK_IN_PARALLEL_MODE) == 0)
569  if ((readonly_flags & COMMAND_OK_IN_RECOVERY) == 0)
571  }
572 
573  pstate = make_parsestate(NULL);
574  pstate->p_sourcetext = queryString;
575  pstate->p_queryEnv = queryEnv;
576 
577  switch (nodeTag(parsetree))
578  {
579  /*
580  * ******************** transactions ********************
581  */
582  case T_TransactionStmt:
583  {
584  TransactionStmt *stmt = (TransactionStmt *) parsetree;
585 
586  switch (stmt->kind)
587  {
588  /*
589  * START TRANSACTION, as defined by SQL99: Identical
590  * to BEGIN. Same code for both.
591  */
592  case TRANS_STMT_BEGIN:
593  case TRANS_STMT_START:
594  {
595  ListCell *lc;
596 
598  foreach(lc, stmt->options)
599  {
600  DefElem *item = (DefElem *) lfirst(lc);
601 
602  if (strcmp(item->defname, "transaction_isolation") == 0)
603  SetPGVariable("transaction_isolation",
604  list_make1(item->arg),
605  true);
606  else if (strcmp(item->defname, "transaction_read_only") == 0)
607  SetPGVariable("transaction_read_only",
608  list_make1(item->arg),
609  true);
610  else if (strcmp(item->defname, "transaction_deferrable") == 0)
611  SetPGVariable("transaction_deferrable",
612  list_make1(item->arg),
613  true);
614  }
615  }
616  break;
617 
618  case TRANS_STMT_COMMIT:
619  if (!EndTransactionBlock(stmt->chain))
620  {
621  /* report unsuccessful commit in qc */
622  if (qc)
623  SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
624  }
625  break;
626 
627  case TRANS_STMT_PREPARE:
628  if (!PrepareTransactionBlock(stmt->gid))
629  {
630  /* report unsuccessful commit in qc */
631  if (qc)
632  SetQueryCompletion(qc, CMDTAG_ROLLBACK, 0);
633  }
634  break;
635 
637  PreventInTransactionBlock(isTopLevel, "COMMIT PREPARED");
638  FinishPreparedTransaction(stmt->gid, true);
639  break;
640 
642  PreventInTransactionBlock(isTopLevel, "ROLLBACK PREPARED");
643  FinishPreparedTransaction(stmt->gid, false);
644  break;
645 
646  case TRANS_STMT_ROLLBACK:
648  break;
649 
651  RequireTransactionBlock(isTopLevel, "SAVEPOINT");
653  break;
654 
655  case TRANS_STMT_RELEASE:
656  RequireTransactionBlock(isTopLevel, "RELEASE SAVEPOINT");
658  break;
659 
661  RequireTransactionBlock(isTopLevel, "ROLLBACK TO SAVEPOINT");
663 
664  /*
665  * CommitTransactionCommand is in charge of
666  * re-defining the savepoint again
667  */
668  break;
669  }
670  }
671  break;
672 
673  /*
674  * Portal (cursor) manipulation
675  */
676  case T_DeclareCursorStmt:
677  PerformCursorOpen(pstate, (DeclareCursorStmt *) parsetree, params,
678  isTopLevel);
679  break;
680 
681  case T_ClosePortalStmt:
682  {
683  ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
684 
685  CheckRestrictedOperation("CLOSE");
687  }
688  break;
689 
690  case T_FetchStmt:
691  PerformPortalFetch((FetchStmt *) parsetree, dest, qc);
692  break;
693 
694  case T_DoStmt:
695  ExecuteDoStmt((DoStmt *) parsetree, isAtomicContext);
696  break;
697 
699  /* no event triggers for global objects */
700  PreventInTransactionBlock(isTopLevel, "CREATE TABLESPACE");
701  CreateTableSpace((CreateTableSpaceStmt *) parsetree);
702  break;
703 
705  /* no event triggers for global objects */
706  PreventInTransactionBlock(isTopLevel, "DROP TABLESPACE");
707  DropTableSpace((DropTableSpaceStmt *) parsetree);
708  break;
709 
711  /* no event triggers for global objects */
713  break;
714 
715  case T_TruncateStmt:
716  ExecuteTruncate((TruncateStmt *) parsetree);
717  break;
718 
719  case T_CopyStmt:
720  {
721  uint64 processed;
722 
723  DoCopy(pstate, (CopyStmt *) parsetree,
724  pstmt->stmt_location, pstmt->stmt_len,
725  &processed);
726  if (qc)
727  SetQueryCompletion(qc, CMDTAG_COPY, processed);
728  }
729  break;
730 
731  case T_PrepareStmt:
732  CheckRestrictedOperation("PREPARE");
733  PrepareQuery(pstate, (PrepareStmt *) parsetree,
734  pstmt->stmt_location, pstmt->stmt_len);
735  break;
736 
737  case T_ExecuteStmt:
738  ExecuteQuery(pstate,
739  (ExecuteStmt *) parsetree, NULL,
740  params,
741  dest, qc);
742  break;
743 
744  case T_DeallocateStmt:
745  CheckRestrictedOperation("DEALLOCATE");
746  DeallocateQuery((DeallocateStmt *) parsetree);
747  break;
748 
749  case T_GrantRoleStmt:
750  /* no event triggers for global objects */
751  GrantRole((GrantRoleStmt *) parsetree);
752  break;
753 
754  case T_CreatedbStmt:
755  /* no event triggers for global objects */
756  PreventInTransactionBlock(isTopLevel, "CREATE DATABASE");
757  createdb(pstate, (CreatedbStmt *) parsetree);
758  break;
759 
760  case T_AlterDatabaseStmt:
761  /* no event triggers for global objects */
762  AlterDatabase(pstate, (AlterDatabaseStmt *) parsetree, isTopLevel);
763  break;
764 
766  /* no event triggers for global objects */
767  AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
768  break;
769 
770  case T_DropdbStmt:
771  /* no event triggers for global objects */
772  PreventInTransactionBlock(isTopLevel, "DROP DATABASE");
773  DropDatabase(pstate, (DropdbStmt *) parsetree);
774  break;
775 
776  /* Query-level asynchronous notification */
777  case T_NotifyStmt:
778  {
779  NotifyStmt *stmt = (NotifyStmt *) parsetree;
780 
781  Async_Notify(stmt->conditionname, stmt->payload);
782  }
783  break;
784 
785  case T_ListenStmt:
786  {
787  ListenStmt *stmt = (ListenStmt *) parsetree;
788 
789  CheckRestrictedOperation("LISTEN");
791  }
792  break;
793 
794  case T_UnlistenStmt:
795  {
796  UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
797 
798  CheckRestrictedOperation("UNLISTEN");
799  if (stmt->conditionname)
801  else
803  }
804  break;
805 
806  case T_LoadStmt:
807  {
808  LoadStmt *stmt = (LoadStmt *) parsetree;
809 
810  closeAllVfds(); /* probably not necessary... */
811  /* Allowed names are restricted if you're not superuser */
812  load_file(stmt->filename, !superuser());
813  }
814  break;
815 
816  case T_CallStmt:
817  ExecuteCallStmt(castNode(CallStmt, parsetree), params, isAtomicContext, dest);
818  break;
819 
820  case T_ClusterStmt:
821  cluster((ClusterStmt *) parsetree, isTopLevel);
822  break;
823 
824  case T_VacuumStmt:
825  ExecVacuum(pstate, (VacuumStmt *) parsetree, isTopLevel);
826  break;
827 
828  case T_ExplainStmt:
829  ExplainQuery(pstate, (ExplainStmt *) parsetree, params, dest);
830  break;
831 
832  case T_AlterSystemStmt:
833  PreventInTransactionBlock(isTopLevel, "ALTER SYSTEM");
835  break;
836 
837  case T_VariableSetStmt:
838  ExecSetVariableStmt((VariableSetStmt *) parsetree, isTopLevel);
839  break;
840 
841  case T_VariableShowStmt:
842  {
843  VariableShowStmt *n = (VariableShowStmt *) parsetree;
844 
845  GetPGVariable(n->name, dest);
846  }
847  break;
848 
849  case T_DiscardStmt:
850  /* should we allow DISCARD PLANS? */
851  CheckRestrictedOperation("DISCARD");
852  DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
853  break;
854 
856  /* no event triggers on event triggers */
858  break;
859 
861  /* no event triggers on event triggers */
862  AlterEventTrigger((AlterEventTrigStmt *) parsetree);
863  break;
864 
865  /*
866  * ******************************** ROLE statements ****
867  */
868  case T_CreateRoleStmt:
869  /* no event triggers for global objects */
870  CreateRole(pstate, (CreateRoleStmt *) parsetree);
871  break;
872 
873  case T_AlterRoleStmt:
874  /* no event triggers for global objects */
875  AlterRole((AlterRoleStmt *) parsetree);
876  break;
877 
878  case T_AlterRoleSetStmt:
879  /* no event triggers for global objects */
880  AlterRoleSet((AlterRoleSetStmt *) parsetree);
881  break;
882 
883  case T_DropRoleStmt:
884  /* no event triggers for global objects */
885  DropRole((DropRoleStmt *) parsetree);
886  break;
887 
888  case T_ReassignOwnedStmt:
889  /* no event triggers for global objects */
891  break;
892 
893  case T_LockStmt:
894 
895  /*
896  * Since the lock would just get dropped immediately, LOCK TABLE
897  * outside a transaction block is presumed to be user error.
898  */
899  RequireTransactionBlock(isTopLevel, "LOCK TABLE");
900  LockTableCommand((LockStmt *) parsetree);
901  break;
902 
904  WarnNoTransactionBlock(isTopLevel, "SET CONSTRAINTS");
906  break;
907 
908  case T_CheckPointStmt:
909  if (!superuser())
910  ereport(ERROR,
911  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
912  errmsg("must be superuser to do CHECKPOINT")));
913 
916  break;
917 
918  case T_ReindexStmt:
919  {
920  ReindexStmt *stmt = (ReindexStmt *) parsetree;
921 
922  if ((stmt->options & REINDEXOPT_CONCURRENTLY) != 0)
923  PreventInTransactionBlock(isTopLevel,
924  "REINDEX CONCURRENTLY");
925 
926  switch (stmt->kind)
927  {
929  ReindexIndex(stmt->relation, stmt->options,
930  isTopLevel);
931  break;
933  ReindexTable(stmt->relation, stmt->options,
934  isTopLevel);
935  break;
939 
940  /*
941  * This cannot run inside a user transaction block; if
942  * we were inside a transaction, then its commit- and
943  * start-transaction-command calls would not have the
944  * intended effect!
945  */
946  PreventInTransactionBlock(isTopLevel,
947  (stmt->kind == REINDEX_OBJECT_SCHEMA) ? "REINDEX SCHEMA" :
948  (stmt->kind == REINDEX_OBJECT_SYSTEM) ? "REINDEX SYSTEM" :
949  "REINDEX DATABASE");
950  ReindexMultipleTables(stmt->name, stmt->kind, stmt->options);
951  break;
952  default:
953  elog(ERROR, "unrecognized object type: %d",
954  (int) stmt->kind);
955  break;
956  }
957  }
958  break;
959 
960  /*
961  * The following statements are supported by Event Triggers only
962  * in some cases, so we "fast path" them in the other cases.
963  */
964 
965  case T_GrantStmt:
966  {
967  GrantStmt *stmt = (GrantStmt *) parsetree;
968 
970  ProcessUtilitySlow(pstate, pstmt, queryString,
971  context, params, queryEnv,
972  dest, qc);
973  else
974  ExecuteGrantStmt(stmt);
975  }
976  break;
977 
978  case T_DropStmt:
979  {
980  DropStmt *stmt = (DropStmt *) parsetree;
981 
983  ProcessUtilitySlow(pstate, pstmt, queryString,
984  context, params, queryEnv,
985  dest, qc);
986  else
987  ExecDropStmt(stmt, isTopLevel);
988  }
989  break;
990 
991  case T_RenameStmt:
992  {
993  RenameStmt *stmt = (RenameStmt *) parsetree;
994 
996  ProcessUtilitySlow(pstate, pstmt, queryString,
997  context, params, queryEnv,
998  dest, qc);
999  else
1000  ExecRenameStmt(stmt);
1001  }
1002  break;
1003 
1005  {
1006  AlterObjectDependsStmt *stmt = (AlterObjectDependsStmt *) parsetree;
1007 
1009  ProcessUtilitySlow(pstate, pstmt, queryString,
1010  context, params, queryEnv,
1011  dest, qc);
1012  else
1013  ExecAlterObjectDependsStmt(stmt, NULL);
1014  }
1015  break;
1016 
1018  {
1019  AlterObjectSchemaStmt *stmt = (AlterObjectSchemaStmt *) parsetree;
1020 
1022  ProcessUtilitySlow(pstate, pstmt, queryString,
1023  context, params, queryEnv,
1024  dest, qc);
1025  else
1026  ExecAlterObjectSchemaStmt(stmt, NULL);
1027  }
1028  break;
1029 
1030  case T_AlterOwnerStmt:
1031  {
1032  AlterOwnerStmt *stmt = (AlterOwnerStmt *) parsetree;
1033 
1035  ProcessUtilitySlow(pstate, pstmt, queryString,
1036  context, params, queryEnv,
1037  dest, qc);
1038  else
1039  ExecAlterOwnerStmt(stmt);
1040  }
1041  break;
1042 
1043  case T_CommentStmt:
1044  {
1045  CommentStmt *stmt = (CommentStmt *) parsetree;
1046 
1048  ProcessUtilitySlow(pstate, pstmt, queryString,
1049  context, params, queryEnv,
1050  dest, qc);
1051  else
1052  CommentObject(stmt);
1053  break;
1054  }
1055 
1056  case T_SecLabelStmt:
1057  {
1058  SecLabelStmt *stmt = (SecLabelStmt *) parsetree;
1059 
1061  ProcessUtilitySlow(pstate, pstmt, queryString,
1062  context, params, queryEnv,
1063  dest, qc);
1064  else
1065  ExecSecLabelStmt(stmt);
1066  break;
1067  }
1068 
1069  default:
1070  /* All other statement types have event trigger support */
1071  ProcessUtilitySlow(pstate, pstmt, queryString,
1072  context, params, queryEnv,
1073  dest, qc);
1074  break;
1075  }
1076 
1077  free_parsestate(pstate);
1078 
1079  /*
1080  * Make effects of commands visible, for instance so that
1081  * PreCommit_on_commit_actions() can see them (see for example bug
1082  * #15631).
1083  */
1085 }
1086 
1087 /*
1088  * The "Slow" variant of ProcessUtility should only receive statements
1089  * supported by the event triggers facility. Therefore, we always
1090  * perform the trigger support calls if the context allows it.
1091  */
1092 static void
1094  PlannedStmt *pstmt,
1095  const char *queryString,
1096  ProcessUtilityContext context,
1097  ParamListInfo params,
1098  QueryEnvironment *queryEnv,
1099  DestReceiver *dest,
1100  QueryCompletion *qc)
1101 {
1102  Node *parsetree = pstmt->utilityStmt;
1103  bool isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
1104  bool isCompleteQuery = (context != PROCESS_UTILITY_SUBCOMMAND);
1105  bool needCleanup;
1106  bool commandCollected = false;
1107  ObjectAddress address;
1108  ObjectAddress secondaryObject = InvalidObjectAddress;
1109 
1110  /* All event trigger calls are done only when isCompleteQuery is true */
1111  needCleanup = isCompleteQuery && EventTriggerBeginCompleteQuery();
1112 
1113  /* PG_TRY block is to ensure we call EventTriggerEndCompleteQuery */
1114  PG_TRY();
1115  {
1116  if (isCompleteQuery)
1117  EventTriggerDDLCommandStart(parsetree);
1118 
1119  switch (nodeTag(parsetree))
1120  {
1121  /*
1122  * relation and attribute manipulation
1123  */
1124  case T_CreateSchemaStmt:
1125  CreateSchemaCommand((CreateSchemaStmt *) parsetree,
1126  queryString,
1127  pstmt->stmt_location,
1128  pstmt->stmt_len);
1129 
1130  /*
1131  * EventTriggerCollectSimpleCommand called by
1132  * CreateSchemaCommand
1133  */
1134  commandCollected = true;
1135  break;
1136 
1137  case T_CreateStmt:
1139  {
1140  List *stmts;
1141  ListCell *l;
1142  RangeVar *table_rv = NULL;
1143 
1144  /* Run parse analysis ... */
1145  stmts = transformCreateStmt((CreateStmt *) parsetree,
1146  queryString);
1147 
1148  /* ... and do it */
1149  foreach(l, stmts)
1150  {
1151  Node *stmt = (Node *) lfirst(l);
1152 
1153  if (IsA(stmt, CreateStmt))
1154  {
1155  CreateStmt *cstmt = (CreateStmt *) stmt;
1156  Datum toast_options;
1157  static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
1158 
1159  /* Remember transformed RangeVar for LIKE */
1160  table_rv = cstmt->relation;
1161 
1162  /* Create the table itself */
1163  address = DefineRelation(cstmt,
1164  RELKIND_RELATION,
1165  InvalidOid, NULL,
1166  queryString);
1168  secondaryObject,
1169  stmt);
1170 
1171  /*
1172  * Let NewRelationCreateToastTable decide if this
1173  * one needs a secondary relation too.
1174  */
1176 
1177  /*
1178  * parse and validate reloptions for the toast
1179  * table
1180  */
1181  toast_options = transformRelOptions((Datum) 0,
1182  cstmt->options,
1183  "toast",
1184  validnsps,
1185  true,
1186  false);
1187  (void) heap_reloptions(RELKIND_TOASTVALUE,
1188  toast_options,
1189  true);
1190 
1192  toast_options);
1193  }
1194  else if (IsA(stmt, CreateForeignTableStmt))
1195  {
1197 
1198  /* Remember transformed RangeVar for LIKE */
1199  table_rv = cstmt->base.relation;
1200 
1201  /* Create the table itself */
1202  address = DefineRelation(&cstmt->base,
1203  RELKIND_FOREIGN_TABLE,
1204  InvalidOid, NULL,
1205  queryString);
1206  CreateForeignTable(cstmt,
1207  address.objectId);
1209  secondaryObject,
1210  stmt);
1211  }
1212  else if (IsA(stmt, TableLikeClause))
1213  {
1214  /*
1215  * Do delayed processing of LIKE options. This
1216  * will result in additional sub-statements for us
1217  * to process. We can just tack those onto the
1218  * to-do list.
1219  */
1220  TableLikeClause *like = (TableLikeClause *) stmt;
1221  List *morestmts;
1222 
1223  Assert(table_rv != NULL);
1224 
1225  morestmts = expandTableLikeClause(table_rv, like);
1226  stmts = list_concat(stmts, morestmts);
1227 
1228  /*
1229  * We don't need a CCI now, besides which the "l"
1230  * list pointer is now possibly invalid, so just
1231  * skip the CCI test below.
1232  */
1233  continue;
1234  }
1235  else
1236  {
1237  /*
1238  * Recurse for anything else. Note the recursive
1239  * call will stash the objects so created into our
1240  * event trigger context.
1241  */
1242  PlannedStmt *wrapper;
1243 
1244  wrapper = makeNode(PlannedStmt);
1245  wrapper->commandType = CMD_UTILITY;
1246  wrapper->canSetTag = false;
1247  wrapper->utilityStmt = stmt;
1248  wrapper->stmt_location = pstmt->stmt_location;
1249  wrapper->stmt_len = pstmt->stmt_len;
1250 
1251  ProcessUtility(wrapper,
1252  queryString,
1254  params,
1255  NULL,
1256  None_Receiver,
1257  NULL);
1258  }
1259 
1260  /* Need CCI between commands */
1261  if (lnext(stmts, l) != NULL)
1263  }
1264 
1265  /*
1266  * The multiple commands generated here are stashed
1267  * individually, so disable collection below.
1268  */
1269  commandCollected = true;
1270  }
1271  break;
1272 
1273  case T_AlterTableStmt:
1274  {
1275  AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
1276  Oid relid;
1277  LOCKMODE lockmode;
1278 
1279  /*
1280  * Figure out lock mode, and acquire lock. This also does
1281  * basic permissions checks, so that we won't wait for a
1282  * lock on (for example) a relation on which we have no
1283  * permissions.
1284  */
1285  lockmode = AlterTableGetLockLevel(atstmt->cmds);
1286  relid = AlterTableLookupRelation(atstmt, lockmode);
1287 
1288  if (OidIsValid(relid))
1289  {
1290  AlterTableUtilityContext atcontext;
1291 
1292  /* Set up info needed for recursive callbacks ... */
1293  atcontext.pstmt = pstmt;
1294  atcontext.queryString = queryString;
1295  atcontext.relid = relid;
1296  atcontext.params = params;
1297  atcontext.queryEnv = queryEnv;
1298 
1299  /* ... ensure we have an event trigger context ... */
1300  EventTriggerAlterTableStart(parsetree);
1302 
1303  /* ... and do it */
1304  AlterTable(atstmt, lockmode, &atcontext);
1305 
1306  /* done */
1308  }
1309  else
1310  ereport(NOTICE,
1311  (errmsg("relation \"%s\" does not exist, skipping",
1312  atstmt->relation->relname)));
1313  }
1314 
1315  /* ALTER TABLE stashes commands internally */
1316  commandCollected = true;
1317  break;
1318 
1319  case T_AlterDomainStmt:
1320  {
1321  AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
1322 
1323  /*
1324  * Some or all of these functions are recursive to cover
1325  * inherited things, so permission checks are done there.
1326  */
1327  switch (stmt->subtype)
1328  {
1329  case 'T': /* ALTER DOMAIN DEFAULT */
1330 
1331  /*
1332  * Recursively alter column default for table and,
1333  * if requested, for descendants
1334  */
1335  address =
1337  stmt->def);
1338  break;
1339  case 'N': /* ALTER DOMAIN DROP NOT NULL */
1340  address =
1342  false);
1343  break;
1344  case 'O': /* ALTER DOMAIN SET NOT NULL */
1345  address =
1347  true);
1348  break;
1349  case 'C': /* ADD CONSTRAINT */
1350  address =
1352  stmt->def,
1353  &secondaryObject);
1354  break;
1355  case 'X': /* DROP CONSTRAINT */
1356  address =
1358  stmt->name,
1359  stmt->behavior,
1360  stmt->missing_ok);
1361  break;
1362  case 'V': /* VALIDATE CONSTRAINT */
1363  address =
1365  stmt->name);
1366  break;
1367  default: /* oops */
1368  elog(ERROR, "unrecognized alter domain type: %d",
1369  (int) stmt->subtype);
1370  break;
1371  }
1372  }
1373  break;
1374 
1375  /*
1376  * ************* object creation / destruction **************
1377  */
1378  case T_DefineStmt:
1379  {
1380  DefineStmt *stmt = (DefineStmt *) parsetree;
1381 
1382  switch (stmt->kind)
1383  {
1384  case OBJECT_AGGREGATE:
1385  address =
1386  DefineAggregate(pstate, stmt->defnames, stmt->args,
1387  stmt->oldstyle,
1388  stmt->definition,
1389  stmt->replace);
1390  break;
1391  case OBJECT_OPERATOR:
1392  Assert(stmt->args == NIL);
1393  address = DefineOperator(stmt->defnames,
1394  stmt->definition);
1395  break;
1396  case OBJECT_TYPE:
1397  Assert(stmt->args == NIL);
1398  address = DefineType(pstate,
1399  stmt->defnames,
1400  stmt->definition);
1401  break;
1402  case OBJECT_TSPARSER:
1403  Assert(stmt->args == NIL);
1404  address = DefineTSParser(stmt->defnames,
1405  stmt->definition);
1406  break;
1407  case OBJECT_TSDICTIONARY:
1408  Assert(stmt->args == NIL);
1409  address = DefineTSDictionary(stmt->defnames,
1410  stmt->definition);
1411  break;
1412  case OBJECT_TSTEMPLATE:
1413  Assert(stmt->args == NIL);
1414  address = DefineTSTemplate(stmt->defnames,
1415  stmt->definition);
1416  break;
1418  Assert(stmt->args == NIL);
1419  address = DefineTSConfiguration(stmt->defnames,
1420  stmt->definition,
1421  &secondaryObject);
1422  break;
1423  case OBJECT_COLLATION:
1424  Assert(stmt->args == NIL);
1425  address = DefineCollation(pstate,
1426  stmt->defnames,
1427  stmt->definition,
1428  stmt->if_not_exists);
1429  break;
1430  default:
1431  elog(ERROR, "unrecognized define stmt type: %d",
1432  (int) stmt->kind);
1433  break;
1434  }
1435  }
1436  break;
1437 
1438  case T_IndexStmt: /* CREATE INDEX */
1439  {
1440  IndexStmt *stmt = (IndexStmt *) parsetree;
1441  Oid relid;
1442  LOCKMODE lockmode;
1443  bool is_alter_table;
1444 
1445  if (stmt->concurrent)
1446  PreventInTransactionBlock(isTopLevel,
1447  "CREATE INDEX CONCURRENTLY");
1448 
1449  /*
1450  * Look up the relation OID just once, right here at the
1451  * beginning, so that we don't end up repeating the name
1452  * lookup later and latching onto a different relation
1453  * partway through. To avoid lock upgrade hazards, it's
1454  * important that we take the strongest lock that will
1455  * eventually be needed here, so the lockmode calculation
1456  * needs to match what DefineIndex() does.
1457  */
1458  lockmode = stmt->concurrent ? ShareUpdateExclusiveLock
1459  : ShareLock;
1460  relid =
1461  RangeVarGetRelidExtended(stmt->relation, lockmode,
1462  0,
1464  NULL);
1465 
1466  /*
1467  * CREATE INDEX on partitioned tables (but not regular
1468  * inherited tables) recurses to partitions, so we must
1469  * acquire locks early to avoid deadlocks.
1470  *
1471  * We also take the opportunity to verify that all
1472  * partitions are something we can put an index on, to
1473  * avoid building some indexes only to fail later.
1474  */
1475  if (stmt->relation->inh &&
1476  get_rel_relkind(relid) == RELKIND_PARTITIONED_TABLE)
1477  {
1478  ListCell *lc;
1479  List *inheritors = NIL;
1480 
1481  inheritors = find_all_inheritors(relid, lockmode, NULL);
1482  foreach(lc, inheritors)
1483  {
1484  char relkind = get_rel_relkind(lfirst_oid(lc));
1485 
1486  if (relkind != RELKIND_RELATION &&
1487  relkind != RELKIND_MATVIEW &&
1488  relkind != RELKIND_PARTITIONED_TABLE &&
1489  relkind != RELKIND_FOREIGN_TABLE)
1490  elog(ERROR, "unexpected relkind \"%c\" on partition \"%s\"",
1491  relkind, stmt->relation->relname);
1492 
1493  if (relkind == RELKIND_FOREIGN_TABLE &&
1494  (stmt->unique || stmt->primary))
1495  ereport(ERROR,
1496  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
1497  errmsg("cannot create unique index on partitioned table \"%s\"",
1498  stmt->relation->relname),
1499  errdetail("Table \"%s\" contains partitions that are foreign tables.",
1500  stmt->relation->relname)));
1501  }
1502  list_free(inheritors);
1503  }
1504 
1505  /*
1506  * If the IndexStmt is already transformed, it must have
1507  * come from generateClonedIndexStmt, which in current
1508  * usage means it came from expandTableLikeClause rather
1509  * than from original parse analysis. And that means we
1510  * must treat it like ALTER TABLE ADD INDEX, not CREATE.
1511  * (This is a bit grotty, but currently it doesn't seem
1512  * worth adding a separate bool field for the purpose.)
1513  */
1514  is_alter_table = stmt->transformed;
1515 
1516  /* Run parse analysis ... */
1517  stmt = transformIndexStmt(relid, stmt, queryString);
1518 
1519  /* ... and do it */
1520  EventTriggerAlterTableStart(parsetree);
1521  address =
1522  DefineIndex(relid, /* OID of heap relation */
1523  stmt,
1524  InvalidOid, /* no predefined OID */
1525  InvalidOid, /* no parent index */
1526  InvalidOid, /* no parent constraint */
1527  is_alter_table,
1528  true, /* check_rights */
1529  true, /* check_not_in_use */
1530  false, /* skip_build */
1531  false); /* quiet */
1532 
1533  /*
1534  * Add the CREATE INDEX node itself to stash right away;
1535  * if there were any commands stashed in the ALTER TABLE
1536  * code, we need them to appear after this one.
1537  */
1538  EventTriggerCollectSimpleCommand(address, secondaryObject,
1539  parsetree);
1540  commandCollected = true;
1542  }
1543  break;
1544 
1545  case T_CreateExtensionStmt:
1546  address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
1547  break;
1548 
1549  case T_AlterExtensionStmt:
1550  address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
1551  break;
1552 
1555  &secondaryObject);
1556  break;
1557 
1558  case T_CreateFdwStmt:
1559  address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1560  break;
1561 
1562  case T_AlterFdwStmt:
1563  address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1564  break;
1565 
1567  address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1568  break;
1569 
1571  address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1572  break;
1573 
1575  address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1576  break;
1577 
1579  address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1580  break;
1581 
1582  case T_DropUserMappingStmt:
1583  RemoveUserMapping((DropUserMappingStmt *) parsetree);
1584  /* no commands stashed for DROP */
1585  commandCollected = true;
1586  break;
1587 
1590  /* commands are stashed inside ImportForeignSchema */
1591  commandCollected = true;
1592  break;
1593 
1594  case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1595  {
1596  CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1597 
1598  address = DefineCompositeType(stmt->typevar,
1599  stmt->coldeflist);
1600  }
1601  break;
1602 
1603  case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1604  address = DefineEnum((CreateEnumStmt *) parsetree);
1605  break;
1606 
1607  case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1608  address = DefineRange((CreateRangeStmt *) parsetree);
1609  break;
1610 
1611  case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1612  address = AlterEnum((AlterEnumStmt *) parsetree);
1613  break;
1614 
1615  case T_ViewStmt: /* CREATE VIEW */
1616  EventTriggerAlterTableStart(parsetree);
1617  address = DefineView((ViewStmt *) parsetree, queryString,
1618  pstmt->stmt_location, pstmt->stmt_len);
1619  EventTriggerCollectSimpleCommand(address, secondaryObject,
1620  parsetree);
1621  /* stashed internally */
1622  commandCollected = true;
1624  break;
1625 
1626  case T_CreateFunctionStmt: /* CREATE FUNCTION */
1627  address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
1628  break;
1629 
1630  case T_AlterFunctionStmt: /* ALTER FUNCTION */
1631  address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
1632  break;
1633 
1634  case T_RuleStmt: /* CREATE RULE */
1635  address = DefineRule((RuleStmt *) parsetree, queryString);
1636  break;
1637 
1638  case T_CreateSeqStmt:
1639  address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
1640  break;
1641 
1642  case T_AlterSeqStmt:
1643  address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
1644  break;
1645 
1646  case T_CreateTableAsStmt:
1647  address = ExecCreateTableAs(pstate, (CreateTableAsStmt *) parsetree,
1648  params, queryEnv, qc);
1649  break;
1650 
1651  case T_RefreshMatViewStmt:
1652 
1653  /*
1654  * REFRESH CONCURRENTLY executes some DDL commands internally.
1655  * Inhibit DDL command collection here to avoid those commands
1656  * from showing up in the deparsed command queue. The refresh
1657  * command itself is queued, which is enough.
1658  */
1660  PG_TRY();
1661  {
1662  address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1663  queryString, params, qc);
1664  }
1665  PG_FINALLY();
1666  {
1668  }
1669  PG_END_TRY();
1670  break;
1671 
1672  case T_CreateTrigStmt:
1673  address = CreateTrigger((CreateTrigStmt *) parsetree,
1674  queryString, InvalidOid, InvalidOid,
1676  InvalidOid, NULL, false, false);
1677  break;
1678 
1679  case T_CreatePLangStmt:
1680  address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1681  break;
1682 
1683  case T_CreateDomainStmt:
1684  address = DefineDomain((CreateDomainStmt *) parsetree);
1685  break;
1686 
1688  address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1689  break;
1690 
1691  case T_CreateCastStmt:
1692  address = CreateCast((CreateCastStmt *) parsetree);
1693  break;
1694 
1695  case T_CreateOpClassStmt:
1696  DefineOpClass((CreateOpClassStmt *) parsetree);
1697  /* command is stashed in DefineOpClass */
1698  commandCollected = true;
1699  break;
1700 
1701  case T_CreateOpFamilyStmt:
1702  address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1703  break;
1704 
1705  case T_CreateTransformStmt:
1706  address = CreateTransform((CreateTransformStmt *) parsetree);
1707  break;
1708 
1709  case T_AlterOpFamilyStmt:
1710  AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1711  /* commands are stashed in AlterOpFamily */
1712  commandCollected = true;
1713  break;
1714 
1716  address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1717  break;
1718 
1721 
1722  /*
1723  * Commands are stashed in MakeConfigurationMapping and
1724  * DropConfigurationMapping, which are called from
1725  * AlterTSConfiguration
1726  */
1727  commandCollected = true;
1728  break;
1729 
1732  /* commands are stashed in AlterTableMoveAll */
1733  commandCollected = true;
1734  break;
1735 
1736  case T_DropStmt:
1737  ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1738  /* no commands stashed for DROP */
1739  commandCollected = true;
1740  break;
1741 
1742  case T_RenameStmt:
1743  address = ExecRenameStmt((RenameStmt *) parsetree);
1744  break;
1745 
1747  address =
1749  &secondaryObject);
1750  break;
1751 
1753  address =
1755  &secondaryObject);
1756  break;
1757 
1758  case T_AlterOwnerStmt:
1759  address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1760  break;
1761 
1762  case T_AlterOperatorStmt:
1763  address = AlterOperator((AlterOperatorStmt *) parsetree);
1764  break;
1765 
1766  case T_AlterTypeStmt:
1767  address = AlterType((AlterTypeStmt *) parsetree);
1768  break;
1769 
1770  case T_CommentStmt:
1771  address = CommentObject((CommentStmt *) parsetree);
1772  break;
1773 
1774  case T_GrantStmt:
1775  ExecuteGrantStmt((GrantStmt *) parsetree);
1776  /* commands are stashed in ExecGrantStmt_oids */
1777  commandCollected = true;
1778  break;
1779 
1780  case T_DropOwnedStmt:
1781  DropOwnedObjects((DropOwnedStmt *) parsetree);
1782  /* no commands stashed for DROP */
1783  commandCollected = true;
1784  break;
1785 
1789  commandCollected = true;
1790  break;
1791 
1792  case T_CreatePolicyStmt: /* CREATE POLICY */
1793  address = CreatePolicy((CreatePolicyStmt *) parsetree);
1794  break;
1795 
1796  case T_AlterPolicyStmt: /* ALTER POLICY */
1797  address = AlterPolicy((AlterPolicyStmt *) parsetree);
1798  break;
1799 
1800  case T_SecLabelStmt:
1801  address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1802  break;
1803 
1804  case T_CreateAmStmt:
1805  address = CreateAccessMethod((CreateAmStmt *) parsetree);
1806  break;
1807 
1809  address = CreatePublication((CreatePublicationStmt *) parsetree);
1810  break;
1811 
1813  AlterPublication((AlterPublicationStmt *) parsetree);
1814 
1815  /*
1816  * AlterPublication calls EventTriggerCollectSimpleCommand
1817  * directly
1818  */
1819  commandCollected = true;
1820  break;
1821 
1823  address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
1824  isTopLevel);
1825  break;
1826 
1828  address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
1829  break;
1830 
1832  DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
1833  /* no commands stashed for DROP */
1834  commandCollected = true;
1835  break;
1836 
1837  case T_CreateStatsStmt:
1838  address = CreateStatistics((CreateStatsStmt *) parsetree);
1839  break;
1840 
1841  case T_AlterStatsStmt:
1842  address = AlterStatistics((AlterStatsStmt *) parsetree);
1843  break;
1844 
1845  case T_AlterCollationStmt:
1846  address = AlterCollation((AlterCollationStmt *) parsetree);
1847  break;
1848 
1849  default:
1850  elog(ERROR, "unrecognized node type: %d",
1851  (int) nodeTag(parsetree));
1852  break;
1853  }
1854 
1855  /*
1856  * Remember the object so that ddl_command_end event triggers have
1857  * access to it.
1858  */
1859  if (!commandCollected)
1860  EventTriggerCollectSimpleCommand(address, secondaryObject,
1861  parsetree);
1862 
1863  if (isCompleteQuery)
1864  {
1865  EventTriggerSQLDrop(parsetree);
1866  EventTriggerDDLCommandEnd(parsetree);
1867  }
1868  }
1869  PG_FINALLY();
1870  {
1871  if (needCleanup)
1873  }
1874  PG_END_TRY();
1875 }
1876 
1877 /*
1878  * ProcessUtilityForAlterTable
1879  * Recursive entry from ALTER TABLE
1880  *
1881  * ALTER TABLE sometimes generates subcommands such as CREATE INDEX.
1882  * It calls this, not the main entry point ProcessUtility, to execute
1883  * such subcommands.
1884  *
1885  * stmt: the utility command to execute
1886  * context: opaque passthrough struct with the info we need
1887  *
1888  * It's caller's responsibility to do CommandCounterIncrement after
1889  * calling this, if needed.
1890  */
1891 void
1893 {
1894  PlannedStmt *wrapper;
1895 
1896  /*
1897  * For event triggers, we must "close" the current complex-command set,
1898  * and start a new one afterwards; this is needed to ensure the ordering
1899  * of command events is consistent with the way they were executed.
1900  */
1902 
1903  /* Create a suitable wrapper */
1904  wrapper = makeNode(PlannedStmt);
1905  wrapper->commandType = CMD_UTILITY;
1906  wrapper->canSetTag = false;
1907  wrapper->utilityStmt = stmt;
1908  wrapper->stmt_location = context->pstmt->stmt_location;
1909  wrapper->stmt_len = context->pstmt->stmt_len;
1910 
1911  ProcessUtility(wrapper,
1912  context->queryString,
1914  context->params,
1915  context->queryEnv,
1916  None_Receiver,
1917  NULL);
1918 
1921 }
1922 
1923 /*
1924  * Dispatch function for DropStmt
1925  */
1926 static void
1927 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1928 {
1929  switch (stmt->removeType)
1930  {
1931  case OBJECT_INDEX:
1932  if (stmt->concurrent)
1933  PreventInTransactionBlock(isTopLevel,
1934  "DROP INDEX CONCURRENTLY");
1935  /* fall through */
1936 
1937  case OBJECT_TABLE:
1938  case OBJECT_SEQUENCE:
1939  case OBJECT_VIEW:
1940  case OBJECT_MATVIEW:
1941  case OBJECT_FOREIGN_TABLE:
1942  RemoveRelations(stmt);
1943  break;
1944  default:
1945  RemoveObjects(stmt);
1946  break;
1947  }
1948 }
1949 
1950 
1951 /*
1952  * UtilityReturnsTuples
1953  * Return "true" if this utility statement will send output to the
1954  * destination.
1955  *
1956  * Generally, there should be a case here for each case in ProcessUtility
1957  * where "dest" is passed on.
1958  */
1959 bool
1961 {
1962  switch (nodeTag(parsetree))
1963  {
1964  case T_CallStmt:
1965  {
1966  CallStmt *stmt = (CallStmt *) parsetree;
1967 
1968  return (stmt->funcexpr->funcresulttype == RECORDOID);
1969  }
1970  case T_FetchStmt:
1971  {
1972  FetchStmt *stmt = (FetchStmt *) parsetree;
1973  Portal portal;
1974 
1975  if (stmt->ismove)
1976  return false;
1977  portal = GetPortalByName(stmt->portalname);
1978  if (!PortalIsValid(portal))
1979  return false; /* not our business to raise error */
1980  return portal->tupDesc ? true : false;
1981  }
1982 
1983  case T_ExecuteStmt:
1984  {
1985  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1986  PreparedStatement *entry;
1987 
1988  entry = FetchPreparedStatement(stmt->name, false);
1989  if (!entry)
1990  return false; /* not our business to raise error */
1991  if (entry->plansource->resultDesc)
1992  return true;
1993  return false;
1994  }
1995 
1996  case T_ExplainStmt:
1997  return true;
1998 
1999  case T_VariableShowStmt:
2000  return true;
2001 
2002  default:
2003  return false;
2004  }
2005 }
2006 
2007 /*
2008  * UtilityTupleDescriptor
2009  * Fetch the actual output tuple descriptor for a utility statement
2010  * for which UtilityReturnsTuples() previously returned "true".
2011  *
2012  * The returned descriptor is created in (or copied into) the current memory
2013  * context.
2014  */
2015 TupleDesc
2017 {
2018  switch (nodeTag(parsetree))
2019  {
2020  case T_CallStmt:
2021  return CallStmtResultDesc((CallStmt *) parsetree);
2022 
2023  case T_FetchStmt:
2024  {
2025  FetchStmt *stmt = (FetchStmt *) parsetree;
2026  Portal portal;
2027 
2028  if (stmt->ismove)
2029  return NULL;
2030  portal = GetPortalByName(stmt->portalname);
2031  if (!PortalIsValid(portal))
2032  return NULL; /* not our business to raise error */
2033  return CreateTupleDescCopy(portal->tupDesc);
2034  }
2035 
2036  case T_ExecuteStmt:
2037  {
2038  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2039  PreparedStatement *entry;
2040 
2041  entry = FetchPreparedStatement(stmt->name, false);
2042  if (!entry)
2043  return NULL; /* not our business to raise error */
2044  return FetchPreparedStatementResultDesc(entry);
2045  }
2046 
2047  case T_ExplainStmt:
2048  return ExplainResultDesc((ExplainStmt *) parsetree);
2049 
2050  case T_VariableShowStmt:
2051  {
2052  VariableShowStmt *n = (VariableShowStmt *) parsetree;
2053 
2054  return GetPGVariableResultDesc(n->name);
2055  }
2056 
2057  default:
2058  return NULL;
2059  }
2060 }
2061 
2062 
2063 /*
2064  * QueryReturnsTuples
2065  * Return "true" if this Query will send output to the destination.
2066  */
2067 #ifdef NOT_USED
2068 bool
2069 QueryReturnsTuples(Query *parsetree)
2070 {
2071  switch (parsetree->commandType)
2072  {
2073  case CMD_SELECT:
2074  /* returns tuples */
2075  return true;
2076  case CMD_INSERT:
2077  case CMD_UPDATE:
2078  case CMD_DELETE:
2079  /* the forms with RETURNING return tuples */
2080  if (parsetree->returningList)
2081  return true;
2082  break;
2083  case CMD_UTILITY:
2084  return UtilityReturnsTuples(parsetree->utilityStmt);
2085  case CMD_UNKNOWN:
2086  case CMD_NOTHING:
2087  /* probably shouldn't get here */
2088  break;
2089  }
2090  return false; /* default */
2091 }
2092 #endif
2093 
2094 
2095 /*
2096  * UtilityContainsQuery
2097  * Return the contained Query, or NULL if there is none
2098  *
2099  * Certain utility statements, such as EXPLAIN, contain a plannable Query.
2100  * This function encapsulates knowledge of exactly which ones do.
2101  * We assume it is invoked only on already-parse-analyzed statements
2102  * (else the contained parsetree isn't a Query yet).
2103  *
2104  * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
2105  * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
2106  * can be nested. This function will drill down to a non-utility Query, or
2107  * return NULL if none.
2108  */
2109 Query *
2111 {
2112  Query *qry;
2113 
2114  switch (nodeTag(parsetree))
2115  {
2116  case T_DeclareCursorStmt:
2117  qry = castNode(Query, ((DeclareCursorStmt *) parsetree)->query);
2118  if (qry->commandType == CMD_UTILITY)
2119  return UtilityContainsQuery(qry->utilityStmt);
2120  return qry;
2121 
2122  case T_ExplainStmt:
2123  qry = castNode(Query, ((ExplainStmt *) parsetree)->query);
2124  if (qry->commandType == CMD_UTILITY)
2125  return UtilityContainsQuery(qry->utilityStmt);
2126  return qry;
2127 
2128  case T_CreateTableAsStmt:
2129  qry = castNode(Query, ((CreateTableAsStmt *) parsetree)->query);
2130  if (qry->commandType == CMD_UTILITY)
2131  return UtilityContainsQuery(qry->utilityStmt);
2132  return qry;
2133 
2134  default:
2135  return NULL;
2136  }
2137 }
2138 
2139 
2140 /*
2141  * AlterObjectTypeCommandTag
2142  * helper function for CreateCommandTag
2143  *
2144  * This covers most cases where ALTER is used with an ObjectType enum.
2145  */
2146 static CommandTag
2148 {
2149  CommandTag tag;
2150 
2151  switch (objtype)
2152  {
2153  case OBJECT_AGGREGATE:
2154  tag = CMDTAG_ALTER_AGGREGATE;
2155  break;
2156  case OBJECT_ATTRIBUTE:
2157  tag = CMDTAG_ALTER_TYPE;
2158  break;
2159  case OBJECT_CAST:
2160  tag = CMDTAG_ALTER_CAST;
2161  break;
2162  case OBJECT_COLLATION:
2163  tag = CMDTAG_ALTER_COLLATION;
2164  break;
2165  case OBJECT_COLUMN:
2166  tag = CMDTAG_ALTER_TABLE;
2167  break;
2168  case OBJECT_CONVERSION:
2169  tag = CMDTAG_ALTER_CONVERSION;
2170  break;
2171  case OBJECT_DATABASE:
2172  tag = CMDTAG_ALTER_DATABASE;
2173  break;
2174  case OBJECT_DOMAIN:
2175  case OBJECT_DOMCONSTRAINT:
2176  tag = CMDTAG_ALTER_DOMAIN;
2177  break;
2178  case OBJECT_EXTENSION:
2179  tag = CMDTAG_ALTER_EXTENSION;
2180  break;
2181  case OBJECT_FDW:
2182  tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
2183  break;
2184  case OBJECT_FOREIGN_SERVER:
2185  tag = CMDTAG_ALTER_SERVER;
2186  break;
2187  case OBJECT_FOREIGN_TABLE:
2188  tag = CMDTAG_ALTER_FOREIGN_TABLE;
2189  break;
2190  case OBJECT_FUNCTION:
2191  tag = CMDTAG_ALTER_FUNCTION;
2192  break;
2193  case OBJECT_INDEX:
2194  tag = CMDTAG_ALTER_INDEX;
2195  break;
2196  case OBJECT_LANGUAGE:
2197  tag = CMDTAG_ALTER_LANGUAGE;
2198  break;
2199  case OBJECT_LARGEOBJECT:
2200  tag = CMDTAG_ALTER_LARGE_OBJECT;
2201  break;
2202  case OBJECT_OPCLASS:
2203  tag = CMDTAG_ALTER_OPERATOR_CLASS;
2204  break;
2205  case OBJECT_OPERATOR:
2206  tag = CMDTAG_ALTER_OPERATOR;
2207  break;
2208  case OBJECT_OPFAMILY:
2209  tag = CMDTAG_ALTER_OPERATOR_FAMILY;
2210  break;
2211  case OBJECT_POLICY:
2212  tag = CMDTAG_ALTER_POLICY;
2213  break;
2214  case OBJECT_PROCEDURE:
2215  tag = CMDTAG_ALTER_PROCEDURE;
2216  break;
2217  case OBJECT_ROLE:
2218  tag = CMDTAG_ALTER_ROLE;
2219  break;
2220  case OBJECT_ROUTINE:
2221  tag = CMDTAG_ALTER_ROUTINE;
2222  break;
2223  case OBJECT_RULE:
2224  tag = CMDTAG_ALTER_RULE;
2225  break;
2226  case OBJECT_SCHEMA:
2227  tag = CMDTAG_ALTER_SCHEMA;
2228  break;
2229  case OBJECT_SEQUENCE:
2230  tag = CMDTAG_ALTER_SEQUENCE;
2231  break;
2232  case OBJECT_TABLE:
2233  case OBJECT_TABCONSTRAINT:
2234  tag = CMDTAG_ALTER_TABLE;
2235  break;
2236  case OBJECT_TABLESPACE:
2237  tag = CMDTAG_ALTER_TABLESPACE;
2238  break;
2239  case OBJECT_TRIGGER:
2240  tag = CMDTAG_ALTER_TRIGGER;
2241  break;
2242  case OBJECT_EVENT_TRIGGER:
2243  tag = CMDTAG_ALTER_EVENT_TRIGGER;
2244  break;
2246  tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
2247  break;
2248  case OBJECT_TSDICTIONARY:
2249  tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
2250  break;
2251  case OBJECT_TSPARSER:
2252  tag = CMDTAG_ALTER_TEXT_SEARCH_PARSER;
2253  break;
2254  case OBJECT_TSTEMPLATE:
2255  tag = CMDTAG_ALTER_TEXT_SEARCH_TEMPLATE;
2256  break;
2257  case OBJECT_TYPE:
2258  tag = CMDTAG_ALTER_TYPE;
2259  break;
2260  case OBJECT_VIEW:
2261  tag = CMDTAG_ALTER_VIEW;
2262  break;
2263  case OBJECT_MATVIEW:
2264  tag = CMDTAG_ALTER_MATERIALIZED_VIEW;
2265  break;
2266  case OBJECT_PUBLICATION:
2267  tag = CMDTAG_ALTER_PUBLICATION;
2268  break;
2269  case OBJECT_SUBSCRIPTION:
2270  tag = CMDTAG_ALTER_SUBSCRIPTION;
2271  break;
2272  case OBJECT_STATISTIC_EXT:
2273  tag = CMDTAG_ALTER_STATISTICS;
2274  break;
2275  default:
2276  tag = CMDTAG_UNKNOWN;
2277  break;
2278  }
2279 
2280  return tag;
2281 }
2282 
2283 /*
2284  * CreateCommandTag
2285  * utility to get a CommandTag for the command operation,
2286  * given either a raw (un-analyzed) parsetree, an analyzed Query,
2287  * or a PlannedStmt.
2288  *
2289  * This must handle all command types, but since the vast majority
2290  * of 'em are utility commands, it seems sensible to keep it here.
2291  */
2292 CommandTag
2294 {
2295  CommandTag tag;
2296 
2297  switch (nodeTag(parsetree))
2298  {
2299  /* recurse if we're given a RawStmt */
2300  case T_RawStmt:
2301  tag = CreateCommandTag(((RawStmt *) parsetree)->stmt);
2302  break;
2303 
2304  /* raw plannable queries */
2305  case T_InsertStmt:
2306  tag = CMDTAG_INSERT;
2307  break;
2308 
2309  case T_DeleteStmt:
2310  tag = CMDTAG_DELETE;
2311  break;
2312 
2313  case T_UpdateStmt:
2314  tag = CMDTAG_UPDATE;
2315  break;
2316 
2317  case T_SelectStmt:
2318  tag = CMDTAG_SELECT;
2319  break;
2320 
2321  /* utility statements --- same whether raw or cooked */
2322  case T_TransactionStmt:
2323  {
2324  TransactionStmt *stmt = (TransactionStmt *) parsetree;
2325 
2326  switch (stmt->kind)
2327  {
2328  case TRANS_STMT_BEGIN:
2329  tag = CMDTAG_BEGIN;
2330  break;
2331 
2332  case TRANS_STMT_START:
2333  tag = CMDTAG_START_TRANSACTION;
2334  break;
2335 
2336  case TRANS_STMT_COMMIT:
2337  tag = CMDTAG_COMMIT;
2338  break;
2339 
2340  case TRANS_STMT_ROLLBACK:
2342  tag = CMDTAG_ROLLBACK;
2343  break;
2344 
2345  case TRANS_STMT_SAVEPOINT:
2346  tag = CMDTAG_SAVEPOINT;
2347  break;
2348 
2349  case TRANS_STMT_RELEASE:
2350  tag = CMDTAG_RELEASE;
2351  break;
2352 
2353  case TRANS_STMT_PREPARE:
2354  tag = CMDTAG_PREPARE_TRANSACTION;
2355  break;
2356 
2358  tag = CMDTAG_COMMIT_PREPARED;
2359  break;
2360 
2362  tag = CMDTAG_ROLLBACK_PREPARED;
2363  break;
2364 
2365  default:
2366  tag = CMDTAG_UNKNOWN;
2367  break;
2368  }
2369  }
2370  break;
2371 
2372  case T_DeclareCursorStmt:
2373  tag = CMDTAG_DECLARE_CURSOR;
2374  break;
2375 
2376  case T_ClosePortalStmt:
2377  {
2378  ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
2379 
2380  if (stmt->portalname == NULL)
2381  tag = CMDTAG_CLOSE_CURSOR_ALL;
2382  else
2383  tag = CMDTAG_CLOSE_CURSOR;
2384  }
2385  break;
2386 
2387  case T_FetchStmt:
2388  {
2389  FetchStmt *stmt = (FetchStmt *) parsetree;
2390 
2391  tag = (stmt->ismove) ? CMDTAG_MOVE : CMDTAG_FETCH;
2392  }
2393  break;
2394 
2395  case T_CreateDomainStmt:
2396  tag = CMDTAG_CREATE_DOMAIN;
2397  break;
2398 
2399  case T_CreateSchemaStmt:
2400  tag = CMDTAG_CREATE_SCHEMA;
2401  break;
2402 
2403  case T_CreateStmt:
2404  tag = CMDTAG_CREATE_TABLE;
2405  break;
2406 
2408  tag = CMDTAG_CREATE_TABLESPACE;
2409  break;
2410 
2411  case T_DropTableSpaceStmt:
2412  tag = CMDTAG_DROP_TABLESPACE;
2413  break;
2414 
2416  tag = CMDTAG_ALTER_TABLESPACE;
2417  break;
2418 
2419  case T_CreateExtensionStmt:
2420  tag = CMDTAG_CREATE_EXTENSION;
2421  break;
2422 
2423  case T_AlterExtensionStmt:
2424  tag = CMDTAG_ALTER_EXTENSION;
2425  break;
2426 
2428  tag = CMDTAG_ALTER_EXTENSION;
2429  break;
2430 
2431  case T_CreateFdwStmt:
2432  tag = CMDTAG_CREATE_FOREIGN_DATA_WRAPPER;
2433  break;
2434 
2435  case T_AlterFdwStmt:
2436  tag = CMDTAG_ALTER_FOREIGN_DATA_WRAPPER;
2437  break;
2438 
2440  tag = CMDTAG_CREATE_SERVER;
2441  break;
2442 
2444  tag = CMDTAG_ALTER_SERVER;
2445  break;
2446 
2448  tag = CMDTAG_CREATE_USER_MAPPING;
2449  break;
2450 
2452  tag = CMDTAG_ALTER_USER_MAPPING;
2453  break;
2454 
2455  case T_DropUserMappingStmt:
2456  tag = CMDTAG_DROP_USER_MAPPING;
2457  break;
2458 
2460  tag = CMDTAG_CREATE_FOREIGN_TABLE;
2461  break;
2462 
2464  tag = CMDTAG_IMPORT_FOREIGN_SCHEMA;
2465  break;
2466 
2467  case T_DropStmt:
2468  switch (((DropStmt *) parsetree)->removeType)
2469  {
2470  case OBJECT_TABLE:
2471  tag = CMDTAG_DROP_TABLE;
2472  break;
2473  case OBJECT_SEQUENCE:
2474  tag = CMDTAG_DROP_SEQUENCE;
2475  break;
2476  case OBJECT_VIEW:
2477  tag = CMDTAG_DROP_VIEW;
2478  break;
2479  case OBJECT_MATVIEW:
2480  tag = CMDTAG_DROP_MATERIALIZED_VIEW;
2481  break;
2482  case OBJECT_INDEX:
2483  tag = CMDTAG_DROP_INDEX;
2484  break;
2485  case OBJECT_TYPE:
2486  tag = CMDTAG_DROP_TYPE;
2487  break;
2488  case OBJECT_DOMAIN:
2489  tag = CMDTAG_DROP_DOMAIN;
2490  break;
2491  case OBJECT_COLLATION:
2492  tag = CMDTAG_DROP_COLLATION;
2493  break;
2494  case OBJECT_CONVERSION:
2495  tag = CMDTAG_DROP_CONVERSION;
2496  break;
2497  case OBJECT_SCHEMA:
2498  tag = CMDTAG_DROP_SCHEMA;
2499  break;
2500  case OBJECT_TSPARSER:
2501  tag = CMDTAG_DROP_TEXT_SEARCH_PARSER;
2502  break;
2503  case OBJECT_TSDICTIONARY:
2504  tag = CMDTAG_DROP_TEXT_SEARCH_DICTIONARY;
2505  break;
2506  case OBJECT_TSTEMPLATE:
2507  tag = CMDTAG_DROP_TEXT_SEARCH_TEMPLATE;
2508  break;
2510  tag = CMDTAG_DROP_TEXT_SEARCH_CONFIGURATION;
2511  break;
2512  case OBJECT_FOREIGN_TABLE:
2513  tag = CMDTAG_DROP_FOREIGN_TABLE;
2514  break;
2515  case OBJECT_EXTENSION:
2516  tag = CMDTAG_DROP_EXTENSION;
2517  break;
2518  case OBJECT_FUNCTION:
2519  tag = CMDTAG_DROP_FUNCTION;
2520  break;
2521  case OBJECT_PROCEDURE:
2522  tag = CMDTAG_DROP_PROCEDURE;
2523  break;
2524  case OBJECT_ROUTINE:
2525  tag = CMDTAG_DROP_ROUTINE;
2526  break;
2527  case OBJECT_AGGREGATE:
2528  tag = CMDTAG_DROP_AGGREGATE;
2529  break;
2530  case OBJECT_OPERATOR:
2531  tag = CMDTAG_DROP_OPERATOR;
2532  break;
2533  case OBJECT_LANGUAGE:
2534  tag = CMDTAG_DROP_LANGUAGE;
2535  break;
2536  case OBJECT_CAST:
2537  tag = CMDTAG_DROP_CAST;
2538  break;
2539  case OBJECT_TRIGGER:
2540  tag = CMDTAG_DROP_TRIGGER;
2541  break;
2542  case OBJECT_EVENT_TRIGGER:
2543  tag = CMDTAG_DROP_EVENT_TRIGGER;
2544  break;
2545  case OBJECT_RULE:
2546  tag = CMDTAG_DROP_RULE;
2547  break;
2548  case OBJECT_FDW:
2549  tag = CMDTAG_DROP_FOREIGN_DATA_WRAPPER;
2550  break;
2551  case OBJECT_FOREIGN_SERVER:
2552  tag = CMDTAG_DROP_SERVER;
2553  break;
2554  case OBJECT_OPCLASS:
2555  tag = CMDTAG_DROP_OPERATOR_CLASS;
2556  break;
2557  case OBJECT_OPFAMILY:
2558  tag = CMDTAG_DROP_OPERATOR_FAMILY;
2559  break;
2560  case OBJECT_POLICY:
2561  tag = CMDTAG_DROP_POLICY;
2562  break;
2563  case OBJECT_TRANSFORM:
2564  tag = CMDTAG_DROP_TRANSFORM;
2565  break;
2566  case OBJECT_ACCESS_METHOD:
2567  tag = CMDTAG_DROP_ACCESS_METHOD;
2568  break;
2569  case OBJECT_PUBLICATION:
2570  tag = CMDTAG_DROP_PUBLICATION;
2571  break;
2572  case OBJECT_STATISTIC_EXT:
2573  tag = CMDTAG_DROP_STATISTICS;
2574  break;
2575  default:
2576  tag = CMDTAG_UNKNOWN;
2577  }
2578  break;
2579 
2580  case T_TruncateStmt:
2581  tag = CMDTAG_TRUNCATE_TABLE;
2582  break;
2583 
2584  case T_CommentStmt:
2585  tag = CMDTAG_COMMENT;
2586  break;
2587 
2588  case T_SecLabelStmt:
2589  tag = CMDTAG_SECURITY_LABEL;
2590  break;
2591 
2592  case T_CopyStmt:
2593  tag = CMDTAG_COPY;
2594  break;
2595 
2596  case T_RenameStmt:
2597 
2598  /*
2599  * When the column is renamed, the command tag is created from its
2600  * relation type
2601  */
2602  tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType == OBJECT_COLUMN ?
2603  ((RenameStmt *) parsetree)->relationType :
2604  ((RenameStmt *) parsetree)->renameType);
2605  break;
2606 
2608  tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
2609  break;
2610 
2612  tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2613  break;
2614 
2615  case T_AlterOwnerStmt:
2616  tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2617  break;
2618 
2620  tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2621  break;
2622 
2623  case T_AlterTableStmt:
2624  tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->objtype);
2625  break;
2626 
2627  case T_AlterDomainStmt:
2628  tag = CMDTAG_ALTER_DOMAIN;
2629  break;
2630 
2631  case T_AlterFunctionStmt:
2632  switch (((AlterFunctionStmt *) parsetree)->objtype)
2633  {
2634  case OBJECT_FUNCTION:
2635  tag = CMDTAG_ALTER_FUNCTION;
2636  break;
2637  case OBJECT_PROCEDURE:
2638  tag = CMDTAG_ALTER_PROCEDURE;
2639  break;
2640  case OBJECT_ROUTINE:
2641  tag = CMDTAG_ALTER_ROUTINE;
2642  break;
2643  default:
2644  tag = CMDTAG_UNKNOWN;
2645  }
2646  break;
2647 
2648  case T_GrantStmt:
2649  {
2650  GrantStmt *stmt = (GrantStmt *) parsetree;
2651 
2652  tag = (stmt->is_grant) ? CMDTAG_GRANT : CMDTAG_REVOKE;
2653  }
2654  break;
2655 
2656  case T_GrantRoleStmt:
2657  {
2658  GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2659 
2660  tag = (stmt->is_grant) ? CMDTAG_GRANT_ROLE : CMDTAG_REVOKE_ROLE;
2661  }
2662  break;
2663 
2665  tag = CMDTAG_ALTER_DEFAULT_PRIVILEGES;
2666  break;
2667 
2668  case T_DefineStmt:
2669  switch (((DefineStmt *) parsetree)->kind)
2670  {
2671  case OBJECT_AGGREGATE:
2672  tag = CMDTAG_CREATE_AGGREGATE;
2673  break;
2674  case OBJECT_OPERATOR:
2675  tag = CMDTAG_CREATE_OPERATOR;
2676  break;
2677  case OBJECT_TYPE:
2678  tag = CMDTAG_CREATE_TYPE;
2679  break;
2680  case OBJECT_TSPARSER:
2681  tag = CMDTAG_CREATE_TEXT_SEARCH_PARSER;
2682  break;
2683  case OBJECT_TSDICTIONARY:
2684  tag = CMDTAG_CREATE_TEXT_SEARCH_DICTIONARY;
2685  break;
2686  case OBJECT_TSTEMPLATE:
2687  tag = CMDTAG_CREATE_TEXT_SEARCH_TEMPLATE;
2688  break;
2690  tag = CMDTAG_CREATE_TEXT_SEARCH_CONFIGURATION;
2691  break;
2692  case OBJECT_COLLATION:
2693  tag = CMDTAG_CREATE_COLLATION;
2694  break;
2695  case OBJECT_ACCESS_METHOD:
2696  tag = CMDTAG_CREATE_ACCESS_METHOD;
2697  break;
2698  default:
2699  tag = CMDTAG_UNKNOWN;
2700  }
2701  break;
2702 
2703  case T_CompositeTypeStmt:
2704  tag = CMDTAG_CREATE_TYPE;
2705  break;
2706 
2707  case T_CreateEnumStmt:
2708  tag = CMDTAG_CREATE_TYPE;
2709  break;
2710 
2711  case T_CreateRangeStmt:
2712  tag = CMDTAG_CREATE_TYPE;
2713  break;
2714 
2715  case T_AlterEnumStmt:
2716  tag = CMDTAG_ALTER_TYPE;
2717  break;
2718 
2719  case T_ViewStmt:
2720  tag = CMDTAG_CREATE_VIEW;
2721  break;
2722 
2723  case T_CreateFunctionStmt:
2724  if (((CreateFunctionStmt *) parsetree)->is_procedure)
2725  tag = CMDTAG_CREATE_PROCEDURE;
2726  else
2727  tag = CMDTAG_CREATE_FUNCTION;
2728  break;
2729 
2730  case T_IndexStmt:
2731  tag = CMDTAG_CREATE_INDEX;
2732  break;
2733 
2734  case T_RuleStmt:
2735  tag = CMDTAG_CREATE_RULE;
2736  break;
2737 
2738  case T_CreateSeqStmt:
2739  tag = CMDTAG_CREATE_SEQUENCE;
2740  break;
2741 
2742  case T_AlterSeqStmt:
2743  tag = CMDTAG_ALTER_SEQUENCE;
2744  break;
2745 
2746  case T_DoStmt:
2747  tag = CMDTAG_DO;
2748  break;
2749 
2750  case T_CreatedbStmt:
2751  tag = CMDTAG_CREATE_DATABASE;
2752  break;
2753 
2754  case T_AlterDatabaseStmt:
2755  tag = CMDTAG_ALTER_DATABASE;
2756  break;
2757 
2759  tag = CMDTAG_ALTER_DATABASE;
2760  break;
2761 
2762  case T_DropdbStmt:
2763  tag = CMDTAG_DROP_DATABASE;
2764  break;
2765 
2766  case T_NotifyStmt:
2767  tag = CMDTAG_NOTIFY;
2768  break;
2769 
2770  case T_ListenStmt:
2771  tag = CMDTAG_LISTEN;
2772  break;
2773 
2774  case T_UnlistenStmt:
2775  tag = CMDTAG_UNLISTEN;
2776  break;
2777 
2778  case T_LoadStmt:
2779  tag = CMDTAG_LOAD;
2780  break;
2781 
2782  case T_CallStmt:
2783  tag = CMDTAG_CALL;
2784  break;
2785 
2786  case T_ClusterStmt:
2787  tag = CMDTAG_CLUSTER;
2788  break;
2789 
2790  case T_VacuumStmt:
2791  if (((VacuumStmt *) parsetree)->is_vacuumcmd)
2792  tag = CMDTAG_VACUUM;
2793  else
2794  tag = CMDTAG_ANALYZE;
2795  break;
2796 
2797  case T_ExplainStmt:
2798  tag = CMDTAG_EXPLAIN;
2799  break;
2800 
2801  case T_CreateTableAsStmt:
2802  switch (((CreateTableAsStmt *) parsetree)->objtype)
2803  {
2804  case OBJECT_TABLE:
2805  if (((CreateTableAsStmt *) parsetree)->is_select_into)
2806  tag = CMDTAG_SELECT_INTO;
2807  else
2808  tag = CMDTAG_CREATE_TABLE_AS;
2809  break;
2810  case OBJECT_MATVIEW:
2811  tag = CMDTAG_CREATE_MATERIALIZED_VIEW;
2812  break;
2813  default:
2814  tag = CMDTAG_UNKNOWN;
2815  }
2816  break;
2817 
2818  case T_RefreshMatViewStmt:
2819  tag = CMDTAG_REFRESH_MATERIALIZED_VIEW;
2820  break;
2821 
2822  case T_AlterSystemStmt:
2823  tag = CMDTAG_ALTER_SYSTEM;
2824  break;
2825 
2826  case T_VariableSetStmt:
2827  switch (((VariableSetStmt *) parsetree)->kind)
2828  {
2829  case VAR_SET_VALUE:
2830  case VAR_SET_CURRENT:
2831  case VAR_SET_DEFAULT:
2832  case VAR_SET_MULTI:
2833  tag = CMDTAG_SET;
2834  break;
2835  case VAR_RESET:
2836  case VAR_RESET_ALL:
2837  tag = CMDTAG_RESET;
2838  break;
2839  default:
2840  tag = CMDTAG_UNKNOWN;
2841  }
2842  break;
2843 
2844  case T_VariableShowStmt:
2845  tag = CMDTAG_SHOW;
2846  break;
2847 
2848  case T_DiscardStmt:
2849  switch (((DiscardStmt *) parsetree)->target)
2850  {
2851  case DISCARD_ALL:
2852  tag = CMDTAG_DISCARD_ALL;
2853  break;
2854  case DISCARD_PLANS:
2855  tag = CMDTAG_DISCARD_PLANS;
2856  break;
2857  case DISCARD_TEMP:
2858  tag = CMDTAG_DISCARD_TEMP;
2859  break;
2860  case DISCARD_SEQUENCES:
2861  tag = CMDTAG_DISCARD_SEQUENCES;
2862  break;
2863  default:
2864  tag = CMDTAG_UNKNOWN;
2865  }
2866  break;
2867 
2868  case T_CreateTransformStmt:
2869  tag = CMDTAG_CREATE_TRANSFORM;
2870  break;
2871 
2872  case T_CreateTrigStmt:
2873  tag = CMDTAG_CREATE_TRIGGER;
2874  break;
2875 
2876  case T_CreateEventTrigStmt:
2877  tag = CMDTAG_CREATE_EVENT_TRIGGER;
2878  break;
2879 
2880  case T_AlterEventTrigStmt:
2881  tag = CMDTAG_ALTER_EVENT_TRIGGER;
2882  break;
2883 
2884  case T_CreatePLangStmt:
2885  tag = CMDTAG_CREATE_LANGUAGE;
2886  break;
2887 
2888  case T_CreateRoleStmt:
2889  tag = CMDTAG_CREATE_ROLE;
2890  break;
2891 
2892  case T_AlterRoleStmt:
2893  tag = CMDTAG_ALTER_ROLE;
2894  break;
2895 
2896  case T_AlterRoleSetStmt:
2897  tag = CMDTAG_ALTER_ROLE;
2898  break;
2899 
2900  case T_DropRoleStmt:
2901  tag = CMDTAG_DROP_ROLE;
2902  break;
2903 
2904  case T_DropOwnedStmt:
2905  tag = CMDTAG_DROP_OWNED;
2906  break;
2907 
2908  case T_ReassignOwnedStmt:
2909  tag = CMDTAG_REASSIGN_OWNED;
2910  break;
2911 
2912  case T_LockStmt:
2913  tag = CMDTAG_LOCK_TABLE;
2914  break;
2915 
2916  case T_ConstraintsSetStmt:
2917  tag = CMDTAG_SET_CONSTRAINTS;
2918  break;
2919 
2920  case T_CheckPointStmt:
2921  tag = CMDTAG_CHECKPOINT;
2922  break;
2923 
2924  case T_ReindexStmt:
2925  tag = CMDTAG_REINDEX;
2926  break;
2927 
2929  tag = CMDTAG_CREATE_CONVERSION;
2930  break;
2931 
2932  case T_CreateCastStmt:
2933  tag = CMDTAG_CREATE_CAST;
2934  break;
2935 
2936  case T_CreateOpClassStmt:
2937  tag = CMDTAG_CREATE_OPERATOR_CLASS;
2938  break;
2939 
2940  case T_CreateOpFamilyStmt:
2941  tag = CMDTAG_CREATE_OPERATOR_FAMILY;
2942  break;
2943 
2944  case T_AlterOpFamilyStmt:
2945  tag = CMDTAG_ALTER_OPERATOR_FAMILY;
2946  break;
2947 
2948  case T_AlterOperatorStmt:
2949  tag = CMDTAG_ALTER_OPERATOR;
2950  break;
2951 
2952  case T_AlterTypeStmt:
2953  tag = CMDTAG_ALTER_TYPE;
2954  break;
2955 
2957  tag = CMDTAG_ALTER_TEXT_SEARCH_DICTIONARY;
2958  break;
2959 
2961  tag = CMDTAG_ALTER_TEXT_SEARCH_CONFIGURATION;
2962  break;
2963 
2964  case T_CreatePolicyStmt:
2965  tag = CMDTAG_CREATE_POLICY;
2966  break;
2967 
2968  case T_AlterPolicyStmt:
2969  tag = CMDTAG_ALTER_POLICY;
2970  break;
2971 
2972  case T_CreateAmStmt:
2973  tag = CMDTAG_CREATE_ACCESS_METHOD;
2974  break;
2975 
2977  tag = CMDTAG_CREATE_PUBLICATION;
2978  break;
2979 
2981  tag = CMDTAG_ALTER_PUBLICATION;
2982  break;
2983 
2985  tag = CMDTAG_CREATE_SUBSCRIPTION;
2986  break;
2987 
2989  tag = CMDTAG_ALTER_SUBSCRIPTION;
2990  break;
2991 
2993  tag = CMDTAG_DROP_SUBSCRIPTION;
2994  break;
2995 
2996  case T_AlterCollationStmt:
2997  tag = CMDTAG_ALTER_COLLATION;
2998  break;
2999 
3000  case T_PrepareStmt:
3001  tag = CMDTAG_PREPARE;
3002  break;
3003 
3004  case T_ExecuteStmt:
3005  tag = CMDTAG_EXECUTE;
3006  break;
3007 
3008  case T_CreateStatsStmt:
3009  tag = CMDTAG_CREATE_STATISTICS;
3010  break;
3011 
3012  case T_AlterStatsStmt:
3013  tag = CMDTAG_ALTER_STATISTICS;
3014  break;
3015 
3016  case T_DeallocateStmt:
3017  {
3018  DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
3019 
3020  if (stmt->name == NULL)
3021  tag = CMDTAG_DEALLOCATE_ALL;
3022  else
3023  tag = CMDTAG_DEALLOCATE;
3024  }
3025  break;
3026 
3027  /* already-planned queries */
3028  case T_PlannedStmt:
3029  {
3030  PlannedStmt *stmt = (PlannedStmt *) parsetree;
3031 
3032  switch (stmt->commandType)
3033  {
3034  case CMD_SELECT:
3035 
3036  /*
3037  * We take a little extra care here so that the result
3038  * will be useful for complaints about read-only
3039  * statements
3040  */
3041  if (stmt->rowMarks != NIL)
3042  {
3043  /* not 100% but probably close enough */
3044  switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
3045  {
3046  case LCS_FORKEYSHARE:
3047  tag = CMDTAG_SELECT_FOR_KEY_SHARE;
3048  break;
3049  case LCS_FORSHARE:
3050  tag = CMDTAG_SELECT_FOR_SHARE;
3051  break;
3052  case LCS_FORNOKEYUPDATE:
3053  tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
3054  break;
3055  case LCS_FORUPDATE:
3056  tag = CMDTAG_SELECT_FOR_UPDATE;
3057  break;
3058  default:
3059  tag = CMDTAG_SELECT;
3060  break;
3061  }
3062  }
3063  else
3064  tag = CMDTAG_SELECT;
3065  break;
3066  case CMD_UPDATE:
3067  tag = CMDTAG_UPDATE;
3068  break;
3069  case CMD_INSERT:
3070  tag = CMDTAG_INSERT;
3071  break;
3072  case CMD_DELETE:
3073  tag = CMDTAG_DELETE;
3074  break;
3075  case CMD_UTILITY:
3076  tag = CreateCommandTag(stmt->utilityStmt);
3077  break;
3078  default:
3079  elog(WARNING, "unrecognized commandType: %d",
3080  (int) stmt->commandType);
3081  tag = CMDTAG_UNKNOWN;
3082  break;
3083  }
3084  }
3085  break;
3086 
3087  /* parsed-and-rewritten-but-not-planned queries */
3088  case T_Query:
3089  {
3090  Query *stmt = (Query *) parsetree;
3091 
3092  switch (stmt->commandType)
3093  {
3094  case CMD_SELECT:
3095 
3096  /*
3097  * We take a little extra care here so that the result
3098  * will be useful for complaints about read-only
3099  * statements
3100  */
3101  if (stmt->rowMarks != NIL)
3102  {
3103  /* not 100% but probably close enough */
3104  switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
3105  {
3106  case LCS_FORKEYSHARE:
3107  tag = CMDTAG_SELECT_FOR_KEY_SHARE;
3108  break;
3109  case LCS_FORSHARE:
3110  tag = CMDTAG_SELECT_FOR_SHARE;
3111  break;
3112  case LCS_FORNOKEYUPDATE:
3113  tag = CMDTAG_SELECT_FOR_NO_KEY_UPDATE;
3114  break;
3115  case LCS_FORUPDATE:
3116  tag = CMDTAG_SELECT_FOR_UPDATE;
3117  break;
3118  default:
3119  tag = CMDTAG_UNKNOWN;
3120  break;
3121  }
3122  }
3123  else
3124  tag = CMDTAG_SELECT;
3125  break;
3126  case CMD_UPDATE:
3127  tag = CMDTAG_UPDATE;
3128  break;
3129  case CMD_INSERT:
3130  tag = CMDTAG_INSERT;
3131  break;
3132  case CMD_DELETE:
3133  tag = CMDTAG_DELETE;
3134  break;
3135  case CMD_UTILITY:
3136  tag = CreateCommandTag(stmt->utilityStmt);
3137  break;
3138  default:
3139  elog(WARNING, "unrecognized commandType: %d",
3140  (int) stmt->commandType);
3141  tag = CMDTAG_UNKNOWN;
3142  break;
3143  }
3144  }
3145  break;
3146 
3147  default:
3148  elog(WARNING, "unrecognized node type: %d",
3149  (int) nodeTag(parsetree));
3150  tag = CMDTAG_UNKNOWN;
3151  break;
3152  }
3153 
3154  return tag;
3155 }
3156 
3157 
3158 /*
3159  * GetCommandLogLevel
3160  * utility to get the minimum log_statement level for a command,
3161  * given either a raw (un-analyzed) parsetree, an analyzed Query,
3162  * or a PlannedStmt.
3163  *
3164  * This must handle all command types, but since the vast majority
3165  * of 'em are utility commands, it seems sensible to keep it here.
3166  */
3169 {
3170  LogStmtLevel lev;
3171 
3172  switch (nodeTag(parsetree))
3173  {
3174  /* recurse if we're given a RawStmt */
3175  case T_RawStmt:
3176  lev = GetCommandLogLevel(((RawStmt *) parsetree)->stmt);
3177  break;
3178 
3179  /* raw plannable queries */
3180  case T_InsertStmt:
3181  case T_DeleteStmt:
3182  case T_UpdateStmt:
3183  lev = LOGSTMT_MOD;
3184  break;
3185 
3186  case T_SelectStmt:
3187  if (((SelectStmt *) parsetree)->intoClause)
3188  lev = LOGSTMT_DDL; /* SELECT INTO */
3189  else
3190  lev = LOGSTMT_ALL;
3191  break;
3192 
3193  /* utility statements --- same whether raw or cooked */
3194  case T_TransactionStmt:
3195  lev = LOGSTMT_ALL;
3196  break;
3197 
3198  case T_DeclareCursorStmt:
3199  lev = LOGSTMT_ALL;
3200  break;
3201 
3202  case T_ClosePortalStmt:
3203  lev = LOGSTMT_ALL;
3204  break;
3205 
3206  case T_FetchStmt:
3207  lev = LOGSTMT_ALL;
3208  break;
3209 
3210  case T_CreateSchemaStmt:
3211  lev = LOGSTMT_DDL;
3212  break;
3213 
3214  case T_CreateStmt:
3216  lev = LOGSTMT_DDL;
3217  break;
3218 
3220  case T_DropTableSpaceStmt:
3222  lev = LOGSTMT_DDL;
3223  break;
3224 
3225  case T_CreateExtensionStmt:
3226  case T_AlterExtensionStmt:
3228  lev = LOGSTMT_DDL;
3229  break;
3230 
3231  case T_CreateFdwStmt:
3232  case T_AlterFdwStmt:
3237  case T_DropUserMappingStmt:
3239  lev = LOGSTMT_DDL;
3240  break;
3241 
3242  case T_DropStmt:
3243  lev = LOGSTMT_DDL;
3244  break;
3245 
3246  case T_TruncateStmt:
3247  lev = LOGSTMT_MOD;
3248  break;
3249 
3250  case T_CommentStmt:
3251  lev = LOGSTMT_DDL;
3252  break;
3253 
3254  case T_SecLabelStmt:
3255  lev = LOGSTMT_DDL;
3256  break;
3257 
3258  case T_CopyStmt:
3259  if (((CopyStmt *) parsetree)->is_from)
3260  lev = LOGSTMT_MOD;
3261  else
3262  lev = LOGSTMT_ALL;
3263  break;
3264 
3265  case T_PrepareStmt:
3266  {
3267  PrepareStmt *stmt = (PrepareStmt *) parsetree;
3268 
3269  /* Look through a PREPARE to the contained stmt */
3270  lev = GetCommandLogLevel(stmt->query);
3271  }
3272  break;
3273 
3274  case T_ExecuteStmt:
3275  {
3276  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
3277  PreparedStatement *ps;
3278 
3279  /* Look through an EXECUTE to the referenced stmt */
3280  ps = FetchPreparedStatement(stmt->name, false);
3281  if (ps && ps->plansource->raw_parse_tree)
3283  else
3284  lev = LOGSTMT_ALL;
3285  }
3286  break;
3287 
3288  case T_DeallocateStmt:
3289  lev = LOGSTMT_ALL;
3290  break;
3291 
3292  case T_RenameStmt:
3293  lev = LOGSTMT_DDL;
3294  break;
3295 
3297  lev = LOGSTMT_DDL;
3298  break;
3299 
3301  lev = LOGSTMT_DDL;
3302  break;
3303 
3304  case T_AlterOwnerStmt:
3305  lev = LOGSTMT_DDL;
3306  break;
3307 
3308  case T_AlterOperatorStmt:
3309  lev = LOGSTMT_DDL;
3310  break;
3311 
3312  case T_AlterTypeStmt:
3313  lev = LOGSTMT_DDL;
3314  break;
3315 
3317  case T_AlterTableStmt:
3318  lev = LOGSTMT_DDL;
3319  break;
3320 
3321  case T_AlterDomainStmt:
3322  lev = LOGSTMT_DDL;
3323  break;
3324 
3325  case T_GrantStmt:
3326  lev = LOGSTMT_DDL;
3327  break;
3328 
3329  case T_GrantRoleStmt:
3330  lev = LOGSTMT_DDL;
3331  break;
3332 
3334  lev = LOGSTMT_DDL;
3335  break;
3336 
3337  case T_DefineStmt:
3338  lev = LOGSTMT_DDL;
3339  break;
3340 
3341  case T_CompositeTypeStmt:
3342  lev = LOGSTMT_DDL;
3343  break;
3344 
3345  case T_CreateEnumStmt:
3346  lev = LOGSTMT_DDL;
3347  break;
3348 
3349  case T_CreateRangeStmt:
3350  lev = LOGSTMT_DDL;
3351  break;
3352 
3353  case T_AlterEnumStmt:
3354  lev = LOGSTMT_DDL;
3355  break;
3356 
3357  case T_ViewStmt:
3358  lev = LOGSTMT_DDL;
3359  break;
3360 
3361  case T_CreateFunctionStmt:
3362  lev = LOGSTMT_DDL;
3363  break;
3364 
3365  case T_AlterFunctionStmt:
3366  lev = LOGSTMT_DDL;
3367  break;
3368 
3369  case T_IndexStmt:
3370  lev = LOGSTMT_DDL;
3371  break;
3372 
3373  case T_RuleStmt:
3374  lev = LOGSTMT_DDL;
3375  break;
3376 
3377  case T_CreateSeqStmt:
3378  lev = LOGSTMT_DDL;
3379  break;
3380 
3381  case T_AlterSeqStmt:
3382  lev = LOGSTMT_DDL;
3383  break;
3384 
3385  case T_DoStmt:
3386  lev = LOGSTMT_ALL;
3387  break;
3388 
3389  case T_CreatedbStmt:
3390  lev = LOGSTMT_DDL;
3391  break;
3392 
3393  case T_AlterDatabaseStmt:
3394  lev = LOGSTMT_DDL;
3395  break;
3396 
3398  lev = LOGSTMT_DDL;
3399  break;
3400 
3401  case T_DropdbStmt:
3402  lev = LOGSTMT_DDL;
3403  break;
3404 
3405  case T_NotifyStmt:
3406  lev = LOGSTMT_ALL;
3407  break;
3408 
3409  case T_ListenStmt:
3410  lev = LOGSTMT_ALL;
3411  break;
3412 
3413  case T_UnlistenStmt:
3414  lev = LOGSTMT_ALL;
3415  break;
3416 
3417  case T_LoadStmt:
3418  lev = LOGSTMT_ALL;
3419  break;
3420 
3421  case T_CallStmt:
3422  lev = LOGSTMT_ALL;
3423  break;
3424 
3425  case T_ClusterStmt:
3426  lev = LOGSTMT_DDL;
3427  break;
3428 
3429  case T_VacuumStmt:
3430  lev = LOGSTMT_ALL;
3431  break;
3432 
3433  case T_ExplainStmt:
3434  {
3435  ExplainStmt *stmt = (ExplainStmt *) parsetree;
3436  bool analyze = false;
3437  ListCell *lc;
3438 
3439  /* Look through an EXPLAIN ANALYZE to the contained stmt */
3440  foreach(lc, stmt->options)
3441  {
3442  DefElem *opt = (DefElem *) lfirst(lc);
3443 
3444  if (strcmp(opt->defname, "analyze") == 0)
3445  analyze = defGetBoolean(opt);
3446  /* don't "break", as explain.c will use the last value */
3447  }
3448  if (analyze)
3449  return GetCommandLogLevel(stmt->query);
3450 
3451  /* Plain EXPLAIN isn't so interesting */
3452  lev = LOGSTMT_ALL;
3453  }
3454  break;
3455 
3456  case T_CreateTableAsStmt:
3457  lev = LOGSTMT_DDL;
3458  break;
3459 
3460  case T_RefreshMatViewStmt:
3461  lev = LOGSTMT_DDL;
3462  break;
3463 
3464  case T_AlterSystemStmt:
3465  lev = LOGSTMT_DDL;
3466  break;
3467 
3468  case T_VariableSetStmt:
3469  lev = LOGSTMT_ALL;
3470  break;
3471 
3472  case T_VariableShowStmt:
3473  lev = LOGSTMT_ALL;
3474  break;
3475 
3476  case T_DiscardStmt:
3477  lev = LOGSTMT_ALL;
3478  break;
3479 
3480  case T_CreateTrigStmt:
3481  lev = LOGSTMT_DDL;
3482  break;
3483 
3484  case T_CreateEventTrigStmt:
3485  lev = LOGSTMT_DDL;
3486  break;
3487 
3488  case T_AlterEventTrigStmt:
3489  lev = LOGSTMT_DDL;
3490  break;
3491 
3492  case T_CreatePLangStmt:
3493  lev = LOGSTMT_DDL;
3494  break;
3495 
3496  case T_CreateDomainStmt:
3497  lev = LOGSTMT_DDL;
3498  break;
3499 
3500  case T_CreateRoleStmt:
3501  lev = LOGSTMT_DDL;
3502  break;
3503 
3504  case T_AlterRoleStmt:
3505  lev = LOGSTMT_DDL;
3506  break;
3507 
3508  case T_AlterRoleSetStmt:
3509  lev = LOGSTMT_DDL;
3510  break;
3511 
3512  case T_DropRoleStmt:
3513  lev = LOGSTMT_DDL;
3514  break;
3515 
3516  case T_DropOwnedStmt:
3517  lev = LOGSTMT_DDL;
3518  break;
3519 
3520  case T_ReassignOwnedStmt:
3521  lev = LOGSTMT_DDL;
3522  break;
3523 
3524  case T_LockStmt:
3525  lev = LOGSTMT_ALL;
3526  break;
3527 
3528  case T_ConstraintsSetStmt:
3529  lev = LOGSTMT_ALL;
3530  break;
3531 
3532  case T_CheckPointStmt:
3533  lev = LOGSTMT_ALL;
3534  break;
3535 
3536  case T_ReindexStmt:
3537  lev = LOGSTMT_ALL; /* should this be DDL? */
3538  break;
3539 
3541  lev = LOGSTMT_DDL;
3542  break;
3543 
3544  case T_CreateCastStmt:
3545  lev = LOGSTMT_DDL;
3546  break;
3547 
3548  case T_CreateOpClassStmt:
3549  lev = LOGSTMT_DDL;
3550  break;
3551 
3552  case T_CreateOpFamilyStmt:
3553  lev = LOGSTMT_DDL;
3554  break;
3555 
3556  case T_CreateTransformStmt:
3557  lev = LOGSTMT_DDL;
3558  break;
3559 
3560  case T_AlterOpFamilyStmt:
3561  lev = LOGSTMT_DDL;
3562  break;
3563 
3564  case T_CreatePolicyStmt:
3565  lev = LOGSTMT_DDL;
3566  break;
3567 
3568  case T_AlterPolicyStmt:
3569  lev = LOGSTMT_DDL;
3570  break;
3571 
3573  lev = LOGSTMT_DDL;
3574  break;
3575 
3577  lev = LOGSTMT_DDL;
3578  break;
3579 
3580  case T_CreateAmStmt:
3581  lev = LOGSTMT_DDL;
3582  break;
3583 
3585  lev = LOGSTMT_DDL;
3586  break;
3587 
3589  lev = LOGSTMT_DDL;
3590  break;
3591 
3593  lev = LOGSTMT_DDL;
3594  break;
3595 
3597  lev = LOGSTMT_DDL;
3598  break;
3599 
3601  lev = LOGSTMT_DDL;
3602  break;
3603 
3604  case T_CreateStatsStmt:
3605  lev = LOGSTMT_DDL;
3606  break;
3607 
3608  case T_AlterStatsStmt:
3609  lev = LOGSTMT_DDL;
3610  break;
3611 
3612  case T_AlterCollationStmt:
3613  lev = LOGSTMT_DDL;
3614  break;
3615 
3616  /* already-planned queries */
3617  case T_PlannedStmt:
3618  {
3619  PlannedStmt *stmt = (PlannedStmt *) parsetree;
3620 
3621  switch (stmt->commandType)
3622  {
3623  case CMD_SELECT:
3624  lev = LOGSTMT_ALL;
3625  break;
3626 
3627  case CMD_UPDATE:
3628  case CMD_INSERT:
3629  case CMD_DELETE:
3630  lev = LOGSTMT_MOD;
3631  break;
3632 
3633  case CMD_UTILITY:
3634  lev = GetCommandLogLevel(stmt->utilityStmt);
3635  break;
3636 
3637  default:
3638  elog(WARNING, "unrecognized commandType: %d",
3639  (int) stmt->commandType);
3640  lev = LOGSTMT_ALL;
3641  break;
3642  }
3643  }
3644  break;
3645 
3646  /* parsed-and-rewritten-but-not-planned queries */
3647  case T_Query:
3648  {
3649  Query *stmt = (Query *) parsetree;
3650 
3651  switch (stmt->commandType)
3652  {
3653  case CMD_SELECT:
3654  lev = LOGSTMT_ALL;
3655  break;
3656 
3657  case CMD_UPDATE:
3658  case CMD_INSERT:
3659  case CMD_DELETE:
3660  lev = LOGSTMT_MOD;
3661  break;
3662 
3663  case CMD_UTILITY:
3664  lev = GetCommandLogLevel(stmt->utilityStmt);
3665  break;
3666 
3667  default:
3668  elog(WARNING, "unrecognized commandType: %d",
3669  (int) stmt->commandType);
3670  lev = LOGSTMT_ALL;
3671  break;
3672  }
3673 
3674  }
3675  break;
3676 
3677  default:
3678  elog(WARNING, "unrecognized node type: %d",
3679  (int) nodeTag(parsetree));
3680  lev = LOGSTMT_ALL;
3681  break;
3682  }
3683 
3684  return lev;
3685 }
TupleDesc GetPGVariableResultDesc(const char *name)
Definition: guc.c:8974
RangeVar * relation
Definition: parsenodes.h:2074
ObjectType objtype
Definition: parsenodes.h:2682
ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
Definition: sequence.c:422
ObjectAddress DefineTSParser(List *names, List *parameters)
Definition: tsearchcmds.c:178
void ExplainQuery(ParseState *pstate, ExplainStmt *stmt, ParamListInfo params, DestReceiver *dest)
Definition: explain.c:161
bytea * heap_reloptions(char relkind, Datum reloptions, bool validate)
Definition: reloptions.c:1996
Oid funcresulttype
Definition: primnodes.h:470
#define NIL
Definition: pg_list.h:65
CommandTag
Definition: cmdtag.h:20
bool primary
Definition: parsenodes.h:2794
void closeAllVfds(void)
Definition: fd.c:2760
bool CommandIsReadOnly(PlannedStmt *pstmt)
Definition: utility.c:99
ObjectAddress AlterForeignServer(AlterForeignServerStmt *stmt)
Definition: foreigncmds.c:969
void CreateForeignTable(CreateForeignTableStmt *stmt, Oid relid)
Definition: foreigncmds.c:1395
void DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
ObjectAddress DefineOperator(List *names, List *parameters)
Definition: operatorcmds.c:65
TupleDesc CreateTupleDescCopy(TupleDesc tupdesc)
Definition: tupdesc.c:110
ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt)
ObjectType objtype
Definition: parsenodes.h:2694
#define IsA(nodeptr, _type_)
Definition: nodes.h:579
ObjectAddress DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
Definition: tsearchcmds.c:893
ObjectAddress CreateTransform(CreateTransformStmt *stmt)
static void ExecDropStmt(DropStmt *stmt, bool isTopLevel)
Definition: utility.c:1927
ObjectAddress DefineIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId, Oid parentIndexId, Oid parentConstraintId, bool is_alter_table, bool check_rights, bool check_not_in_use, bool skip_build, bool quiet)
Definition: indexcmds.c:492
void(* ProcessUtility_hook_type)(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
Definition: utility.h:71
void PerformPortalClose(const char *name)
Definition: portalcmds.c:215
ObjectAddress AlterDomainAddConstraint(List *names, Node *newConstraint, ObjectAddress *constrAddr)
Definition: typecmds.c:2494
bool EndTransactionBlock(bool chain)
Definition: xact.c:3758
Datum transformRelOptions(Datum oldOptions, List *defList, const char *namspace, char *validnsps[], bool acceptOidsOff, bool isReset)
Definition: reloptions.c:1132
ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt)
Definition: foreigncmds.c:562
void PreventCommandIfParallelMode(const char *cmdname)
Definition: utility.c:425
DropBehavior behavior
Definition: parsenodes.h:1910
ObjectAddress CommentObject(CommentStmt *stmt)
Definition: comment.c:40
ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
Definition: functioncmds.c:922
FuncExpr * funcexpr
Definition: parsenodes.h:2903
static ListCell * lnext(const List *l, const ListCell *c)
Definition: pg_list.h:310
static CommandTag AlterObjectTypeCommandTag(ObjectType objtype)
Definition: utility.c:2147
ObjectType renameType
Definition: parsenodes.h:2919
int LOCKMODE
Definition: lockdefs.h:26
ObjectAddress CreatePublication(CreatePublicationStmt *stmt)
ObjectAddress ExecSecLabelStmt(SecLabelStmt *stmt)
Definition: seclabel.c:113
void WarnNoTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3440
#define castNode(_type_, nodeptr)
Definition: nodes.h:597
QueryEnvironment * p_queryEnv
Definition: parse_node.h:203
CachedPlanSource * plansource
Definition: prepare.h:31
LogStmtLevel
Definition: tcopprot.h:35
PlannedStmt * pstmt
Definition: utility.h:32
Oid AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode)
Definition: tablecmds.c:3617
Portal GetPortalByName(const char *name)
Definition: portalmem.c:130
ObjectAddress AlterDomainValidateConstraint(List *names, const char *constrName)
Definition: typecmds.c:2610
ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List *parameters, bool replace)
Definition: aggregatecmds.c:57
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1915
Oid ReindexTable(RangeVar *relation, int options, bool isTopLevel)
Definition: indexcmds.c:2555
ObjectAddress AlterEnum(AlterEnumStmt *stmt)
Definition: typecmds.c:1215
void DropOwnedObjects(DropOwnedStmt *stmt)
Definition: user.c:1371
Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
Definition: dbcommands.c:1650
ObjectType objectType
Definition: parsenodes.h:2965
void DefineSavepoint(const char *name)
Definition: xact.c:4087
RangeVar * typevar
Definition: parsenodes.h:3075
void AfterTriggerSetState(ConstraintsSetStmt *stmt)
Definition: trigger.c:4972
TupleDesc CallStmtResultDesc(CallStmt *stmt)
void EventTriggerDDLCommandEnd(Node *parsetree)
void ExecuteCallStmt(CallStmt *stmt, ParamListInfo params, bool atomic, DestReceiver *dest)
static void CheckRestrictedOperation(const char *cmdname)
Definition: utility.c:462
ProcessUtility_hook_type ProcessUtility_hook
Definition: utility.c:75
Definition: nodes.h:528
ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, ObjectAddress *objAddr)
Definition: extension.c:3277
bool PrepareTransactionBlock(const char *gid)
Definition: xact.c:3706
List * list_concat(List *list1, const List *list2)
Definition: list.c:515
int errcode(int sqlerrcode)
Definition: elog.c:610
ObjectAddress CreateProceduralLanguage(CreatePLangStmt *stmt)
Definition: proclang.c:39
ProcessUtilityContext
Definition: utility.h:20
bool superuser(void)
Definition: superuser.c:46
char * filename
Definition: parsenodes.h:3145
void EventTriggerInhibitCommandCollection(void)
ObjectAddress DefineDomain(CreateDomainStmt *stmt)
Definition: typecmds.c:658
void PrepareQuery(ParseState *pstate, PrepareStmt *stmt, int stmt_location, int stmt_len)
Definition: prepare.c:58
List * options
Definition: parsenodes.h:3259
void Async_Listen(const char *channel)
Definition: async.c:756
ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist)
Definition: typecmds.c:2086
Oid CreateTableSpace(CreateTableSpaceStmt *stmt)
Definition: tablespace.c:233
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:8074
static int ClassifyUtilityCommandAsReadOnly(Node *parsetree)
Definition: utility.c:132
List * rowMarks
Definition: parsenodes.h:164
void ExecuteTruncate(TruncateStmt *stmt)
Definition: tablecmds.c:1560
void RemoveObjects(DropStmt *stmt)
Definition: dropcmds.c:57
Node * utilityStmt
Definition: parsenodes.h:120
ObjectAddress DefineOpClass(CreateOpClassStmt *stmt)
Definition: opclasscmds.c:328
DestReceiver * None_Receiver
Definition: dest.c:96
ObjectAddress CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
void NewRelationCreateToastTable(Oid relOid, Datum reloptions)
Definition: toasting.c:69
#define OidIsValid(objectId)
Definition: c.h:651
int stmt_len
Definition: plannodes.h:96
Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
Definition: user.c:71
ObjectType removeType
Definition: parsenodes.h:2657
void RollbackToSavepoint(const char *name)
Definition: xact.c:4281
void GetPGVariable(const char *name, DestReceiver *dest)
Definition: guc.c:8965
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:43
TupleDesc resultDesc
Definition: plancache.h:108
Query * UtilityContainsQuery(Node *parsetree)
Definition: utility.c:2110
void EventTriggerAlterTableStart(Node *parsetree)
#define list_make1(x1)
Definition: pg_list.h:206
bool IsTransactionBlock(void)
Definition: xact.c:4684
char * relname
Definition: primnodes.h:68
Node * query
Definition: parsenodes.h:3258
static void ProcessUtilitySlow(ParseState *pstate, PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
Definition: utility.c:1093
void AlterTable(AlterTableStmt *stmt, LOCKMODE lockmode, AlterTableUtilityContext *context)
Definition: tablecmds.c:3673
void DeallocateQuery(DeallocateStmt *stmt)
Definition: prepare.c:540
#define true
Definition: c.h:328
RangeVar * relation
Definition: parsenodes.h:2778
bool defGetBoolean(DefElem *def)
Definition: define.c:111
ObjectAddress AlterPolicy(AlterPolicyStmt *stmt)
Definition: policy.c:870
void RemoveRelations(DropStmt *drop)
Definition: tablecmds.c:1259
ObjectAddress AlterStatistics(AlterStatsStmt *stmt)
Definition: statscmds.c:427
#define COMMAND_OK_IN_RECOVERY
Definition: utility.h:58
bool IsInParallelMode(void)
Definition: xact.c:1012
#define linitial(l)
Definition: pg_list.h:174
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition: tablecmds.c:15615
List * args
Definition: parsenodes.h:2573
#define ERROR
Definition: elog.h:43
ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw)
Definition: typecmds.c:2144
void PreventCommandDuringRecovery(const char *cmdname)
Definition: utility.c:444
char * savepoint_name
Definition: parsenodes.h:3063
void standard_ProcessUtility(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
Definition: utility.c:541
bool concurrent
Definition: parsenodes.h:2660
void GrantRole(GrantRoleStmt *stmt)
Definition: user.c:1312
ObjectAddress AlterOperator(AlterOperatorStmt *stmt)
Definition: operatorcmds.c:409
TupleDesc ExplainResultDesc(ExplainStmt *stmt)
Definition: explain.c:322
void EventTriggerDDLCommandStart(Node *parsetree)
void PerformCursorOpen(ParseState *pstate, DeclareCursorStmt *cstmt, ParamListInfo params, bool isTopLevel)
Definition: portalcmds.c:42
RangeVar * relation
Definition: parsenodes.h:3373
ObjectAddress CreatePolicy(CreatePolicyStmt *stmt)
Definition: policy.c:670
void EventTriggerSQLDrop(Node *parsetree)
void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, QueryCompletion *qc)
Definition: portalcmds.c:168
ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
Definition: tsearchcmds.c:1109
ObjectAddress AlterType(AlterTypeStmt *stmt)
Definition: typecmds.c:3676
ObjectAddress AlterDomainNotNull(List *names, bool notNull)
Definition: typecmds.c:2275
Oid RemoveUserMapping(DropUserMappingStmt *stmt)
Definition: foreigncmds.c:1315
ObjectAddress CreateUserMapping(CreateUserMappingStmt *stmt)
Definition: foreigncmds.c:1095
void ExecSetVariableStmt(VariableSetStmt *stmt, bool isTopLevel)
Definition: guc.c:8347
int stmt_location
Definition: plannodes.h:95
Node * stmt
Definition: parsenodes.h:1509
ObjectAddress AlterTSDictionary(AlterTSDictionaryStmt *stmt)
Definition: tsearchcmds.c:487
void check_stack_depth(void)
Definition: postgres.c:3312
bool transformed
Definition: parsenodes.h:2798
#define RowExclusiveLock
Definition: lockdefs.h:38
int errdetail(const char *fmt,...)
Definition: elog.c:957
void ExecuteQuery(ParseState *pstate, ExecuteStmt *stmt, IntoClause *intoClause, ParamListInfo params, DestReceiver *dest, QueryCompletion *qc)
Definition: prepare.c:187
Node * utilityStmt
Definition: plannodes.h:92
ObjectAddress DefineRange(CreateRangeStmt *stmt)
Definition: typecmds.c:1285
void PreventInTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3380
const char * queryString
Definition: utility.h:33
List * options
Definition: parsenodes.h:2082
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, uint32 flags, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:236
ObjectAddress DefineEnum(CreateEnumStmt *stmt)
Definition: typecmds.c:1093
bool UtilityReturnsTuples(Node *parsetree)
Definition: utility.c:1960
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:105
ObjectAddress DefineView(ViewStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
Definition: view.c:407
Oid CreateSchemaCommand(CreateSchemaStmt *stmt, const char *queryString, int stmt_location, int stmt_len)
Definition: schemacmds.c:50
void ExecuteDoStmt(DoStmt *stmt, bool atomic)
#define HEAP_RELOPT_NAMESPACES
Definition: reloptions.h:61
const char * p_sourcetext
Definition: parse_node.h:179
void DropTableSpace(DropTableSpaceStmt *stmt)
Definition: tablespace.c:413
ObjectAddress AlterUserMapping(AlterUserMappingStmt *stmt)
Definition: foreigncmds.c:1217
List * returningList
Definition: parsenodes.h:146
char * conditionname
Definition: parsenodes.h:3027
ObjectAddress ExecRenameStmt(RenameStmt *stmt)
Definition: alter.c:331
char * portalname
Definition: parsenodes.h:2759
#define CHECKPOINT_FORCE
Definition: xlog.h:225
ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
Definition: sequence.c:118
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition: tablecmds.c:584
QueryEnvironment * queryEnv
Definition: utility.h:36
void ExecAlterDefaultPrivilegesStmt(ParseState *pstate, AlterDefaultPrivilegesStmt *stmt)
Definition: aclchk.c:888
ObjectAddress DefineType(ParseState *pstate, List *names, List *parameters)
Definition: typecmds.c:140
Oid AlterEventTrigger(AlterEventTrigStmt *stmt)
bool inh
Definition: primnodes.h:69
Node * arg
Definition: parsenodes.h:734
ObjectType
Definition: parsenodes.h:1694
void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, int options)
Definition: indexcmds.c:2610
ObjectAddress CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
Definition: extension.c:1680
void BeginTransactionBlock(void)
Definition: xact.c:3638
void EventTriggerEndCompleteQuery(void)
bool is_grant
Definition: parsenodes.h:1929
#define WARNING
Definition: elog.h:40
Oid AlterRole(AlterRoleStmt *stmt)
Definition: user.c:531
LOCKMODE AlterTableGetLockLevel(List *cmds)
Definition: tablecmds.c:3747
ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt)
Definition: foreigncmds.c:842
bool replace
Definition: parsenodes.h:2576
#define PortalIsValid(p)
Definition: portal.h:203
void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
Definition: guc.c:8133
#define PG_FINALLY()
Definition: elog.h:312
Definition: nodes.h:312
bool canSetTag
Definition: plannodes.h:54
bool ismove
Definition: parsenodes.h:2760
void EventTriggerUndoInhibitCommandCollection(void)
uintptr_t Datum
Definition: postgres.h:367
void CommandCounterIncrement(void)
Definition: xact.c:1021
CmdType commandType
Definition: plannodes.h:46
void ReleaseSavepoint(const char *name)
Definition: xact.c:4172
Oid AlterRoleSet(AlterRoleSetStmt *stmt)
Definition: user.c:913
Oid CreateEventTrigger(CreateEventTrigStmt *stmt)
TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt)
Definition: prepare.c:501
bool unique
Definition: parsenodes.h:2793
ObjectType kind
Definition: parsenodes.h:2570
char * conditionname
Definition: parsenodes.h:3016
ObjectAddress ExecAlterObjectDependsStmt(AlterObjectDependsStmt *stmt, ObjectAddress *refAddress)
Definition: alter.c:431
void EventTriggerCollectAlterDefPrivs(AlterDefaultPrivilegesStmt *stmt)
List * rowMarks
Definition: plannodes.h:84
List * expandTableLikeClause(RangeVar *heapRel, TableLikeClause *table_like_clause)
TupleDesc tupDesc
Definition: portal.h:159
#define InvalidOid
Definition: postgres_ext.h:36
ObjectAddress DefineCollation(ParseState *pstate, List *names, List *parameters, bool if_not_exists)
Definition: collationcmds.c:52
CommandTag commandTag
Definition: cmdtag.h:30
List * defnames
Definition: parsenodes.h:2572
#define ereport(elevel,...)
Definition: elog.h:144
bool EventTriggerSupportsObjectType(ObjectType obtype)
bool XactReadOnly
Definition: xact.c:78
#define NOTICE
Definition: elog.h:37
Oid AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
Definition: dbcommands.c:1471
CmdType commandType
Definition: parsenodes.h:112
ObjectAddress CreateCast(CreateCastStmt *stmt)
void FinishPreparedTransaction(const char *gid, bool isCommit)
Definition: twophase.c:1397
#define CHECKPOINT_WAIT
Definition: xlog.h:229
ObjectAddress ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
Definition: extension.c:2969
ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, ObjectAddress *oldSchemaAddr)
Definition: alter.c:495
#define makeNode(_type_)
Definition: nodes.h:576
#define REINDEXOPT_CONCURRENTLY
Definition: parsenodes.h:3357
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
ObjectAddress DefineTSDictionary(List *names, List *parameters)
Definition: tsearchcmds.c:391
void ExecVacuum(ParseState *pstate, VacuumStmt *vacstmt, bool isTopLevel)
Definition: vacuum.c:98
void DoCopy(ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
Definition: copy.c:888
#define Assert(condition)
Definition: c.h:745
#define lfirst(lc)
Definition: pg_list.h:169
ReindexObjectType kind
Definition: parsenodes.h:3371
CommandTag CreateCommandTag(Node *parsetree)
Definition: utility.c:2293
bool InSecurityRestrictedOperation(void)
Definition: miscinit.c:608
static void SetQueryCompletion(QueryCompletion *qc, CommandTag commandTag, uint64 nprocessed)
Definition: cmdtag.h:36
bool hasModifyingCTE
Definition: plannodes.h:52
ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, ParamListInfo params, QueryCompletion *qc)
Definition: matview.c:138
void load_file(const char *filename, bool restricted)
Definition: dfmgr.c:146
Node * query
Definition: parsenodes.h:3429
ObjectAddress CreateConversionCommand(CreateConversionStmt *stmt)
void Async_UnlistenAll(void)
Definition: async.c:788
Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
Definition: tablecmds.c:13327
ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt)
Definition: foreigncmds.c:678
List * transformCreateStmt(CreateStmt *stmt, const char *queryString)
ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
Definition: alter.c:833
ObjectAddress ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt, ParamListInfo params, QueryEnvironment *queryEnv, QueryCompletion *qc)
Definition: createas.c:226
struct RawStmt * raw_parse_tree
Definition: plancache.h:99
void PreventCommandIfReadOnly(const char *cmdname)
Definition: utility.c:407
#define nodeTag(nodeptr)
Definition: nodes.h:533
void EventTriggerAlterTableRelid(Oid objectId)
void Async_Notify(const char *channel, const char *payload)
Definition: async.c:609
Oid AlterOpFamily(AlterOpFamilyStmt *stmt)
Definition: opclasscmds.c:808
#define COMMAND_IS_NOT_READ_ONLY
Definition: utility.h:68
ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt)
Definition: opclasscmds.c:763
const char * GetCommandTagName(CommandTag commandTag)
Definition: cmdtag.c:45
ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok)
Definition: typecmds.c:2395
bool concurrent
Definition: parsenodes.h:2799
ObjectAddress DefineRule(RuleStmt *stmt, const char *queryString)
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
Definition: pg_inherits.c:165
void LockTableCommand(LockStmt *lockstmt)
Definition: lockcmds.c:41
Oid createdb(ParseState *pstate, const CreatedbStmt *stmt)
Definition: dbcommands.c:100
void ReindexIndex(RangeVar *indexRelation, int options, bool isTopLevel)
Definition: indexcmds.c:2436
bool is_from
Definition: parsenodes.h:2017
const ObjectAddress InvalidObjectAddress
void ImportForeignSchema(ImportForeignSchemaStmt *stmt)
Definition: foreigncmds.c:1475
int errmsg(const char *fmt,...)
Definition: elog.c:824
RangeVar * relation
Definition: parsenodes.h:1778
void list_free(List *list)
Definition: list.c:1376
#define elog(elevel,...)
Definition: elog.h:214
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
Definition: user.c:1397
ObjectAddress AlterCollation(AlterCollationStmt *stmt)
#define ShareLock
Definition: lockdefs.h:41
#define COMMAND_IS_STRICTLY_READ_ONLY
Definition: utility.h:65
#define COMMAND_OK_IN_READ_ONLY_TXN
Definition: utility.h:56
ObjectType objtype
Definition: parsenodes.h:1931
ObjectAddress DefineTSTemplate(List *names, List *parameters)
Definition: tsearchcmds.c:684
char * name
Definition: parsenodes.h:3441
bool if_not_exists
Definition: parsenodes.h:2575
#define CHECKPOINT_IMMEDIATE
Definition: xlog.h:224
ObjectAddress CreateTrigger(CreateTrigStmt *stmt, const char *queryString, Oid relOid, Oid refRelOid, Oid constraintOid, Oid indexOid, Oid funcoid, Oid parentTriggerOid, Node *whenClause, bool isInternal, bool in_partition)
Definition: trigger.c:157
void DropRole(DropRoleStmt *stmt)
Definition: user.c:994
const char * name
Definition: parsenodes.h:3374
char * defname
Definition: parsenodes.h:733
ObjectAddress CreateAccessMethod(CreateAmStmt *stmt)
Definition: amcmds.c:43
List * definition
Definition: parsenodes.h:2574
void ProcessUtilityForAlterTable(Node *stmt, AlterTableUtilityContext *context)
Definition: utility.c:1892
void EventTriggerCollectSimpleCommand(ObjectAddress address, ObjectAddress secondaryObject, Node *parsetree)
void UserAbortTransactionBlock(bool chain)
Definition: xact.c:3918
#define PG_TRY()
Definition: elog.h:295
#define COMMAND_OK_IN_PARALLEL_MODE
Definition: utility.h:57
void free_parsestate(ParseState *pstate)
Definition: parse_node.c:76
IndexStmt * transformIndexStmt(Oid relid, IndexStmt *stmt, const char *queryString)
PreparedStatement * FetchPreparedStatement(const char *stmt_name, bool throwError)
Definition: prepare.c:469
Definition: pg_list.h:50
ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:2016
ParamListInfo params
Definition: utility.h:35
void DropDatabase(ParseState *pstate, DropdbStmt *stmt)
Definition: dbcommands.c:1446
void ProcessUtility(PlannedStmt *pstmt, const char *queryString, ProcessUtilityContext context, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest, QueryCompletion *qc)
Definition: utility.c:501
static long analyze(struct nfa *nfa)
Definition: regc_nfa.c:2816
bool oldstyle
Definition: parsenodes.h:2571
#define PG_END_TRY()
Definition: elog.h:320
void DiscardCommand(DiscardStmt *stmt, bool isTopLevel)
Definition: discard.c:31
void RequireTransactionBlock(bool isTopLevel, const char *stmtType)
Definition: xact.c:3446
void Async_Unlisten(const char *channel)
Definition: async.c:770
#define lfirst_oid(lc)
Definition: pg_list.h:171
void AlterPublication(AlterPublicationStmt *stmt)
void SetPGVariable(const char *name, List *args, bool is_local)
Definition: guc.c:8491
LogStmtLevel GetCommandLogLevel(Node *parsetree)
Definition: utility.c:3168
bool EventTriggerBeginCompleteQuery(void)
void RequestCheckpoint(int flags)
Definition: checkpointer.c:913
char * payload
Definition: parsenodes.h:3017
TransactionStmtKind kind
Definition: parsenodes.h:3061
void ExecuteGrantStmt(GrantStmt *stmt)
Definition: aclchk.c:359
void EventTriggerAlterTableEnd(void)
ObjectAddress CreateStatistics(CreateStatsStmt *stmt)
Definition: statscmds.c:62
char * conditionname
Definition: parsenodes.h:3037
Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
Definition: tablespace.c:1010