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