1 /*-------------------------------------------------------------------------
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
8 * Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
9 * Portions Copyright (c) 1994, Regents of the University of California
13 * src/backend/tcop/utility.c
15 *-------------------------------------------------------------------------
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.
74 CheckRelationOwnership(RangeVar
*rel
, bool noCatalogs
)
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
,
90 if (!allowSystemTableMods
&&
91 IsSystemClass((Form_pg_class
) GETSTRUCT(tuple
)))
93 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE
),
94 errmsg("permission denied: \"%s\" is a system catalog",
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
112 CommandIsReadOnly(Node
*parsetree
)
114 if (IsA(parsetree
, PlannedStmt
))
116 PlannedStmt
*stmt
= (PlannedStmt
*) parsetree
;
118 switch (stmt
->commandType
)
121 if (stmt
->intoClause
!= NULL
)
122 return false; /* SELECT INTO */
123 else if (stmt
->rowMarks
!= NIL
)
124 return false; /* SELECT FOR UPDATE/SHARE */
132 elog(WARNING
, "unrecognized commandType: %d",
133 (int) stmt
->commandType
);
137 /* For now, treat all utility commands as read/write */
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.
148 check_xact_readonly(Node
*parsetree
)
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
:
171 case T_AlterTableStmt
:
175 case T_CreateCastStmt
:
176 case T_CreateConversionStmt
:
178 case T_CreateDomainStmt
:
179 case T_CreateFunctionStmt
:
180 case T_CreateRoleStmt
:
182 case T_CreatePLangStmt
:
183 case T_CreateOpClassStmt
:
184 case T_CreateOpFamilyStmt
:
185 case T_AlterOpFamilyStmt
:
187 case T_CreateSchemaStmt
:
188 case T_CreateSeqStmt
:
190 case T_CreateTableSpaceStmt
:
191 case T_CreateTrigStmt
:
192 case T_CompositeTypeStmt
:
193 case T_CreateEnumStmt
:
194 case T_AlterEnumStmt
:
199 case T_DropTableSpaceStmt
:
200 case T_RemoveFuncStmt
:
202 case T_DropPLangStmt
:
203 case T_RemoveOpClassStmt
:
204 case T_RemoveOpFamilyStmt
:
205 case T_DropPropertyStmt
:
207 case T_GrantRoleStmt
:
208 case T_AlterDefaultPrivilegesStmt
:
210 case T_DropOwnedStmt
:
211 case T_ReassignOwnedStmt
:
212 case T_AlterTSDictionaryStmt
:
213 case T_AlterTSConfigurationStmt
:
214 case T_CreateExtensionStmt
:
215 case T_CreateFdwStmt
:
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
:
227 PreventCommandIfReadOnly(CreateCommandTag(parsetree
));
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.
242 PreventCommandIfReadOnly(const char *cmdname
)
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",
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.
261 PreventCommandDuringRecovery(const char *cmdname
)
263 if (RecoveryInProgress())
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",
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.
279 CheckRestrictedOperation(const char *cmdname
)
281 if (InSecurityRestrictedOperation())
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",
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.
311 ProcessUtility(Node
*parsetree
,
312 const char *queryString
,
313 ParamListInfo params
,
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
);
329 standard_ProcessUtility(parsetree
, queryString
, params
,
330 isTopLevel
, dest
, completionTag
);
334 standard_ProcessUtility(Node
*parsetree
,
335 const char *queryString
,
336 ParamListInfo params
,
341 check_xact_readonly(parsetree
);
344 completionTag
[0] = '\0';
346 switch (nodeTag(parsetree
))
349 * ******************** transactions ********************
351 case T_TransactionStmt
:
353 TransactionStmt
*stmt
= (TransactionStmt
*) parsetree
;
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
:
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
),
375 else if (strcmp(item
->defname
, "transaction_read_only") == 0)
376 SetPGVariable("transaction_read_only",
377 list_make1(item
->arg
),
379 else if (strcmp(item
->defname
, "transaction_deferrable") == 0)
380 SetPGVariable("transaction_deferrable",
381 list_make1(item
->arg
),
387 case TRANS_STMT_COMMIT
:
388 if (!EndTransactionBlock())
390 /* report unsuccessful commit in completionTag */
392 strcpy(completionTag
, "ROLLBACK");
396 case TRANS_STMT_PREPARE
:
397 PreventCommandDuringRecovery("PREPARE TRANSACTION");
398 if (!PrepareTransactionBlock(stmt
->gid
))
400 /* report unsuccessful commit in completionTag */
402 strcpy(completionTag
, "ROLLBACK");
406 case TRANS_STMT_COMMIT_PREPARED
:
407 PreventTransactionChain(isTopLevel
, "COMMIT PREPARED");
408 PreventCommandDuringRecovery("COMMIT PREPARED");
409 FinishPreparedTransaction(stmt
->gid
, true);
412 case TRANS_STMT_ROLLBACK_PREPARED
:
413 PreventTransactionChain(isTopLevel
, "ROLLBACK PREPARED");
414 PreventCommandDuringRecovery("ROLLBACK PREPARED");
415 FinishPreparedTransaction(stmt
->gid
, false);
418 case TRANS_STMT_ROLLBACK
:
419 UserAbortTransactionBlock();
422 case TRANS_STMT_SAVEPOINT
:
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
);
443 case TRANS_STMT_RELEASE
:
444 RequireTransactionChain(isTopLevel
, "RELEASE SAVEPOINT");
445 ReleaseSavepoint(stmt
->options
);
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
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
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
);
479 case T_ClosePortalStmt
:
481 ClosePortalStmt
*stmt
= (ClosePortalStmt
*) parsetree
;
483 CheckRestrictedOperation("CLOSE");
484 PerformPortalClose(stmt
->portalname
);
489 PerformPortalFetch((FetchStmt
*) parsetree
, dest
,
494 * relation and attribute manipulation
496 case T_CreateSchemaStmt
:
497 CreateSchemaCommand((CreateSchemaStmt
*) parsetree
,
502 case T_CreateForeignTableStmt
:
508 /* Run parse analysis ... */
509 stmts
= transformCreateStmt((CreateStmt
*) parsetree
,
515 Node
*stmt
= (Node
*) lfirst(l
);
517 if (IsA(stmt
, CreateStmt
))
520 static char *validnsps
[] = HEAP_RELOPT_NAMESPACES
;
522 /* Create the table itself */
523 relOid
= DefineRelation((CreateStmt
*) stmt
,
528 * If "IF NOT EXISTS" was specified and the relation
529 * already exists, do nothing further.
531 if (relOid
== InvalidOid
)
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
,
546 (void) heap_reloptions(RELKIND_TOASTVALUE
, toast_options
,
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
,
559 * Unless "IF NOT EXISTS" was specified and the
560 * relation already exists, create the pg_foreign_table
563 if (relOid
!= InvalidOid
)
564 CreateForeignTable((CreateForeignTableStmt
*) stmt
,
569 /* Recurse for anything else */
578 /* Need CCI between commands */
579 if (lnext(l
) != NULL
)
580 CommandCounterIncrement();
585 case T_CreateTableSpaceStmt
:
586 PreventTransactionChain(isTopLevel
, "CREATE TABLESPACE");
587 CreateTableSpace((CreateTableSpaceStmt
*) parsetree
);
590 case T_DropTableSpaceStmt
:
591 PreventTransactionChain(isTopLevel
, "DROP TABLESPACE");
592 DropTableSpace((DropTableSpaceStmt
*) parsetree
);
595 case T_AlterTableSpaceOptionsStmt
:
596 AlterTableSpaceOptions((AlterTableSpaceOptionsStmt
*) parsetree
);
599 case T_CreateExtensionStmt
:
600 CreateExtension((CreateExtensionStmt
*) parsetree
);
603 case T_CreateFdwStmt
:
604 CreateForeignDataWrapper((CreateFdwStmt
*) parsetree
);
608 AlterForeignDataWrapper((AlterFdwStmt
*) parsetree
);
612 RemoveForeignDataWrapper((DropFdwStmt
*) parsetree
);
615 case T_CreateForeignServerStmt
:
616 CreateForeignServer((CreateForeignServerStmt
*) parsetree
);
619 case T_AlterForeignServerStmt
:
620 AlterForeignServer((AlterForeignServerStmt
*) parsetree
);
623 case T_DropForeignServerStmt
:
624 RemoveForeignServer((DropForeignServerStmt
*) parsetree
);
627 case T_CreateUserMappingStmt
:
628 CreateUserMapping((CreateUserMappingStmt
*) parsetree
);
631 case T_AlterUserMappingStmt
:
632 AlterUserMapping((AlterUserMappingStmt
*) parsetree
);
635 case T_DropUserMappingStmt
:
636 RemoveUserMapping((DropUserMappingStmt
*) parsetree
);
641 DropStmt
*stmt
= (DropStmt
*) parsetree
;
643 switch (stmt
->removeType
)
646 case OBJECT_SEQUENCE
:
649 case OBJECT_FOREIGN_TABLE
:
650 RemoveRelations(stmt
);
658 case OBJECT_CONVERSION
:
659 DropConversionsCommand(stmt
);
666 case OBJECT_TSPARSER
:
667 RemoveTSParsers(stmt
);
670 case OBJECT_TSDICTIONARY
:
671 RemoveTSDictionaries(stmt
);
674 case OBJECT_TSTEMPLATE
:
675 RemoveTSTemplates(stmt
);
678 case OBJECT_TSCONFIGURATION
:
679 RemoveTSConfigurations(stmt
);
682 case OBJECT_EXTENSION
:
683 RemoveExtensions(stmt
);
687 elog(ERROR
, "unrecognized drop object type: %d",
688 (int) stmt
->removeType
);
695 ExecuteTruncate((TruncateStmt
*) parsetree
);
699 CommentObject((CommentStmt
*) parsetree
);
703 ExecSecLabelStmt((SecLabelStmt
*) parsetree
);
710 processed
= DoCopy((CopyStmt
*) parsetree
, queryString
);
712 snprintf(completionTag
, COMPLETION_TAG_BUFSIZE
,
713 "COPY " UINT64_FORMAT
, processed
);
718 CheckRestrictedOperation("PREPARE");
719 PrepareQuery((PrepareStmt
*) parsetree
, queryString
);
723 ExecuteQuery((ExecuteStmt
*) parsetree
, queryString
, params
,
724 dest
, completionTag
);
727 case T_DeallocateStmt
:
728 CheckRestrictedOperation("DEALLOCATE");
729 DeallocateQuery((DeallocateStmt
*) parsetree
);
736 ExecRenameStmt((RenameStmt
*) parsetree
);
739 case T_AlterObjectSchemaStmt
:
740 ExecAlterObjectSchemaStmt((AlterObjectSchemaStmt
*) parsetree
);
743 case T_AlterOwnerStmt
:
744 ExecAlterOwnerStmt((AlterOwnerStmt
*) parsetree
);
747 case T_AlterTableStmt
:
752 /* Run parse analysis ... */
753 stmts
= transformAlterTableStmt((AlterTableStmt
*) parsetree
,
759 Node
*stmt
= (Node
*) lfirst(l
);
761 if (IsA(stmt
, AlterTableStmt
))
763 /* Do the table alteration proper */
764 AlterTable((AlterTableStmt
*) stmt
);
768 /* Recurse for anything else */
777 /* Need CCI between commands */
778 if (lnext(l
) != NULL
)
779 CommandCounterIncrement();
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
,
803 case 'N': /* ALTER DOMAIN DROP NOT NULL */
804 AlterDomainNotNull(stmt
->typeName
,
807 case 'O': /* ALTER DOMAIN SET NOT NULL */
808 AlterDomainNotNull(stmt
->typeName
,
811 case 'C': /* ADD CONSTRAINT */
812 AlterDomainAddConstraint(stmt
->typeName
,
815 case 'X': /* DROP CONSTRAINT */
816 AlterDomainDropConstraint(stmt
->typeName
,
821 elog(ERROR
, "unrecognized alter domain type: %d",
822 (int) stmt
->subtype
);
829 ExecuteGrantStmt((GrantStmt
*) parsetree
);
832 case T_GrantRoleStmt
:
833 GrantRole((GrantRoleStmt
*) parsetree
);
836 case T_AlterDefaultPrivilegesStmt
:
837 ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt
*) parsetree
);
841 * **************** object creation / destruction *****************
845 DefineStmt
*stmt
= (DefineStmt
*) parsetree
;
849 case OBJECT_AGGREGATE
:
850 DefineAggregate(stmt
->defnames
, stmt
->args
,
851 stmt
->oldstyle
, stmt
->definition
);
853 case OBJECT_OPERATOR
:
854 Assert(stmt
->args
== NIL
);
855 DefineOperator(stmt
->defnames
, stmt
->definition
);
858 Assert(stmt
->args
== NIL
);
859 DefineType(stmt
->defnames
, stmt
->definition
);
861 case OBJECT_TSPARSER
:
862 Assert(stmt
->args
== NIL
);
863 DefineTSParser(stmt
->defnames
, stmt
->definition
);
865 case OBJECT_TSDICTIONARY
:
866 Assert(stmt
->args
== NIL
);
867 DefineTSDictionary(stmt
->defnames
, stmt
->definition
);
869 case OBJECT_TSTEMPLATE
:
870 Assert(stmt
->args
== NIL
);
871 DefineTSTemplate(stmt
->defnames
, stmt
->definition
);
873 case OBJECT_TSCONFIGURATION
:
874 Assert(stmt
->args
== NIL
);
875 DefineTSConfiguration(stmt
->defnames
, stmt
->definition
);
878 elog(ERROR
, "unrecognized define stmt type: %d",
885 case T_CompositeTypeStmt
: /* CREATE TYPE (composite) */
887 CompositeTypeStmt
*stmt
= (CompositeTypeStmt
*) parsetree
;
889 DefineCompositeType(stmt
->typevar
, stmt
->coldeflist
);
893 case T_CreateEnumStmt
: /* CREATE TYPE (enum) */
894 DefineEnum((CreateEnumStmt
*) parsetree
);
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
);
907 case T_ViewStmt
: /* CREATE VIEW */
908 DefineView((ViewStmt
*) parsetree
, queryString
);
911 case T_CreateFunctionStmt
: /* CREATE FUNCTION */
912 CreateFunction((CreateFunctionStmt
*) parsetree
, queryString
);
915 case T_AlterFunctionStmt
: /* ALTER FUNCTION */
916 AlterFunction((AlterFunctionStmt
*) parsetree
);
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
);
933 DefineIndex(stmt
->relation
, /* relation */
934 stmt
->idxname
, /* index name */
935 InvalidOid
, /* no predefined OID */
936 stmt
->accessMethod
, /* am name */
938 stmt
->indexParams
, /* parameters */
939 (Expr
*) stmt
->whereClause
,
941 stmt
->excludeOpNames
,
947 false, /* is_alter_table */
948 true, /* check_rights */
949 false, /* skip_build */
951 stmt
->concurrent
); /* concurrent */
955 case T_RuleStmt
: /* CREATE RULE */
956 DefineRule((RuleStmt
*) parsetree
, queryString
);
959 case T_CreateSeqStmt
:
960 DefineSequence((CreateSeqStmt
*) parsetree
);
964 AlterSequence((AlterSeqStmt
*) parsetree
);
967 case T_RemoveFuncStmt
:
969 RemoveFuncStmt
*stmt
= (RemoveFuncStmt
*) parsetree
;
973 case OBJECT_FUNCTION
:
974 RemoveFunction(stmt
);
976 case OBJECT_AGGREGATE
:
977 RemoveAggregate(stmt
);
979 case OBJECT_OPERATOR
:
980 RemoveOperator(stmt
);
983 elog(ERROR
, "unrecognized object type: %d",
991 ExecuteDoStmt((DoStmt
*) parsetree
);
995 PreventTransactionChain(isTopLevel
, "CREATE DATABASE");
996 createdb((CreatedbStmt
*) parsetree
);
999 case T_AlterDatabaseStmt
:
1000 AlterDatabase((AlterDatabaseStmt
*) parsetree
, isTopLevel
);
1003 case T_AlterDatabaseSetStmt
:
1004 AlterDatabaseSet((AlterDatabaseSetStmt
*) parsetree
);
1009 DropdbStmt
*stmt
= (DropdbStmt
*) parsetree
;
1011 PreventTransactionChain(isTopLevel
, "DROP DATABASE");
1012 dropdb(stmt
->dbname
, stmt
->missing_ok
);
1016 /* Query-level asynchronous notification */
1019 NotifyStmt
*stmt
= (NotifyStmt
*) parsetree
;
1021 PreventCommandDuringRecovery("NOTIFY");
1022 Async_Notify(stmt
->conditionname
, stmt
->payload
);
1028 ListenStmt
*stmt
= (ListenStmt
*) parsetree
;
1030 PreventCommandDuringRecovery("LISTEN");
1031 CheckRestrictedOperation("LISTEN");
1032 Async_Listen(stmt
->conditionname
);
1036 case T_UnlistenStmt
:
1038 UnlistenStmt
*stmt
= (UnlistenStmt
*) parsetree
;
1040 PreventCommandDuringRecovery("UNLISTEN");
1041 CheckRestrictedOperation("UNLISTEN");
1042 if (stmt
->conditionname
)
1043 Async_Unlisten(stmt
->conditionname
);
1045 Async_UnlistenAll();
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());
1060 /* we choose to allow this during "read only" transactions */
1061 PreventCommandDuringRecovery("CLUSTER");
1062 cluster((ClusterStmt
*) parsetree
, isTopLevel
);
1066 /* we choose to allow this during "read only" transactions */
1067 PreventCommandDuringRecovery("VACUUM");
1068 vacuum((VacuumStmt
*) parsetree
, InvalidOid
, true, NULL
, false,
1073 ExplainQuery((ExplainStmt
*) parsetree
, queryString
, params
, dest
);
1076 case T_VariableSetStmt
:
1077 ExecSetVariableStmt((VariableSetStmt
*) parsetree
);
1080 case T_VariableShowStmt
:
1082 VariableShowStmt
*n
= (VariableShowStmt
*) parsetree
;
1084 GetPGVariable(n
->name
, dest
);
1089 /* should we allow DISCARD PLANS? */
1090 CheckRestrictedOperation("DISCARD");
1091 DiscardCommand((DiscardStmt
*) parsetree
, isTopLevel
);
1094 case T_CreateTrigStmt
:
1095 (void) CreateTrigger((CreateTrigStmt
*) parsetree
, queryString
,
1096 InvalidOid
, InvalidOid
, false);
1099 case T_DropPropertyStmt
:
1101 DropPropertyStmt
*stmt
= (DropPropertyStmt
*) parsetree
;
1104 relId
= RangeVarGetRelid(stmt
->relation
, false);
1106 switch (stmt
->removeType
)
1109 /* RemoveRewriteRule checks permissions */
1110 RemoveRewriteRule(relId
, stmt
->property
,
1111 stmt
->behavior
, stmt
->missing_ok
);
1113 case OBJECT_TRIGGER
:
1114 /* DropTrigger checks permissions */
1115 DropTrigger(relId
, stmt
->property
,
1116 stmt
->behavior
, stmt
->missing_ok
);
1119 elog(ERROR
, "unrecognized object type: %d",
1120 (int) stmt
->removeType
);
1126 case T_CreatePLangStmt
:
1127 CreateProceduralLanguage((CreatePLangStmt
*) parsetree
);
1130 case T_DropPLangStmt
:
1131 DropProceduralLanguage((DropPLangStmt
*) parsetree
);
1135 * ******************************** DOMAIN statements ****
1137 case T_CreateDomainStmt
:
1138 DefineDomain((CreateDomainStmt
*) parsetree
);
1142 * ******************************** ROLE statements ****
1144 case T_CreateRoleStmt
:
1145 CreateRole((CreateRoleStmt
*) parsetree
);
1148 case T_AlterRoleStmt
:
1149 AlterRole((AlterRoleStmt
*) parsetree
);
1152 case T_AlterRoleSetStmt
:
1153 AlterRoleSet((AlterRoleSetStmt
*) parsetree
);
1156 case T_DropRoleStmt
:
1157 DropRole((DropRoleStmt
*) parsetree
);
1160 case T_DropOwnedStmt
:
1161 DropOwnedObjects((DropOwnedStmt
*) parsetree
);
1164 case T_ReassignOwnedStmt
:
1165 ReassignOwnedObjects((ReassignOwnedStmt
*) parsetree
);
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
);
1178 case T_ConstraintsSetStmt
:
1179 AfterTriggerSetState((ConstraintsSetStmt
*) parsetree
);
1182 case T_CheckPointStmt
:
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
));
1201 ReindexStmt
*stmt
= (ReindexStmt
*) parsetree
;
1203 /* we choose to allow this during "read only" transactions */
1204 PreventCommandDuringRecovery("REINDEX");
1208 ReindexIndex(stmt
->relation
);
1211 ReindexTable(stmt
->relation
);
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
1221 PreventTransactionChain(isTopLevel
,
1222 "REINDEX DATABASE");
1223 ReindexDatabase(stmt
->name
,
1224 stmt
->do_system
, stmt
->do_user
);
1227 elog(ERROR
, "unrecognized object type: %d",
1235 case T_CreateConversionStmt
:
1236 CreateConversionCommand((CreateConversionStmt
*) parsetree
);
1239 case T_CreateCastStmt
:
1240 CreateCast((CreateCastStmt
*) parsetree
);
1243 case T_DropCastStmt
:
1244 DropCast((DropCastStmt
*) parsetree
);
1247 case T_CreateOpClassStmt
:
1248 DefineOpClass((CreateOpClassStmt
*) parsetree
);
1251 case T_CreateOpFamilyStmt
:
1252 DefineOpFamily((CreateOpFamilyStmt
*) parsetree
);
1255 case T_AlterOpFamilyStmt
:
1256 AlterOpFamily((AlterOpFamilyStmt
*) parsetree
);
1259 case T_RemoveOpClassStmt
:
1260 RemoveOpClass((RemoveOpClassStmt
*) parsetree
);
1263 case T_RemoveOpFamilyStmt
:
1264 RemoveOpFamily((RemoveOpFamilyStmt
*) parsetree
);
1267 case T_AlterTSDictionaryStmt
:
1268 AlterTSDictionary((AlterTSDictionaryStmt
*) parsetree
);
1271 case T_AlterTSConfigurationStmt
:
1272 AlterTSConfiguration((AlterTSConfigurationStmt
*) parsetree
);
1276 elog(ERROR
, "unrecognized node type: %d",
1277 (int) nodeTag(parsetree
));
1283 * UtilityReturnsTuples
1284 * Return "true" if this utility statement will send output to the
1287 * Generally, there should be a case here for each case in ProcessUtility
1288 * where "dest" is passed on.
1291 UtilityReturnsTuples(Node
*parsetree
)
1293 switch (nodeTag(parsetree
))
1297 FetchStmt
*stmt
= (FetchStmt
*) parsetree
;
1302 portal
= GetPortalByName(stmt
->portalname
);
1303 if (!PortalIsValid(portal
))
1304 return false; /* not our business to raise error */
1305 return portal
->tupDesc
? true : false;
1310 ExecuteStmt
*stmt
= (ExecuteStmt
*) parsetree
;
1311 PreparedStatement
*entry
;
1315 entry
= FetchPreparedStatement(stmt
->name
, false);
1317 return false; /* not our business to raise error */
1318 if (entry
->plansource
->resultDesc
)
1326 case T_VariableShowStmt
:
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
1343 UtilityTupleDescriptor(Node
*parsetree
)
1345 switch (nodeTag(parsetree
))
1349 FetchStmt
*stmt
= (FetchStmt
*) parsetree
;
1354 portal
= GetPortalByName(stmt
->portalname
);
1355 if (!PortalIsValid(portal
))
1356 return NULL
; /* not our business to raise error */
1357 return CreateTupleDescCopy(portal
->tupDesc
);
1362 ExecuteStmt
*stmt
= (ExecuteStmt
*) parsetree
;
1363 PreparedStatement
*entry
;
1367 entry
= FetchPreparedStatement(stmt
->name
, false);
1369 return NULL
; /* not our business to raise error */
1370 return FetchPreparedStatementResultDesc(entry
);
1374 return ExplainResultDesc((ExplainStmt
*) parsetree
);
1376 case T_VariableShowStmt
:
1378 VariableShowStmt
*n
= (VariableShowStmt
*) parsetree
;
1380 return GetPGVariableResultDesc(n
->name
);
1390 * QueryReturnsTuples
1391 * Return "true" if this Query will send output to the destination.
1395 QueryReturnsTuples(Query
*parsetree
)
1397 switch (parsetree
->commandType
)
1400 /* returns tuples ... unless it's DECLARE CURSOR or SELECT INTO */
1401 if (parsetree
->utilityStmt
== NULL
&&
1402 parsetree
->intoClause
== NULL
)
1408 /* the forms with RETURNING return tuples */
1409 if (parsetree
->returningList
)
1413 return UtilityReturnsTuples(parsetree
->utilityStmt
);
1416 /* probably shouldn't get here */
1419 return false; /* default */
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).
1436 CreateCommandTag(Node
*parsetree
)
1440 switch (nodeTag(parsetree
))
1442 /* raw plannable queries */
1459 /* utility statements --- same whether raw or cooked */
1460 case T_TransactionStmt
:
1462 TransactionStmt
*stmt
= (TransactionStmt
*) parsetree
;
1466 case TRANS_STMT_BEGIN
:
1470 case TRANS_STMT_START
:
1471 tag
= "START TRANSACTION";
1474 case TRANS_STMT_COMMIT
:
1478 case TRANS_STMT_ROLLBACK
:
1479 case TRANS_STMT_ROLLBACK_TO
:
1483 case TRANS_STMT_SAVEPOINT
:
1487 case TRANS_STMT_RELEASE
:
1491 case TRANS_STMT_PREPARE
:
1492 tag
= "PREPARE TRANSACTION";
1495 case TRANS_STMT_COMMIT_PREPARED
:
1496 tag
= "COMMIT PREPARED";
1499 case TRANS_STMT_ROLLBACK_PREPARED
:
1500 tag
= "ROLLBACK PREPARED";
1510 case T_DeclareCursorStmt
:
1511 tag
= "DECLARE CURSOR";
1514 case T_ClosePortalStmt
:
1516 ClosePortalStmt
*stmt
= (ClosePortalStmt
*) parsetree
;
1518 if (stmt
->portalname
== NULL
)
1519 tag
= "CLOSE CURSOR ALL";
1521 tag
= "CLOSE CURSOR";
1527 FetchStmt
*stmt
= (FetchStmt
*) parsetree
;
1529 tag
= (stmt
->ismove
) ? "MOVE" : "FETCH";
1533 case T_CreateDomainStmt
:
1534 tag
= "CREATE DOMAIN";
1537 case T_CreateSchemaStmt
:
1538 tag
= "CREATE SCHEMA";
1542 tag
= "CREATE TABLE";
1545 case T_CreateTableSpaceStmt
:
1546 tag
= "CREATE TABLESPACE";
1549 case T_DropTableSpaceStmt
:
1550 tag
= "DROP TABLESPACE";
1553 case T_AlterTableSpaceOptionsStmt
:
1554 tag
= "ALTER TABLESPACE";
1557 case T_CreateExtensionStmt
:
1558 tag
= "CREATE EXTENSION";
1561 case T_CreateFdwStmt
:
1562 tag
= "CREATE FOREIGN DATA WRAPPER";
1565 case T_AlterFdwStmt
:
1566 tag
= "ALTER FOREIGN DATA WRAPPER";
1570 tag
= "DROP FOREIGN DATA WRAPPER";
1573 case T_CreateForeignServerStmt
:
1574 tag
= "CREATE SERVER";
1577 case T_AlterForeignServerStmt
:
1578 tag
= "ALTER SERVER";
1581 case T_DropForeignServerStmt
:
1582 tag
= "DROP SERVER";
1585 case T_CreateUserMappingStmt
:
1586 tag
= "CREATE USER MAPPING";
1589 case T_AlterUserMappingStmt
:
1590 tag
= "ALTER USER MAPPING";
1593 case T_DropUserMappingStmt
:
1594 tag
= "DROP USER MAPPING";
1597 case T_CreateForeignTableStmt
:
1598 tag
= "CREATE FOREIGN TABLE";
1602 switch (((DropStmt
*) parsetree
)->removeType
)
1607 case OBJECT_SEQUENCE
:
1608 tag
= "DROP SEQUENCE";
1620 tag
= "DROP DOMAIN";
1622 case OBJECT_CONVERSION
:
1623 tag
= "DROP CONVERSION";
1626 tag
= "DROP SCHEMA";
1628 case OBJECT_TSPARSER
:
1629 tag
= "DROP TEXT SEARCH PARSER";
1631 case OBJECT_TSDICTIONARY
:
1632 tag
= "DROP TEXT SEARCH DICTIONARY";
1634 case OBJECT_TSTEMPLATE
:
1635 tag
= "DROP TEXT SEARCH TEMPLATE";
1637 case OBJECT_TSCONFIGURATION
:
1638 tag
= "DROP TEXT SEARCH CONFIGURATION";
1640 case OBJECT_FOREIGN_TABLE
:
1641 tag
= "DROP FOREIGN TABLE";
1643 case OBJECT_EXTENSION
:
1644 tag
= "DROP EXTENSION";
1651 case T_TruncateStmt
:
1652 tag
= "TRUNCATE TABLE";
1659 case T_SecLabelStmt
:
1660 tag
= "SECURITY LABEL";
1668 switch (((RenameStmt
*) parsetree
)->renameType
)
1670 case OBJECT_AGGREGATE
:
1671 tag
= "ALTER AGGREGATE";
1673 case OBJECT_CONVERSION
:
1674 tag
= "ALTER CONVERSION";
1676 case OBJECT_DATABASE
:
1677 tag
= "ALTER DATABASE";
1679 case OBJECT_FUNCTION
:
1680 tag
= "ALTER FUNCTION";
1683 tag
= "ALTER INDEX";
1685 case OBJECT_LANGUAGE
:
1686 tag
= "ALTER LANGUAGE";
1688 case OBJECT_OPCLASS
:
1689 tag
= "ALTER OPERATOR CLASS";
1691 case OBJECT_OPFAMILY
:
1692 tag
= "ALTER OPERATOR FAMILY";
1698 tag
= "ALTER SCHEMA";
1700 case OBJECT_SEQUENCE
:
1701 tag
= "ALTER SEQUENCE";
1705 RenameStmt
*stmt
= (RenameStmt
*) parsetree
;
1706 if (stmt
->relationType
== OBJECT_FOREIGN_TABLE
)
1707 tag
= "ALTER FOREIGN TABLE";
1709 tag
= "ALTER TABLE";
1713 tag
= "ALTER TABLE";
1715 case OBJECT_TABLESPACE
:
1716 tag
= "ALTER TABLESPACE";
1718 case OBJECT_TRIGGER
:
1719 tag
= "ALTER TRIGGER";
1724 case OBJECT_FOREIGN_TABLE
:
1725 tag
= "ALTER FOREIGN TABLE";
1727 case OBJECT_TSPARSER
:
1728 tag
= "ALTER TEXT SEARCH PARSER";
1730 case OBJECT_TSDICTIONARY
:
1731 tag
= "ALTER TEXT SEARCH DICTIONARY";
1733 case OBJECT_TSTEMPLATE
:
1734 tag
= "ALTER TEXT SEARCH TEMPLATE";
1736 case OBJECT_TSCONFIGURATION
:
1737 tag
= "ALTER TEXT SEARCH CONFIGURATION";
1739 case OBJECT_ATTRIBUTE
:
1749 case T_AlterObjectSchemaStmt
:
1750 switch (((AlterObjectSchemaStmt
*) parsetree
)->objectType
)
1752 case OBJECT_AGGREGATE
:
1753 tag
= "ALTER AGGREGATE";
1755 case OBJECT_CONVERSION
:
1756 tag
= "ALTER CONVERSION";
1759 tag
= "ALTER DOMAIN";
1761 case OBJECT_EXTENSION
:
1762 tag
= "ALTER EXTENSION";
1764 case OBJECT_OPERATOR
:
1765 tag
= "ALTER OPERATOR";
1767 case OBJECT_OPCLASS
:
1768 tag
= "ALTER OPERATOR CLASS";
1770 case OBJECT_OPFAMILY
:
1771 tag
= "ALTER OPERATOR FAMILY";
1773 case OBJECT_FUNCTION
:
1774 tag
= "ALTER FUNCTION";
1776 case OBJECT_SEQUENCE
:
1777 tag
= "ALTER SEQUENCE";
1780 tag
= "ALTER TABLE";
1785 case OBJECT_TSPARSER
:
1786 tag
= "ALTER TEXT SEARCH PARSER";
1788 case OBJECT_TSDICTIONARY
:
1789 tag
= "ALTER TEXT SEARCH DICTIONARY";
1791 case OBJECT_TSTEMPLATE
:
1792 tag
= "ALTER TEXT SEARCH TEMPLATE";
1794 case OBJECT_TSCONFIGURATION
:
1795 tag
= "ALTER TEXT SEARCH CONFIGURATION";
1800 case OBJECT_FOREIGN_TABLE
:
1801 tag
= "ALTER FOREIGN TABLE";
1809 case T_AlterOwnerStmt
:
1810 switch (((AlterOwnerStmt
*) parsetree
)->objectType
)
1812 case OBJECT_AGGREGATE
:
1813 tag
= "ALTER AGGREGATE";
1815 case OBJECT_CONVERSION
:
1816 tag
= "ALTER CONVERSION";
1818 case OBJECT_DATABASE
:
1819 tag
= "ALTER DATABASE";
1822 tag
= "ALTER DOMAIN";
1824 case OBJECT_FUNCTION
:
1825 tag
= "ALTER FUNCTION";
1827 case OBJECT_LANGUAGE
:
1828 tag
= "ALTER LANGUAGE";
1830 case OBJECT_LARGEOBJECT
:
1831 tag
= "ALTER LARGE OBJECT";
1833 case OBJECT_OPERATOR
:
1834 tag
= "ALTER OPERATOR";
1836 case OBJECT_OPCLASS
:
1837 tag
= "ALTER OPERATOR CLASS";
1839 case OBJECT_OPFAMILY
:
1840 tag
= "ALTER OPERATOR FAMILY";
1843 tag
= "ALTER SCHEMA";
1845 case OBJECT_TABLESPACE
:
1846 tag
= "ALTER TABLESPACE";
1851 case OBJECT_TSCONFIGURATION
:
1852 tag
= "ALTER TEXT SEARCH CONFIGURATION";
1854 case OBJECT_TSDICTIONARY
:
1855 tag
= "ALTER TEXT SEARCH DICTIONARY";
1858 tag
= "ALTER FOREIGN DATA WRAPPER";
1860 case OBJECT_FOREIGN_SERVER
:
1861 tag
= "ALTER SERVER";
1863 case OBJECT_FOREIGN_TABLE
:
1864 tag
= "ALTER FOREIGN TABLE";
1872 case T_AlterTableStmt
:
1873 switch (((AlterTableStmt
*) parsetree
)->relkind
)
1876 tag
= "ALTER TABLE";
1879 tag
= "ALTER INDEX";
1881 case OBJECT_SEQUENCE
:
1882 tag
= "ALTER SEQUENCE";
1890 case OBJECT_FOREIGN_TABLE
:
1891 tag
= "ALTER FOREIGN TABLE";
1899 case T_AlterDomainStmt
:
1900 tag
= "ALTER DOMAIN";
1903 case T_AlterFunctionStmt
:
1904 tag
= "ALTER FUNCTION";
1909 GrantStmt
*stmt
= (GrantStmt
*) parsetree
;
1911 tag
= (stmt
->is_grant
) ? "GRANT" : "REVOKE";
1915 case T_GrantRoleStmt
:
1917 GrantRoleStmt
*stmt
= (GrantRoleStmt
*) parsetree
;
1919 tag
= (stmt
->is_grant
) ? "GRANT ROLE" : "REVOKE ROLE";
1923 case T_AlterDefaultPrivilegesStmt
:
1924 tag
= "ALTER DEFAULT PRIVILEGES";
1928 switch (((DefineStmt
*) parsetree
)->kind
)
1930 case OBJECT_AGGREGATE
:
1931 tag
= "CREATE AGGREGATE";
1933 case OBJECT_OPERATOR
:
1934 tag
= "CREATE OPERATOR";
1937 tag
= "CREATE TYPE";
1939 case OBJECT_TSPARSER
:
1940 tag
= "CREATE TEXT SEARCH PARSER";
1942 case OBJECT_TSDICTIONARY
:
1943 tag
= "CREATE TEXT SEARCH DICTIONARY";
1945 case OBJECT_TSTEMPLATE
:
1946 tag
= "CREATE TEXT SEARCH TEMPLATE";
1948 case OBJECT_TSCONFIGURATION
:
1949 tag
= "CREATE TEXT SEARCH CONFIGURATION";
1956 case T_CompositeTypeStmt
:
1957 tag
= "CREATE TYPE";
1960 case T_CreateEnumStmt
:
1961 tag
= "CREATE TYPE";
1964 case T_AlterEnumStmt
:
1969 tag
= "CREATE VIEW";
1972 case T_CreateFunctionStmt
:
1973 tag
= "CREATE FUNCTION";
1977 tag
= "CREATE INDEX";
1981 tag
= "CREATE RULE";
1984 case T_CreateSeqStmt
:
1985 tag
= "CREATE SEQUENCE";
1988 case T_AlterSeqStmt
:
1989 tag
= "ALTER SEQUENCE";
1992 case T_RemoveFuncStmt
:
1993 switch (((RemoveFuncStmt
*) parsetree
)->kind
)
1995 case OBJECT_FUNCTION
:
1996 tag
= "DROP FUNCTION";
1998 case OBJECT_AGGREGATE
:
1999 tag
= "DROP AGGREGATE";
2001 case OBJECT_OPERATOR
:
2002 tag
= "DROP OPERATOR";
2013 case T_CreatedbStmt
:
2014 tag
= "CREATE DATABASE";
2017 case T_AlterDatabaseStmt
:
2018 tag
= "ALTER DATABASE";
2021 case T_AlterDatabaseSetStmt
:
2022 tag
= "ALTER DATABASE";
2026 tag
= "DROP DATABASE";
2037 case T_UnlistenStmt
:
2050 if (((VacuumStmt
*) parsetree
)->options
& VACOPT_VACUUM
)
2060 case T_VariableSetStmt
:
2061 switch (((VariableSetStmt
*) parsetree
)->kind
)
2064 case VAR_SET_CURRENT
:
2065 case VAR_SET_DEFAULT
:
2078 case T_VariableShowStmt
:
2083 switch (((DiscardStmt
*) parsetree
)->target
)
2086 tag
= "DISCARD ALL";
2089 tag
= "DISCARD PLANS";
2092 tag
= "DISCARD TEMP";
2099 case T_CreateTrigStmt
:
2100 tag
= "CREATE TRIGGER";
2103 case T_DropPropertyStmt
:
2104 switch (((DropPropertyStmt
*) parsetree
)->removeType
)
2106 case OBJECT_TRIGGER
:
2107 tag
= "DROP TRIGGER";
2117 case T_CreatePLangStmt
:
2118 tag
= "CREATE LANGUAGE";
2121 case T_DropPLangStmt
:
2122 tag
= "DROP LANGUAGE";
2125 case T_CreateRoleStmt
:
2126 tag
= "CREATE ROLE";
2129 case T_AlterRoleStmt
:
2133 case T_AlterRoleSetStmt
:
2137 case T_DropRoleStmt
:
2141 case T_DropOwnedStmt
:
2145 case T_ReassignOwnedStmt
:
2146 tag
= "REASSIGN OWNED";
2153 case T_ConstraintsSetStmt
:
2154 tag
= "SET CONSTRAINTS";
2157 case T_CheckPointStmt
:
2165 case T_CreateConversionStmt
:
2166 tag
= "CREATE CONVERSION";
2169 case T_CreateCastStmt
:
2170 tag
= "CREATE CAST";
2173 case T_DropCastStmt
:
2177 case T_CreateOpClassStmt
:
2178 tag
= "CREATE OPERATOR CLASS";
2181 case T_CreateOpFamilyStmt
:
2182 tag
= "CREATE OPERATOR FAMILY";
2185 case T_AlterOpFamilyStmt
:
2186 tag
= "ALTER OPERATOR FAMILY";
2189 case T_RemoveOpClassStmt
:
2190 tag
= "DROP OPERATOR CLASS";
2193 case T_RemoveOpFamilyStmt
:
2194 tag
= "DROP OPERATOR FAMILY";
2197 case T_AlterTSDictionaryStmt
:
2198 tag
= "ALTER TEXT SEARCH DICTIONARY";
2201 case T_AlterTSConfigurationStmt
:
2202 tag
= "ALTER TEXT SEARCH CONFIGURATION";
2213 case T_DeallocateStmt
:
2215 DeallocateStmt
*stmt
= (DeallocateStmt
*) parsetree
;
2217 if (stmt
->name
== NULL
)
2218 tag
= "DEALLOCATE ALL";
2224 /* already-planned queries */
2227 PlannedStmt
*stmt
= (PlannedStmt
*) parsetree
;
2229 switch (stmt
->commandType
)
2234 * We take a little extra care here so that the result
2235 * will be useful for complaints about read-only
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";
2251 tag
= "SELECT FOR SHARE";
2266 elog(WARNING
, "unrecognized commandType: %d",
2267 (int) stmt
->commandType
);
2274 /* parsed-and-rewritten-but-not-planned queries */
2277 Query
*stmt
= (Query
*) parsetree
;
2279 switch (stmt
->commandType
)
2284 * We take a little extra care here so that the result
2285 * will be useful for complaints about read-only
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";
2301 tag
= "SELECT FOR SHARE";
2316 tag
= CreateCommandTag(stmt
->utilityStmt
);
2319 elog(WARNING
, "unrecognized commandType: %d",
2320 (int) stmt
->commandType
);
2328 elog(WARNING
, "unrecognized node type: %d",
2329 (int) nodeTag(parsetree
));
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.
2347 GetCommandLogLevel(Node
*parsetree
)
2351 switch (nodeTag(parsetree
))
2353 /* raw plannable queries */
2361 if (((SelectStmt
*) parsetree
)->intoClause
)
2362 lev
= LOGSTMT_DDL
; /* CREATE AS, SELECT INTO */
2367 /* utility statements --- same whether raw or cooked */
2368 case T_TransactionStmt
:
2372 case T_DeclareCursorStmt
:
2376 case T_ClosePortalStmt
:
2384 case T_CreateSchemaStmt
:
2389 case T_CreateForeignTableStmt
:
2393 case T_CreateTableSpaceStmt
:
2397 case T_DropTableSpaceStmt
:
2401 case T_AlterTableSpaceOptionsStmt
:
2405 case T_CreateExtensionStmt
:
2409 case T_CreateFdwStmt
:
2410 case T_AlterFdwStmt
:
2412 case T_CreateForeignServerStmt
:
2413 case T_AlterForeignServerStmt
:
2414 case T_DropForeignServerStmt
:
2415 case T_CreateUserMappingStmt
:
2416 case T_AlterUserMappingStmt
:
2417 case T_DropUserMappingStmt
:
2425 case T_TruncateStmt
:
2433 case T_SecLabelStmt
:
2438 if (((CopyStmt
*) parsetree
)->is_from
)
2446 PrepareStmt
*stmt
= (PrepareStmt
*) parsetree
;
2448 /* Look through a PREPARE to the contained stmt */
2449 lev
= GetCommandLogLevel(stmt
->query
);
2455 ExecuteStmt
*stmt
= (ExecuteStmt
*) parsetree
;
2456 PreparedStatement
*ps
;
2458 /* Look through an EXECUTE to the referenced stmt */
2459 ps
= FetchPreparedStatement(stmt
->name
, false);
2461 lev
= GetCommandLogLevel(ps
->plansource
->raw_parse_tree
);
2467 case T_DeallocateStmt
:
2475 case T_AlterObjectSchemaStmt
:
2479 case T_AlterOwnerStmt
:
2483 case T_AlterTableStmt
:
2487 case T_AlterDomainStmt
:
2495 case T_GrantRoleStmt
:
2499 case T_AlterDefaultPrivilegesStmt
:
2507 case T_CompositeTypeStmt
:
2511 case T_CreateEnumStmt
:
2515 case T_AlterEnumStmt
:
2523 case T_CreateFunctionStmt
:
2527 case T_AlterFunctionStmt
:
2539 case T_CreateSeqStmt
:
2543 case T_AlterSeqStmt
:
2547 case T_RemoveFuncStmt
:
2555 case T_CreatedbStmt
:
2559 case T_AlterDatabaseStmt
:
2563 case T_AlterDatabaseSetStmt
:
2579 case T_UnlistenStmt
:
2597 ExplainStmt
*stmt
= (ExplainStmt
*) parsetree
;
2598 bool analyze
= false;
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 */
2611 return GetCommandLogLevel(stmt
->query
);
2613 /* Plain EXPLAIN isn't so interesting */
2618 case T_VariableSetStmt
:
2622 case T_VariableShowStmt
:
2630 case T_CreateTrigStmt
:
2634 case T_DropPropertyStmt
:
2638 case T_CreatePLangStmt
:
2642 case T_DropPLangStmt
:
2646 case T_CreateDomainStmt
:
2650 case T_CreateRoleStmt
:
2654 case T_AlterRoleStmt
:
2658 case T_AlterRoleSetStmt
:
2662 case T_DropRoleStmt
:
2666 case T_DropOwnedStmt
:
2670 case T_ReassignOwnedStmt
:
2678 case T_ConstraintsSetStmt
:
2682 case T_CheckPointStmt
:
2687 lev
= LOGSTMT_ALL
; /* should this be DDL? */
2690 case T_CreateConversionStmt
:
2694 case T_CreateCastStmt
:
2698 case T_DropCastStmt
:
2702 case T_CreateOpClassStmt
:
2706 case T_CreateOpFamilyStmt
:
2710 case T_AlterOpFamilyStmt
:
2714 case T_RemoveOpClassStmt
:
2718 case T_RemoveOpFamilyStmt
:
2722 case T_AlterTSDictionaryStmt
:
2726 case T_AlterTSConfigurationStmt
:
2730 /* already-planned queries */
2733 PlannedStmt
*stmt
= (PlannedStmt
*) parsetree
;
2735 switch (stmt
->commandType
)
2738 if (stmt
->intoClause
!= NULL
)
2739 lev
= LOGSTMT_DDL
; /* CREATE AS, SELECT INTO */
2741 lev
= LOGSTMT_ALL
; /* SELECT or DECLARE CURSOR */
2751 elog(WARNING
, "unrecognized commandType: %d",
2752 (int) stmt
->commandType
);
2759 /* parsed-and-rewritten-but-not-planned queries */
2762 Query
*stmt
= (Query
*) parsetree
;
2764 switch (stmt
->commandType
)
2767 if (stmt
->intoClause
!= NULL
)
2768 lev
= LOGSTMT_DDL
; /* CREATE AS, SELECT INTO */
2770 lev
= LOGSTMT_ALL
; /* SELECT or DECLARE CURSOR */
2780 lev
= GetCommandLogLevel(stmt
->utilityStmt
);
2784 elog(WARNING
, "unrecognized commandType: %d",
2785 (int) stmt
->commandType
);
2794 elog(WARNING
, "unrecognized node type: %d",
2795 (int) nodeTag(parsetree
));