Tom Lane <t...@sss.pgh.pa.us> writes:
> Yeah, I was just looking at the IfSupported variant.  In the structure
> I just suggested (separate ProcessSlowUtility function), we could make
> that work by having switch cases for some statements in both functions,

I've done it the way you propose here, and then in the Slow variant we
have two set of cases again: those with some manual transactionnal
behavior or some other code complexities, and the really simple ones.

The attached patch involves a second layer of distinction to simplify
the code fully and remove all the Event Trigger related macrology that I
didn't much like. Maybe that's going a tad too far, see what you think.

Of course the patch passes make check.

Also, some switch cases are now duplicated for the sole benefit of
keeping some compiler help, but I don't know how much help we're talking
about now that we have 3 different switches. It seemed cleaner to do it
that way as it allows to ERROR out in the very last default case.

Finally, I've been surprised to find out that those cases are only
triggering for "ddl_event_start" (and not "ddl_event_end"), I think
that's a bug we should be fixing:

                case T_AlterDomainStmt:
                case T_DefineStmt:
                case T_IndexStmt:               /* CREATE INDEX */

The T_IndexStmt should be triggering ddl_event_end when stmt->concurrent
is false, and that's not the case in the code in the master's branch.
The two other cases should just be moved to the later switch so that
both start and end triggers happen.

Or maybe I'm missing something here. Given that it might as well be the
case, I did only refactor the code keeping its current behavior rather
than fixing what I think is a bug while doing so.

Regards,
-- 
Dimitri Fontaine
http://2ndQuadrant.fr     PostgreSQL : Expertise, Formation et Support

*** a/src/backend/tcop/utility.c
--- b/src/backend/tcop/utility.c
***************
*** 68,73 ****
--- 68,80 ----
  /* Hook for plugins to get control in ProcessUtility() */
  ProcessUtility_hook_type ProcessUtility_hook = NULL;
  
+ /* local function declarations */
+ void standard_ProcessSlowUtility(Node *parsetree,
+ 								 const char *queryString,
+ 								 ParamListInfo params,
+ 								 DestReceiver *dest,
+ 								 char *completionTag,
+ 								 ProcessUtilityContext context);
  
  /*
   * Verify user has ownership of specified relation, else ereport.
***************
*** 342,411 **** ProcessUtility(Node *parsetree,
  								dest, completionTag, context);
  }
  
- #define InvokeDDLCommandEventTriggers(parsetree, fncall) \
- 	do { \
- 	    if (isCompleteQuery) \
-         { \
- 			EventTriggerDDLCommandStart(parsetree); \
- 		} \
- 		fncall; \
-         if (isCompleteQuery) \
-         { \
- 			EventTriggerSQLDrop(parsetree); \
- 			EventTriggerDDLCommandEnd(parsetree); \
- 		} \
- 	} while (0)
- 
- #define InvokeDDLCommandEventTriggersIfSupported(parsetree, fncall, objtype) \
- 	do { \
- 		bool	_supported = EventTriggerSupportsObjectType(objtype); \
- 		\
- 		if (_supported) \
- 		{ \
- 			EventTriggerDDLCommandStart(parsetree); \
- 		} \
- 		fncall; \
- 		if (_supported) \
- 		{ \
- 			EventTriggerSQLDrop(parsetree); \
- 			EventTriggerDDLCommandEnd(parsetree); \
- 		} \
- 	} while (0)
- 
  /*
!  * UTILITY_BEGIN_QUERY and UTILITY_END_QUERY are a pair of macros to enclose
!  * execution of a single DDL command, to ensure the event trigger environment
!  * is appropriately set up before starting, and tore down after completion or
!  * error.
   */
- #define UTILITY_BEGIN_QUERY(isComplete) \
- 	do { \
- 		bool		_needCleanup; \
- 		\
- 		_needCleanup = (isComplete) && EventTriggerBeginCompleteQuery(); \
- 		\
- 		PG_TRY(); \
- 		{ \
- 			/* avoid empty statement when followed by a semicolon */ \
- 			(void) 0
- 
- #define UTILITY_END_QUERY() \
- 		} \
- 		PG_CATCH(); \
- 		{ \
- 			if (_needCleanup) \
- 			{ \
- 				EventTriggerEndCompleteQuery(); \
- 			} \
- 			PG_RE_THROW(); \
- 		} \
- 		PG_END_TRY(); \
- 		if (_needCleanup) \
- 		{ \
- 			EventTriggerEndCompleteQuery(); \
- 		} \
- 	} while (0)
- 
  void
  standard_ProcessUtility(Node *parsetree,
  						const char *queryString,
--- 349,364 ----
  								dest, completionTag, context);
  }
  
  /*
!  * Processing a Utility statement is now divided into two functions. A fast
!  * path is taken for statements for which we have not Event Trigger support, so
!  * that there's no need to do any Event Trigger specific setup.
!  *
!  * It's not just a performance requirement, mind you, because refreshing the
!  * Event Triggers cache (see src/backend/utils/cache/evtcache.c) is prone to
!  * taking a snapshot, which can not occur with in a START TRANSACTION statement
!  * for example.
   */
  void
  standard_ProcessUtility(Node *parsetree,
  						const char *queryString,
***************
*** 415,429 **** standard_ProcessUtility(Node *parsetree,
  						ProcessUtilityContext context)
  {
  	bool		isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
- 	bool		isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
  
  	check_xact_readonly(parsetree);
  
  	if (completionTag)
  		completionTag[0] = '\0';
  
- 	UTILITY_BEGIN_QUERY(isCompleteQuery);
- 
  	switch (nodeTag(parsetree))
  	{
  			/*
--- 368,379 ----
***************
*** 571,665 **** standard_ProcessUtility(Node *parsetree,
  							   completionTag);
  			break;
  
- 			/*
- 			 * relation and attribute manipulation
- 			 */
- 		case T_CreateSchemaStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				CreateSchemaCommand((CreateSchemaStmt *) parsetree,
- 									queryString));
- 			break;
- 
- 		case T_CreateStmt:
- 		case T_CreateForeignTableStmt:
- 			{
- 				List	   *stmts;
- 				ListCell   *l;
- 				Oid			relOid;
- 
- 				if (isCompleteQuery)
- 					EventTriggerDDLCommandStart(parsetree);
- 
- 				/* Run parse analysis ... */
- 				stmts = transformCreateStmt((CreateStmt *) parsetree,
- 											queryString);
- 
- 				/* ... and do it */
- 				foreach(l, stmts)
- 				{
- 					Node	   *stmt = (Node *) lfirst(l);
- 
- 					if (IsA(stmt, CreateStmt))
- 					{
- 						Datum		toast_options;
- 						static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
- 
- 						/* Create the table itself */
- 						relOid = DefineRelation((CreateStmt *) stmt,
- 												RELKIND_RELATION,
- 												InvalidOid);
- 
- 						/*
- 						 * Let AlterTableCreateToastTable decide if this one
- 						 * needs a secondary relation too.
- 						 */
- 						CommandCounterIncrement();
- 
- 						/* parse and validate reloptions for the toast table */
- 						toast_options = transformRelOptions((Datum) 0,
- 											  ((CreateStmt *) stmt)->options,
- 															"toast",
- 															validnsps,
- 															true, false);
- 						(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
- 											   true);
- 
- 						AlterTableCreateToastTable(relOid, toast_options);
- 					}
- 					else if (IsA(stmt, CreateForeignTableStmt))
- 					{
- 						/* Create the table itself */
- 						relOid = DefineRelation((CreateStmt *) stmt,
- 												RELKIND_FOREIGN_TABLE,
- 												InvalidOid);
- 						CreateForeignTable((CreateForeignTableStmt *) stmt,
- 										   relOid);
- 					}
- 					else
- 					{
- 						/* Recurse for anything else */
- 						ProcessUtility(stmt,
- 									   queryString,
- 									   params,
- 									   None_Receiver,
- 									   NULL,
- 									   PROCESS_UTILITY_GENERATED);
- 					}
- 
- 					/* Need CCI between commands */
- 					if (lnext(l) != NULL)
- 						CommandCounterIncrement();
- 				}
- 
- 				if (isCompleteQuery)
- 				{
- 					EventTriggerSQLDrop(parsetree);
- 					EventTriggerDDLCommandEnd(parsetree);
- 				}
- 			}
- 			break;
- 
  		case T_CreateTableSpaceStmt:
  			/* no event triggers for global objects */
  			PreventTransactionChain(isTopLevel, "CREATE TABLESPACE");
--- 521,526 ----
***************
*** 677,784 **** standard_ProcessUtility(Node *parsetree,
  			AlterTableSpaceOptions((AlterTableSpaceOptionsStmt *) parsetree);
  			break;
  
- 		case T_CreateExtensionStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				CreateExtension((CreateExtensionStmt *) parsetree));
- 			break;
- 
- 		case T_AlterExtensionStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree));
- 			break;
- 
- 		case T_AlterExtensionContentsStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree));
- 			break;
- 
- 		case T_CreateFdwStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				CreateForeignDataWrapper((CreateFdwStmt *) parsetree));
- 			break;
- 
- 		case T_AlterFdwStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				AlterForeignDataWrapper((AlterFdwStmt *) parsetree));
- 			break;
- 
- 		case T_CreateForeignServerStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				CreateForeignServer((CreateForeignServerStmt *) parsetree));
- 			break;
- 
- 		case T_AlterForeignServerStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				AlterForeignServer((AlterForeignServerStmt *) parsetree));
- 			break;
- 
- 		case T_CreateUserMappingStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				CreateUserMapping((CreateUserMappingStmt *) parsetree));
- 			break;
- 
- 		case T_AlterUserMappingStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				AlterUserMapping((AlterUserMappingStmt *) parsetree));
- 			break;
- 
- 		case T_DropUserMappingStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				RemoveUserMapping((DropUserMappingStmt *) parsetree));
- 			break;
- 
- 		case T_DropStmt:
- 			{
- 				DropStmt   *stmt = (DropStmt *) parsetree;
- 
- 				if (isCompleteQuery
- 					&& EventTriggerSupportsObjectType(stmt->removeType))
- 					EventTriggerDDLCommandStart(parsetree);
- 
- 				switch (stmt->removeType)
- 				{
- 					case OBJECT_INDEX:
- 						if (stmt->concurrent)
- 							PreventTransactionChain(isTopLevel,
- 													"DROP INDEX CONCURRENTLY");
- 						/* fall through */
- 
- 					case OBJECT_TABLE:
- 					case OBJECT_SEQUENCE:
- 					case OBJECT_VIEW:
- 					case OBJECT_MATVIEW:
- 					case OBJECT_FOREIGN_TABLE:
- 						RemoveRelations((DropStmt *) parsetree);
- 						break;
- 					default:
- 						RemoveObjects((DropStmt *) parsetree);
- 						break;
- 				}
- 
- 				if (isCompleteQuery
- 					&& EventTriggerSupportsObjectType(stmt->removeType))
- 				{
- 					EventTriggerSQLDrop(parsetree);
- 					EventTriggerDDLCommandEnd(parsetree);
- 				}
- 
- 				break;
- 			}
- 
- 		case T_TruncateStmt:
- 			ExecuteTruncate((TruncateStmt *) parsetree);
- 			break;
- 
  		case T_CommentStmt:
  			CommentObject((CommentStmt *) parsetree);
  			break;
--- 538,543 ----
***************
*** 814,872 **** standard_ProcessUtility(Node *parsetree,
  			DeallocateQuery((DeallocateStmt *) parsetree);
  			break;
  
! 			/*
! 			 * schema
! 			 */
! 		case T_RenameStmt:
  			{
! 				RenameStmt *stmt = (RenameStmt *) parsetree;
  
! 				InvokeDDLCommandEventTriggersIfSupported(parsetree,
! 														 ExecRenameStmt(stmt),
! 														 stmt->renameType);
! 				break;
  			}
  
! 		case T_AlterObjectSchemaStmt:
  			{
! 				AlterObjectSchemaStmt  *stmt = (AlterObjectSchemaStmt *) parsetree;
! 				InvokeDDLCommandEventTriggersIfSupported(parsetree,
! 														 ExecAlterObjectSchemaStmt(stmt),
! 														 stmt->objectType);
! 				break;
  			}
  
! 		case T_AlterOwnerStmt:
  			{
! 				AlterOwnerStmt  *stmt = (AlterOwnerStmt *) parsetree;
! 				InvokeDDLCommandEventTriggersIfSupported(parsetree,
! 														 ExecAlterOwnerStmt(stmt),
! 														 stmt->objectType);
! 				break;
  			}
  
! 		case T_AlterTableStmt:
  			{
! 				AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
! 				Oid			relid;
! 				List	   *stmts;
! 				ListCell   *l;
! 				LOCKMODE	lockmode;
  
! 				if (isCompleteQuery)
! 					EventTriggerDDLCommandStart(parsetree);
  
! 				/*
! 				 * Figure out lock mode, and acquire lock.	This also does
! 				 * basic permissions checks, so that we won't wait for a lock
! 				 * on (for example) a relation on which we have no
! 				 * permissions.
! 				 */
! 				lockmode = AlterTableGetLockLevel(atstmt->cmds);
! 				relid = AlterTableLookupRelation(atstmt, lockmode);
  
! 				if (OidIsValid(relid))
! 				{
  					/* Run parse analysis ... */
  					stmts = transformAlterTableStmt(atstmt, queryString);
  
--- 573,1089 ----
  			DeallocateQuery((DeallocateStmt *) parsetree);
  			break;
  
! 		case T_TruncateStmt:
! 			ExecuteTruncate((TruncateStmt *) parsetree);
! 			break;
! 
! 		case T_GrantStmt:
! 			ExecuteGrantStmt((GrantStmt *) parsetree);
! 			break;
! 
! 		case T_GrantRoleStmt:
! 			GrantRole((GrantRoleStmt *) parsetree);
! 			break;
! 
! 		case T_DoStmt:
! 			ExecuteDoStmt((DoStmt *) parsetree);
! 			break;
! 
! 		case T_CreatedbStmt:
! 			/* no event triggers for global objects */
! 			PreventTransactionChain(isTopLevel, "CREATE DATABASE");
! 			createdb((CreatedbStmt *) parsetree);
! 			break;
! 
! 		case T_AlterDatabaseStmt:
! 			/* no event triggers for global objects */
! 			AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
! 			break;
! 
! 		case T_AlterDatabaseSetStmt:
! 			/* no event triggers for global objects */
! 			AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
! 			break;
! 
! 		case T_DropdbStmt:
  			{
! 				DropdbStmt *stmt = (DropdbStmt *) parsetree;
  
! 				/* no event triggers for global objects */
! 				PreventTransactionChain(isTopLevel, "DROP DATABASE");
! 				dropdb(stmt->dbname, stmt->missing_ok);
  			}
+ 			break;
  
! 			/* Query-level asynchronous notification */
! 		case T_NotifyStmt:
  			{
! 				NotifyStmt *stmt = (NotifyStmt *) parsetree;
! 
! 				PreventCommandDuringRecovery("NOTIFY");
! 				Async_Notify(stmt->conditionname, stmt->payload);
  			}
+ 			break;
  
! 		case T_ListenStmt:
  			{
! 				ListenStmt *stmt = (ListenStmt *) parsetree;
! 
! 				PreventCommandDuringRecovery("LISTEN");
! 				CheckRestrictedOperation("LISTEN");
! 				Async_Listen(stmt->conditionname);
  			}
+ 			break;
  
! 		case T_UnlistenStmt:
  			{
! 				UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
  
! 				PreventCommandDuringRecovery("UNLISTEN");
! 				CheckRestrictedOperation("UNLISTEN");
! 				if (stmt->conditionname)
! 					Async_Unlisten(stmt->conditionname);
! 				else
! 					Async_UnlistenAll();
! 			}
! 			break;
  
! 		case T_LoadStmt:
! 			{
! 				LoadStmt   *stmt = (LoadStmt *) parsetree;
  
! 				closeAllVfds(); /* probably not necessary... */
! 				/* Allowed names are restricted if you're not superuser */
! 				load_file(stmt->filename, !superuser());
! 			}
! 			break;
! 
! 		case T_ClusterStmt:
! 			/* we choose to allow this during "read only" transactions */
! 			PreventCommandDuringRecovery("CLUSTER");
! 			cluster((ClusterStmt *) parsetree, isTopLevel);
! 			break;
! 
! 		case T_VacuumStmt:
! 			{
! 				VacuumStmt *stmt = (VacuumStmt *) parsetree;
! 
! 				/* we choose to allow this during "read only" transactions */
! 				PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
! 											 "VACUUM" : "ANALYZE");
! 				vacuum(stmt, InvalidOid, true, NULL, false, isTopLevel);
! 			}
! 			break;
! 
! 		case T_ExplainStmt:
! 			ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
! 			break;
! 
! 		case T_VariableSetStmt:
! 			ExecSetVariableStmt((VariableSetStmt *) parsetree);
! 			break;
! 
! 		case T_VariableShowStmt:
! 			{
! 				VariableShowStmt *n = (VariableShowStmt *) parsetree;
! 
! 				GetPGVariable(n->name, dest);
! 			}
! 			break;
! 
! 		case T_DiscardStmt:
! 			/* should we allow DISCARD PLANS? */
! 			CheckRestrictedOperation("DISCARD");
! 			DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
! 			break;
! 
! 		case T_CreateEventTrigStmt:
! 			/* no event triggers on event triggers */
! 			CreateEventTrigger((CreateEventTrigStmt *) parsetree);
! 			break;
! 
! 		case T_AlterEventTrigStmt:
! 			/* no event triggers on event triggers */
! 			AlterEventTrigger((AlterEventTrigStmt *) parsetree);
! 			break;
! 
! 			/*
! 			 * ******************************** ROLE statements ****
! 			 */
! 		case T_CreateRoleStmt:
! 			/* no event triggers for global objects */
! 			CreateRole((CreateRoleStmt *) parsetree);
! 			break;
! 
! 		case T_AlterRoleStmt:
! 			/* no event triggers for global objects */
! 			AlterRole((AlterRoleStmt *) parsetree);
! 			break;
! 
! 		case T_AlterRoleSetStmt:
! 			/* no event triggers for global objects */
! 			AlterRoleSet((AlterRoleSetStmt *) parsetree);
! 			break;
! 
! 		case T_DropRoleStmt:
! 			/* no event triggers for global objects */
! 			DropRole((DropRoleStmt *) parsetree);
! 			break;
! 
! 		case T_ReassignOwnedStmt:
! 			/* no event triggers for global objects */
! 			ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
! 			break;
! 
! 		case T_LockStmt:
! 
! 			/*
! 			 * Since the lock would just get dropped immediately, LOCK TABLE
! 			 * outside a transaction block is presumed to be user error.
! 			 */
! 			RequireTransactionChain(isTopLevel, "LOCK TABLE");
! 			LockTableCommand((LockStmt *) parsetree);
! 			break;
! 
! 		case T_ConstraintsSetStmt:
! 			AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
! 			break;
! 
! 		case T_CheckPointStmt:
! 			if (!superuser())
! 				ereport(ERROR,
! 						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 						 errmsg("must be superuser to do CHECKPOINT")));
! 
! 			/*
! 			 * You might think we should have a PreventCommandDuringRecovery()
! 			 * here, but we interpret a CHECKPOINT command during recovery as
! 			 * a request for a restartpoint instead. We allow this since it
! 			 * can be a useful way of reducing switchover time when using
! 			 * various forms of replication.
! 			 */
! 			RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
! 							  (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
! 			break;
! 
! 		case T_ReindexStmt:
! 			{
! 				ReindexStmt *stmt = (ReindexStmt *) parsetree;
! 
! 				/* we choose to allow this during "read only" transactions */
! 				PreventCommandDuringRecovery("REINDEX");
! 				switch (stmt->kind)
! 				{
! 					case OBJECT_INDEX:
! 						ReindexIndex(stmt->relation);
! 						break;
! 					case OBJECT_TABLE:
! 					case OBJECT_MATVIEW:
! 						ReindexTable(stmt->relation);
! 						break;
! 					case OBJECT_DATABASE:
! 
! 						/*
! 						 * This cannot run inside a user transaction block; if
! 						 * we were inside a transaction, then its commit- and
! 						 * start-transaction-command calls would not have the
! 						 * intended effect!
! 						 */
! 						PreventTransactionChain(isTopLevel,
! 												"REINDEX DATABASE");
! 						ReindexDatabase(stmt->name,
! 										stmt->do_system, stmt->do_user);
! 						break;
! 					default:
! 						elog(ERROR, "unrecognized object type: %d",
! 							 (int) stmt->kind);
! 						break;
! 				}
! 				break;
! 			}
! 			break;
! 
! 			/*
! 			 * The following statements are supported by Event Triggers only in
! 			 * some cases, so we "fast path" them in the other cases.
! 			 */
! 		case T_RenameStmt:
! 			{
! 				RenameStmt *stmt = (RenameStmt *) parsetree;
! 
! 				if (EventTriggerSupportsObjectType(stmt->renameType))
! 					standard_ProcessSlowUtility(parsetree, queryString, params,
! 												dest, completionTag, context);
! 				else
! 					ExecRenameStmt(stmt);
! 
! 				break;
! 			}
! 
! 		case T_AlterObjectSchemaStmt:
! 			{
! 				AlterObjectSchemaStmt  *stmt = (AlterObjectSchemaStmt *) parsetree;
! 
! 				if (EventTriggerSupportsObjectType(stmt->objectType))
! 					standard_ProcessSlowUtility(parsetree, queryString, params,
! 												dest, completionTag, context);
! 				else
! 					ExecAlterObjectSchemaStmt(stmt);
! 
! 				break;
! 			}
! 
! 		case T_AlterOwnerStmt:
! 			{
! 				AlterOwnerStmt  *stmt = (AlterOwnerStmt *) parsetree;
! 
! 				if (EventTriggerSupportsObjectType(stmt->objectType))
! 					standard_ProcessSlowUtility(parsetree, queryString, params,
! 												dest, completionTag, context);
! 				else
! 					ExecAlterOwnerStmt(stmt);
! 
! 				break;
! 			}
! 
! 			/*
! 			 * All the other cases are involving some Event Trigger special
! 			 * support code, so we handle here the main setup and teardown of
! 			 * it.
! 			 */
! 		default:
! 		{
! 			bool isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
! 			bool needCleanup =
! 				isCompleteQuery && EventTriggerBeginCompleteQuery();
! 
! 			PG_TRY();
! 			{
! 				standard_ProcessSlowUtility(parsetree, queryString, params,
! 											dest, completionTag, context);
! 			}
! 			PG_CATCH();
! 			{
! 				if (needCleanup)
! 					EventTriggerEndCompleteQuery();
! 				PG_RE_THROW();
! 			}
! 			PG_END_TRY();
! 
! 			if (needCleanup)
! 				EventTriggerEndCompleteQuery();
! 		}
! 	}
! }
! 
! /*
!  * The "Slow" variant of Process Utility is only concerned with statements
!  * supported by the Event Triggers facility.
!  */
! void
! standard_ProcessSlowUtility(Node *parsetree,
! 							const char *queryString,
! 							ParamListInfo params,
! 							DestReceiver *dest,
! 							char *completionTag,
! 							ProcessUtilityContext context)
! {
! 	bool		isTopLevel = (context == PROCESS_UTILITY_TOPLEVEL);
! 	bool		isCompleteQuery = (context <= PROCESS_UTILITY_QUERY);
! 	bool		done = true;
! 
! 	check_xact_readonly(parsetree);
! 
! 	if (completionTag)
! 		completionTag[0] = '\0';
! 
! 	/*
! 	 * A first switch for "special" cases, where we might not want to always
! 	 * prepare for Event Trigger mechanism.
! 	 */
! 	switch (nodeTag(parsetree))
! 	{
! 		case T_CreateStmt:
! 		case T_CreateForeignTableStmt:
! 			{
! 				List	   *stmts;
! 				ListCell   *l;
! 				Oid			relOid;
! 
! 				if (isCompleteQuery)
! 					EventTriggerDDLCommandStart(parsetree);
! 
! 				/* Run parse analysis ... */
! 				stmts = transformCreateStmt((CreateStmt *) parsetree,
! 											queryString);
! 
! 				/* ... and do it */
! 				foreach(l, stmts)
! 				{
! 					Node	   *stmt = (Node *) lfirst(l);
! 
! 					if (IsA(stmt, CreateStmt))
! 					{
! 						Datum		toast_options;
! 						static char *validnsps[] = HEAP_RELOPT_NAMESPACES;
! 
! 						/* Create the table itself */
! 						relOid = DefineRelation((CreateStmt *) stmt,
! 												RELKIND_RELATION,
! 												InvalidOid);
! 
! 						/*
! 						 * Let AlterTableCreateToastTable decide if this one
! 						 * needs a secondary relation too.
! 						 */
! 						CommandCounterIncrement();
! 
! 						/* parse and validate reloptions for the toast table */
! 						toast_options = transformRelOptions((Datum) 0,
! 											  ((CreateStmt *) stmt)->options,
! 															"toast",
! 															validnsps,
! 															true, false);
! 						(void) heap_reloptions(RELKIND_TOASTVALUE, toast_options,
! 											   true);
! 
! 						AlterTableCreateToastTable(relOid, toast_options);
! 					}
! 					else if (IsA(stmt, CreateForeignTableStmt))
! 					{
! 						/* Create the table itself */
! 						relOid = DefineRelation((CreateStmt *) stmt,
! 												RELKIND_FOREIGN_TABLE,
! 												InvalidOid);
! 						CreateForeignTable((CreateForeignTableStmt *) stmt,
! 										   relOid);
! 					}
! 					else
! 					{
! 						/* Recurse for anything else */
! 						ProcessUtility(stmt,
! 									   queryString,
! 									   params,
! 									   None_Receiver,
! 									   NULL,
! 									   PROCESS_UTILITY_GENERATED);
! 					}
! 
! 					/* Need CCI between commands */
! 					if (lnext(l) != NULL)
! 						CommandCounterIncrement();
! 				}
! 
! 				if (isCompleteQuery)
! 				{
! 					EventTriggerSQLDrop(parsetree);
! 					EventTriggerDDLCommandEnd(parsetree);
! 				}
! 			}
! 			break;
! 
! 		case T_DropStmt:
! 			{
! 				DropStmt   *stmt = (DropStmt *) parsetree;
! 
! 				if (isCompleteQuery
! 					&& EventTriggerSupportsObjectType(stmt->removeType))
! 					EventTriggerDDLCommandStart(parsetree);
! 
! 				switch (stmt->removeType)
! 				{
! 					case OBJECT_INDEX:
! 						if (stmt->concurrent)
! 							PreventTransactionChain(isTopLevel,
! 													"DROP INDEX CONCURRENTLY");
! 						/* fall through */
! 
! 					case OBJECT_TABLE:
! 					case OBJECT_SEQUENCE:
! 					case OBJECT_VIEW:
! 					case OBJECT_MATVIEW:
! 					case OBJECT_FOREIGN_TABLE:
! 						RemoveRelations((DropStmt *) parsetree);
! 						break;
! 					default:
! 						RemoveObjects((DropStmt *) parsetree);
! 						break;
! 				}
! 
! 				if (isCompleteQuery
! 					&& EventTriggerSupportsObjectType(stmt->removeType))
! 				{
! 					EventTriggerSQLDrop(parsetree);
! 					EventTriggerDDLCommandEnd(parsetree);
! 				}
! 
! 				break;
! 			}
! 
! 			/* event trigger support has already been checked */
! 		case T_RenameStmt:
! 			{
! 				RenameStmt *stmt = (RenameStmt *) parsetree;
! 
! 				EventTriggerDDLCommandStart(parsetree);
! 
! 				ExecRenameStmt(stmt);
! 
! 				EventTriggerSQLDrop(parsetree);
! 				EventTriggerDDLCommandEnd(parsetree);
! 				break;
! 			}
! 
! 			/* event trigger support has already been checked */
! 		case T_AlterObjectSchemaStmt:
! 			{
! 				AlterObjectSchemaStmt  *stmt = (AlterObjectSchemaStmt *) parsetree;
! 
! 				EventTriggerDDLCommandStart(parsetree);
! 
! 				ExecAlterObjectSchemaStmt(stmt);
! 
! 				EventTriggerSQLDrop(parsetree);
! 				EventTriggerDDLCommandEnd(parsetree);
! 				break;
! 			}
! 
! 			/* event trigger support has already been checked */
! 		case T_AlterOwnerStmt:
! 			{
! 				AlterOwnerStmt  *stmt = (AlterOwnerStmt *) parsetree;
! 
! 				EventTriggerDDLCommandStart(parsetree);
! 
! 				ExecAlterOwnerStmt(stmt);
! 
! 				EventTriggerSQLDrop(parsetree);
! 				EventTriggerDDLCommandEnd(parsetree);
! 				break;
! 			}
! 
! 		case T_AlterTableStmt:
! 			{
! 				AlterTableStmt *atstmt = (AlterTableStmt *) parsetree;
! 				Oid			relid;
! 				List	   *stmts;
! 				ListCell   *l;
! 				LOCKMODE	lockmode;
! 
! 				if (isCompleteQuery)
! 					EventTriggerDDLCommandStart(parsetree);
! 
! 				/*
! 				 * Figure out lock mode, and acquire lock.	This also does
! 				 * basic permissions checks, so that we won't wait for a lock
! 				 * on (for example) a relation on which we have no
! 				 * permissions.
! 				 */
! 				lockmode = AlterTableGetLockLevel(atstmt->cmds);
! 				relid = AlterTableLookupRelation(atstmt, lockmode);
! 
! 				if (OidIsValid(relid))
! 				{
  					/* Run parse analysis ... */
  					stmts = transformAlterTableStmt(atstmt, queryString);
  
***************
*** 961,980 **** standard_ProcessUtility(Node *parsetree,
  			}
  			break;
  
- 		case T_GrantStmt:
- 			ExecuteGrantStmt((GrantStmt *) parsetree);
- 			break;
- 
- 		case T_GrantRoleStmt:
- 			GrantRole((GrantRoleStmt *) parsetree);
- 			break;
- 
- 		case T_AlterDefaultPrivilegesStmt:
- 			InvokeDDLCommandEventTriggers(
- 				parsetree,
- 				ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree));
- 			break;
- 
  			/*
  			 * **************** object creation / destruction *****************
  			 */
--- 1178,1183 ----
***************
*** 1010,1076 **** standard_ProcessUtility(Node *parsetree,
  					case OBJECT_TSTEMPLATE:
  						Assert(stmt->args == NIL);
  						DefineTSTemplate(stmt->defnames, stmt->definition);
! 						break;
! 					case OBJECT_TSCONFIGURATION:
! 						Assert(stmt->args == NIL);
! 						DefineTSConfiguration(stmt->defnames, stmt->definition);
! 						break;
! 					case OBJECT_COLLATION:
! 						Assert(stmt->args == NIL);
! 						DefineCollation(stmt->defnames, stmt->definition);
! 						break;
! 					default:
! 						elog(ERROR, "unrecognized define stmt type: %d",
! 							 (int) stmt->kind);
! 						break;
! 				}
! 			}
! 			break;
! 
! 		case T_CompositeTypeStmt:		/* CREATE TYPE (composite) */
! 			{
! 				CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
! 
! 				InvokeDDLCommandEventTriggers(
! 					parsetree,
! 					DefineCompositeType(stmt->typevar, stmt->coldeflist));
! 			}
! 			break;
! 
! 		case T_CreateEnumStmt:	/* CREATE TYPE AS ENUM */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineEnum((CreateEnumStmt *) parsetree));
! 			break;
! 
! 		case T_CreateRangeStmt:	/* CREATE TYPE AS RANGE */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineRange((CreateRangeStmt *) parsetree));
! 			break;
! 
! 		case T_AlterEnumStmt:	/* ALTER TYPE (enum) */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterEnum((AlterEnumStmt *) parsetree, isTopLevel));
! 			break;
! 
! 		case T_ViewStmt:		/* CREATE VIEW */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineView((ViewStmt *) parsetree, queryString));
! 			break;
! 
! 		case T_CreateFunctionStmt:		/* CREATE FUNCTION */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				CreateFunction((CreateFunctionStmt *) parsetree, queryString));
! 			break;
! 
! 		case T_AlterFunctionStmt:		/* ALTER FUNCTION */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterFunction((AlterFunctionStmt *) parsetree));
  			break;
  
  		case T_IndexStmt:		/* CREATE INDEX */
--- 1213,1233 ----
  					case OBJECT_TSTEMPLATE:
  						Assert(stmt->args == NIL);
  						DefineTSTemplate(stmt->defnames, stmt->definition);
! 						break;
! 					case OBJECT_TSCONFIGURATION:
! 						Assert(stmt->args == NIL);
! 						DefineTSConfiguration(stmt->defnames, stmt->definition);
! 						break;
! 					case OBJECT_COLLATION:
! 						Assert(stmt->args == NIL);
! 						DefineCollation(stmt->defnames, stmt->definition);
! 						break;
! 					default:
! 						elog(ERROR, "unrecognized define stmt type: %d",
! 							 (int) stmt->kind);
! 						break;
! 				}
! 			}
  			break;
  
  		case T_IndexStmt:		/* CREATE INDEX */
***************
*** 1098,1421 **** standard_ProcessUtility(Node *parsetree,
  			}
  			break;
  
! 		case T_RuleStmt:		/* CREATE RULE */
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineRule((RuleStmt *) parsetree, queryString));
! 			break;
! 
! 		case T_CreateSeqStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineSequence((CreateSeqStmt *) parsetree));
! 			break;
! 
! 		case T_AlterSeqStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterSequence((AlterSeqStmt *) parsetree));
! 			break;
! 
! 		case T_DoStmt:
! 			ExecuteDoStmt((DoStmt *) parsetree);
  			break;
  
! 		case T_CreatedbStmt:
! 			/* no event triggers for global objects */
! 			PreventTransactionChain(isTopLevel, "CREATE DATABASE");
! 			createdb((CreatedbStmt *) parsetree);
! 			break;
  
! 		case T_AlterDatabaseStmt:
! 			/* no event triggers for global objects */
! 			AlterDatabase((AlterDatabaseStmt *) parsetree, isTopLevel);
! 			break;
  
! 		case T_AlterDatabaseSetStmt:
! 			/* no event triggers for global objects */
! 			AlterDatabaseSet((AlterDatabaseSetStmt *) parsetree);
  			break;
  
! 		case T_DropdbStmt:
! 			{
! 				DropdbStmt *stmt = (DropdbStmt *) parsetree;
! 
! 				/* no event triggers for global objects */
! 				PreventTransactionChain(isTopLevel, "DROP DATABASE");
! 				dropdb(stmt->dbname, stmt->missing_ok);
! 			}
  			break;
  
! 			/* Query-level asynchronous notification */
! 		case T_NotifyStmt:
! 			{
! 				NotifyStmt *stmt = (NotifyStmt *) parsetree;
! 
! 				PreventCommandDuringRecovery("NOTIFY");
! 				Async_Notify(stmt->conditionname, stmt->payload);
! 			}
  			break;
  
! 		case T_ListenStmt:
! 			{
! 				ListenStmt *stmt = (ListenStmt *) parsetree;
! 
! 				PreventCommandDuringRecovery("LISTEN");
! 				CheckRestrictedOperation("LISTEN");
! 				Async_Listen(stmt->conditionname);
! 			}
  			break;
  
! 		case T_UnlistenStmt:
! 			{
! 				UnlistenStmt *stmt = (UnlistenStmt *) parsetree;
! 
! 				PreventCommandDuringRecovery("UNLISTEN");
! 				CheckRestrictedOperation("UNLISTEN");
! 				if (stmt->conditionname)
! 					Async_Unlisten(stmt->conditionname);
! 				else
! 					Async_UnlistenAll();
! 			}
  			break;
  
! 		case T_LoadStmt:
! 			{
! 				LoadStmt   *stmt = (LoadStmt *) parsetree;
! 
! 				closeAllVfds(); /* probably not necessary... */
! 				/* Allowed names are restricted if you're not superuser */
! 				load_file(stmt->filename, !superuser());
! 			}
  			break;
  
! 		case T_ClusterStmt:
! 			/* we choose to allow this during "read only" transactions */
! 			PreventCommandDuringRecovery("CLUSTER");
! 			cluster((ClusterStmt *) parsetree, isTopLevel);
  			break;
  
! 		case T_VacuumStmt:
! 			{
! 				VacuumStmt *stmt = (VacuumStmt *) parsetree;
! 
! 				/* we choose to allow this during "read only" transactions */
! 				PreventCommandDuringRecovery((stmt->options & VACOPT_VACUUM) ?
! 											 "VACUUM" : "ANALYZE");
! 				vacuum(stmt, InvalidOid, true, NULL, false, isTopLevel);
! 			}
  			break;
  
! 		case T_ExplainStmt:
! 			ExplainQuery((ExplainStmt *) parsetree, queryString, params, dest);
  			break;
  
! 		case T_CreateTableAsStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				ExecCreateTableAs((CreateTableAsStmt *) parsetree,
! 								  queryString, params, completionTag));
  			break;
  
! 		case T_RefreshMatViewStmt:
! 			if (isCompleteQuery)
! 				EventTriggerDDLCommandStart(parsetree);
! 			ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
! 								queryString, params, completionTag);
  			break;
  
! 		case T_VariableSetStmt:
! 			ExecSetVariableStmt((VariableSetStmt *) parsetree);
  			break;
  
! 		case T_VariableShowStmt:
  			{
! 				VariableShowStmt *n = (VariableShowStmt *) parsetree;
! 
! 				GetPGVariable(n->name, dest);
  			}
  			break;
  
! 		case T_DiscardStmt:
! 			/* should we allow DISCARD PLANS? */
! 			CheckRestrictedOperation("DISCARD");
! 			DiscardCommand((DiscardStmt *) parsetree, isTopLevel);
! 			break;
! 
! 		case T_CreateTrigStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				(void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
! 									 InvalidOid, InvalidOid, false));
  			break;
  
! 		case T_CreateEventTrigStmt:
! 			/* no event triggers on event triggers */
! 			CreateEventTrigger((CreateEventTrigStmt *) parsetree);
  			break;
  
! 		case T_AlterEventTrigStmt:
! 			/* no event triggers on event triggers */
! 			AlterEventTrigger((AlterEventTrigStmt *) parsetree);
  			break;
  
! 		case T_CreatePLangStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				CreateProceduralLanguage((CreatePLangStmt *) parsetree));
  			break;
  
! 			/*
! 			 * ******************************** DOMAIN statements ****
! 			 */
! 		case T_CreateDomainStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineDomain((CreateDomainStmt *) parsetree));
  			break;
  
! 			/*
! 			 * ******************************** ROLE statements ****
! 			 */
! 		case T_CreateRoleStmt:
! 			/* no event triggers for global objects */
! 			CreateRole((CreateRoleStmt *) parsetree);
  			break;
  
! 		case T_AlterRoleStmt:
! 			/* no event triggers for global objects */
! 			AlterRole((AlterRoleStmt *) parsetree);
  			break;
  
! 		case T_AlterRoleSetStmt:
! 			/* no event triggers for global objects */
! 			AlterRoleSet((AlterRoleSetStmt *) parsetree);
  			break;
  
! 		case T_DropRoleStmt:
! 			/* no event triggers for global objects */
! 			DropRole((DropRoleStmt *) parsetree);
  			break;
  
! 		case T_DropOwnedStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DropOwnedObjects((DropOwnedStmt *) parsetree));
  			break;
  
! 		case T_ReassignOwnedStmt:
! 			/* no event triggers for global objects */
! 			ReassignOwnedObjects((ReassignOwnedStmt *) parsetree);
  			break;
  
! 		case T_LockStmt:
! 
! 			/*
! 			 * Since the lock would just get dropped immediately, LOCK TABLE
! 			 * outside a transaction block is presumed to be user error.
! 			 */
! 			RequireTransactionChain(isTopLevel, "LOCK TABLE");
! 			LockTableCommand((LockStmt *) parsetree);
  			break;
  
! 		case T_ConstraintsSetStmt:
! 			AfterTriggerSetState((ConstraintsSetStmt *) parsetree);
  			break;
  
- 		case T_CheckPointStmt:
- 			if (!superuser())
- 				ereport(ERROR,
- 						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
- 						 errmsg("must be superuser to do CHECKPOINT")));
- 
  			/*
! 			 * You might think we should have a PreventCommandDuringRecovery()
! 			 * here, but we interpret a CHECKPOINT command during recovery as
! 			 * a request for a restartpoint instead. We allow this since it
! 			 * can be a useful way of reducing switchover time when using
! 			 * various forms of replication.
  			 */
! 			RequestCheckpoint(CHECKPOINT_IMMEDIATE | CHECKPOINT_WAIT |
! 							  (RecoveryInProgress() ? 0 : CHECKPOINT_FORCE));
  			break;
  
! 		case T_ReindexStmt:
! 			{
! 				ReindexStmt *stmt = (ReindexStmt *) parsetree;
! 
! 				/* we choose to allow this during "read only" transactions */
! 				PreventCommandDuringRecovery("REINDEX");
! 				switch (stmt->kind)
! 				{
! 					case OBJECT_INDEX:
! 						ReindexIndex(stmt->relation);
! 						break;
! 					case OBJECT_TABLE:
! 					case OBJECT_MATVIEW:
! 						ReindexTable(stmt->relation);
! 						break;
! 					case OBJECT_DATABASE:
! 
! 						/*
! 						 * This cannot run inside a user transaction block; if
! 						 * we were inside a transaction, then its commit- and
! 						 * start-transaction-command calls would not have the
! 						 * intended effect!
! 						 */
! 						PreventTransactionChain(isTopLevel,
! 												"REINDEX DATABASE");
! 						ReindexDatabase(stmt->name,
! 										stmt->do_system, stmt->do_user);
! 						break;
! 					default:
! 						elog(ERROR, "unrecognized object type: %d",
! 							 (int) stmt->kind);
! 						break;
! 				}
! 				break;
! 			}
  			break;
  
  		case T_CreateConversionStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				CreateConversionCommand((CreateConversionStmt *) parsetree));
  			break;
  
  		case T_CreateCastStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				CreateCast((CreateCastStmt *) parsetree));
  			break;
  
  		case T_CreateOpClassStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineOpClass((CreateOpClassStmt *) parsetree));
  			break;
  
  		case T_CreateOpFamilyStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				DefineOpFamily((CreateOpFamilyStmt *) parsetree));
  			break;
  
  		case T_AlterOpFamilyStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterOpFamily((AlterOpFamilyStmt *) parsetree));
  			break;
  
  		case T_AlterTSDictionaryStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterTSDictionary((AlterTSDictionaryStmt *) parsetree));
  			break;
  
  		case T_AlterTSConfigurationStmt:
! 			InvokeDDLCommandEventTriggers(
! 				parsetree,
! 				AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree));
  			break;
  
  		default:
--- 1255,1441 ----
  			}
  			break;
  
! 		default:
! 			/* the case is handled in the next switch */
! 			done = false;
  			break;
+ 	}
  
! 	if (done)
! 		return;
  
! 	/*
! 	 * Now all remaining cases are the simple straight Event Trigger Supported
! 	 * Statements case.
! 	 */
! 	if (isCompleteQuery)
! 		EventTriggerDDLCommandStart(parsetree);
  
! 	switch (nodeTag(parsetree))
! 	{
! 			/*
! 			 * relation and attribute manipulation
! 			 */
! 		case T_CreateSchemaStmt:
! 			CreateSchemaCommand((CreateSchemaStmt *) parsetree, queryString);
  			break;
  
! 		case T_CreateExtensionStmt:
! 			CreateExtension((CreateExtensionStmt *) parsetree);
  			break;
  
! 		case T_AlterExtensionStmt:
! 			ExecAlterExtensionStmt((AlterExtensionStmt *) parsetree);
  			break;
  
! 		case T_AlterExtensionContentsStmt:
! 			ExecAlterExtensionContentsStmt((AlterExtensionContentsStmt *) parsetree);
  			break;
  
! 		case T_CreateFdwStmt:
! 			CreateForeignDataWrapper((CreateFdwStmt *) parsetree);
  			break;
  
! 		case T_AlterFdwStmt:
! 			AlterForeignDataWrapper((AlterFdwStmt *) parsetree);
  			break;
  
! 		case T_CreateForeignServerStmt:
! 			CreateForeignServer((CreateForeignServerStmt *) parsetree);
  			break;
  
! 		case T_AlterForeignServerStmt:
! 			AlterForeignServer((AlterForeignServerStmt *) parsetree);
  			break;
  
! 		case T_CreateUserMappingStmt:
! 			CreateUserMapping((CreateUserMappingStmt *) parsetree);
  			break;
  
! 		case T_AlterUserMappingStmt:
! 			AlterUserMapping((AlterUserMappingStmt *) parsetree);
  			break;
  
! 		case T_DropUserMappingStmt:
! 			RemoveUserMapping((DropUserMappingStmt *) parsetree);
  			break;
  
! 		case T_AlterDefaultPrivilegesStmt:
! 			ExecAlterDefaultPrivilegesStmt((AlterDefaultPrivilegesStmt *) parsetree);
  			break;
  
! 		case T_CompositeTypeStmt:		/* CREATE TYPE (composite) */
  			{
! 				CompositeTypeStmt *stmt = (CompositeTypeStmt *) parsetree;
! 				DefineCompositeType(stmt->typevar, stmt->coldeflist);
  			}
  			break;
  
! 		case T_CreateEnumStmt:	/* CREATE TYPE AS ENUM */
! 			DefineEnum((CreateEnumStmt *) parsetree);
  			break;
  
! 		case T_CreateRangeStmt:	/* CREATE TYPE AS RANGE */
! 			DefineRange((CreateRangeStmt *) parsetree);
  			break;
  
! 		case T_AlterEnumStmt:	/* ALTER TYPE (enum) */
! 			AlterEnum((AlterEnumStmt *) parsetree, isTopLevel);
  			break;
  
! 		case T_ViewStmt:		/* CREATE VIEW */
! 			DefineView((ViewStmt *) parsetree, queryString);
  			break;
  
! 		case T_CreateFunctionStmt:		/* CREATE FUNCTION */
! 			CreateFunction((CreateFunctionStmt *) parsetree, queryString);
  			break;
  
! 		case T_AlterFunctionStmt:		/* ALTER FUNCTION */
! 			AlterFunction((AlterFunctionStmt *) parsetree);
  			break;
  
! 		case T_RuleStmt:		/* CREATE RULE */
! 			DefineRule((RuleStmt *) parsetree, queryString);
  			break;
  
! 		case T_CreateSeqStmt:
! 			DefineSequence((CreateSeqStmt *) parsetree);
  			break;
  
! 		case T_AlterSeqStmt:
! 			AlterSequence((AlterSeqStmt *) parsetree);
  			break;
  
! 		case T_CreateTableAsStmt:
! 			ExecCreateTableAs((CreateTableAsStmt *) parsetree,
! 							  queryString, params, completionTag);
  			break;
  
! 		case T_RefreshMatViewStmt:
! 			ExecRefreshMatView((RefreshMatViewStmt *) parsetree,
! 							   queryString, params, completionTag);
  			break;
  
! 		case T_CreateTrigStmt:
! 			(void) CreateTrigger((CreateTrigStmt *) parsetree, queryString,
! 								 InvalidOid, InvalidOid, false);
  			break;
  
! 		case T_CreatePLangStmt:
! 			CreateProceduralLanguage((CreatePLangStmt *) parsetree);
  			break;
  
  			/*
! 			 * ******************************** DOMAIN statements ****
  			 */
! 		case T_CreateDomainStmt:
! 			DefineDomain((CreateDomainStmt *) parsetree);
  			break;
  
! 		case T_DropOwnedStmt:
! 			DropOwnedObjects((DropOwnedStmt *) parsetree);
  			break;
  
  		case T_CreateConversionStmt:
! 			CreateConversionCommand((CreateConversionStmt *) parsetree);
  			break;
  
  		case T_CreateCastStmt:
! 			CreateCast((CreateCastStmt *) parsetree);
  			break;
  
  		case T_CreateOpClassStmt:
! 			DefineOpClass((CreateOpClassStmt *) parsetree);
  			break;
  
  		case T_CreateOpFamilyStmt:
! 			DefineOpFamily((CreateOpFamilyStmt *) parsetree);
  			break;
  
  		case T_AlterOpFamilyStmt:
! 			AlterOpFamily((AlterOpFamilyStmt *) parsetree);
  			break;
  
  		case T_AlterTSDictionaryStmt:
! 			AlterTSDictionary((AlterTSDictionaryStmt *) parsetree);
  			break;
  
  		case T_AlterTSConfigurationStmt:
! 			AlterTSConfiguration((AlterTSConfigurationStmt *) parsetree);
! 			break;
! 
! 		case T_CreateStmt:
! 		case T_CreateForeignTableStmt:
! 		case T_DropStmt:
! 		case T_RenameStmt:
! 		case T_AlterObjectSchemaStmt:
! 		case T_AlterOwnerStmt:
! 		case T_AlterTableStmt:
! 		case T_AlterDomainStmt:
! 		case T_DefineStmt:
! 		case T_IndexStmt:
! 			/* no ERROR, we just handled them in the previous switch above */
  			break;
  
  		default:
***************
*** 1424,1430 **** standard_ProcessUtility(Node *parsetree,
  			break;
  	}
  
! 	UTILITY_END_QUERY();
  }
  
  /*
--- 1444,1455 ----
  			break;
  	}
  
! 	if (isCompleteQuery)
! 	{
! 		EventTriggerSQLDrop(parsetree);
! 		EventTriggerDDLCommandEnd(parsetree);
! 	}
! 	return;
  }
  
  /*
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to