Core support for "extensions", which are packages of SQL objects.
[pgsql.git] / src / backend / tcop / utility.c
blob10a4438995f94d0a0d8412616528046bf7ec9089
1 /*-------------------------------------------------------------------------
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.
8 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
12 * IDENTIFICATION
13 * src/backend/tcop/utility.c
15 *-------------------------------------------------------------------------
17 #include "postgres.h"
19 #include "access/reloptions.h"
20 #include "access/twophase.h"
21 #include "access/xact.h"
22 #include "catalog/catalog.h"
23 #include "catalog/namespace.h"
24 #include "catalog/toasting.h"
25 #include "commands/alter.h"
26 #include "commands/async.h"
27 #include "commands/cluster.h"
28 #include "commands/comment.h"
29 #include "commands/conversioncmds.h"
30 #include "commands/copy.h"
31 #include "commands/dbcommands.h"
32 #include "commands/defrem.h"
33 #include "commands/discard.h"
34 #include "commands/explain.h"
35 #include "commands/extension.h"
36 #include "commands/lockcmds.h"
37 #include "commands/portalcmds.h"
38 #include "commands/prepare.h"
39 #include "commands/proclang.h"
40 #include "commands/schemacmds.h"
41 #include "commands/seclabel.h"
42 #include "commands/sequence.h"
43 #include "commands/tablecmds.h"
44 #include "commands/tablespace.h"
45 #include "commands/trigger.h"
46 #include "commands/typecmds.h"
47 #include "commands/user.h"
48 #include "commands/vacuum.h"
49 #include "commands/view.h"
50 #include "miscadmin.h"
51 #include "parser/parse_utilcmd.h"
52 #include "postmaster/bgwriter.h"
53 #include "rewrite/rewriteDefine.h"
54 #include "rewrite/rewriteRemove.h"
55 #include "storage/fd.h"
56 #include "tcop/pquery.h"
57 #include "tcop/utility.h"
58 #include "utils/acl.h"
59 #include "utils/guc.h"
60 #include "utils/syscache.h"
63 /* Hook for plugins to get control in ProcessUtility() */
64 ProcessUtility_hook_type ProcessUtility_hook = NULL;
68 * Verify user has ownership of specified relation, else ereport.
70 * If noCatalogs is true then we also deny access to system catalogs,
71 * except when allowSystemTableMods is true.
73 void
74 CheckRelationOwnership(RangeVar *rel, bool noCatalogs)
76 Oid relOid;
77 HeapTuple tuple;
79 relOid = RangeVarGetRelid(rel, false);
80 tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
81 if (!HeapTupleIsValid(tuple)) /* should not happen */
82 elog(ERROR, "cache lookup failed for relation %u", relOid);
84 if (!pg_class_ownercheck(relOid, GetUserId()))
85 aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS,
86 rel->relname);
88 if (noCatalogs)
90 if (!allowSystemTableMods &&
91 IsSystemClass((Form_pg_class) GETSTRUCT(tuple)))
92 ereport(ERROR,
93 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
94 errmsg("permission denied: \"%s\" is a system catalog",
95 rel->relname)));
98 ReleaseSysCache(tuple);
103 * CommandIsReadOnly: is an executable query read-only?
105 * This is a much stricter test than we apply for XactReadOnly mode;
106 * the query must be *in truth* read-only, because the caller wishes
107 * not to do CommandCounterIncrement for it.
109 * Note: currently no need to support Query nodes here
111 bool
112 CommandIsReadOnly(Node *parsetree)
114 if (IsA(parsetree, PlannedStmt))
116 PlannedStmt *stmt = (PlannedStmt *) parsetree;
118 switch (stmt->commandType)
120 case CMD_SELECT:
121 if (stmt->intoClause != NULL)
122 return false; /* SELECT INTO */
123 else if (stmt->rowMarks != NIL)
124 return false; /* SELECT FOR UPDATE/SHARE */
125 else
126 return true;
127 case CMD_UPDATE:
128 case CMD_INSERT:
129 case CMD_DELETE:
130 return false;
131 default:
132 elog(WARNING, "unrecognized commandType: %d",
133 (int) stmt->commandType);
134 break;
137 /* For now, treat all utility commands as read/write */
138 return false;
142 * check_xact_readonly: is a utility command read-only?
144 * Here we use the loose rules of XactReadOnly mode: no permanent effects
145 * on the database are allowed.
147 static void
148 check_xact_readonly(Node *parsetree)
150 if (!XactReadOnly)
151 return;
154 * Note: Commands that need to do more complicated checking are handled
155 * elsewhere, in particular COPY and plannable statements do their own
156 * checking. However they should all call PreventCommandIfReadOnly to
157 * actually throw the error.
160 switch (nodeTag(parsetree))
162 case T_AlterDatabaseStmt:
163 case T_AlterDatabaseSetStmt:
164 case T_AlterDomainStmt:
165 case T_AlterFunctionStmt:
166 case T_AlterRoleStmt:
167 case T_AlterRoleSetStmt:
168 case T_AlterObjectSchemaStmt:
169 case T_AlterOwnerStmt:
170 case T_AlterSeqStmt:
171 case T_AlterTableStmt:
172 case T_RenameStmt:
173 case T_CommentStmt:
174 case T_DefineStmt:
175 case T_CreateCastStmt:
176 case T_CreateConversionStmt:
177 case T_CreatedbStmt:
178 case T_CreateDomainStmt:
179 case T_CreateFunctionStmt:
180 case T_CreateRoleStmt:
181 case T_IndexStmt:
182 case T_CreatePLangStmt:
183 case T_CreateOpClassStmt:
184 case T_CreateOpFamilyStmt:
185 case T_AlterOpFamilyStmt:
186 case T_RuleStmt:
187 case T_CreateSchemaStmt:
188 case T_CreateSeqStmt:
189 case T_CreateStmt:
190 case T_CreateTableSpaceStmt:
191 case T_CreateTrigStmt:
192 case T_CompositeTypeStmt:
193 case T_CreateEnumStmt:
194 case T_AlterEnumStmt:
195 case T_ViewStmt:
196 case T_DropCastStmt:
197 case T_DropStmt:
198 case T_DropdbStmt:
199 case T_DropTableSpaceStmt:
200 case T_RemoveFuncStmt:
201 case T_DropRoleStmt:
202 case T_DropPLangStmt:
203 case T_RemoveOpClassStmt:
204 case T_RemoveOpFamilyStmt:
205 case T_DropPropertyStmt:
206 case T_GrantStmt:
207 case T_GrantRoleStmt:
208 case T_AlterDefaultPrivilegesStmt:
209 case T_TruncateStmt:
210 case T_DropOwnedStmt:
211 case T_ReassignOwnedStmt:
212 case T_AlterTSDictionaryStmt:
213 case T_AlterTSConfigurationStmt:
214 case T_CreateExtensionStmt:
215 case T_CreateFdwStmt:
216 case T_AlterFdwStmt:
217 case T_DropFdwStmt:
218 case T_CreateForeignServerStmt:
219 case T_AlterForeignServerStmt:
220 case T_DropForeignServerStmt:
221 case T_CreateUserMappingStmt:
222 case T_AlterUserMappingStmt:
223 case T_DropUserMappingStmt:
224 case T_AlterTableSpaceOptionsStmt:
225 case T_CreateForeignTableStmt:
226 case T_SecLabelStmt:
227 PreventCommandIfReadOnly(CreateCommandTag(parsetree));
228 break;
229 default:
230 /* do nothing */
231 break;
236 * PreventCommandIfReadOnly: throw error if XactReadOnly
238 * This is useful mainly to ensure consistency of the error message wording;
239 * most callers have checked XactReadOnly for themselves.
241 void
242 PreventCommandIfReadOnly(const char *cmdname)
244 if (XactReadOnly)
245 ereport(ERROR,
246 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
247 /* translator: %s is name of a SQL command, eg CREATE */
248 errmsg("cannot execute %s in a read-only transaction",
249 cmdname)));
253 * PreventCommandDuringRecovery: throw error if RecoveryInProgress
255 * The majority of operations that are unsafe in a Hot Standby slave
256 * will be rejected by XactReadOnly tests. However there are a few
257 * commands that are allowed in "read-only" xacts but cannot be allowed
258 * in Hot Standby mode. Those commands should call this function.
260 void
261 PreventCommandDuringRecovery(const char *cmdname)
263 if (RecoveryInProgress())
264 ereport(ERROR,
265 (errcode(ERRCODE_READ_ONLY_SQL_TRANSACTION),
266 /* translator: %s is name of a SQL command, eg CREATE */
267 errmsg("cannot execute %s during recovery",
268 cmdname)));
272 * CheckRestrictedOperation: throw error for hazardous command if we're
273 * inside a security restriction context.
275 * This is needed to protect session-local state for which there is not any
276 * better-defined protection mechanism, such as ownership.
278 static void
279 CheckRestrictedOperation(const char *cmdname)
281 if (InSecurityRestrictedOperation())
282 ereport(ERROR,
283 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
284 /* translator: %s is name of a SQL command, eg PREPARE */
285 errmsg("cannot execute %s within security-restricted operation",
286 cmdname)));
291 * ProcessUtility
292 * general utility function invoker
294 * parsetree: the parse tree for the utility statement
295 * queryString: original source text of command
296 * params: parameters to use during execution
297 * isTopLevel: true if executing a "top level" (interactively issued) command
298 * dest: where to send results
299 * completionTag: points to a buffer of size COMPLETION_TAG_BUFSIZE
300 * in which to store a command completion status string.
302 * Notes: as of PG 8.4, caller MUST supply a queryString; it is not
303 * allowed anymore to pass NULL. (If you really don't have source text,
304 * you can pass a constant string, perhaps "(query not available)".)
306 * completionTag is only set nonempty if we want to return a nondefault status.
308 * completionTag may be NULL if caller doesn't want a status string.
310 void
311 ProcessUtility(Node *parsetree,
312 const char *queryString,
313 ParamListInfo params,
314 bool isTopLevel,
315 DestReceiver *dest,
316 char *completionTag)
318 Assert(queryString != NULL); /* required as of 8.4 */
321 * We provide a function hook variable that lets loadable plugins get
322 * control when ProcessUtility is called. Such a plugin would normally
323 * call standard_ProcessUtility().
325 if (ProcessUtility_hook)
326 (*ProcessUtility_hook) (parsetree, queryString, params,
327 isTopLevel, dest, completionTag);
328 else
329 standard_ProcessUtility(parsetree, queryString, params,
330 isTopLevel, dest, completionTag);
333 void
334 standard_ProcessUtility(Node *parsetree,
335 const char *queryString,
336 ParamListInfo params,
337 bool isTopLevel,
338 DestReceiver *dest,
339 char *completionTag)
341 check_xact_readonly(parsetree);
343 if (completionTag)
344 completionTag[0] = '\0';
346 switch (nodeTag(parsetree))
349 * ******************** transactions ********************
351 case T_TransactionStmt:
353 TransactionStmt *stmt = (TransactionStmt *) parsetree;
355 switch (stmt->kind)
358 * START TRANSACTION, as defined by SQL99: Identical
359 * to BEGIN. Same code for both.
361 case TRANS_STMT_BEGIN:
362 case TRANS_STMT_START:
364 ListCell *lc;
366 BeginTransactionBlock();
367 foreach(lc, stmt->options)
369 DefElem *item = (DefElem *) lfirst(lc);
371 if (strcmp(item->defname, "transaction_isolation") == 0)
372 SetPGVariable("transaction_isolation",
373 list_make1(item->arg),
374 true);
375 else if (strcmp(item->defname, "transaction_read_only") == 0)
376 SetPGVariable("transaction_read_only",
377 list_make1(item->arg),
378 true);
379 else if (strcmp(item->defname, "transaction_deferrable") == 0)
380 SetPGVariable("transaction_deferrable",
381 list_make1(item->arg),
382 true);
385 break;
387 case TRANS_STMT_COMMIT:
388 if (!EndTransactionBlock())
390 /* report unsuccessful commit in completionTag */
391 if (completionTag)
392 strcpy(completionTag, "ROLLBACK");
394 break;
396 case TRANS_STMT_PREPARE:
397 PreventCommandDuringRecovery("PREPARE TRANSACTION");
398 if (!PrepareTransactionBlock(stmt->gid))
400 /* report unsuccessful commit in completionTag */
401 if (completionTag)
402 strcpy(completionTag, "ROLLBACK");
404 break;
406 case TRANS_STMT_COMMIT_PREPARED:
407 PreventTransactionChain(isTopLevel, "COMMIT PREPARED");
408 PreventCommandDuringRecovery("COMMIT PREPARED");
409 FinishPreparedTransaction(stmt->gid, true);
410 break;
412 case TRANS_STMT_ROLLBACK_PREPARED:
413 PreventTransactionChain(isTopLevel, "ROLLBACK PREPARED");
414 PreventCommandDuringRecovery("ROLLBACK PREPARED");
415 FinishPreparedTransaction(stmt->gid, false);
416 break;
418 case TRANS_STMT_ROLLBACK:
419 UserAbortTransactionBlock();
420 break;
422 case TRANS_STMT_SAVEPOINT:
424 ListCell *cell;
425 char *name = NULL;
427 RequireTransactionChain(isTopLevel, "SAVEPOINT");
429 foreach(cell, stmt->options)
431 DefElem *elem = lfirst(cell);
433 if (strcmp(elem->defname, "savepoint_name") == 0)
434 name = strVal(elem->arg);
437 Assert(PointerIsValid(name));
439 DefineSavepoint(name);
441 break;
443 case TRANS_STMT_RELEASE:
444 RequireTransactionChain(isTopLevel, "RELEASE SAVEPOINT");
445 ReleaseSavepoint(stmt->options);
446 break;
448 case TRANS_STMT_ROLLBACK_TO:
449 RequireTransactionChain(isTopLevel, "ROLLBACK TO SAVEPOINT");
450 RollbackToSavepoint(stmt->options);
453 * CommitTransactionCommand is in charge of
454 * re-defining the savepoint again
456 break;
459 break;
462 * Portal (cursor) manipulation
464 * Note: DECLARE CURSOR is processed mostly as a SELECT, and
465 * therefore what we will get here is a PlannedStmt not a bare
466 * DeclareCursorStmt.
468 case T_PlannedStmt:
470 PlannedStmt *stmt = (PlannedStmt *) parsetree;
472 if (stmt->utilityStmt == NULL ||
473 !IsA(stmt->utilityStmt, DeclareCursorStmt))
474 elog(ERROR, "non-DECLARE CURSOR PlannedStmt passed to ProcessUtility");
475 PerformCursorOpen(stmt, params, queryString, isTopLevel);
477 break;
479 case T_ClosePortalStmt:
481 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
483 CheckRestrictedOperation("CLOSE");
484 PerformPortalClose(stmt->portalname);
486 break;
488 case T_FetchStmt:
489 PerformPortalFetch((FetchStmt *) parsetree, dest,
490 completionTag);
491 break;
494 * relation and attribute manipulation
496 case T_CreateSchemaStmt:
497 CreateSchemaCommand((CreateSchemaStmt *) parsetree,
498 queryString);
499 break;
501 case T_CreateStmt:
502 case T_CreateForeignTableStmt:
504 List *stmts;
505 ListCell *l;
506 Oid relOid;
508 /* Run parse analysis ... */
509 stmts = transformCreateStmt((CreateStmt *) parsetree,
510 queryString);
512 /* ... and do it */
513 foreach(l, stmts)
515 Node *stmt = (Node *) lfirst(l);
517 if (IsA(stmt, CreateStmt))
519 Datum toast_options;
520 static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
522 /* Create the table itself */
523 relOid = DefineRelation((CreateStmt *) stmt,
524 RELKIND_RELATION,
525 InvalidOid);
528 * If "IF NOT EXISTS" was specified and the relation
529 * already exists, do nothing further.
531 if (relOid == InvalidOid)
532 continue;
535 * Let AlterTableCreateToastTable decide if this one
536 * needs a secondary relation too.
538 CommandCounterIncrement();
540 /* parse and validate reloptions for the toast table */
541 toast_options = transformRelOptions((Datum) 0,
542 ((CreateStmt *) stmt)->options,
543 "toast",
544 validnsps,
545 true, false);
546 (void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
547 true);
549 AlterTableCreateToastTable(relOid, toast_options);
551 else if (IsA(stmt, CreateForeignTableStmt))
553 /* Create the table itself */
554 relOid = DefineRelation((CreateStmt *) stmt,
555 RELKIND_FOREIGN_TABLE,
556 InvalidOid);
559 * Unless "IF NOT EXISTS" was specified and the
560 * relation already exists, create the pg_foreign_table
561 * entry.
563 if (relOid != InvalidOid)
564 CreateForeignTable((CreateForeignTableStmt *) stmt,
565 relOid);
567 else
569 /* Recurse for anything else */
570 ProcessUtility(stmt,
571 queryString,
572 params,
573 false,
574 None_Receiver,
575 NULL);
578 /* Need CCI between commands */
579 if (lnext(l) != NULL)
580 CommandCounterIncrement();
583 break;
585 case T_CreateTableSpaceStmt:
586 PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
587 CreateTableSpace((CreateTableSpaceStmt *) parsetree);
588 break;
590 case T_DropTableSpaceStmt:
591 PreventTransactionChain(isTopLevel, "DROP TABLESPACE");
592 DropTableSpace((DropTableSpaceStmt *) parsetree);
593 break;
595 case T_AlterTableSpaceOptionsStmt:
596 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
597 break;
599 case T_CreateExtensionStmt:
600 CreateExtension((CreateExtensionStmt *) parsetree);
601 break;
603 case T_CreateFdwStmt:
604 CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
605 break;
607 case T_AlterFdwStmt:
608 AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
609 break;
611 case T_DropFdwStmt:
612 RemoveForeignDataWrapper((DropFdwStmt *) parsetree);
613 break;
615 case T_CreateForeignServerStmt:
616 CreateForeignServer((CreateForeignServerStmt *) parsetree);
617 break;
619 case T_AlterForeignServerStmt:
620 AlterForeignServer((AlterForeignServerStmt *) parsetree);
621 break;
623 case T_DropForeignServerStmt:
624 RemoveForeignServer((DropForeignServerStmt *) parsetree);
625 break;
627 case T_CreateUserMappingStmt:
628 CreateUserMapping((CreateUserMappingStmt *) parsetree);
629 break;
631 case T_AlterUserMappingStmt:
632 AlterUserMapping((AlterUserMappingStmt *) parsetree);
633 break;
635 case T_DropUserMappingStmt:
636 RemoveUserMapping((DropUserMappingStmt *) parsetree);
637 break;
639 case T_DropStmt:
641 DropStmt *stmt = (DropStmt *) parsetree;
643 switch (stmt->removeType)
645 case OBJECT_TABLE:
646 case OBJECT_SEQUENCE:
647 case OBJECT_VIEW:
648 case OBJECT_INDEX:
649 case OBJECT_FOREIGN_TABLE:
650 RemoveRelations(stmt);
651 break;
653 case OBJECT_TYPE:
654 case OBJECT_DOMAIN:
655 RemoveTypes(stmt);
656 break;
658 case OBJECT_CONVERSION:
659 DropConversionsCommand(stmt);
660 break;
662 case OBJECT_SCHEMA:
663 RemoveSchemas(stmt);
664 break;
666 case OBJECT_TSPARSER:
667 RemoveTSParsers(stmt);
668 break;
670 case OBJECT_TSDICTIONARY:
671 RemoveTSDictionaries(stmt);
672 break;
674 case OBJECT_TSTEMPLATE:
675 RemoveTSTemplates(stmt);
676 break;
678 case OBJECT_TSCONFIGURATION:
679 RemoveTSConfigurations(stmt);
680 break;
682 case OBJECT_EXTENSION:
683 RemoveExtensions(stmt);
684 break;
686 default:
687 elog(ERROR, "unrecognized drop object type: %d",
688 (int) stmt->removeType);
689 break;
692 break;
694 case T_TruncateStmt:
695 ExecuteTruncate((TruncateStmt *) parsetree);
696 break;
698 case T_CommentStmt:
699 CommentObject((CommentStmt *) parsetree);
700 break;
702 case T_SecLabelStmt:
703 ExecSecLabelStmt((SecLabelStmt *) parsetree);
704 break;
706 case T_CopyStmt:
708 uint64 processed;
710 processed = DoCopy((CopyStmt *) parsetree, queryString);
711 if (completionTag)
712 snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
713 "COPY " UINT64_FORMAT, processed);
715 break;
717 case T_PrepareStmt:
718 CheckRestrictedOperation("PREPARE");
719 PrepareQuery((PrepareStmt *) parsetree, queryString);
720 break;
722 case T_ExecuteStmt:
723 ExecuteQuery((ExecuteStmt *) parsetree, queryString, params,
724 dest, completionTag);
725 break;
727 case T_DeallocateStmt:
728 CheckRestrictedOperation("DEALLOCATE");
729 DeallocateQuery((DeallocateStmt *) parsetree);
730 break;
733 * schema
735 case T_RenameStmt:
736 ExecRenameStmt((RenameStmt *) parsetree);
737 break;
739 case T_AlterObjectSchemaStmt:
740 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt *) parsetree);
741 break;
743 case T_AlterOwnerStmt:
744 ExecAlterOwnerStmt((AlterOwnerStmt *) parsetree);
745 break;
747 case T_AlterTableStmt:
749 List *stmts;
750 ListCell *l;
752 /* Run parse analysis ... */
753 stmts = transformAlterTableStmt((AlterTableStmt *) parsetree,
754 queryString);
756 /* ... and do it */
757 foreach(l, stmts)
759 Node *stmt = (Node *) lfirst(l);
761 if (IsA(stmt, AlterTableStmt))
763 /* Do the table alteration proper */
764 AlterTable((AlterTableStmt *) stmt);
766 else
768 /* Recurse for anything else */
769 ProcessUtility(stmt,
770 queryString,
771 params,
772 false,
773 None_Receiver,
774 NULL);
777 /* Need CCI between commands */
778 if (lnext(l) != NULL)
779 CommandCounterIncrement();
782 break;
784 case T_AlterDomainStmt:
786 AlterDomainStmt *stmt = (AlterDomainStmt *) parsetree;
789 * Some or all of these functions are recursive to cover
790 * inherited things, so permission checks are done there.
792 switch (stmt->subtype)
794 case 'T': /* ALTER DOMAIN DEFAULT */
797 * Recursively alter column default for table and, if
798 * requested, for descendants
800 AlterDomainDefault(stmt->typeName,
801 stmt->def);
802 break;
803 case 'N': /* ALTER DOMAIN DROP NOT NULL */
804 AlterDomainNotNull(stmt->typeName,
805 false);
806 break;
807 case 'O': /* ALTER DOMAIN SET NOT NULL */
808 AlterDomainNotNull(stmt->typeName,
809 true);
810 break;
811 case 'C': /* ADD CONSTRAINT */
812 AlterDomainAddConstraint(stmt->typeName,
813 stmt->def);
814 break;
815 case 'X': /* DROP CONSTRAINT */
816 AlterDomainDropConstraint(stmt->typeName,
817 stmt->name,
818 stmt->behavior);
819 break;
820 default: /* oops */
821 elog(ERROR, "unrecognized alter domain type: %d",
822 (int) stmt->subtype);
823 break;
826 break;
828 case T_GrantStmt:
829 ExecuteGrantStmt((GrantStmt *) parsetree);
830 break;
832 case T_GrantRoleStmt:
833 GrantRole((GrantRoleStmt *) parsetree);
834 break;
836 case T_AlterDefaultPrivilegesStmt:
837 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
838 break;
841 * **************** object creation / destruction *****************
843 case T_DefineStmt:
845 DefineStmt *stmt = (DefineStmt *) parsetree;
847 switch (stmt->kind)
849 case OBJECT_AGGREGATE:
850 DefineAggregate(stmt->defnames, stmt->args,
851 stmt->oldstyle, stmt->definition);
852 break;
853 case OBJECT_OPERATOR:
854 Assert(stmt->args == NIL);
855 DefineOperator(stmt->defnames, stmt->definition);
856 break;
857 case OBJECT_TYPE:
858 Assert(stmt->args == NIL);
859 DefineType(stmt->defnames, stmt->definition);
860 break;
861 case OBJECT_TSPARSER:
862 Assert(stmt->args == NIL);
863 DefineTSParser(stmt->defnames, stmt->definition);
864 break;
865 case OBJECT_TSDICTIONARY:
866 Assert(stmt->args == NIL);
867 DefineTSDictionary(stmt->defnames, stmt->definition);
868 break;
869 case OBJECT_TSTEMPLATE:
870 Assert(stmt->args == NIL);
871 DefineTSTemplate(stmt->defnames, stmt->definition);
872 break;
873 case OBJECT_TSCONFIGURATION:
874 Assert(stmt->args == NIL);
875 DefineTSConfiguration(stmt->defnames, stmt->definition);
876 break;
877 default:
878 elog(ERROR, "unrecognized define stmt type: %d",
879 (int) stmt->kind);
880 break;
883 break;
885 case T_CompositeTypeStmt: /* CREATE TYPE (composite) */
887 CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
889 DefineCompositeType(stmt->typevar, stmt->coldeflist);
891 break;
893 case T_CreateEnumStmt: /* CREATE TYPE (enum) */
894 DefineEnum((CreateEnumStmt *) parsetree);
895 break;
897 case T_AlterEnumStmt: /* ALTER TYPE (enum) */
899 * We disallow this in transaction blocks, because we can't cope
900 * with enum OID values getting into indexes and then having their
901 * defining pg_enum entries go away.
903 PreventTransactionChain(isTopLevel, "ALTER TYPE ... ADD");
904 AlterEnum((AlterEnumStmt *) parsetree);
905 break;
907 case T_ViewStmt: /* CREATE VIEW */
908 DefineView((ViewStmt *) parsetree, queryString);
909 break;
911 case T_CreateFunctionStmt: /* CREATE FUNCTION */
912 CreateFunction((CreateFunctionStmt *) parsetree, queryString);
913 break;
915 case T_AlterFunctionStmt: /* ALTER FUNCTION */
916 AlterFunction((AlterFunctionStmt *) parsetree);
917 break;
919 case T_IndexStmt: /* CREATE INDEX */
921 IndexStmt *stmt = (IndexStmt *) parsetree;
923 if (stmt->concurrent)
924 PreventTransactionChain(isTopLevel,
925 "CREATE INDEX CONCURRENTLY");
927 CheckRelationOwnership(stmt->relation, true);
929 /* Run parse analysis ... */
930 stmt = transformIndexStmt(stmt, queryString);
932 /* ... and do it */
933 DefineIndex(stmt->relation, /* relation */
934 stmt->idxname, /* index name */
935 InvalidOid, /* no predefined OID */
936 stmt->accessMethod, /* am name */
937 stmt->tableSpace,
938 stmt->indexParams, /* parameters */
939 (Expr *) stmt->whereClause,
940 stmt->options,
941 stmt->excludeOpNames,
942 stmt->unique,
943 stmt->primary,
944 stmt->isconstraint,
945 stmt->deferrable,
946 stmt->initdeferred,
947 false, /* is_alter_table */
948 true, /* check_rights */
949 false, /* skip_build */
950 false, /* quiet */
951 stmt->concurrent); /* concurrent */
953 break;
955 case T_RuleStmt: /* CREATE RULE */
956 DefineRule((RuleStmt *) parsetree, queryString);
957 break;
959 case T_CreateSeqStmt:
960 DefineSequence((CreateSeqStmt *) parsetree);
961 break;
963 case T_AlterSeqStmt:
964 AlterSequence((AlterSeqStmt *) parsetree);
965 break;
967 case T_RemoveFuncStmt:
969 RemoveFuncStmt *stmt = (RemoveFuncStmt *) parsetree;
971 switch (stmt->kind)
973 case OBJECT_FUNCTION:
974 RemoveFunction(stmt);
975 break;
976 case OBJECT_AGGREGATE:
977 RemoveAggregate(stmt);
978 break;
979 case OBJECT_OPERATOR:
980 RemoveOperator(stmt);
981 break;
982 default:
983 elog(ERROR, "unrecognized object type: %d",
984 (int) stmt->kind);
985 break;
988 break;
990 case T_DoStmt:
991 ExecuteDoStmt((DoStmt *) parsetree);
992 break;
994 case T_CreatedbStmt:
995 PreventTransactionChain(isTopLevel, "CREATE DATABASE");
996 createdb((CreatedbStmt *) parsetree);
997 break;
999 case T_AlterDatabaseStmt:
1000 AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
1001 break;
1003 case T_AlterDatabaseSetStmt:
1004 AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
1005 break;
1007 case T_DropdbStmt:
1009 DropdbStmt *stmt = (DropdbStmt *) parsetree;
1011 PreventTransactionChain(isTopLevel, "DROP DATABASE");
1012 dropdb(stmt->dbname, stmt->missing_ok);
1014 break;
1016 /* Query-level asynchronous notification */
1017 case T_NotifyStmt:
1019 NotifyStmt *stmt = (NotifyStmt *) parsetree;
1021 PreventCommandDuringRecovery("NOTIFY");
1022 Async_Notify(stmt->conditionname, stmt->payload);
1024 break;
1026 case T_ListenStmt:
1028 ListenStmt *stmt = (ListenStmt *) parsetree;
1030 PreventCommandDuringRecovery("LISTEN");
1031 CheckRestrictedOperation("LISTEN");
1032 Async_Listen(stmt->conditionname);
1034 break;
1036 case T_UnlistenStmt:
1038 UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
1040 PreventCommandDuringRecovery("UNLISTEN");
1041 CheckRestrictedOperation("UNLISTEN");
1042 if (stmt->conditionname)
1043 Async_Unlisten(stmt->conditionname);
1044 else
1045 Async_UnlistenAll();
1047 break;
1049 case T_LoadStmt:
1051 LoadStmt *stmt = (LoadStmt *) parsetree;
1053 closeAllVfds(); /* probably not necessary... */
1054 /* Allowed names are restricted if you're not superuser */
1055 load_file(stmt->filename, !superuser());
1057 break;
1059 case T_ClusterStmt:
1060 /* we choose to allow this during "read only" transactions */
1061 PreventCommandDuringRecovery("CLUSTER");
1062 cluster((ClusterStmt *) parsetree, isTopLevel);
1063 break;
1065 case T_VacuumStmt:
1066 /* we choose to allow this during "read only" transactions */
1067 PreventCommandDuringRecovery("VACUUM");
1068 vacuum((VacuumStmt *) parsetree, InvalidOid, true, NULL, false,
1069 isTopLevel);
1070 break;
1072 case T_ExplainStmt:
1073 ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
1074 break;
1076 case T_VariableSetStmt:
1077 ExecSetVariableStmt((VariableSetStmt *) parsetree);
1078 break;
1080 case T_VariableShowStmt:
1082 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1084 GetPGVariable(n->name, dest);
1086 break;
1088 case T_DiscardStmt:
1089 /* should we allow DISCARD PLANS? */
1090 CheckRestrictedOperation("DISCARD");
1091 DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
1092 break;
1094 case T_CreateTrigStmt:
1095 (void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
1096 InvalidOid, InvalidOid, false);
1097 break;
1099 case T_DropPropertyStmt:
1101 DropPropertyStmt *stmt = (DropPropertyStmt *) parsetree;
1102 Oid relId;
1104 relId = RangeVarGetRelid(stmt->relation, false);
1106 switch (stmt->removeType)
1108 case OBJECT_RULE:
1109 /* RemoveRewriteRule checks permissions */
1110 RemoveRewriteRule(relId, stmt->property,
1111 stmt->behavior, stmt->missing_ok);
1112 break;
1113 case OBJECT_TRIGGER:
1114 /* DropTrigger checks permissions */
1115 DropTrigger(relId, stmt->property,
1116 stmt->behavior, stmt->missing_ok);
1117 break;
1118 default:
1119 elog(ERROR, "unrecognized object type: %d",
1120 (int) stmt->removeType);
1121 break;
1124 break;
1126 case T_CreatePLangStmt:
1127 CreateProceduralLanguage((CreatePLangStmt *) parsetree);
1128 break;
1130 case T_DropPLangStmt:
1131 DropProceduralLanguage((DropPLangStmt *) parsetree);
1132 break;
1135 * ******************************** DOMAIN statements ****
1137 case T_CreateDomainStmt:
1138 DefineDomain((CreateDomainStmt *) parsetree);
1139 break;
1142 * ******************************** ROLE statements ****
1144 case T_CreateRoleStmt:
1145 CreateRole((CreateRoleStmt *) parsetree);
1146 break;
1148 case T_AlterRoleStmt:
1149 AlterRole((AlterRoleStmt *) parsetree);
1150 break;
1152 case T_AlterRoleSetStmt:
1153 AlterRoleSet((AlterRoleSetStmt *) parsetree);
1154 break;
1156 case T_DropRoleStmt:
1157 DropRole((DropRoleStmt *) parsetree);
1158 break;
1160 case T_DropOwnedStmt:
1161 DropOwnedObjects((DropOwnedStmt *) parsetree);
1162 break;
1164 case T_ReassignOwnedStmt:
1165 ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
1166 break;
1168 case T_LockStmt:
1171 * Since the lock would just get dropped immediately, LOCK TABLE
1172 * outside a transaction block is presumed to be user error.
1174 RequireTransactionChain(isTopLevel, "LOCK TABLE");
1175 LockTableCommand((LockStmt *) parsetree);
1176 break;
1178 case T_ConstraintsSetStmt:
1179 AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
1180 break;
1182 case T_CheckPointStmt:
1183 if (!superuser())
1184 ereport(ERROR,
1185 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
1186 errmsg("must be superuser to do CHECKPOINT")));
1189 * You might think we should have a PreventCommandDuringRecovery()
1190 * here, but we interpret a CHECKPOINT command during recovery as
1191 * a request for a restartpoint instead. We allow this since it
1192 * can be a useful way of reducing switchover time when using
1193 * various forms of replication.
1195 RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
1196 (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
1197 break;
1199 case T_ReindexStmt:
1201 ReindexStmt *stmt = (ReindexStmt *) parsetree;
1203 /* we choose to allow this during "read only" transactions */
1204 PreventCommandDuringRecovery("REINDEX");
1205 switch (stmt->kind)
1207 case OBJECT_INDEX:
1208 ReindexIndex(stmt->relation);
1209 break;
1210 case OBJECT_TABLE:
1211 ReindexTable(stmt->relation);
1212 break;
1213 case OBJECT_DATABASE:
1216 * This cannot run inside a user transaction block; if
1217 * we were inside a transaction, then its commit- and
1218 * start-transaction-command calls would not have the
1219 * intended effect!
1221 PreventTransactionChain(isTopLevel,
1222 "REINDEX DATABASE");
1223 ReindexDatabase(stmt->name,
1224 stmt->do_system, stmt->do_user);
1225 break;
1226 default:
1227 elog(ERROR, "unrecognized object type: %d",
1228 (int) stmt->kind);
1229 break;
1231 break;
1233 break;
1235 case T_CreateConversionStmt:
1236 CreateConversionCommand((CreateConversionStmt *) parsetree);
1237 break;
1239 case T_CreateCastStmt:
1240 CreateCast((CreateCastStmt *) parsetree);
1241 break;
1243 case T_DropCastStmt:
1244 DropCast((DropCastStmt *) parsetree);
1245 break;
1247 case T_CreateOpClassStmt:
1248 DefineOpClass((CreateOpClassStmt *) parsetree);
1249 break;
1251 case T_CreateOpFamilyStmt:
1252 DefineOpFamily((CreateOpFamilyStmt *) parsetree);
1253 break;
1255 case T_AlterOpFamilyStmt:
1256 AlterOpFamily((AlterOpFamilyStmt *) parsetree);
1257 break;
1259 case T_RemoveOpClassStmt:
1260 RemoveOpClass((RemoveOpClassStmt *) parsetree);
1261 break;
1263 case T_RemoveOpFamilyStmt:
1264 RemoveOpFamily((RemoveOpFamilyStmt *) parsetree);
1265 break;
1267 case T_AlterTSDictionaryStmt:
1268 AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
1269 break;
1271 case T_AlterTSConfigurationStmt:
1272 AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
1273 break;
1275 default:
1276 elog(ERROR, "unrecognized node type: %d",
1277 (int) nodeTag(parsetree));
1278 break;
1283 * UtilityReturnsTuples
1284 * Return "true" if this utility statement will send output to the
1285 * destination.
1287 * Generally, there should be a case here for each case in ProcessUtility
1288 * where "dest" is passed on.
1290 bool
1291 UtilityReturnsTuples(Node *parsetree)
1293 switch (nodeTag(parsetree))
1295 case T_FetchStmt:
1297 FetchStmt *stmt = (FetchStmt *) parsetree;
1298 Portal portal;
1300 if (stmt->ismove)
1301 return false;
1302 portal = GetPortalByName(stmt->portalname);
1303 if (!PortalIsValid(portal))
1304 return false; /* not our business to raise error */
1305 return portal->tupDesc ? true : false;
1308 case T_ExecuteStmt:
1310 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1311 PreparedStatement *entry;
1313 if (stmt->into)
1314 return false;
1315 entry = FetchPreparedStatement(stmt->name, false);
1316 if (!entry)
1317 return false; /* not our business to raise error */
1318 if (entry->plansource->resultDesc)
1319 return true;
1320 return false;
1323 case T_ExplainStmt:
1324 return true;
1326 case T_VariableShowStmt:
1327 return true;
1329 default:
1330 return false;
1335 * UtilityTupleDescriptor
1336 * Fetch the actual output tuple descriptor for a utility statement
1337 * for which UtilityReturnsTuples() previously returned "true".
1339 * The returned descriptor is created in (or copied into) the current memory
1340 * context.
1342 TupleDesc
1343 UtilityTupleDescriptor(Node *parsetree)
1345 switch (nodeTag(parsetree))
1347 case T_FetchStmt:
1349 FetchStmt *stmt = (FetchStmt *) parsetree;
1350 Portal portal;
1352 if (stmt->ismove)
1353 return NULL;
1354 portal = GetPortalByName(stmt->portalname);
1355 if (!PortalIsValid(portal))
1356 return NULL; /* not our business to raise error */
1357 return CreateTupleDescCopy(portal->tupDesc);
1360 case T_ExecuteStmt:
1362 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
1363 PreparedStatement *entry;
1365 if (stmt->into)
1366 return NULL;
1367 entry = FetchPreparedStatement(stmt->name, false);
1368 if (!entry)
1369 return NULL; /* not our business to raise error */
1370 return FetchPreparedStatementResultDesc(entry);
1373 case T_ExplainStmt:
1374 return ExplainResultDesc((ExplainStmt *) parsetree);
1376 case T_VariableShowStmt:
1378 VariableShowStmt *n = (VariableShowStmt *) parsetree;
1380 return GetPGVariableResultDesc(n->name);
1383 default:
1384 return NULL;
1390 * QueryReturnsTuples
1391 * Return "true" if this Query will send output to the destination.
1393 #ifdef NOT_USED
1394 bool
1395 QueryReturnsTuples(Query *parsetree)
1397 switch (parsetree->commandType)
1399 case CMD_SELECT:
1400 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1401 if (parsetree->utilityStmt == NULL &&
1402 parsetree->intoClause == NULL)
1403 return true;
1404 break;
1405 case CMD_INSERT:
1406 case CMD_UPDATE:
1407 case CMD_DELETE:
1408 /* the forms with RETURNING return tuples */
1409 if (parsetree->returningList)
1410 return true;
1411 break;
1412 case CMD_UTILITY:
1413 return UtilityReturnsTuples(parsetree->utilityStmt);
1414 case CMD_UNKNOWN:
1415 case CMD_NOTHING:
1416 /* probably shouldn't get here */
1417 break;
1419 return false; /* default */
1421 #endif
1425 * CreateCommandTag
1426 * utility to get a string representation of the command operation,
1427 * given either a raw (un-analyzed) parsetree or a planned query.
1429 * This must handle all command types, but since the vast majority
1430 * of 'em are utility commands, it seems sensible to keep it here.
1432 * NB: all result strings must be shorter than COMPLETION_TAG_BUFSIZE.
1433 * Also, the result must point at a true constant (permanent storage).
1435 const char *
1436 CreateCommandTag(Node *parsetree)
1438 const char *tag;
1440 switch (nodeTag(parsetree))
1442 /* raw plannable queries */
1443 case T_InsertStmt:
1444 tag = "INSERT";
1445 break;
1447 case T_DeleteStmt:
1448 tag = "DELETE";
1449 break;
1451 case T_UpdateStmt:
1452 tag = "UPDATE";
1453 break;
1455 case T_SelectStmt:
1456 tag = "SELECT";
1457 break;
1459 /* utility statements --- same whether raw or cooked */
1460 case T_TransactionStmt:
1462 TransactionStmt *stmt = (TransactionStmt *) parsetree;
1464 switch (stmt->kind)
1466 case TRANS_STMT_BEGIN:
1467 tag = "BEGIN";
1468 break;
1470 case TRANS_STMT_START:
1471 tag = "START TRANSACTION";
1472 break;
1474 case TRANS_STMT_COMMIT:
1475 tag = "COMMIT";
1476 break;
1478 case TRANS_STMT_ROLLBACK:
1479 case TRANS_STMT_ROLLBACK_TO:
1480 tag = "ROLLBACK";
1481 break;
1483 case TRANS_STMT_SAVEPOINT:
1484 tag = "SAVEPOINT";
1485 break;
1487 case TRANS_STMT_RELEASE:
1488 tag = "RELEASE";
1489 break;
1491 case TRANS_STMT_PREPARE:
1492 tag = "PREPARE TRANSACTION";
1493 break;
1495 case TRANS_STMT_COMMIT_PREPARED:
1496 tag = "COMMIT PREPARED";
1497 break;
1499 case TRANS_STMT_ROLLBACK_PREPARED:
1500 tag = "ROLLBACK PREPARED";
1501 break;
1503 default:
1504 tag = "???";
1505 break;
1508 break;
1510 case T_DeclareCursorStmt:
1511 tag = "DECLARE CURSOR";
1512 break;
1514 case T_ClosePortalStmt:
1516 ClosePortalStmt *stmt = (ClosePortalStmt *) parsetree;
1518 if (stmt->portalname == NULL)
1519 tag = "CLOSE CURSOR ALL";
1520 else
1521 tag = "CLOSE CURSOR";
1523 break;
1525 case T_FetchStmt:
1527 FetchStmt *stmt = (FetchStmt *) parsetree;
1529 tag = (stmt->ismove) ? "MOVE" : "FETCH";
1531 break;
1533 case T_CreateDomainStmt:
1534 tag = "CREATE DOMAIN";
1535 break;
1537 case T_CreateSchemaStmt:
1538 tag = "CREATE SCHEMA";
1539 break;
1541 case T_CreateStmt:
1542 tag = "CREATE TABLE";
1543 break;
1545 case T_CreateTableSpaceStmt:
1546 tag = "CREATE TABLESPACE";
1547 break;
1549 case T_DropTableSpaceStmt:
1550 tag = "DROP TABLESPACE";
1551 break;
1553 case T_AlterTableSpaceOptionsStmt:
1554 tag = "ALTER TABLESPACE";
1555 break;
1557 case T_CreateExtensionStmt:
1558 tag = "CREATE EXTENSION";
1559 break;
1561 case T_CreateFdwStmt:
1562 tag = "CREATE FOREIGN DATA WRAPPER";
1563 break;
1565 case T_AlterFdwStmt:
1566 tag = "ALTER FOREIGN DATA WRAPPER";
1567 break;
1569 case T_DropFdwStmt:
1570 tag = "DROP FOREIGN DATA WRAPPER";
1571 break;
1573 case T_CreateForeignServerStmt:
1574 tag = "CREATE SERVER";
1575 break;
1577 case T_AlterForeignServerStmt:
1578 tag = "ALTER SERVER";
1579 break;
1581 case T_DropForeignServerStmt:
1582 tag = "DROP SERVER";
1583 break;
1585 case T_CreateUserMappingStmt:
1586 tag = "CREATE USER MAPPING";
1587 break;
1589 case T_AlterUserMappingStmt:
1590 tag = "ALTER USER MAPPING";
1591 break;
1593 case T_DropUserMappingStmt:
1594 tag = "DROP USER MAPPING";
1595 break;
1597 case T_CreateForeignTableStmt:
1598 tag = "CREATE FOREIGN TABLE";
1599 break;
1601 case T_DropStmt:
1602 switch (((DropStmt *) parsetree)->removeType)
1604 case OBJECT_TABLE:
1605 tag = "DROP TABLE";
1606 break;
1607 case OBJECT_SEQUENCE:
1608 tag = "DROP SEQUENCE";
1609 break;
1610 case OBJECT_VIEW:
1611 tag = "DROP VIEW";
1612 break;
1613 case OBJECT_INDEX:
1614 tag = "DROP INDEX";
1615 break;
1616 case OBJECT_TYPE:
1617 tag = "DROP TYPE";
1618 break;
1619 case OBJECT_DOMAIN:
1620 tag = "DROP DOMAIN";
1621 break;
1622 case OBJECT_CONVERSION:
1623 tag = "DROP CONVERSION";
1624 break;
1625 case OBJECT_SCHEMA:
1626 tag = "DROP SCHEMA";
1627 break;
1628 case OBJECT_TSPARSER:
1629 tag = "DROP TEXT SEARCH PARSER";
1630 break;
1631 case OBJECT_TSDICTIONARY:
1632 tag = "DROP TEXT SEARCH DICTIONARY";
1633 break;
1634 case OBJECT_TSTEMPLATE:
1635 tag = "DROP TEXT SEARCH TEMPLATE";
1636 break;
1637 case OBJECT_TSCONFIGURATION:
1638 tag = "DROP TEXT SEARCH CONFIGURATION";
1639 break;
1640 case OBJECT_FOREIGN_TABLE:
1641 tag = "DROP FOREIGN TABLE";
1642 break;
1643 case OBJECT_EXTENSION:
1644 tag = "DROP EXTENSION";
1645 break;
1646 default:
1647 tag = "???";
1649 break;
1651 case T_TruncateStmt:
1652 tag = "TRUNCATE TABLE";
1653 break;
1655 case T_CommentStmt:
1656 tag = "COMMENT";
1657 break;
1659 case T_SecLabelStmt:
1660 tag = "SECURITY LABEL";
1661 break;
1663 case T_CopyStmt:
1664 tag = "COPY";
1665 break;
1667 case T_RenameStmt:
1668 switch (((RenameStmt *) parsetree)->renameType)
1670 case OBJECT_AGGREGATE:
1671 tag = "ALTER AGGREGATE";
1672 break;
1673 case OBJECT_CONVERSION:
1674 tag = "ALTER CONVERSION";
1675 break;
1676 case OBJECT_DATABASE:
1677 tag = "ALTER DATABASE";
1678 break;
1679 case OBJECT_FUNCTION:
1680 tag = "ALTER FUNCTION";
1681 break;
1682 case OBJECT_INDEX:
1683 tag = "ALTER INDEX";
1684 break;
1685 case OBJECT_LANGUAGE:
1686 tag = "ALTER LANGUAGE";
1687 break;
1688 case OBJECT_OPCLASS:
1689 tag = "ALTER OPERATOR CLASS";
1690 break;
1691 case OBJECT_OPFAMILY:
1692 tag = "ALTER OPERATOR FAMILY";
1693 break;
1694 case OBJECT_ROLE:
1695 tag = "ALTER ROLE";
1696 break;
1697 case OBJECT_SCHEMA:
1698 tag = "ALTER SCHEMA";
1699 break;
1700 case OBJECT_SEQUENCE:
1701 tag = "ALTER SEQUENCE";
1702 break;
1703 case OBJECT_COLUMN:
1705 RenameStmt *stmt = (RenameStmt *) parsetree;
1706 if (stmt->relationType == OBJECT_FOREIGN_TABLE)
1707 tag = "ALTER FOREIGN TABLE";
1708 else
1709 tag = "ALTER TABLE";
1711 break;
1712 case OBJECT_TABLE:
1713 tag = "ALTER TABLE";
1714 break;
1715 case OBJECT_TABLESPACE:
1716 tag = "ALTER TABLESPACE";
1717 break;
1718 case OBJECT_TRIGGER:
1719 tag = "ALTER TRIGGER";
1720 break;
1721 case OBJECT_VIEW:
1722 tag = "ALTER VIEW";
1723 break;
1724 case OBJECT_FOREIGN_TABLE:
1725 tag = "ALTER FOREIGN TABLE";
1726 break;
1727 case OBJECT_TSPARSER:
1728 tag = "ALTER TEXT SEARCH PARSER";
1729 break;
1730 case OBJECT_TSDICTIONARY:
1731 tag = "ALTER TEXT SEARCH DICTIONARY";
1732 break;
1733 case OBJECT_TSTEMPLATE:
1734 tag = "ALTER TEXT SEARCH TEMPLATE";
1735 break;
1736 case OBJECT_TSCONFIGURATION:
1737 tag = "ALTER TEXT SEARCH CONFIGURATION";
1738 break;
1739 case OBJECT_ATTRIBUTE:
1740 case OBJECT_TYPE:
1741 tag = "ALTER TYPE";
1742 break;
1743 default:
1744 tag = "???";
1745 break;
1747 break;
1749 case T_AlterObjectSchemaStmt:
1750 switch (((AlterObjectSchemaStmt *) parsetree)->objectType)
1752 case OBJECT_AGGREGATE:
1753 tag = "ALTER AGGREGATE";
1754 break;
1755 case OBJECT_CONVERSION:
1756 tag = "ALTER CONVERSION";
1757 break;
1758 case OBJECT_DOMAIN:
1759 tag = "ALTER DOMAIN";
1760 break;
1761 case OBJECT_EXTENSION:
1762 tag = "ALTER EXTENSION";
1763 break;
1764 case OBJECT_OPERATOR:
1765 tag = "ALTER OPERATOR";
1766 break;
1767 case OBJECT_OPCLASS:
1768 tag = "ALTER OPERATOR CLASS";
1769 break;
1770 case OBJECT_OPFAMILY:
1771 tag = "ALTER OPERATOR FAMILY";
1772 break;
1773 case OBJECT_FUNCTION:
1774 tag = "ALTER FUNCTION";
1775 break;
1776 case OBJECT_SEQUENCE:
1777 tag = "ALTER SEQUENCE";
1778 break;
1779 case OBJECT_TABLE:
1780 tag = "ALTER TABLE";
1781 break;
1782 case OBJECT_TYPE:
1783 tag = "ALTER TYPE";
1784 break;
1785 case OBJECT_TSPARSER:
1786 tag = "ALTER TEXT SEARCH PARSER";
1787 break;
1788 case OBJECT_TSDICTIONARY:
1789 tag = "ALTER TEXT SEARCH DICTIONARY";
1790 break;
1791 case OBJECT_TSTEMPLATE:
1792 tag = "ALTER TEXT SEARCH TEMPLATE";
1793 break;
1794 case OBJECT_TSCONFIGURATION:
1795 tag = "ALTER TEXT SEARCH CONFIGURATION";
1796 break;
1797 case OBJECT_VIEW:
1798 tag = "ALTER VIEW";
1799 break;
1800 case OBJECT_FOREIGN_TABLE:
1801 tag = "ALTER FOREIGN TABLE";
1802 break;
1803 default:
1804 tag = "???";
1805 break;
1807 break;
1809 case T_AlterOwnerStmt:
1810 switch (((AlterOwnerStmt *) parsetree)->objectType)
1812 case OBJECT_AGGREGATE:
1813 tag = "ALTER AGGREGATE";
1814 break;
1815 case OBJECT_CONVERSION:
1816 tag = "ALTER CONVERSION";
1817 break;
1818 case OBJECT_DATABASE:
1819 tag = "ALTER DATABASE";
1820 break;
1821 case OBJECT_DOMAIN:
1822 tag = "ALTER DOMAIN";
1823 break;
1824 case OBJECT_FUNCTION:
1825 tag = "ALTER FUNCTION";
1826 break;
1827 case OBJECT_LANGUAGE:
1828 tag = "ALTER LANGUAGE";
1829 break;
1830 case OBJECT_LARGEOBJECT:
1831 tag = "ALTER LARGE OBJECT";
1832 break;
1833 case OBJECT_OPERATOR:
1834 tag = "ALTER OPERATOR";
1835 break;
1836 case OBJECT_OPCLASS:
1837 tag = "ALTER OPERATOR CLASS";
1838 break;
1839 case OBJECT_OPFAMILY:
1840 tag = "ALTER OPERATOR FAMILY";
1841 break;
1842 case OBJECT_SCHEMA:
1843 tag = "ALTER SCHEMA";
1844 break;
1845 case OBJECT_TABLESPACE:
1846 tag = "ALTER TABLESPACE";
1847 break;
1848 case OBJECT_TYPE:
1849 tag = "ALTER TYPE";
1850 break;
1851 case OBJECT_TSCONFIGURATION:
1852 tag = "ALTER TEXT SEARCH CONFIGURATION";
1853 break;
1854 case OBJECT_TSDICTIONARY:
1855 tag = "ALTER TEXT SEARCH DICTIONARY";
1856 break;
1857 case OBJECT_FDW:
1858 tag = "ALTER FOREIGN DATA WRAPPER";
1859 break;
1860 case OBJECT_FOREIGN_SERVER:
1861 tag = "ALTER SERVER";
1862 break;
1863 case OBJECT_FOREIGN_TABLE:
1864 tag = "ALTER FOREIGN TABLE";
1865 break;
1866 default:
1867 tag = "???";
1868 break;
1870 break;
1872 case T_AlterTableStmt:
1873 switch (((AlterTableStmt *) parsetree)->relkind)
1875 case OBJECT_TABLE:
1876 tag = "ALTER TABLE";
1877 break;
1878 case OBJECT_INDEX:
1879 tag = "ALTER INDEX";
1880 break;
1881 case OBJECT_SEQUENCE:
1882 tag = "ALTER SEQUENCE";
1883 break;
1884 case OBJECT_TYPE:
1885 tag = "ALTER TYPE";
1886 break;
1887 case OBJECT_VIEW:
1888 tag = "ALTER VIEW";
1889 break;
1890 case OBJECT_FOREIGN_TABLE:
1891 tag = "ALTER FOREIGN TABLE";
1892 break;
1893 default:
1894 tag = "???";
1895 break;
1897 break;
1899 case T_AlterDomainStmt:
1900 tag = "ALTER DOMAIN";
1901 break;
1903 case T_AlterFunctionStmt:
1904 tag = "ALTER FUNCTION";
1905 break;
1907 case T_GrantStmt:
1909 GrantStmt *stmt = (GrantStmt *) parsetree;
1911 tag = (stmt->is_grant) ? "GRANT" : "REVOKE";
1913 break;
1915 case T_GrantRoleStmt:
1917 GrantRoleStmt *stmt = (GrantRoleStmt *) parsetree;
1919 tag = (stmt->is_grant) ? "GRANT ROLE" : "REVOKE ROLE";
1921 break;
1923 case T_AlterDefaultPrivilegesStmt:
1924 tag = "ALTER DEFAULT PRIVILEGES";
1925 break;
1927 case T_DefineStmt:
1928 switch (((DefineStmt *) parsetree)->kind)
1930 case OBJECT_AGGREGATE:
1931 tag = "CREATE AGGREGATE";
1932 break;
1933 case OBJECT_OPERATOR:
1934 tag = "CREATE OPERATOR";
1935 break;
1936 case OBJECT_TYPE:
1937 tag = "CREATE TYPE";
1938 break;
1939 case OBJECT_TSPARSER:
1940 tag = "CREATE TEXT SEARCH PARSER";
1941 break;
1942 case OBJECT_TSDICTIONARY:
1943 tag = "CREATE TEXT SEARCH DICTIONARY";
1944 break;
1945 case OBJECT_TSTEMPLATE:
1946 tag = "CREATE TEXT SEARCH TEMPLATE";
1947 break;
1948 case OBJECT_TSCONFIGURATION:
1949 tag = "CREATE TEXT SEARCH CONFIGURATION";
1950 break;
1951 default:
1952 tag = "???";
1954 break;
1956 case T_CompositeTypeStmt:
1957 tag = "CREATE TYPE";
1958 break;
1960 case T_CreateEnumStmt:
1961 tag = "CREATE TYPE";
1962 break;
1964 case T_AlterEnumStmt:
1965 tag = "ALTER TYPE";
1966 break;
1968 case T_ViewStmt:
1969 tag = "CREATE VIEW";
1970 break;
1972 case T_CreateFunctionStmt:
1973 tag = "CREATE FUNCTION";
1974 break;
1976 case T_IndexStmt:
1977 tag = "CREATE INDEX";
1978 break;
1980 case T_RuleStmt:
1981 tag = "CREATE RULE";
1982 break;
1984 case T_CreateSeqStmt:
1985 tag = "CREATE SEQUENCE";
1986 break;
1988 case T_AlterSeqStmt:
1989 tag = "ALTER SEQUENCE";
1990 break;
1992 case T_RemoveFuncStmt:
1993 switch (((RemoveFuncStmt *) parsetree)->kind)
1995 case OBJECT_FUNCTION:
1996 tag = "DROP FUNCTION";
1997 break;
1998 case OBJECT_AGGREGATE:
1999 tag = "DROP AGGREGATE";
2000 break;
2001 case OBJECT_OPERATOR:
2002 tag = "DROP OPERATOR";
2003 break;
2004 default:
2005 tag = "???";
2007 break;
2009 case T_DoStmt:
2010 tag = "DO";
2011 break;
2013 case T_CreatedbStmt:
2014 tag = "CREATE DATABASE";
2015 break;
2017 case T_AlterDatabaseStmt:
2018 tag = "ALTER DATABASE";
2019 break;
2021 case T_AlterDatabaseSetStmt:
2022 tag = "ALTER DATABASE";
2023 break;
2025 case T_DropdbStmt:
2026 tag = "DROP DATABASE";
2027 break;
2029 case T_NotifyStmt:
2030 tag = "NOTIFY";
2031 break;
2033 case T_ListenStmt:
2034 tag = "LISTEN";
2035 break;
2037 case T_UnlistenStmt:
2038 tag = "UNLISTEN";
2039 break;
2041 case T_LoadStmt:
2042 tag = "LOAD";
2043 break;
2045 case T_ClusterStmt:
2046 tag = "CLUSTER";
2047 break;
2049 case T_VacuumStmt:
2050 if (((VacuumStmt *) parsetree)->options & VACOPT_VACUUM)
2051 tag = "VACUUM";
2052 else
2053 tag = "ANALYZE";
2054 break;
2056 case T_ExplainStmt:
2057 tag = "EXPLAIN";
2058 break;
2060 case T_VariableSetStmt:
2061 switch (((VariableSetStmt *) parsetree)->kind)
2063 case VAR_SET_VALUE:
2064 case VAR_SET_CURRENT:
2065 case VAR_SET_DEFAULT:
2066 case VAR_SET_MULTI:
2067 tag = "SET";
2068 break;
2069 case VAR_RESET:
2070 case VAR_RESET_ALL:
2071 tag = "RESET";
2072 break;
2073 default:
2074 tag = "???";
2076 break;
2078 case T_VariableShowStmt:
2079 tag = "SHOW";
2080 break;
2082 case T_DiscardStmt:
2083 switch (((DiscardStmt *) parsetree)->target)
2085 case DISCARD_ALL:
2086 tag = "DISCARD ALL";
2087 break;
2088 case DISCARD_PLANS:
2089 tag = "DISCARD PLANS";
2090 break;
2091 case DISCARD_TEMP:
2092 tag = "DISCARD TEMP";
2093 break;
2094 default:
2095 tag = "???";
2097 break;
2099 case T_CreateTrigStmt:
2100 tag = "CREATE TRIGGER";
2101 break;
2103 case T_DropPropertyStmt:
2104 switch (((DropPropertyStmt *) parsetree)->removeType)
2106 case OBJECT_TRIGGER:
2107 tag = "DROP TRIGGER";
2108 break;
2109 case OBJECT_RULE:
2110 tag = "DROP RULE";
2111 break;
2112 default:
2113 tag = "???";
2115 break;
2117 case T_CreatePLangStmt:
2118 tag = "CREATE LANGUAGE";
2119 break;
2121 case T_DropPLangStmt:
2122 tag = "DROP LANGUAGE";
2123 break;
2125 case T_CreateRoleStmt:
2126 tag = "CREATE ROLE";
2127 break;
2129 case T_AlterRoleStmt:
2130 tag = "ALTER ROLE";
2131 break;
2133 case T_AlterRoleSetStmt:
2134 tag = "ALTER ROLE";
2135 break;
2137 case T_DropRoleStmt:
2138 tag = "DROP ROLE";
2139 break;
2141 case T_DropOwnedStmt:
2142 tag = "DROP OWNED";
2143 break;
2145 case T_ReassignOwnedStmt:
2146 tag = "REASSIGN OWNED";
2147 break;
2149 case T_LockStmt:
2150 tag = "LOCK TABLE";
2151 break;
2153 case T_ConstraintsSetStmt:
2154 tag = "SET CONSTRAINTS";
2155 break;
2157 case T_CheckPointStmt:
2158 tag = "CHECKPOINT";
2159 break;
2161 case T_ReindexStmt:
2162 tag = "REINDEX";
2163 break;
2165 case T_CreateConversionStmt:
2166 tag = "CREATE CONVERSION";
2167 break;
2169 case T_CreateCastStmt:
2170 tag = "CREATE CAST";
2171 break;
2173 case T_DropCastStmt:
2174 tag = "DROP CAST";
2175 break;
2177 case T_CreateOpClassStmt:
2178 tag = "CREATE OPERATOR CLASS";
2179 break;
2181 case T_CreateOpFamilyStmt:
2182 tag = "CREATE OPERATOR FAMILY";
2183 break;
2185 case T_AlterOpFamilyStmt:
2186 tag = "ALTER OPERATOR FAMILY";
2187 break;
2189 case T_RemoveOpClassStmt:
2190 tag = "DROP OPERATOR CLASS";
2191 break;
2193 case T_RemoveOpFamilyStmt:
2194 tag = "DROP OPERATOR FAMILY";
2195 break;
2197 case T_AlterTSDictionaryStmt:
2198 tag = "ALTER TEXT SEARCH DICTIONARY";
2199 break;
2201 case T_AlterTSConfigurationStmt:
2202 tag = "ALTER TEXT SEARCH CONFIGURATION";
2203 break;
2205 case T_PrepareStmt:
2206 tag = "PREPARE";
2207 break;
2209 case T_ExecuteStmt:
2210 tag = "EXECUTE";
2211 break;
2213 case T_DeallocateStmt:
2215 DeallocateStmt *stmt = (DeallocateStmt *) parsetree;
2217 if (stmt->name == NULL)
2218 tag = "DEALLOCATE ALL";
2219 else
2220 tag = "DEALLOCATE";
2222 break;
2224 /* already-planned queries */
2225 case T_PlannedStmt:
2227 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2229 switch (stmt->commandType)
2231 case CMD_SELECT:
2234 * We take a little extra care here so that the result
2235 * will be useful for complaints about read-only
2236 * statements
2238 if (stmt->utilityStmt != NULL)
2240 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2241 tag = "DECLARE CURSOR";
2243 else if (stmt->intoClause != NULL)
2244 tag = "SELECT INTO";
2245 else if (stmt->rowMarks != NIL)
2247 /* not 100% but probably close enough */
2248 if (((PlanRowMark *) linitial(stmt->rowMarks))->markType == ROW_MARK_EXCLUSIVE)
2249 tag = "SELECT FOR UPDATE";
2250 else
2251 tag = "SELECT FOR SHARE";
2253 else
2254 tag = "SELECT";
2255 break;
2256 case CMD_UPDATE:
2257 tag = "UPDATE";
2258 break;
2259 case CMD_INSERT:
2260 tag = "INSERT";
2261 break;
2262 case CMD_DELETE:
2263 tag = "DELETE";
2264 break;
2265 default:
2266 elog(WARNING, "unrecognized commandType: %d",
2267 (int) stmt->commandType);
2268 tag = "???";
2269 break;
2272 break;
2274 /* parsed-and-rewritten-but-not-planned queries */
2275 case T_Query:
2277 Query *stmt = (Query *) parsetree;
2279 switch (stmt->commandType)
2281 case CMD_SELECT:
2284 * We take a little extra care here so that the result
2285 * will be useful for complaints about read-only
2286 * statements
2288 if (stmt->utilityStmt != NULL)
2290 Assert(IsA(stmt->utilityStmt, DeclareCursorStmt));
2291 tag = "DECLARE CURSOR";
2293 else if (stmt->intoClause != NULL)
2294 tag = "SELECT INTO";
2295 else if (stmt->rowMarks != NIL)
2297 /* not 100% but probably close enough */
2298 if (((RowMarkClause *) linitial(stmt->rowMarks))->forUpdate)
2299 tag = "SELECT FOR UPDATE";
2300 else
2301 tag = "SELECT FOR SHARE";
2303 else
2304 tag = "SELECT";
2305 break;
2306 case CMD_UPDATE:
2307 tag = "UPDATE";
2308 break;
2309 case CMD_INSERT:
2310 tag = "INSERT";
2311 break;
2312 case CMD_DELETE:
2313 tag = "DELETE";
2314 break;
2315 case CMD_UTILITY:
2316 tag = CreateCommandTag(stmt->utilityStmt);
2317 break;
2318 default:
2319 elog(WARNING, "unrecognized commandType: %d",
2320 (int) stmt->commandType);
2321 tag = "???";
2322 break;
2325 break;
2327 default:
2328 elog(WARNING, "unrecognized node type: %d",
2329 (int) nodeTag(parsetree));
2330 tag = "???";
2331 break;
2334 return tag;
2339 * GetCommandLogLevel
2340 * utility to get the minimum log_statement level for a command,
2341 * given either a raw (un-analyzed) parsetree or a planned query.
2343 * This must handle all command types, but since the vast majority
2344 * of 'em are utility commands, it seems sensible to keep it here.
2346 LogStmtLevel
2347 GetCommandLogLevel(Node *parsetree)
2349 LogStmtLevel lev;
2351 switch (nodeTag(parsetree))
2353 /* raw plannable queries */
2354 case T_InsertStmt:
2355 case T_DeleteStmt:
2356 case T_UpdateStmt:
2357 lev = LOGSTMT_MOD;
2358 break;
2360 case T_SelectStmt:
2361 if (((SelectStmt *) parsetree)->intoClause)
2362 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2363 else
2364 lev = LOGSTMT_ALL;
2365 break;
2367 /* utility statements --- same whether raw or cooked */
2368 case T_TransactionStmt:
2369 lev = LOGSTMT_ALL;
2370 break;
2372 case T_DeclareCursorStmt:
2373 lev = LOGSTMT_ALL;
2374 break;
2376 case T_ClosePortalStmt:
2377 lev = LOGSTMT_ALL;
2378 break;
2380 case T_FetchStmt:
2381 lev = LOGSTMT_ALL;
2382 break;
2384 case T_CreateSchemaStmt:
2385 lev = LOGSTMT_DDL;
2386 break;
2388 case T_CreateStmt:
2389 case T_CreateForeignTableStmt:
2390 lev = LOGSTMT_DDL;
2391 break;
2393 case T_CreateTableSpaceStmt:
2394 lev = LOGSTMT_DDL;
2395 break;
2397 case T_DropTableSpaceStmt:
2398 lev = LOGSTMT_DDL;
2399 break;
2401 case T_AlterTableSpaceOptionsStmt:
2402 lev = LOGSTMT_DDL;
2403 break;
2405 case T_CreateExtensionStmt:
2406 lev = LOGSTMT_DDL;
2407 break;
2409 case T_CreateFdwStmt:
2410 case T_AlterFdwStmt:
2411 case T_DropFdwStmt:
2412 case T_CreateForeignServerStmt:
2413 case T_AlterForeignServerStmt:
2414 case T_DropForeignServerStmt:
2415 case T_CreateUserMappingStmt:
2416 case T_AlterUserMappingStmt:
2417 case T_DropUserMappingStmt:
2418 lev = LOGSTMT_DDL;
2419 break;
2421 case T_DropStmt:
2422 lev = LOGSTMT_DDL;
2423 break;
2425 case T_TruncateStmt:
2426 lev = LOGSTMT_MOD;
2427 break;
2429 case T_CommentStmt:
2430 lev = LOGSTMT_DDL;
2431 break;
2433 case T_SecLabelStmt:
2434 lev = LOGSTMT_DDL;
2435 break;
2437 case T_CopyStmt:
2438 if (((CopyStmt *) parsetree)->is_from)
2439 lev = LOGSTMT_MOD;
2440 else
2441 lev = LOGSTMT_ALL;
2442 break;
2444 case T_PrepareStmt:
2446 PrepareStmt *stmt = (PrepareStmt *) parsetree;
2448 /* Look through a PREPARE to the contained stmt */
2449 lev = GetCommandLogLevel(stmt->query);
2451 break;
2453 case T_ExecuteStmt:
2455 ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
2456 PreparedStatement *ps;
2458 /* Look through an EXECUTE to the referenced stmt */
2459 ps = FetchPreparedStatement(stmt->name, false);
2460 if (ps)
2461 lev = GetCommandLogLevel(ps->plansource->raw_parse_tree);
2462 else
2463 lev = LOGSTMT_ALL;
2465 break;
2467 case T_DeallocateStmt:
2468 lev = LOGSTMT_ALL;
2469 break;
2471 case T_RenameStmt:
2472 lev = LOGSTMT_DDL;
2473 break;
2475 case T_AlterObjectSchemaStmt:
2476 lev = LOGSTMT_DDL;
2477 break;
2479 case T_AlterOwnerStmt:
2480 lev = LOGSTMT_DDL;
2481 break;
2483 case T_AlterTableStmt:
2484 lev = LOGSTMT_DDL;
2485 break;
2487 case T_AlterDomainStmt:
2488 lev = LOGSTMT_DDL;
2489 break;
2491 case T_GrantStmt:
2492 lev = LOGSTMT_DDL;
2493 break;
2495 case T_GrantRoleStmt:
2496 lev = LOGSTMT_DDL;
2497 break;
2499 case T_AlterDefaultPrivilegesStmt:
2500 lev = LOGSTMT_DDL;
2501 break;
2503 case T_DefineStmt:
2504 lev = LOGSTMT_DDL;
2505 break;
2507 case T_CompositeTypeStmt:
2508 lev = LOGSTMT_DDL;
2509 break;
2511 case T_CreateEnumStmt:
2512 lev = LOGSTMT_DDL;
2513 break;
2515 case T_AlterEnumStmt:
2516 lev = LOGSTMT_DDL;
2517 break;
2519 case T_ViewStmt:
2520 lev = LOGSTMT_DDL;
2521 break;
2523 case T_CreateFunctionStmt:
2524 lev = LOGSTMT_DDL;
2525 break;
2527 case T_AlterFunctionStmt:
2528 lev = LOGSTMT_DDL;
2529 break;
2531 case T_IndexStmt:
2532 lev = LOGSTMT_DDL;
2533 break;
2535 case T_RuleStmt:
2536 lev = LOGSTMT_DDL;
2537 break;
2539 case T_CreateSeqStmt:
2540 lev = LOGSTMT_DDL;
2541 break;
2543 case T_AlterSeqStmt:
2544 lev = LOGSTMT_DDL;
2545 break;
2547 case T_RemoveFuncStmt:
2548 lev = LOGSTMT_DDL;
2549 break;
2551 case T_DoStmt:
2552 lev = LOGSTMT_ALL;
2553 break;
2555 case T_CreatedbStmt:
2556 lev = LOGSTMT_DDL;
2557 break;
2559 case T_AlterDatabaseStmt:
2560 lev = LOGSTMT_DDL;
2561 break;
2563 case T_AlterDatabaseSetStmt:
2564 lev = LOGSTMT_DDL;
2565 break;
2567 case T_DropdbStmt:
2568 lev = LOGSTMT_DDL;
2569 break;
2571 case T_NotifyStmt:
2572 lev = LOGSTMT_ALL;
2573 break;
2575 case T_ListenStmt:
2576 lev = LOGSTMT_ALL;
2577 break;
2579 case T_UnlistenStmt:
2580 lev = LOGSTMT_ALL;
2581 break;
2583 case T_LoadStmt:
2584 lev = LOGSTMT_ALL;
2585 break;
2587 case T_ClusterStmt:
2588 lev = LOGSTMT_DDL;
2589 break;
2591 case T_VacuumStmt:
2592 lev = LOGSTMT_ALL;
2593 break;
2595 case T_ExplainStmt:
2597 ExplainStmt *stmt = (ExplainStmt *) parsetree;
2598 bool analyze = false;
2599 ListCell *lc;
2601 /* Look through an EXPLAIN ANALYZE to the contained stmt */
2602 foreach(lc, stmt->options)
2604 DefElem *opt = (DefElem *) lfirst(lc);
2606 if (strcmp(opt->defname, "analyze") == 0)
2607 analyze = defGetBoolean(opt);
2608 /* don't "break", as explain.c will use the last value */
2610 if (analyze)
2611 return GetCommandLogLevel(stmt->query);
2613 /* Plain EXPLAIN isn't so interesting */
2614 lev = LOGSTMT_ALL;
2616 break;
2618 case T_VariableSetStmt:
2619 lev = LOGSTMT_ALL;
2620 break;
2622 case T_VariableShowStmt:
2623 lev = LOGSTMT_ALL;
2624 break;
2626 case T_DiscardStmt:
2627 lev = LOGSTMT_ALL;
2628 break;
2630 case T_CreateTrigStmt:
2631 lev = LOGSTMT_DDL;
2632 break;
2634 case T_DropPropertyStmt:
2635 lev = LOGSTMT_DDL;
2636 break;
2638 case T_CreatePLangStmt:
2639 lev = LOGSTMT_DDL;
2640 break;
2642 case T_DropPLangStmt:
2643 lev = LOGSTMT_DDL;
2644 break;
2646 case T_CreateDomainStmt:
2647 lev = LOGSTMT_DDL;
2648 break;
2650 case T_CreateRoleStmt:
2651 lev = LOGSTMT_DDL;
2652 break;
2654 case T_AlterRoleStmt:
2655 lev = LOGSTMT_DDL;
2656 break;
2658 case T_AlterRoleSetStmt:
2659 lev = LOGSTMT_DDL;
2660 break;
2662 case T_DropRoleStmt:
2663 lev = LOGSTMT_DDL;
2664 break;
2666 case T_DropOwnedStmt:
2667 lev = LOGSTMT_DDL;
2668 break;
2670 case T_ReassignOwnedStmt:
2671 lev = LOGSTMT_DDL;
2672 break;
2674 case T_LockStmt:
2675 lev = LOGSTMT_ALL;
2676 break;
2678 case T_ConstraintsSetStmt:
2679 lev = LOGSTMT_ALL;
2680 break;
2682 case T_CheckPointStmt:
2683 lev = LOGSTMT_ALL;
2684 break;
2686 case T_ReindexStmt:
2687 lev = LOGSTMT_ALL; /* should this be DDL? */
2688 break;
2690 case T_CreateConversionStmt:
2691 lev = LOGSTMT_DDL;
2692 break;
2694 case T_CreateCastStmt:
2695 lev = LOGSTMT_DDL;
2696 break;
2698 case T_DropCastStmt:
2699 lev = LOGSTMT_DDL;
2700 break;
2702 case T_CreateOpClassStmt:
2703 lev = LOGSTMT_DDL;
2704 break;
2706 case T_CreateOpFamilyStmt:
2707 lev = LOGSTMT_DDL;
2708 break;
2710 case T_AlterOpFamilyStmt:
2711 lev = LOGSTMT_DDL;
2712 break;
2714 case T_RemoveOpClassStmt:
2715 lev = LOGSTMT_DDL;
2716 break;
2718 case T_RemoveOpFamilyStmt:
2719 lev = LOGSTMT_DDL;
2720 break;
2722 case T_AlterTSDictionaryStmt:
2723 lev = LOGSTMT_DDL;
2724 break;
2726 case T_AlterTSConfigurationStmt:
2727 lev = LOGSTMT_DDL;
2728 break;
2730 /* already-planned queries */
2731 case T_PlannedStmt:
2733 PlannedStmt *stmt = (PlannedStmt *) parsetree;
2735 switch (stmt->commandType)
2737 case CMD_SELECT:
2738 if (stmt->intoClause != NULL)
2739 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2740 else
2741 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2742 break;
2744 case CMD_UPDATE:
2745 case CMD_INSERT:
2746 case CMD_DELETE:
2747 lev = LOGSTMT_MOD;
2748 break;
2750 default:
2751 elog(WARNING, "unrecognized commandType: %d",
2752 (int) stmt->commandType);
2753 lev = LOGSTMT_ALL;
2754 break;
2757 break;
2759 /* parsed-and-rewritten-but-not-planned queries */
2760 case T_Query:
2762 Query *stmt = (Query *) parsetree;
2764 switch (stmt->commandType)
2766 case CMD_SELECT:
2767 if (stmt->intoClause != NULL)
2768 lev = LOGSTMT_DDL; /* CREATE AS, SELECT INTO */
2769 else
2770 lev = LOGSTMT_ALL; /* SELECT or DECLARE CURSOR */
2771 break;
2773 case CMD_UPDATE:
2774 case CMD_INSERT:
2775 case CMD_DELETE:
2776 lev = LOGSTMT_MOD;
2777 break;
2779 case CMD_UTILITY:
2780 lev = GetCommandLogLevel(stmt->utilityStmt);
2781 break;
2783 default:
2784 elog(WARNING, "unrecognized commandType: %d",
2785 (int) stmt->commandType);
2786 lev = LOGSTMT_ALL;
2787 break;
2791 break;
2793 default:
2794 elog(WARNING, "unrecognized node type: %d",
2795 (int) nodeTag(parsetree));
2796 lev = LOGSTMT_ALL;
2797 break;
2800 return lev;