On Thu, Nov 2, 2017 at 5:42 AM, Aleksandr Parfenov < a.parfe...@postgrespro.ru> wrote: > > The following review has been posted through the commitfest application: > make installcheck-world: not tested > Implements feature: not tested > Spec compliant: not tested > Documentation: not tested > > Hi, > > Unfortunately, patches 0001 and 0002 don't apply to current master. > > The new status of this patch is: Waiting on Author >
Thanks for your review. Rebased versions attached. Regards, -- Fabrízio de Royes Mello Consultoria/Coaching PostgreSQL >> Timbira: http://www.timbira.com.br >> Blog: http://fabriziomello.github.io >> Linkedin: http://br.linkedin.com/in/fabriziomello >> Twitter: http://twitter.com/fabriziomello >> Github: http://github.com/fabriziomello
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 2c7260e..24346fb 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -169,6 +169,9 @@ static ProcSignalReason RecoveryConflictReason; static MemoryContext row_description_context = NULL; static StringInfoData row_description_buf; +/* Hook for plugins to get control at start of session */ +session_start_hook_type session_start_hook = NULL; + /* ---------------------------------------------------------------- * decls for routines only used in this file * ---------------------------------------------------------------- @@ -3857,6 +3860,9 @@ PostgresMain(int argc, char *argv[], if (!IsUnderPostmaster) PgStartTime = GetCurrentTimestamp(); + if (session_start_hook) + (*session_start_hook) (dbname, username); + /* * POSTGRES main processing loop begins here * diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index f8c535c..d349592 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -35,6 +35,11 @@ extern PGDLLIMPORT const char *debug_query_string; extern int max_stack_depth; extern int PostAuthDelay; +/* Hook for plugins to get control at start of session */ +typedef void (*session_start_hook_type) (const char *dbname, + const char *username); +extern PGDLLIMPORT session_start_hook_type session_start_hook; + /* GUC-configurable parameters */ typedef enum
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 24346fb..0dbbd7b 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -169,9 +169,9 @@ static ProcSignalReason RecoveryConflictReason; static MemoryContext row_description_context = NULL; static StringInfoData row_description_buf; -/* Hook for plugins to get control at start of session */ +/* Hook for plugins to get control at start or end of session */ session_start_hook_type session_start_hook = NULL; - +session_end_hook_type session_end_hook = NULL; /* ---------------------------------------------------------------- * decls for routines only used in this file * ---------------------------------------------------------------- @@ -196,6 +196,7 @@ static void drop_unnamed_stmt(void); static void log_disconnections(int code, Datum arg); static void enable_statement_timeout(void); static void disable_statement_timeout(void); +static void do_session_end_hook(int code, Datum arg); /* ---------------------------------------------------------------- @@ -3864,6 +3865,12 @@ PostgresMain(int argc, char *argv[], (*session_start_hook) (dbname, username); /* + * Setup handler to session end hook + */ + if (IsUnderPostmaster) + on_proc_exit(do_session_end_hook, 0); + + /* * POSTGRES main processing loop begins here * * If an exception is encountered, processing resumes here so we abort the @@ -4615,3 +4622,15 @@ disable_statement_timeout(void) stmt_timeout_active = false; } } + +/* + * on_proc_exit handler to call session end hook + */ +static void +do_session_end_hook(int code, Datum arg) +{ + Port *port = MyProcPort; + + if (session_end_hook) + (*session_end_hook) (port->database_name, port->user_name); +} \ No newline at end of file diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index d349592..b7fb8c3 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -35,10 +35,14 @@ extern PGDLLIMPORT const char *debug_query_string; extern int max_stack_depth; extern int PostAuthDelay; -/* Hook for plugins to get control at start of session */ +/* Hook for plugins to get control at start and end of session */ typedef void (*session_start_hook_type) (const char *dbname, const char *username); +typedef void (*session_end_hook_type) (const char *dbname, + const char *username); + extern PGDLLIMPORT session_start_hook_type session_start_hook; +extern PGDLLIMPORT session_end_hook_type session_end_hook; /* GUC-configurable parameters */
diff --git a/src/test/modules/Makefile b/src/test/modules/Makefile index b7ed0af..a3c8c1e 100644 --- a/src/test/modules/Makefile +++ b/src/test/modules/Makefile @@ -11,6 +11,7 @@ SUBDIRS = \ snapshot_too_old \ test_ddl_deparse \ test_extensions \ + test_session_hooks \ test_parser \ test_pg_dump \ test_rbtree \ diff --git a/src/test/modules/test_session_hooks/.gitignore b/src/test/modules/test_session_hooks/.gitignore new file mode 100644 index 0000000..5dcb3ff --- /dev/null +++ b/src/test/modules/test_session_hooks/.gitignore @@ -0,0 +1,4 @@ +# Generated subdirectories +/log/ +/results/ +/tmp_check/ diff --git a/src/test/modules/test_session_hooks/Makefile b/src/test/modules/test_session_hooks/Makefile new file mode 100644 index 0000000..9cabd3f --- /dev/null +++ b/src/test/modules/test_session_hooks/Makefile @@ -0,0 +1,26 @@ +# src/test/modules/test_session_hooks/Makefile + +MODULES = test_session_hooks +PGFILEDESC = "test_session_hooks - Test session hooks with an extension" + +EXTENSION = test_session_hooks +DATA = test_session_hooks--1.0.sql + +REGRESS = test_session_hooks +REGRESS_OPTS = --temp-config=$(top_srcdir)/src/test/modules/test_session_hooks/session_hooks.conf + +ifdef USE_PGXS +PG_CONFIG = pg_config +PGXS := $(shell $(PG_CONFIG) --pgxs) +include $(PGXS) +else +subdir = src/test/modules/test_session_hooks +top_builddir = ../../../.. +include $(top_builddir)/src/Makefile.global +include $(top_srcdir)/contrib/contrib-global.mk +endif + +check: prove-check + +prove-check: + $(prove_check) diff --git a/src/test/modules/test_session_hooks/README b/src/test/modules/test_session_hooks/README new file mode 100644 index 0000000..e6c78b8 --- /dev/null +++ b/src/test/modules/test_session_hooks/README @@ -0,0 +1,2 @@ +test_pg_dump is an extension explicitly to test pg_dump when +extensions are present in the system. diff --git a/src/test/modules/test_session_hooks/expected/test_session_hooks.out b/src/test/modules/test_session_hooks/expected/test_session_hooks.out new file mode 100644 index 0000000..602819c --- /dev/null +++ b/src/test/modules/test_session_hooks/expected/test_session_hooks.out @@ -0,0 +1,10 @@ +SHOW test_session_hooks.message; +ERROR: unrecognized configuration parameter "test_session_hooks.message" +CREATE DATABASE test; +\c test +SHOW test_session_hooks.message; + test_session_hooks.message +---------------------------- + Session Start Hook Handled +(1 row) + diff --git a/src/test/modules/test_session_hooks/session_hooks.conf b/src/test/modules/test_session_hooks/session_hooks.conf new file mode 100644 index 0000000..a66e60e --- /dev/null +++ b/src/test/modules/test_session_hooks/session_hooks.conf @@ -0,0 +1 @@ +shared_preload_libraries = 'test_session_hooks' diff --git a/src/test/modules/test_session_hooks/sql/test_session_hooks.sql b/src/test/modules/test_session_hooks/sql/test_session_hooks.sql new file mode 100644 index 0000000..b75f2f8 --- /dev/null +++ b/src/test/modules/test_session_hooks/sql/test_session_hooks.sql @@ -0,0 +1,4 @@ +SHOW test_session_hooks.message; +CREATE DATABASE test; +\c test +SHOW test_session_hooks.message; diff --git a/src/test/modules/test_session_hooks/t/001_base.pl b/src/test/modules/test_session_hooks/t/001_base.pl new file mode 100644 index 0000000..442fb8a --- /dev/null +++ b/src/test/modules/test_session_hooks/t/001_base.pl @@ -0,0 +1,24 @@ +# Test session end hook log messages + +use strict; +use warnings; + +use TestLib; +use Test::More tests => 2; +use PostgresNode; + +my $node = get_new_node('main'); +$node->init; +$node->append_conf( + 'postgresql.conf', + qq{shared_preload_libraries = 'test_session_hooks'} +); +$node->start; +$node->safe_psql('postgres', 'CREATE DATABASE test'); +my ($ret, $stdout, $stderr) = $node->psql('test','show test_session_hooks.message'); + +# check session start hook +like($stdout, qr/Session Start Hook Handled/, 'error during session start hook'); + +# check session end hook +like(slurp_file($node->logfile()), qr/Session End Hook Handled/, 'error during session end hook'); diff --git a/src/test/modules/test_session_hooks/test_session_hooks--1.0.sql b/src/test/modules/test_session_hooks/test_session_hooks--1.0.sql new file mode 100644 index 0000000..16bcee9 --- /dev/null +++ b/src/test/modules/test_session_hooks/test_session_hooks--1.0.sql @@ -0,0 +1,4 @@ +/* src/test/modules/test_hook_session/test_hook_session--1.0.sql */ + +-- complain if script is sourced in psql, rather than via CREATE EXTENSION +\echo Use "CREATE EXTENSION test_hook_session" to load this file. \quit diff --git a/src/test/modules/test_session_hooks/test_session_hooks.c b/src/test/modules/test_session_hooks/test_session_hooks.c new file mode 100644 index 0000000..ff63b83 --- /dev/null +++ b/src/test/modules/test_session_hooks/test_session_hooks.c @@ -0,0 +1,80 @@ +/* ------------------------------------------------------------------------- + * + * test_session_hooks.c + * Code for testing SESSION hooks. + * + * Copyright (c) 2010-2017, PostgreSQL Global Development Group + * + * IDENTIFICATION + * src/test/modules/test_session_hooks/test_session_hooks.c + * + * ------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/xact.h" +#include "executor/spi.h" +#include "tcop/tcopprot.h" + +PG_MODULE_MAGIC; + +void _PG_init(void); +void _PG_fini(void); + +/* Original Hook */ +static session_start_hook_type prev_session_start_hook = NULL; +static session_end_hook_type prev_session_end_hook = NULL; + +/* sample session start hook function */ +static void +sample_session_start_hook(const char *dbname, const char *username) +{ + if (prev_session_start_hook) + prev_session_start_hook(dbname, username); + + if (!strcmp(dbname, "test")) + { + StartTransactionCommand(); + SPI_connect(); + SPI_exec("SET test_session_hooks.message TO 'Session Start Hook Handled'", 1); + SPI_finish(); + CommitTransactionCommand(); + } +} + +/* sample sessoin end hook function */ +static void +sample_session_end_hook(const char *dbname, const char *username) +{ + if (prev_session_end_hook) + prev_session_end_hook(dbname, username); + + if (!strcmp(dbname, "test")) + elog(LOG, "Session End Hook Handled"); +} + +/* + * Module Load Callback + */ +void +_PG_init(void) +{ + /* Save Hooks for Unload */ + prev_session_start_hook = session_start_hook; + prev_session_end_hook = session_end_hook; + + /* Set New Hooks */ + session_start_hook = sample_session_start_hook; + session_end_hook = sample_session_end_hook; +} + +/* + * Module Unload Callback + */ +void +_PG_fini(void) +{ + /* Uninstall Hooks */ + session_start_hook = prev_session_start_hook; + session_end_hook = prev_session_end_hook; +} diff --git a/src/test/modules/test_session_hooks/test_session_hooks.control b/src/test/modules/test_session_hooks/test_session_hooks.control new file mode 100644 index 0000000..7d7ef9f --- /dev/null +++ b/src/test/modules/test_session_hooks/test_session_hooks.control @@ -0,0 +1,3 @@ +comment = 'Test start/end hook session with an extension' +default_version = '1.0' +relocatable = true
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers