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