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