diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8b6b5bbaaab4a..86e5e8ac02059 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -205,6 +205,8 @@ static void log_disconnections(int code, Datum arg); static void enable_statement_timeout(void); static void disable_statement_timeout(void); +/* Hooks for plugins to get control at end of start_xact_command() */ +XactCommandStart_hook_type start_xact_command_hook = NULL; /* ---------------------------------------------------------------- * routines to obtain user input @@ -1025,6 +1027,13 @@ exec_simple_query(const char *query_string) */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* * Zap any pre-existing unnamed statement. (While not strictly necessary, * it seems best to define simple-Query mode as if it used the unnamed @@ -1118,6 +1127,13 @@ exec_simple_query(const char *query_string) /* Make sure we are in a transaction command */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* * If using an implicit transaction block, and we're not already in a * transaction block, start an implicit block to force this statement @@ -1397,6 +1413,13 @@ exec_parse_message(const char *query_string, /* string to execute */ */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* * Switch to appropriate context for constructing parsetrees. * @@ -1661,6 +1684,13 @@ exec_bind_message(StringInfo input_message) */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* Switch back to message context */ MemoryContextSwitchTo(MessageContext); @@ -2154,6 +2184,13 @@ exec_execute_message(const char *portal_name, long max_rows) */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* * If we re-issue an Execute protocol request against an existing portal, * then we are only fetching more rows rather than completely re-executing @@ -2560,6 +2597,13 @@ exec_describe_statement_message(const char *stmt_name) */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* Switch back to message context */ MemoryContextSwitchTo(MessageContext); @@ -2654,6 +2698,13 @@ exec_describe_portal_message(const char *portal_name) */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* Switch back to message context */ MemoryContextSwitchTo(MessageContext); @@ -4619,6 +4670,13 @@ PostgresMain(const char *dbname, const char *username) /* start an xact for this function invocation */ start_xact_command(); + /* + * Now give loadable modules a chance to execute code + * before a transaction command is processed. + */ + if (start_xact_command_hook) + (*start_xact_command_hook) (); + /* * Note: we may at this point be inside an aborted * transaction. We can't throw error for that until we've diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h index f9a6882ecb0ab..349ea6c014601 100644 --- a/src/include/tcop/pquery.h +++ b/src/include/tcop/pquery.h @@ -48,4 +48,8 @@ extern bool PlannedStmtRequiresSnapshot(struct PlannedStmt *pstmt); extern void EnsurePortalSnapshotExists(void); +/* Hook for plugins to get control in start_xact_command() and finish_xact_command() */ +typedef void (*XactCommandStart_hook_type) (void); +extern PGDLLIMPORT XactCommandStart_hook_type start_xact_command_hook; + #endif /* PQUERY_H */ diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list index 4fb746930aa09..681c2c5422185 100644 --- a/src/tools/pgindent/typedefs.list +++ b/src/tools/pgindent/typedefs.list @@ -3052,6 +3052,7 @@ XPVIV XPVMG XactCallback XactCallbackItem +XactCommandStart_hook_type XactEvent XactLockTableWaitInfo XidBoundsViolation