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 slave
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
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
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  false, /* skip_build */
1333  false); /* quiet */
1334 
1335  /*
1336  * Add the CREATE INDEX node itself to stash right away;
1337  * if there were any commands stashed in the ALTER TABLE
1338  * code, we need them to appear after this one.
1339  */
1340  EventTriggerCollectSimpleCommand(address, secondaryObject,
1341  parsetree);
1342  commandCollected = true;
1344  }
1345  break;
1346 
1347  case T_CreateExtensionStmt:
1348  address = CreateExtension(pstate, (CreateExtensionStmt *) parsetree);
1349  break;
1350 
1351  case T_AlterExtensionStmt:
1352  address = ExecAlterExtensionStmt(pstate, (AlterExtensionStmt *) parsetree);
1353  break;
1354 
1357  &secondaryObject);
1358  break;
1359 
1360  case T_CreateFdwStmt:
1361  address = CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
1362  break;
1363 
1364  case T_AlterFdwStmt:
1365  address = AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
1366  break;
1367 
1369  address = CreateForeignServer((CreateForeignServerStmt *) parsetree);
1370  break;
1371 
1373  address = AlterForeignServer((AlterForeignServerStmt *) parsetree);
1374  break;
1375 
1377  address = CreateUserMapping((CreateUserMappingStmt *) parsetree);
1378  break;
1379 
1381  address = AlterUserMapping((AlterUserMappingStmt *) parsetree);
1382  break;
1383 
1384  case T_DropUserMappingStmt:
1385  RemoveUserMapping((DropUserMappingStmt *) parsetree);
1386  /* no commands stashed for DROP */
1387  commandCollected = true;
1388  break;
1389 
1392  /* commands are stashed inside ImportForeignSchema */
1393  commandCollected = true;
1394  break;
1395 
1396  case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
1397  {
1398  CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
1399 
1400  address = DefineCompositeType(stmt->typevar,
1401  stmt->coldeflist);
1402  }
1403  break;
1404 
1405  case T_CreateEnumStmt: /* CREATE TYPE AS ENUM */
1406  address = DefineEnum((CreateEnumStmt *) parsetree);
1407  break;
1408 
1409  case T_CreateRangeStmt: /* CREATE TYPE AS RANGE */
1410  address = DefineRange((CreateRangeStmt *) parsetree);
1411  break;
1412 
1413  case T_AlterEnumStmt: /* ALTER TYPE (enum) */
1414  address = AlterEnum((AlterEnumStmt *) parsetree);
1415  break;
1416 
1417  case T_ViewStmt: /* CREATE VIEW */
1418  EventTriggerAlterTableStart(parsetree);
1419  address = DefineView((ViewStmt *) parsetree, queryString,
1420  pstmt->stmt_location, pstmt->stmt_len);
1421  EventTriggerCollectSimpleCommand(address, secondaryObject,
1422  parsetree);
1423  /* stashed internally */
1424  commandCollected = true;
1426  break;
1427 
1428  case T_CreateFunctionStmt: /* CREATE FUNCTION */
1429  address = CreateFunction(pstate, (CreateFunctionStmt *) parsetree);
1430  break;
1431 
1432  case T_AlterFunctionStmt: /* ALTER FUNCTION */
1433  address = AlterFunction(pstate, (AlterFunctionStmt *) parsetree);
1434  break;
1435 
1436  case T_RuleStmt: /* CREATE RULE */
1437  address = DefineRule((RuleStmt *) parsetree, queryString);
1438  break;
1439 
1440  case T_CreateSeqStmt:
1441  address = DefineSequence(pstate, (CreateSeqStmt *) parsetree);
1442  break;
1443 
1444  case T_AlterSeqStmt:
1445  address = AlterSequence(pstate, (AlterSeqStmt *) parsetree);
1446  break;
1447 
1448  case T_CreateTableAsStmt:
1449  address = ExecCreateTableAs((CreateTableAsStmt *) parsetree,
1450  queryString, params, queryEnv,
1451  completionTag);
1452  break;
1453 
1454  case T_RefreshMatViewStmt:
1455  /*
1456  * REFRESH CONCURRENTLY executes some DDL commands internally.
1457  * Inhibit DDL command collection here to avoid those commands
1458  * from showing up in the deparsed command queue. The refresh
1459  * command itself is queued, which is enough.
1460  */
1462  PG_TRY();
1463  {
1464  address = ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
1465  queryString, params, completionTag);
1466  }
1467  PG_CATCH();
1468  {
1470  PG_RE_THROW();
1471  }
1472  PG_END_TRY();
1474  break;
1475 
1476  case T_CreateTrigStmt:
1477  address = CreateTrigger((CreateTrigStmt *) parsetree,
1478  queryString, InvalidOid, InvalidOid,
1479  InvalidOid, InvalidOid, false);
1480  break;
1481 
1482  case T_CreatePLangStmt:
1483  address = CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1484  break;
1485 
1486  case T_CreateDomainStmt:
1487  address = DefineDomain((CreateDomainStmt *) parsetree);
1488  break;
1489 
1491  address = CreateConversionCommand((CreateConversionStmt *) parsetree);
1492  break;
1493 
1494  case T_CreateCastStmt:
1495  address = CreateCast((CreateCastStmt *) parsetree);
1496  break;
1497 
1498  case T_CreateOpClassStmt:
1499  DefineOpClass((CreateOpClassStmt *) parsetree);
1500  /* command is stashed in DefineOpClass */
1501  commandCollected = true;
1502  break;
1503 
1504  case T_CreateOpFamilyStmt:
1505  address = DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1506  break;
1507 
1508  case T_CreateTransformStmt:
1509  address = CreateTransform((CreateTransformStmt *) parsetree);
1510  break;
1511 
1512  case T_AlterOpFamilyStmt:
1513  AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1514  /* commands are stashed in AlterOpFamily */
1515  commandCollected = true;
1516  break;
1517 
1519  address = AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1520  break;
1521 
1524 
1525  /*
1526  * Commands are stashed in MakeConfigurationMapping and
1527  * DropConfigurationMapping, which are called from
1528  * AlterTSConfiguration
1529  */
1530  commandCollected = true;
1531  break;
1532 
1535  /* commands are stashed in AlterTableMoveAll */
1536  commandCollected = true;
1537  break;
1538 
1539  case T_DropStmt:
1540  ExecDropStmt((DropStmt *) parsetree, isTopLevel);
1541  /* no commands stashed for DROP */
1542  commandCollected = true;
1543  break;
1544 
1545  case T_RenameStmt:
1546  address = ExecRenameStmt((RenameStmt *) parsetree);
1547  break;
1548 
1550  address =
1552  &secondaryObject);
1553  break;
1554 
1556  address =
1558  &secondaryObject);
1559  break;
1560 
1561  case T_AlterOwnerStmt:
1562  address = ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
1563  break;
1564 
1565  case T_AlterOperatorStmt:
1566  address = AlterOperator((AlterOperatorStmt *) parsetree);
1567  break;
1568 
1569  case T_CommentStmt:
1570  address = CommentObject((CommentStmt *) parsetree);
1571  break;
1572 
1573  case T_GrantStmt:
1574  ExecuteGrantStmt((GrantStmt *) parsetree);
1575  /* commands are stashed in ExecGrantStmt_oids */
1576  commandCollected = true;
1577  break;
1578 
1579  case T_DropOwnedStmt:
1580  DropOwnedObjects((DropOwnedStmt *) parsetree);
1581  /* no commands stashed for DROP */
1582  commandCollected = true;
1583  break;
1584 
1588  commandCollected = true;
1589  break;
1590 
1591  case T_CreatePolicyStmt: /* CREATE POLICY */
1592  address = CreatePolicy((CreatePolicyStmt *) parsetree);
1593  break;
1594 
1595  case T_AlterPolicyStmt: /* ALTER POLICY */
1596  address = AlterPolicy((AlterPolicyStmt *) parsetree);
1597  break;
1598 
1599  case T_SecLabelStmt:
1600  address = ExecSecLabelStmt((SecLabelStmt *) parsetree);
1601  break;
1602 
1603  case T_CreateAmStmt:
1604  address = CreateAccessMethod((CreateAmStmt *) parsetree);
1605  break;
1606 
1608  address = CreatePublication((CreatePublicationStmt *) parsetree);
1609  break;
1610 
1612  AlterPublication((AlterPublicationStmt *) parsetree);
1613  /*
1614  * AlterPublication calls EventTriggerCollectSimpleCommand
1615  * directly
1616  */
1617  commandCollected = true;
1618  break;
1619 
1621  address = CreateSubscription((CreateSubscriptionStmt *) parsetree,
1622  isTopLevel);
1623  break;
1624 
1626  address = AlterSubscription((AlterSubscriptionStmt *) parsetree);
1627  break;
1628 
1630  DropSubscription((DropSubscriptionStmt *) parsetree, isTopLevel);
1631  /* no commands stashed for DROP */
1632  commandCollected = true;
1633  break;
1634 
1635  case T_CreateStatsStmt:
1636  address = CreateStatistics((CreateStatsStmt *) parsetree);
1637  break;
1638 
1639  case T_AlterCollationStmt:
1640  address = AlterCollation((AlterCollationStmt *) parsetree);
1641  break;
1642 
1643  default:
1644  elog(ERROR, "unrecognized node type: %d",
1645  (int) nodeTag(parsetree));
1646  break;
1647  }
1648 
1649  /*
1650  * Remember the object so that ddl_command_end event triggers have
1651  * access to it.
1652  */
1653  if (!commandCollected)
1654  EventTriggerCollectSimpleCommand(address, secondaryObject,
1655  parsetree);
1656 
1657  if (isCompleteQuery)
1658  {
1659  EventTriggerSQLDrop(parsetree);
1660  EventTriggerDDLCommandEnd(parsetree);
1661  }
1662  }
1663  PG_CATCH();
1664  {
1665  if (needCleanup)
1667  PG_RE_THROW();
1668  }
1669  PG_END_TRY();
1670 
1671  if (needCleanup)
1673 }
1674 
1675 /*
1676  * Dispatch function for DropStmt
1677  */
1678 static void
1679 ExecDropStmt(DropStmt *stmt, bool isTopLevel)
1680 {
1681  switch (stmt->removeType)
1682  {
1683  case OBJECT_INDEX:
1684  if (stmt->concurrent)
1685  PreventTransactionChain(isTopLevel,
1686  "DROP INDEX CONCURRENTLY");
1687  /* fall through */
1688 
1689  case OBJECT_TABLE:
1690  case OBJECT_SEQUENCE:
1691  case OBJECT_VIEW:
1692  case OBJECT_MATVIEW:
1693  case OBJECT_FOREIGN_TABLE:
1694  RemoveRelations(stmt);
1695  break;
1696  default:
1697  RemoveObjects(stmt);
1698  break;
1699  }
1700 }
1701 
1702 
1703 /*
1704  * UtilityReturnsTuples
1705  * Return "true" if this utility statement will send output to the
1706  * destination.
1707  *
1708  * Generally, there should be a case here for each case in ProcessUtility
1709  * where "dest" is passed on.
1710  */
1711 bool
1713 {
1714  switch (nodeTag(parsetree))
1715  {
1716  case T_FetchStmt:
1717  {
1718  FetchStmt *stmt = (FetchStmt *) parsetree;
1719  Portal portal;
1720 
1721  if (stmt->ismove)
1722  return false;
1723  portal = GetPortalByName(stmt->portalname);
1724  if (!PortalIsValid(portal))
1725  return false; /* not our business to raise error */
1726  return portal->tupDesc ? true : false;
1727  }
1728 
1729  case T_ExecuteStmt:
1730  {
1731  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1732  PreparedStatement *entry;
1733 
1734  entry = FetchPreparedStatement(stmt->name, false);
1735  if (!entry)
1736  return false; /* not our business to raise error */
1737  if (entry->plansource->resultDesc)
1738  return true;
1739  return false;
1740  }
1741 
1742  case T_ExplainStmt:
1743  return true;
1744 
1745  case T_VariableShowStmt:
1746  return true;
1747 
1748  default:
1749  return false;
1750  }
1751 }
1752 
1753 /*
1754  * UtilityTupleDescriptor
1755  * Fetch the actual output tuple descriptor for a utility statement
1756  * for which UtilityReturnsTuples() previously returned "true".
1757  *
1758  * The returned descriptor is created in (or copied into) the current memory
1759  * context.
1760  */
1761 TupleDesc
1763 {
1764  switch (nodeTag(parsetree))
1765  {
1766  case T_FetchStmt:
1767  {
1768  FetchStmt *stmt = (FetchStmt *) parsetree;
1769  Portal portal;
1770 
1771  if (stmt->ismove)
1772  return NULL;
1773  portal = GetPortalByName(stmt->portalname);
1774  if (!PortalIsValid(portal))
1775  return NULL; /* not our business to raise error */
1776  return CreateTupleDescCopy(portal->tupDesc);
1777  }
1778 
1779  case T_ExecuteStmt:
1780  {
1781  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1782  PreparedStatement *entry;
1783 
1784  entry = FetchPreparedStatement(stmt->name, false);
1785  if (!entry)
1786  return NULL; /* not our business to raise error */
1787  return FetchPreparedStatementResultDesc(entry);
1788  }
1789 
1790  case T_ExplainStmt:
1791  return ExplainResultDesc((ExplainStmt *) parsetree);
1792 
1793  case T_VariableShowStmt:
1794  {
1795  VariableShowStmt *n = (VariableShowStmt *) parsetree;
1796 
1797  return GetPGVariableResultDesc(n->name);
1798  }
1799 
1800  default:
1801  return NULL;
1802  }
1803 }
1804 
1805 
1806 /*
1807  * QueryReturnsTuples
1808  * Return "true" if this Query will send output to the destination.
1809  */
1810 #ifdef NOT_USED
1811 bool
1812 QueryReturnsTuples(Query *parsetree)
1813 {
1814  switch (parsetree->commandType)
1815  {
1816  case CMD_SELECT:
1817  /* returns tuples */
1818  return true;
1819  case CMD_INSERT:
1820  case CMD_UPDATE:
1821  case CMD_DELETE:
1822  /* the forms with RETURNING return tuples */
1823  if (parsetree->returningList)
1824  return true;
1825  break;
1826  case CMD_UTILITY:
1827  return UtilityReturnsTuples(parsetree->utilityStmt);
1828  case CMD_UNKNOWN:
1829  case CMD_NOTHING:
1830  /* probably shouldn't get here */
1831  break;
1832  }
1833  return false; /* default */
1834 }
1835 #endif
1836 
1837 
1838 /*
1839  * UtilityContainsQuery
1840  * Return the contained Query, or NULL if there is none
1841  *
1842  * Certain utility statements, such as EXPLAIN, contain a plannable Query.
1843  * This function encapsulates knowledge of exactly which ones do.
1844  * We assume it is invoked only on already-parse-analyzed statements
1845  * (else the contained parsetree isn't a Query yet).
1846  *
1847  * In some cases (currently, only EXPLAIN of CREATE TABLE AS/SELECT INTO and
1848  * CREATE MATERIALIZED VIEW), potentially Query-containing utility statements
1849  * can be nested. This function will drill down to a non-utility Query, or
1850  * return NULL if none.
1851  */
1852 Query *
1854 {
1855  Query *qry;
1856 
1857  switch (nodeTag(parsetree))
1858  {
1859  case T_DeclareCursorStmt:
1860  qry = castNode(Query, ((DeclareCursorStmt *) parsetree)->query);
1861  if (qry->commandType == CMD_UTILITY)
1862  return UtilityContainsQuery(qry->utilityStmt);
1863  return qry;
1864 
1865  case T_ExplainStmt:
1866  qry = castNode(Query, ((ExplainStmt *) parsetree)->query);
1867  if (qry->commandType == CMD_UTILITY)
1868  return UtilityContainsQuery(qry->utilityStmt);
1869  return qry;
1870 
1871  case T_CreateTableAsStmt:
1872  qry = castNode(Query, ((CreateTableAsStmt *) parsetree)->query);
1873  if (qry->commandType == CMD_UTILITY)
1874  return UtilityContainsQuery(qry->utilityStmt);
1875  return qry;
1876 
1877  default:
1878  return NULL;
1879  }
1880 }
1881 
1882 
1883 /*
1884  * AlterObjectTypeCommandTag
1885  * helper function for CreateCommandTag
1886  *
1887  * This covers most cases where ALTER is used with an ObjectType enum.
1888  */
1889 static const char *
1891 {
1892  const char *tag;
1893 
1894  switch (objtype)
1895  {
1896  case OBJECT_AGGREGATE:
1897  tag = "ALTER AGGREGATE";
1898  break;
1899  case OBJECT_ATTRIBUTE:
1900  tag = "ALTER TYPE";
1901  break;
1902  case OBJECT_CAST:
1903  tag = "ALTER CAST";
1904  break;
1905  case OBJECT_COLLATION:
1906  tag = "ALTER COLLATION";
1907  break;
1908  case OBJECT_COLUMN:
1909  tag = "ALTER TABLE";
1910  break;
1911  case OBJECT_CONVERSION:
1912  tag = "ALTER CONVERSION";
1913  break;
1914  case OBJECT_DATABASE:
1915  tag = "ALTER DATABASE";
1916  break;
1917  case OBJECT_DOMAIN:
1918  case OBJECT_DOMCONSTRAINT:
1919  tag = "ALTER DOMAIN";
1920  break;
1921  case OBJECT_EXTENSION:
1922  tag = "ALTER EXTENSION";
1923  break;
1924  case OBJECT_FDW:
1925  tag = "ALTER FOREIGN DATA WRAPPER";
1926  break;
1927  case OBJECT_FOREIGN_SERVER:
1928  tag = "ALTER SERVER";
1929  break;
1930  case OBJECT_FOREIGN_TABLE:
1931  tag = "ALTER FOREIGN TABLE";
1932  break;
1933  case OBJECT_FUNCTION:
1934  tag = "ALTER FUNCTION";
1935  break;
1936  case OBJECT_INDEX:
1937  tag = "ALTER INDEX";
1938  break;
1939  case OBJECT_LANGUAGE:
1940  tag = "ALTER LANGUAGE";
1941  break;
1942  case OBJECT_LARGEOBJECT:
1943  tag = "ALTER LARGE OBJECT";
1944  break;
1945  case OBJECT_OPCLASS:
1946  tag = "ALTER OPERATOR CLASS";
1947  break;
1948  case OBJECT_OPERATOR:
1949  tag = "ALTER OPERATOR";
1950  break;
1951  case OBJECT_OPFAMILY:
1952  tag = "ALTER OPERATOR FAMILY";
1953  break;
1954  case OBJECT_POLICY:
1955  tag = "ALTER POLICY";
1956  break;
1957  case OBJECT_ROLE:
1958  tag = "ALTER ROLE";
1959  break;
1960  case OBJECT_RULE:
1961  tag = "ALTER RULE";
1962  break;
1963  case OBJECT_SCHEMA:
1964  tag = "ALTER SCHEMA";
1965  break;
1966  case OBJECT_SEQUENCE:
1967  tag = "ALTER SEQUENCE";
1968  break;
1969  case OBJECT_TABLE:
1970  case OBJECT_TABCONSTRAINT:
1971  tag = "ALTER TABLE";
1972  break;
1973  case OBJECT_TABLESPACE:
1974  tag = "ALTER TABLESPACE";
1975  break;
1976  case OBJECT_TRIGGER:
1977  tag = "ALTER TRIGGER";
1978  break;
1979  case OBJECT_EVENT_TRIGGER:
1980  tag = "ALTER EVENT TRIGGER";
1981  break;
1983  tag = "ALTER TEXT SEARCH CONFIGURATION";
1984  break;
1985  case OBJECT_TSDICTIONARY:
1986  tag = "ALTER TEXT SEARCH DICTIONARY";
1987  break;
1988  case OBJECT_TSPARSER:
1989  tag = "ALTER TEXT SEARCH PARSER";
1990  break;
1991  case OBJECT_TSTEMPLATE:
1992  tag = "ALTER TEXT SEARCH TEMPLATE";
1993  break;
1994  case OBJECT_TYPE:
1995  tag = "ALTER TYPE";
1996  break;
1997  case OBJECT_VIEW:
1998  tag = "ALTER VIEW";
1999  break;
2000  case OBJECT_MATVIEW:
2001  tag = "ALTER MATERIALIZED VIEW";
2002  break;
2003  case OBJECT_PUBLICATION:
2004  tag = "ALTER PUBLICATION";
2005  break;
2006  case OBJECT_SUBSCRIPTION:
2007  tag = "ALTER SUBSCRIPTION";
2008  break;
2009  case OBJECT_STATISTIC_EXT:
2010  tag = "ALTER STATISTICS";
2011  break;
2012  default:
2013  tag = "???";
2014  break;
2015  }
2016 
2017  return tag;
2018 }
2019 
2020 /*
2021  * CreateCommandTag
2022  * utility to get a string representation of the command operation,
2023  * given either a raw (un-analyzed) parsetree, an analyzed Query,
2024  * or a PlannedStmt.
2025  *
2026  * This must handle all command types, but since the vast majority
2027  * of 'em are utility commands, it seems sensible to keep it here.
2028  *
2029  * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
2030  * Also, the result must point at a true constant (permanent storage).
2031  */
2032 const char *
2034 {
2035  const char *tag;
2036 
2037  switch (nodeTag(parsetree))
2038  {
2039  /* recurse if we're given a RawStmt */
2040  case T_RawStmt:
2041  tag = CreateCommandTag(((RawStmt *) parsetree)->stmt);
2042  break;
2043 
2044  /* raw plannable queries */
2045  case T_InsertStmt:
2046  tag = "INSERT";
2047  break;
2048 
2049  case T_DeleteStmt:
2050  tag = "DELETE";
2051  break;
2052 
2053  case T_UpdateStmt:
2054  tag = "UPDATE";
2055  break;
2056 
2057  case T_SelectStmt:
2058  tag = "SELECT";
2059  break;
2060 
2061  /* utility statements --- same whether raw or cooked */
2062  case T_TransactionStmt:
2063  {
2064  TransactionStmt *stmt = (TransactionStmt *) parsetree;
2065 
2066  switch (stmt->kind)
2067  {
2068  case TRANS_STMT_BEGIN:
2069  tag = "BEGIN";
2070  break;
2071 
2072  case TRANS_STMT_START:
2073  tag = "START TRANSACTION";
2074  break;
2075 
2076  case TRANS_STMT_COMMIT:
2077  tag = "COMMIT";
2078  break;
2079 
2080  case TRANS_STMT_ROLLBACK:
2082  tag = "ROLLBACK";
2083  break;
2084 
2085  case TRANS_STMT_SAVEPOINT:
2086  tag = "SAVEPOINT";
2087  break;
2088 
2089  case TRANS_STMT_RELEASE:
2090  tag = "RELEASE";
2091  break;
2092 
2093  case TRANS_STMT_PREPARE:
2094  tag = "PREPARE TRANSACTION";
2095  break;
2096 
2098  tag = "COMMIT PREPARED";
2099  break;
2100 
2102  tag = "ROLLBACK PREPARED";
2103  break;
2104 
2105  default:
2106  tag = "???";
2107  break;
2108  }
2109  }
2110  break;
2111 
2112  case T_DeclareCursorStmt:
2113  tag = "DECLARE CURSOR";
2114  break;
2115 
2116  case T_ClosePortalStmt:
2117  {
2118  ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
2119 
2120  if (stmt->portalname == NULL)
2121  tag = "CLOSE CURSOR ALL";
2122  else
2123  tag = "CLOSE CURSOR";
2124  }
2125  break;
2126 
2127  case T_FetchStmt:
2128  {
2129  FetchStmt *stmt = (FetchStmt *) parsetree;
2130 
2131  tag = (stmt->ismove) ? "MOVE" : "FETCH";
2132  }
2133  break;
2134 
2135  case T_CreateDomainStmt:
2136  tag = "CREATE DOMAIN";
2137  break;
2138 
2139  case T_CreateSchemaStmt:
2140  tag = "CREATE SCHEMA";
2141  break;
2142 
2143  case T_CreateStmt:
2144  tag = "CREATE TABLE";
2145  break;
2146 
2148  tag = "CREATE TABLESPACE";
2149  break;
2150 
2151  case T_DropTableSpaceStmt:
2152  tag = "DROP TABLESPACE";
2153  break;
2154 
2156  tag = "ALTER TABLESPACE";
2157  break;
2158 
2159  case T_CreateExtensionStmt:
2160  tag = "CREATE EXTENSION";
2161  break;
2162 
2163  case T_AlterExtensionStmt:
2164  tag = "ALTER EXTENSION";
2165  break;
2166 
2168  tag = "ALTER EXTENSION";
2169  break;
2170 
2171  case T_CreateFdwStmt:
2172  tag = "CREATE FOREIGN DATA WRAPPER";
2173  break;
2174 
2175  case T_AlterFdwStmt:
2176  tag = "ALTER FOREIGN DATA WRAPPER";
2177  break;
2178 
2180  tag = "CREATE SERVER";
2181  break;
2182 
2184  tag = "ALTER SERVER";
2185  break;
2186 
2188  tag = "CREATE USER MAPPING";
2189  break;
2190 
2192  tag = "ALTER USER MAPPING";
2193  break;
2194 
2195  case T_DropUserMappingStmt:
2196  tag = "DROP USER MAPPING";
2197  break;
2198 
2200  tag = "CREATE FOREIGN TABLE";
2201  break;
2202 
2204  tag = "IMPORT FOREIGN SCHEMA";
2205  break;
2206 
2207  case T_DropStmt:
2208  switch (((DropStmt *) parsetree)->removeType)
2209  {
2210  case OBJECT_TABLE:
2211  tag = "DROP TABLE";
2212  break;
2213  case OBJECT_SEQUENCE:
2214  tag = "DROP SEQUENCE";
2215  break;
2216  case OBJECT_VIEW:
2217  tag = "DROP VIEW";
2218  break;
2219  case OBJECT_MATVIEW:
2220  tag = "DROP MATERIALIZED VIEW";
2221  break;
2222  case OBJECT_INDEX:
2223  tag = "DROP INDEX";
2224  break;
2225  case OBJECT_TYPE:
2226  tag = "DROP TYPE";
2227  break;
2228  case OBJECT_DOMAIN:
2229  tag = "DROP DOMAIN";
2230  break;
2231  case OBJECT_COLLATION:
2232  tag = "DROP COLLATION";
2233  break;
2234  case OBJECT_CONVERSION:
2235  tag = "DROP CONVERSION";
2236  break;
2237  case OBJECT_SCHEMA:
2238  tag = "DROP SCHEMA";
2239  break;
2240  case OBJECT_TSPARSER:
2241  tag = "DROP TEXT SEARCH PARSER";
2242  break;
2243  case OBJECT_TSDICTIONARY:
2244  tag = "DROP TEXT SEARCH DICTIONARY";
2245  break;
2246  case OBJECT_TSTEMPLATE:
2247  tag = "DROP TEXT SEARCH TEMPLATE";
2248  break;
2250  tag = "DROP TEXT SEARCH CONFIGURATION";
2251  break;
2252  case OBJECT_FOREIGN_TABLE:
2253  tag = "DROP FOREIGN TABLE";
2254  break;
2255  case OBJECT_EXTENSION:
2256  tag = "DROP EXTENSION";
2257  break;
2258  case OBJECT_FUNCTION:
2259  tag = "DROP FUNCTION";
2260  break;
2261  case OBJECT_AGGREGATE:
2262  tag = "DROP AGGREGATE";
2263  break;
2264  case OBJECT_OPERATOR:
2265  tag = "DROP OPERATOR";
2266  break;
2267  case OBJECT_LANGUAGE:
2268  tag = "DROP LANGUAGE";
2269  break;
2270  case OBJECT_CAST:
2271  tag = "DROP CAST";
2272  break;
2273  case OBJECT_TRIGGER:
2274  tag = "DROP TRIGGER";
2275  break;
2276  case OBJECT_EVENT_TRIGGER:
2277  tag = "DROP EVENT TRIGGER";
2278  break;
2279  case OBJECT_RULE:
2280  tag = "DROP RULE";
2281  break;
2282  case OBJECT_FDW:
2283  tag = "DROP FOREIGN DATA WRAPPER";
2284  break;
2285  case OBJECT_FOREIGN_SERVER:
2286  tag = "DROP SERVER";
2287  break;
2288  case OBJECT_OPCLASS:
2289  tag = "DROP OPERATOR CLASS";
2290  break;
2291  case OBJECT_OPFAMILY:
2292  tag = "DROP OPERATOR FAMILY";
2293  break;
2294  case OBJECT_POLICY:
2295  tag = "DROP POLICY";
2296  break;
2297  case OBJECT_TRANSFORM:
2298  tag = "DROP TRANSFORM";
2299  break;
2300  case OBJECT_ACCESS_METHOD:
2301  tag = "DROP ACCESS METHOD";
2302  break;
2303  case OBJECT_PUBLICATION:
2304  tag = "DROP PUBLICATION";
2305  break;
2306  case OBJECT_STATISTIC_EXT:
2307  tag = "DROP STATISTICS";
2308  break;
2309  default:
2310  tag = "???";
2311  }
2312  break;
2313 
2314  case T_TruncateStmt:
2315  tag = "TRUNCATE TABLE";
2316  break;
2317 
2318  case T_CommentStmt:
2319  tag = "COMMENT";
2320  break;
2321 
2322  case T_SecLabelStmt:
2323  tag = "SECURITY LABEL";
2324  break;
2325 
2326  case T_CopyStmt:
2327  tag = "COPY";
2328  break;
2329 
2330  case T_RenameStmt:
2331  tag = AlterObjectTypeCommandTag(((RenameStmt *) parsetree)->renameType);
2332  break;
2333 
2335  tag = AlterObjectTypeCommandTag(((AlterObjectDependsStmt *) parsetree)->objectType);
2336  break;
2337 
2339  tag = AlterObjectTypeCommandTag(((AlterObjectSchemaStmt *) parsetree)->objectType);
2340  break;
2341 
2342  case T_AlterOwnerStmt:
2343  tag = AlterObjectTypeCommandTag(((AlterOwnerStmt *) parsetree)->objectType);
2344  break;
2345 
2347  tag = AlterObjectTypeCommandTag(((AlterTableMoveAllStmt *) parsetree)->objtype);
2348  break;
2349 
2350  case T_AlterTableStmt:
2351  tag = AlterObjectTypeCommandTag(((AlterTableStmt *) parsetree)->relkind);
2352  break;
2353 
2354  case T_AlterDomainStmt:
2355  tag = "ALTER DOMAIN";
2356  break;
2357 
2358  case T_AlterFunctionStmt:
2359  tag = "ALTER FUNCTION";
2360  break;
2361 
2362  case T_GrantStmt:
2363  {
2364  GrantStmt *stmt = (GrantStmt *) parsetree;
2365 
2366  tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
2367  }
2368  break;
2369 
2370  case T_GrantRoleStmt:
2371  {
2372  GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
2373 
2374  tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
2375  }
2376  break;
2377 
2379  tag = "ALTER DEFAULT PRIVILEGES";
2380  break;
2381 
2382  case T_DefineStmt:
2383  switch (((DefineStmt *) parsetree)->kind)
2384  {
2385  case OBJECT_AGGREGATE:
2386  tag = "CREATE AGGREGATE";
2387  break;
2388  case OBJECT_OPERATOR:
2389  tag = "CREATE OPERATOR";
2390  break;
2391  case OBJECT_TYPE:
2392  tag = "CREATE TYPE";
2393  break;
2394  case OBJECT_TSPARSER:
2395  tag = "CREATE TEXT SEARCH PARSER";
2396  break;
2397  case OBJECT_TSDICTIONARY:
2398  tag = "CREATE TEXT SEARCH DICTIONARY";
2399  break;
2400  case OBJECT_TSTEMPLATE:
2401  tag = "CREATE TEXT SEARCH TEMPLATE";
2402  break;
2404  tag = "CREATE TEXT SEARCH CONFIGURATION";
2405  break;
2406  case OBJECT_COLLATION:
2407  tag = "CREATE COLLATION";
2408  break;
2409  case OBJECT_ACCESS_METHOD:
2410  tag = "CREATE ACCESS METHOD";
2411  break;
2412  default:
2413  tag = "???";
2414  }
2415  break;
2416 
2417  case T_CompositeTypeStmt:
2418  tag = "CREATE TYPE";
2419  break;
2420 
2421  case T_CreateEnumStmt:
2422  tag = "CREATE TYPE";
2423  break;
2424 
2425  case T_CreateRangeStmt:
2426  tag = "CREATE TYPE";
2427  break;
2428 
2429  case T_AlterEnumStmt:
2430  tag = "ALTER TYPE";
2431  break;
2432 
2433  case T_ViewStmt:
2434  tag = "CREATE VIEW";
2435  break;
2436 
2437  case T_CreateFunctionStmt:
2438  tag = "CREATE FUNCTION";
2439  break;
2440 
2441  case T_IndexStmt:
2442  tag = "CREATE INDEX";
2443  break;
2444 
2445  case T_RuleStmt:
2446  tag = "CREATE RULE";
2447  break;
2448 
2449  case T_CreateSeqStmt:
2450  tag = "CREATE SEQUENCE";
2451  break;
2452 
2453  case T_AlterSeqStmt:
2454  tag = "ALTER SEQUENCE";
2455  break;
2456 
2457  case T_DoStmt:
2458  tag = "DO";
2459  break;
2460 
2461  case T_CreatedbStmt:
2462  tag = "CREATE DATABASE";
2463  break;
2464 
2465  case T_AlterDatabaseStmt:
2466  tag = "ALTER DATABASE";
2467  break;
2468 
2470  tag = "ALTER DATABASE";
2471  break;
2472 
2473  case T_DropdbStmt:
2474  tag = "DROP DATABASE";
2475  break;
2476 
2477  case T_NotifyStmt:
2478  tag = "NOTIFY";
2479  break;
2480 
2481  case T_ListenStmt:
2482  tag = "LISTEN";
2483  break;
2484 
2485  case T_UnlistenStmt:
2486  tag = "UNLISTEN";
2487  break;
2488 
2489  case T_LoadStmt:
2490  tag = "LOAD";
2491  break;
2492 
2493  case T_ClusterStmt:
2494  tag = "CLUSTER";
2495  break;
2496 
2497  case T_VacuumStmt:
2498  if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2499  tag = "VACUUM";
2500  else
2501  tag = "ANALYZE";
2502  break;
2503 
2504  case T_ExplainStmt:
2505  tag = "EXPLAIN";
2506  break;
2507 
2508  case T_CreateTableAsStmt:
2509  switch (((CreateTableAsStmt *) parsetree)->relkind)
2510  {
2511  case OBJECT_TABLE:
2512  if (((CreateTableAsStmt *) parsetree)->is_select_into)
2513  tag = "SELECT INTO";
2514  else
2515  tag = "CREATE TABLE AS";
2516  break;
2517  case OBJECT_MATVIEW:
2518  tag = "CREATE MATERIALIZED VIEW";
2519  break;
2520  default:
2521  tag = "???";
2522  }
2523  break;
2524 
2525  case T_RefreshMatViewStmt:
2526  tag = "REFRESH MATERIALIZED VIEW";
2527  break;
2528 
2529  case T_AlterSystemStmt:
2530  tag = "ALTER SYSTEM";
2531  break;
2532 
2533  case T_VariableSetStmt:
2534  switch (((VariableSetStmt *) parsetree)->kind)
2535  {
2536  case VAR_SET_VALUE:
2537  case VAR_SET_CURRENT:
2538  case VAR_SET_DEFAULT:
2539  case VAR_SET_MULTI:
2540  tag = "SET";
2541  break;
2542  case VAR_RESET:
2543  case VAR_RESET_ALL:
2544  tag = "RESET";
2545  break;
2546  default:
2547  tag = "???";
2548  }
2549  break;
2550 
2551  case T_VariableShowStmt:
2552  tag = "SHOW";
2553  break;
2554 
2555  case T_DiscardStmt:
2556  switch (((DiscardStmt *) parsetree)->target)
2557  {
2558  case DISCARD_ALL:
2559  tag = "DISCARD ALL";
2560  break;
2561  case DISCARD_PLANS:
2562  tag = "DISCARD PLANS";
2563  break;
2564  case DISCARD_TEMP:
2565  tag = "DISCARD TEMP";
2566  break;
2567  case DISCARD_SEQUENCES:
2568  tag = "DISCARD SEQUENCES";
2569  break;
2570  default:
2571  tag = "???";
2572  }
2573  break;
2574 
2575  case T_CreateTransformStmt:
2576  tag = "CREATE TRANSFORM";
2577  break;
2578 
2579  case T_CreateTrigStmt:
2580  tag = "CREATE TRIGGER";
2581  break;
2582 
2583  case T_CreateEventTrigStmt:
2584  tag = "CREATE EVENT TRIGGER";
2585  break;
2586 
2587  case T_AlterEventTrigStmt:
2588  tag = "ALTER EVENT TRIGGER";
2589  break;
2590 
2591  case T_CreatePLangStmt:
2592  tag = "CREATE LANGUAGE";
2593  break;
2594 
2595  case T_CreateRoleStmt:
2596  tag = "CREATE ROLE";
2597  break;
2598 
2599  case T_AlterRoleStmt:
2600  tag = "ALTER ROLE";
2601  break;
2602 
2603  case T_AlterRoleSetStmt:
2604  tag = "ALTER ROLE";
2605  break;
2606 
2607  case T_DropRoleStmt:
2608  tag = "DROP ROLE";
2609  break;
2610 
2611  case T_DropOwnedStmt:
2612  tag = "DROP OWNED";
2613  break;
2614 
2615  case T_ReassignOwnedStmt:
2616  tag = "REASSIGN OWNED";
2617  break;
2618 
2619  case T_LockStmt:
2620  tag = "LOCK TABLE";
2621  break;
2622 
2623  case T_ConstraintsSetStmt:
2624  tag = "SET CONSTRAINTS";
2625  break;
2626 
2627  case T_CheckPointStmt:
2628  tag = "CHECKPOINT";
2629  break;
2630 
2631  case T_ReindexStmt:
2632  tag = "REINDEX";
2633  break;
2634 
2636  tag = "CREATE CONVERSION";
2637  break;
2638 
2639  case T_CreateCastStmt:
2640  tag = "CREATE CAST";
2641  break;
2642 
2643  case T_CreateOpClassStmt:
2644  tag = "CREATE OPERATOR CLASS";
2645  break;
2646 
2647  case T_CreateOpFamilyStmt:
2648  tag = "CREATE OPERATOR FAMILY";
2649  break;
2650 
2651  case T_AlterOpFamilyStmt:
2652  tag = "ALTER OPERATOR FAMILY";
2653  break;
2654 
2655  case T_AlterOperatorStmt:
2656  tag = "ALTER OPERATOR";
2657  break;
2658 
2660  tag = "ALTER TEXT SEARCH DICTIONARY";
2661  break;
2662 
2664  tag = "ALTER TEXT SEARCH CONFIGURATION";
2665  break;
2666 
2667  case T_CreatePolicyStmt:
2668  tag = "CREATE POLICY";
2669  break;
2670 
2671  case T_AlterPolicyStmt:
2672  tag = "ALTER POLICY";
2673  break;
2674 
2675  case T_CreateAmStmt:
2676  tag = "CREATE ACCESS METHOD";
2677  break;
2678 
2680  tag = "CREATE PUBLICATION";
2681  break;
2682 
2684  tag = "ALTER PUBLICATION";
2685  break;
2686 
2688  tag = "CREATE SUBSCRIPTION";
2689  break;
2690 
2692  tag = "ALTER SUBSCRIPTION";
2693  break;
2694 
2696  tag = "DROP SUBSCRIPTION";
2697  break;
2698 
2699  case T_AlterCollationStmt:
2700  tag = "ALTER COLLATION";
2701  break;
2702 
2703  case T_PrepareStmt:
2704  tag = "PREPARE";
2705  break;
2706 
2707  case T_ExecuteStmt:
2708  tag = "EXECUTE";
2709  break;
2710 
2711  case T_CreateStatsStmt:
2712  tag = "CREATE STATISTICS";
2713  break;
2714 
2715  case T_DeallocateStmt:
2716  {
2717  DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2718 
2719  if (stmt->name == NULL)
2720  tag = "DEALLOCATE ALL";
2721  else
2722  tag = "DEALLOCATE";
2723  }
2724  break;
2725 
2726  /* already-planned queries */
2727  case T_PlannedStmt:
2728  {
2729  PlannedStmt *stmt = (PlannedStmt *) parsetree;
2730 
2731  switch (stmt->commandType)
2732  {
2733  case CMD_SELECT:
2734 
2735  /*
2736  * We take a little extra care here so that the result
2737  * will be useful for complaints about read-only
2738  * statements
2739  */
2740  if (stmt->rowMarks != NIL)
2741  {
2742  /* not 100% but probably close enough */
2743  switch (((PlanRowMark *) linitial(stmt->rowMarks))->strength)
2744  {
2745  case LCS_FORKEYSHARE:
2746  tag = "SELECT FOR KEY SHARE";
2747  break;
2748  case LCS_FORSHARE:
2749  tag = "SELECT FOR SHARE";
2750  break;
2751  case LCS_FORNOKEYUPDATE:
2752  tag = "SELECT FOR NO KEY UPDATE";
2753  break;
2754  case LCS_FORUPDATE:
2755  tag = "SELECT FOR UPDATE";
2756  break;
2757  default:
2758  tag = "SELECT";
2759  break;
2760  }
2761  }
2762  else
2763  tag = "SELECT";
2764  break;
2765  case CMD_UPDATE:
2766  tag = "UPDATE";
2767  break;
2768  case CMD_INSERT:
2769  tag = "INSERT";
2770  break;
2771  case CMD_DELETE:
2772  tag = "DELETE";
2773  break;
2774  case CMD_UTILITY:
2775  tag = CreateCommandTag(stmt->utilityStmt);
2776  break;
2777  default:
2778  elog(WARNING, "unrecognized commandType: %d",
2779  (int) stmt->commandType);
2780  tag = "???";
2781  break;
2782  }
2783  }
2784  break;
2785 
2786  /* parsed-and-rewritten-but-not-planned queries */
2787  case T_Query:
2788  {
2789  Query *stmt = (Query *) parsetree;
2790 
2791  switch (stmt->commandType)
2792  {
2793  case CMD_SELECT:
2794 
2795  /*
2796  * We take a little extra care here so that the result
2797  * will be useful for complaints about read-only
2798  * statements
2799  */
2800  if (stmt->rowMarks != NIL)
2801  {
2802  /* not 100% but probably close enough */
2803  switch (((RowMarkClause *) linitial(stmt->rowMarks))->strength)
2804  {
2805  case LCS_FORKEYSHARE:
2806  tag = "SELECT FOR KEY SHARE";
2807  break;
2808  case LCS_FORSHARE:
2809  tag = "SELECT FOR SHARE";
2810  break;
2811  case LCS_FORNOKEYUPDATE:
2812  tag = "SELECT FOR NO KEY UPDATE";
2813  break;
2814  case LCS_FORUPDATE:
2815  tag = "SELECT FOR UPDATE";
2816  break;
2817  default:
2818  tag = "???";
2819  break;
2820  }
2821  }
2822  else
2823  tag = "SELECT";
2824  break;
2825  case CMD_UPDATE:
2826  tag = "UPDATE";
2827  break;
2828  case CMD_INSERT:
2829  tag = "INSERT";
2830  break;
2831  case CMD_DELETE:
2832  tag = "DELETE";
2833  break;
2834  case CMD_UTILITY:
2835  tag = CreateCommandTag(stmt->utilityStmt);
2836  break;
2837  default:
2838  elog(WARNING, "unrecognized commandType: %d",
2839  (int) stmt->commandType);
2840  tag = "???";
2841  break;
2842  }
2843  }
2844  break;
2845 
2846  default:
2847  elog(WARNING, "unrecognized node type: %d",
2848  (int) nodeTag(parsetree));
2849  tag = "???";
2850  break;
2851  }
2852 
2853  return tag;
2854 }
2855 
2856 
2857 /*
2858  * GetCommandLogLevel
2859  * utility to get the minimum log_statement level for a command,
2860  * given either a raw (un-analyzed) parsetree, an analyzed Query,
2861  * or a PlannedStmt.
2862  *
2863  * This must handle all command types, but since the vast majority
2864  * of 'em are utility commands, it seems sensible to keep it here.
2865  */
2868 {
2869  LogStmtLevel lev;
2870 
2871  switch (nodeTag(parsetree))
2872  {
2873  /* recurse if we're given a RawStmt */
2874  case T_RawStmt:
2875  lev = GetCommandLogLevel(((RawStmt *) parsetree)->stmt);
2876  break;
2877 
2878  /* raw plannable queries */
2879  case T_InsertStmt:
2880  case T_DeleteStmt:
2881  case T_UpdateStmt:
2882  lev = LOGSTMT_MOD;
2883  break;
2884 
2885  case T_SelectStmt:
2886  if (((SelectStmt *) parsetree)->intoClause)
2887  lev = LOGSTMT_DDL; /* SELECT INTO */
2888  else
2889  lev = LOGSTMT_ALL;
2890  break;
2891 
2892  /* utility statements --- same whether raw or cooked */
2893  case T_TransactionStmt:
2894  lev = LOGSTMT_ALL;
2895  break;
2896 
2897  case T_DeclareCursorStmt:
2898  lev = LOGSTMT_ALL;
2899  break;
2900 
2901  case T_ClosePortalStmt:
2902  lev = LOGSTMT_ALL;
2903  break;
2904 
2905  case T_FetchStmt:
2906  lev = LOGSTMT_ALL;
2907  break;
2908 
2909  case T_CreateSchemaStmt:
2910  lev = LOGSTMT_DDL;
2911  break;
2912 
2913  case T_CreateStmt:
2915  lev = LOGSTMT_DDL;
2916  break;
2917 
2919  case T_DropTableSpaceStmt:
2921  lev = LOGSTMT_DDL;
2922  break;
2923 
2924  case T_CreateExtensionStmt:
2925  case T_AlterExtensionStmt:
2927  lev = LOGSTMT_DDL;
2928  break;
2929 
2930  case T_CreateFdwStmt:
2931  case T_AlterFdwStmt:
2936  case T_DropUserMappingStmt:
2938  lev = LOGSTMT_DDL;
2939  break;
2940 
2941  case T_DropStmt:
2942  lev = LOGSTMT_DDL;
2943  break;
2944 
2945  case T_TruncateStmt:
2946  lev = LOGSTMT_MOD;
2947  break;
2948 
2949  case T_CommentStmt:
2950  lev = LOGSTMT_DDL;
2951  break;
2952 
2953  case T_SecLabelStmt:
2954  lev = LOGSTMT_DDL;
2955  break;
2956 
2957  case T_CopyStmt:
2958  if (((CopyStmt *) parsetree)->is_from)
2959  lev = LOGSTMT_MOD;
2960  else
2961  lev = LOGSTMT_ALL;
2962  break;
2963 
2964  case T_PrepareStmt:
2965  {
2966  PrepareStmt *stmt = (PrepareStmt *) parsetree;
2967 
2968  /* Look through a PREPARE to the contained stmt */
2969  lev = GetCommandLogLevel(stmt->query);
2970  }
2971  break;
2972 
2973  case T_ExecuteStmt:
2974  {
2975  ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2976  PreparedStatement *ps;
2977 
2978  /* Look through an EXECUTE to the referenced stmt */
2979  ps = FetchPreparedStatement(stmt->name, false);
2980  if (ps && ps->plansource->raw_parse_tree)
2982  else
2983  lev = LOGSTMT_ALL;
2984  }
2985  break;
2986 
2987  case T_DeallocateStmt:
2988  lev = LOGSTMT_ALL;
2989  break;
2990 
2991  case T_RenameStmt:
2992  lev = LOGSTMT_DDL;
2993  break;
2994 
2996  lev = LOGSTMT_DDL;
2997  break;
2998 
3000  lev = LOGSTMT_DDL;
3001  break;
3002 
3003  case T_AlterOwnerStmt:
3004  lev = LOGSTMT_DDL;
3005  break;
3006 
3008  case T_AlterTableStmt:
3009  lev = LOGSTMT_DDL;
3010  break;
3011 
3012  case T_AlterDomainStmt:
3013  lev = LOGSTMT_DDL;
3014  break;
3015 
3016  case T_GrantStmt:
3017  lev = LOGSTMT_DDL;
3018  break;
3019 
3020  case T_GrantRoleStmt:
3021  lev = LOGSTMT_DDL;
3022  break;
3023 
3025  lev = LOGSTMT_DDL;
3026  break;
3027 
3028  case T_DefineStmt:
3029  lev = LOGSTMT_DDL;
3030  break;
3031 
3032  case T_CompositeTypeStmt:
3033  lev = LOGSTMT_DDL;
3034  break;
3035 
3036  case T_CreateEnumStmt:
3037  lev = LOGSTMT_DDL;
3038  break;
3039 
3040  case T_CreateRangeStmt:
3041  lev = LOGSTMT_DDL;
3042  break;
3043 
3044  case T_AlterEnumStmt:
3045  lev = LOGSTMT_DDL;
3046  break;
3047 
3048  case T_ViewStmt:
3049  lev = LOGSTMT_DDL;
3050  break;
3051 
3052  case T_CreateFunctionStmt:
3053  lev = LOGSTMT_DDL;
3054  break;
3055 
3056  case T_AlterFunctionStmt:
3057  lev = LOGSTMT_DDL;
3058  break;
3059 
3060  case T_IndexStmt:
3061  lev = LOGSTMT_DDL;
3062  break;
3063 
3064  case T_RuleStmt:
3065  lev = LOGSTMT_DDL;
3066  break;
3067 
3068  case T_CreateSeqStmt:
3069  lev = LOGSTMT_DDL;
3070  break;
3071 
3072  case T_AlterSeqStmt:
3073  lev = LOGSTMT_DDL;
3074  break;
3075 
3076  case T_DoStmt:
3077  lev = LOGSTMT_ALL;
3078  break;
3079 
3080  case T_CreatedbStmt:
3081  lev = LOGSTMT_DDL;
3082  break;
3083 
3084  case T_AlterDatabaseStmt:
3085  lev = LOGSTMT_DDL;
3086  break;
3087 
3089  lev = LOGSTMT_DDL;
3090  break;
3091 
3092  case T_DropdbStmt:
3093  lev = LOGSTMT_DDL;
3094  break;
3095 
3096  case T_NotifyStmt:
3097  lev = LOGSTMT_ALL;
3098  break;
3099 
3100  case T_ListenStmt:
3101  lev = LOGSTMT_ALL;
3102  break;
3103 
3104  case T_UnlistenStmt:
3105  lev = LOGSTMT_ALL;
3106  break;
3107 
3108  case T_LoadStmt:
3109  lev = LOGSTMT_ALL;
3110  break;
3111 
3112  case T_ClusterStmt:
3113  lev = LOGSTMT_DDL;
3114  break;
3115 
3116  case T_VacuumStmt:
3117  lev = LOGSTMT_ALL;
3118  break;
3119 
3120  case T_ExplainStmt:
3121  {
3122  ExplainStmt *stmt = (ExplainStmt *) parsetree;
3123  bool analyze = false;
3124  ListCell *lc;
3125 
3126  /* Look through an EXPLAIN ANALYZE to the contained stmt */
3127  foreach(lc, stmt->options)
3128  {
3129  DefElem *opt = (DefElem *) lfirst(lc);
3130 
3131  if (strcmp(opt->defname, "analyze") == 0)
3132  analyze = defGetBoolean(opt);
3133  /* don't "break", as explain.c will use the last value */
3134  }
3135  if (analyze)
3136  return GetCommandLogLevel(stmt->query);
3137 
3138  /* Plain EXPLAIN isn't so interesting */
3139  lev = LOGSTMT_ALL;
3140  }
3141  break;
3142 
3143  case T_CreateTableAsStmt:
3144  lev = LOGSTMT_DDL;
3145  break;
3146 
3147  case T_RefreshMatViewStmt:
3148  lev = LOGSTMT_DDL;
3149  break;
3150 
3151  case T_AlterSystemStmt:
3152  lev = LOGSTMT_DDL;
3153  break;
3154 
3155  case T_VariableSetStmt:
3156  lev = LOGSTMT_ALL;
3157  break;
3158 
3159  case T_VariableShowStmt:
3160  lev = LOGSTMT_ALL;
3161  break;
3162 
3163  case T_DiscardStmt:
3164  lev = LOGSTMT_ALL;
3165  break;
3166 
3167  case T_CreateTrigStmt:
3168  lev = LOGSTMT_DDL;
3169  break;
3170 
3171  case T_CreateEventTrigStmt:
3172  lev = LOGSTMT_DDL;
3173  break;
3174 
3175  case T_AlterEventTrigStmt:
3176  lev = LOGSTMT_DDL;
3177  break;
3178 
3179  case T_CreatePLangStmt:
3180  lev = LOGSTMT_DDL;
3181  break;
3182 
3183  case T_CreateDomainStmt:
3184  lev = LOGSTMT_DDL;
3185  break;
3186 
3187  case T_CreateRoleStmt:
3188  lev = LOGSTMT_DDL;
3189  break;
3190 
3191  case T_AlterRoleStmt:
3192  lev = LOGSTMT_DDL;
3193  break;
3194 
3195  case T_AlterRoleSetStmt:
3196  lev = LOGSTMT_DDL;
3197  break;
3198 
3199  case T_DropRoleStmt:
3200  lev = LOGSTMT_DDL;
3201  break;
3202 
3203  case T_DropOwnedStmt:
3204  lev = LOGSTMT_DDL;
3205  break;
3206 
3207  case T_ReassignOwnedStmt:
3208  lev = LOGSTMT_DDL;
3209  break;
3210 
3211  case T_LockStmt:
3212  lev = LOGSTMT_ALL;
3213  break;
3214 
3215  case T_ConstraintsSetStmt:
3216  lev = LOGSTMT_ALL;
3217  break;
3218 
3219  case T_CheckPointStmt:
3220  lev = LOGSTMT_ALL;
3221  break;
3222 
3223  case T_ReindexStmt:
3224  lev = LOGSTMT_ALL; /* should this be DDL? */
3225  break;
3226 
3228  lev = LOGSTMT_DDL;
3229  break;
3230 
3231  case T_CreateCastStmt:
3232  lev = LOGSTMT_DDL;
3233  break;
3234 
3235  case T_CreateOpClassStmt:
3236  lev = LOGSTMT_DDL;
3237  break;
3238 
3239  case T_CreateOpFamilyStmt:
3240  lev = LOGSTMT_DDL;
3241  break;
3242 
3243  case T_CreateTransformStmt:
3244  lev = LOGSTMT_DDL;
3245  break;
3246 
3247  case T_AlterOpFamilyStmt:
3248  lev = LOGSTMT_DDL;
3249  break;
3250 
3251  case T_CreatePolicyStmt:
3252  lev = LOGSTMT_DDL;
3253  break;
3254 
3255  case T_AlterPolicyStmt:
3256  lev = LOGSTMT_DDL;
3257  break;
3258 
3260  lev = LOGSTMT_DDL;
3261  break;
3262 
3264  lev = LOGSTMT_DDL;
3265  break;
3266 
3267  case T_CreateAmStmt:
3268  lev = LOGSTMT_DDL;
3269  break;
3270 
3272  lev = LOGSTMT_DDL;
3273  break;
3274 
3276  lev = LOGSTMT_DDL;
3277  break;
3278 
3280  lev = LOGSTMT_DDL;
3281  break;
3282 
3284  lev = LOGSTMT_DDL;
3285  break;
3286 
3288  lev = LOGSTMT_DDL;
3289  break;
3290 
3291  /* already-planned queries */
3292  case T_PlannedStmt:
3293  {
3294  PlannedStmt *stmt = (PlannedStmt *) parsetree;
3295 
3296  switch (stmt->commandType)
3297  {
3298  case CMD_SELECT:
3299  lev = LOGSTMT_ALL;
3300  break;
3301 
3302  case CMD_UPDATE:
3303  case CMD_INSERT:
3304  case CMD_DELETE:
3305  lev = LOGSTMT_MOD;
3306  break;
3307 
3308  case CMD_UTILITY:
3309  lev = GetCommandLogLevel(stmt->utilityStmt);
3310  break;
3311 
3312  default:
3313  elog(WARNING, "unrecognized commandType: %d",
3314  (int) stmt->commandType);
3315  lev = LOGSTMT_ALL;
3316  break;
3317  }
3318  }
3319  break;
3320 
3321  /* parsed-and-rewritten-but-not-planned queries */
3322  case T_Query:
3323  {
3324  Query *stmt = (Query *) parsetree;
3325 
3326  switch (stmt->commandType)
3327  {
3328  case CMD_SELECT:
3329  lev = LOGSTMT_ALL;
3330  break;
3331 
3332  case CMD_UPDATE:
3333  case CMD_INSERT:
3334  case CMD_DELETE:
3335  lev = LOGSTMT_MOD;
3336  break;
3337 
3338  case CMD_UTILITY:
3339  lev = GetCommandLogLevel(stmt->utilityStmt);
3340  break;
3341 
3342  default:
3343  elog(WARNING, "unrecognized commandType: %d",
3344  (int) stmt->commandType);
3345  lev = LOGSTMT_ALL;
3346  break;
3347  }
3348 
3349  }
3350  break;
3351 
3352  default:
3353  elog(WARNING, "unrecognized node type: %d",
3354  (int) nodeTag(parsetree));
3355  lev = LOGSTMT_ALL;
3356  break;
3357  }
3358 
3359  return lev;
3360 }
TupleDesc GetPGVariableResultDesc(const char *name)
Definition: guc.c:7907
ObjectType objtype
Definition: parsenodes.h:2567
ObjectAddress AlterSequence(ParseState *pstate, AlterSeqStmt *stmt)
Definition: sequence.c:410
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:2499
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:141
ObjectAddress AlterSubscription(AlterSubscriptionStmt *stmt)
ObjectType objtype
Definition: parsenodes.h:2579
#define IsA(nodeptr, _type_)
Definition: nodes.h:560
ObjectAddress DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
Definition: tsearchcmds.c:960
ObjectAddress CreateTransform(CreateTransformStmt *stmt)
static void ExecDropStmt(DropStmt *stmt, bool isTopLevel)
Definition: utility.c:1679
void PerformPortalClose(const char *name)
Definition: portalcmds.c:216
ObjectAddress AlterDomainAddConstraint(List *names, Node *newConstraint, ObjectAddress *constrAddr)
Definition: typecmds.c:2470
ObjectAddress CreateForeignDataWrapper(CreateFdwStmt *stmt)
Definition: foreigncmds.c:560
void PreventCommandIfParallelMode(const char *cmdname)
Definition: utility.c:254
DropBehavior behavior
Definition: parsenodes.h:1787
ObjectAddress CommentObject(CommentStmt *stmt)
Definition: comment.c:40
ObjectAddress CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
Definition: functioncmds.c:861
ObjectType renameType
Definition: parsenodes.h:2765
Oid ReindexTable(RangeVar *relation, int options)
Definition: indexcmds.c:1831
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:578
Oid RangeVarGetRelidExtended(const RangeVar *relation, LOCKMODE lockmode, bool missing_ok, bool nowait, RangeVarGetRelidCallback callback, void *callback_arg)
Definition: namespace.c:217
CachedPlanSource * plansource
Definition: prepare.h:31
LogStmtLevel
Definition: tcopprot.h:40
Oid AlterTableLookupRelation(AlterTableStmt *stmt, LOCKMODE lockmode)
Definition: tablecmds.c:3043
Portal GetPortalByName(const char *name)
Definition: portalmem.c:129
void ExecuteDoStmt(DoStmt *stmt)
ObjectAddress AlterEnum(AlterEnumStmt *stmt)
Definition: typecmds.c:1228
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:138
void DropOwnedObjects(DropOwnedStmt *stmt)
Definition: user.c:1321
Oid AlterDatabaseSet(AlterDatabaseSetStmt *stmt)
Definition: dbcommands.c:1575
ObjectType objectType
Definition: parsenodes.h:2810
RangeVar * typevar
Definition: parsenodes.h:2909
void AfterTriggerSetState(ConstraintsSetStmt *stmt)
Definition: trigger.c:4721
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:509
#define strVal(v)
Definition: value.h:54
ObjectAddress ExecAlterExtensionContentsStmt(AlterExtensionContentsStmt *stmt, ObjectAddress *objAddr)
Definition: extension.c:3166
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:2979
void EventTriggerInhibitCommandCollection(void)
Oid ReindexIndex(RangeVar *indexRelation, int options)
Definition: indexcmds.c:1737
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:3084
void Async_Listen(const char *channel)
Definition: async.c:635
ObjectAddress DefineCompositeType(RangeVar *typevar, List *coldeflist)
Definition: typecmds.c:2068
Oid CreateTableSpace(CreateTableSpaceStmt *stmt)
Definition: tablespace.c:233
void AlterTable(Oid relid, LOCKMODE lockmode, AlterTableStmt *stmt)
Definition: tablecmds.c:3093
ObjectAddress AlterDomainValidateConstraint(List *names, char *constrName)
Definition: typecmds.c:2579
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7874
List * rowMarks
Definition: parsenodes.h:161
void ExecuteTruncate(TruncateStmt *stmt)
Definition: tablecmds.c:1205
void RemoveObjects(DropStmt *stmt)
Definition: dropcmds.c:54
Node * utilityStmt
Definition: parsenodes.h:118
ObjectAddress DefineOpClass(CreateOpClassStmt *stmt)
Definition: opclasscmds.c:323
bool EndTransactionBlock(void)
Definition: xact.c:3525
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:538
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:88
Oid CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
Definition: user.c:72
ObjectType removeType
Definition: parsenodes.h:2542
void GetPGVariable(const char *name, DestReceiver *dest)
Definition: guc.c:7898
ParseState * make_parsestate(ParseState *parentParseState)
Definition: parse_node.c:44
TupleDesc resultDesc
Definition: plancache.h:92
Query * UtilityContainsQuery(Node *parsetree)
Definition: utility.c:1853
void EventTriggerAlterTableStart(Node *parsetree)
#define list_make1(x1)
Definition: pg_list.h:139
char * relname
Definition: primnodes.h:68
Node * query
Definition: parsenodes.h:3083
ObjectAddress DefineAggregate(ParseState *pstate, List *name, List *args, bool oldstyle, List *parameters)
Definition: aggregatecmds.c:54
void DeallocateQuery(DeallocateStmt *stmt)
Definition: prepare.c:565
RangeVar * relation
Definition: parsenodes.h:2663
bool defGetBoolean(DefElem *def)
Definition: define.c:111
ObjectAddress AlterPolicy(AlterPolicyStmt *stmt)
Definition: policy.c:877
void RemoveRelations(DropStmt *drop)
Definition: tablecmds.c:964
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:913
#define linitial(l)
Definition: pg_list.h:111
void RangeVarCallbackOwnsRelation(const RangeVar *relation, Oid relId, Oid oldRelId, void *arg)
Definition: tablecmds.c:12967
List * args
Definition: parsenodes.h:2459
#define ERROR
Definition: elog.h:43
ObjectAddress AlterDomainDefault(List *names, Node *defaultRaw)
Definition: typecmds.c:2126
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:2545
void GrantRole(GrantRoleStmt *stmt)
Definition: user.c:1262
ObjectAddress AlterOperator(AlterOperatorStmt *stmt)
Definition: operatorcmds.c:385
TupleDesc ExplainResultDesc(ExplainStmt *stmt)
Definition: explain.c:302
void PerformPortalFetch(FetchStmt *stmt, DestReceiver *dest, char *completionTag)
Definition: portalcmds.c:168
void EventTriggerDDLCommandStart(Node *parsetree)
RangeVar * relation
Definition: parsenodes.h:3195
ObjectAddress CreatePolicy(CreatePolicyStmt *stmt)
Definition: policy.c:682
void EventTriggerSQLDrop(Node *parsetree)
void UserAbortTransactionBlock(void)
Definition: xact.c:3649
ObjectAddress AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
Definition: tsearchcmds.c:1173
ObjectAddress AlterDomainNotNull(List *names, bool notNull)
Definition: typecmds.c:2265
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:7289
int stmt_location
Definition: plannodes.h:87
Node * stmt
Definition: parsenodes.h:1391
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:85
Node * utilityStmt
Definition: plannodes.h:84
ObjectAddress DefineRange(CreateRangeStmt *stmt)
Definition: typecmds.c:1298
ObjectAddress DefineEnum(CreateEnumStmt *stmt)
Definition: typecmds.c:1107
bool UtilityReturnsTuples(Node *parsetree)
Definition: utility.c:1712
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:168
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:2863
ObjectAddress ExecRenameStmt(RenameStmt *stmt)
Definition: alter.c:325
char * portalname
Definition: parsenodes.h:2644
#define CHECKPOINT_FORCE
Definition: xlog.h:180
ObjectAddress DefineSequence(ParseState *pstate, CreateSeqStmt *seq)
Definition: sequence.c:114
#define lnext(lc)
Definition: pg_list.h:105
ObjectAddress DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, ObjectAddress *typaddress, const char *queryString)
Definition: tablecmds.c:489
#define ereport(elevel, rest)
Definition: elog.h:122
const char * CreateCommandTag(Node *parsetree)
Definition: utility.c:2033
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:1575
void ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind, int options)
Definition: indexcmds.c:1859
ObjectAddress CreateExtension(ParseState *pstate, CreateExtensionStmt *stmt)
Definition: extension.c:1617
bool missing_ok
Definition: parsenodes.h:3019
void BeginTransactionBlock(void)
Definition: xact.c:3415
void EventTriggerEndCompleteQuery(void)
bool is_grant
Definition: parsenodes.h:1823
#define WARNING
Definition: elog.h:40
Oid AlterRole(AlterRoleStmt *stmt)
Definition: user.c:493
bool PrepareTransactionBlock(char *gid)
Definition: xact.c:3474
LOCKMODE AlterTableGetLockLevel(List *cmds)
Definition: tablecmds.c:3162
ObjectAddress CreateForeignServer(CreateForeignServerStmt *stmt)
Definition: foreigncmds.c:861
void WarnNoTransactionChain(bool isTopLevel, const char *stmtType)
Definition: xact.c:3202
#define PortalIsValid(p)
Definition: portal.h:199
void AlterSystemSetConfigFile(AlterSystemStmt *altersysstmt)
Definition: guc.c:7074
Definition: nodes.h:304
void DefineSavepoint(char *name)
Definition: xact.c:3748
bool canSetTag
Definition: plannodes.h:53
bool ismove
Definition: parsenodes.h:2645
#define RELKIND_TOASTVALUE
Definition: pg_class.h:163
void EventTriggerUndoInhibitCommandCollection(void)
uintptr_t Datum
Definition: postgres.h:372
void CommandCounterIncrement(void)
Definition: xact.c:922
CmdType commandType
Definition: plannodes.h:45
Oid AlterRoleSet(AlterRoleSetStmt *stmt)
Definition: user.c:874
Oid CreateEventTrigger(CreateEventTrigStmt *stmt)
TupleDesc FetchPreparedStatementResultDesc(PreparedStatement *stmt)
Definition: prepare.c:526
ObjectType kind
Definition: parsenodes.h:2456
char * conditionname
Definition: parsenodes.h:2852
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:76
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:44
List * defnames
Definition: parsenodes.h:2458
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:3208
#define CHECKPOINT_WAIT
Definition: xlog.h:184
ObjectAddress ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
Definition: extension.c:2858
ObjectAddress ExecAlterObjectSchemaStmt(AlterObjectSchemaStmt *stmt, ObjectAddress *oldSchemaAddr)
Definition: alter.c:461
#define PG_CATCH()
Definition: elog.h:293
#define makeNode(_type_)
Definition: nodes.h:557
#define ShareUpdateExclusiveLock
Definition: lockdefs.h:39
#define COMPLETION_TAG_BUFSIZE
Definition: dest.h:74
#define NULL
Definition: c.h:229
ObjectAddress DefineTSDictionary(List *names, List *parameters)
Definition: tsearchcmds.c:409
void DoCopy(ParseState *pstate, const CopyStmt *stmt, int stmt_location, int stmt_len, uint64 *processed)
Definition: copy.c:781
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
ReindexObjectType kind
Definition: parsenodes.h:3193
bool InSecurityRestrictedOperation(void)
Definition: miscinit.c:415
bool hasModifyingCTE
Definition: plannodes.h:51
void load_file(const char *filename, bool restricted)
Definition: dfmgr.c:137
ObjectAddress DefineIndex(Oid relationId, IndexStmt *stmt, Oid indexRelationId, bool is_alter_table, bool check_rights, bool skip_build, bool quiet)
Definition: indexcmds.c:305
Node * query
Definition: parsenodes.h:3251
ObjectAddress CreateConversionCommand(CreateConversionStmt *stmt)
void Async_UnlistenAll(void)
Definition: async.c:667
Oid AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
Definition: tablecmds.c:10621
ObjectAddress AlterForeignDataWrapper(AlterFdwStmt *stmt)
Definition: foreigncmds.c:673
List * transformCreateStmt(CreateStmt *stmt, const char *queryString)
ObjectAddress ExecAlterOwnerStmt(AlterOwnerStmt *stmt)
Definition: alter.c:766
#define PG_RE_THROW()
Definition: elog.h:314
struct RawStmt * raw_parse_tree
Definition: plancache.h:83
void ReleaseSavepoint(List *options)
Definition: xact.c:3811
const char * name
Definition: encode.c:521
void RollbackToSavepoint(List *options)
Definition: xact.c:3924
void PreventCommandIfReadOnly(const char *cmdname)
Definition: utility.c:236
#define nodeTag(nodeptr)
Definition: nodes.h:514
void EventTriggerAlterTableRelid(Oid objectId)
void ExplainQuery(ParseState *pstate, ExplainStmt *stmt, const char *queryString, ParamListInfo params, QueryEnvironment *queryEnv, DestReceiver *dest)
Definition: explain.c:145
void Async_Notify(const char *channel, const char *payload)
Definition: async.c:540
Oid AlterOpFamily(AlterOpFamilyStmt *stmt)
Definition: opclasscmds.c:763
ObjectAddress DefineOpFamily(CreateOpFamilyStmt *stmt)
Definition: opclasscmds.c:718
ObjectAddress AlterDomainDropConstraint(List *names, const char *constrName, DropBehavior behavior, bool missing_ok)
Definition: typecmds.c:2380
bool concurrent
Definition: parsenodes.h:2679
bool EventTriggerSupportsGrantObjectType(GrantObjectType objtype)
ObjectAddress DefineRule(RuleStmt *stmt, const char *queryString)
GrantObjectType objtype
Definition: parsenodes.h:1825
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:1657
void ReassignOwnedObjects(ReassignOwnedStmt *stmt)
Definition: user.c:1347
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:3263
bool if_not_exists
Definition: parsenodes.h:2461
#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:954
ObjectAddress ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString, ParamListInfo params, char *completionTag)
Definition: matview.c:137
const char * name
Definition: parsenodes.h:3196
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:2460
#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:1890
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:526
ObjectAddress AlterFunction(ParseState *pstate, AlterFunctionStmt *stmt)
TupleDesc UtilityTupleDescriptor(Node *parsetree)
Definition: utility.c:1762
#define UINT64_FORMAT
Definition: c.h:316
static long analyze(struct nfa *nfa)
Definition: regc_nfa.c:2816
bool oldstyle
Definition: parsenodes.h:2457
char * dbname
Definition: parsenodes.h:3018
#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:649
void AlterPublication(AlterPublicationStmt *stmt)
void SetPGVariable(const char *name, List *args, bool is_local)
Definition: guc.c:7433
LogStmtLevel GetCommandLogLevel(Node *parsetree)
Definition: utility.c:2867
bool EventTriggerBeginCompleteQuery(void)
void RequestCheckpoint(int flags)
Definition: checkpointer.c:967
void PreventTransactionChain(bool isTopLevel, const char *stmtType)
Definition: xact.c:3154
char * payload
Definition: parsenodes.h:2853
TransactionStmtKind kind
Definition: parsenodes.h:2897
void ExecuteGrantStmt(GrantStmt *stmt)
Definition: aclchk.c:385
void EventTriggerAlterTableEnd(void)
ObjectAddress CreateStatistics(CreateStatsStmt *stmt)
Definition: statscmds.c:49
char * conditionname
Definition: parsenodes.h:2873
Oid AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
Definition: tablespace.c:986