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