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