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