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