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