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