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