Hi,
I occasionally need to perform some action whenever a user connects, and
there's nothing like an "AFTER LOGON" trigger (available in some other
databases).
Is there any particular reason why there's not a "backend start hook",
executed right after a backend is initialized? I've tried a very simple
PoC (basically just a new hook definition, called from PostgresMain(),
see the after-logon-hook.diff (and a simple module that uses it is in
logon.c).
This obviously is not a complete patch or something, but is there a good
reason why this is a stupid idea?
Obviously this is a bit low-level approach, as most of the time the
triggers are implemented in a PL. But who says you can't call a PL from
the C module ...
Tomas
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
new file mode 100644
index 976a832..35f1926
*** a/src/backend/tcop/postgres.c
--- b/src/backend/tcop/postgres.c
*************** int max_stack_depth = 100;
*** 104,110 ****
/* wait N seconds to allow attach from a debugger */
int PostAuthDelay = 0;
!
/* ----------------
* private variables
--- 104,110 ----
/* wait N seconds to allow attach from a debugger */
int PostAuthDelay = 0;
! backend_startup_hook_type backend_startup_hook = NULL;
/* ----------------
* private variables
*************** PostgresMain(int argc, char *argv[], con
*** 3750,3755 ****
--- 3750,3769 ----
if (!ignore_till_sync)
send_ready_for_query = true; /* initially, or after error */
+ if (backend_startup_hook != NULL)
+ {
+ PG_TRY();
+ {
+ backend_startup_hook(MyProcPid, MyDatabaseId, dbname,
username);
+ }
+ PG_CATCH();
+ {
+ elog(FATAL, "Error calling after-logon trigger");
+ proc_exit(0);
+ }
+ PG_END_TRY();
+ }
+
/*
* Non-error queries loop here.
*/
diff --git a/src/include/miscadmin.h b/src/include/miscadmin.h
new file mode 100644
index 9d19417..3971268
*** a/src/include/miscadmin.h
--- b/src/include/miscadmin.h
*************** extern bool is_authenticated_user_replic
*** 388,391 ****
--- 388,396 ----
extern bool BackupInProgress(void);
extern void CancelBackup(void);
+ typedef void (*backend_startup_hook_type) (pid_t pid, Oid databaseOid,
+ const char * dbname, const char *
username);
+
+ extern backend_startup_hook_type backend_startup_hook;
+
#endif /* MISCADMIN_H */
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include <limits.h>
#include "postgres.h"
#include "utils/array.h"
#include "utils/lsyscache.h"
#include "utils/numeric.h"
#include "utils/builtins.h"
#include "utils/memutils.h"
#include "catalog/pg_type.h"
#include "miscadmin.h"
static backend_startup_hook_type prev_backend_startup_hook = NULL;
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
void _PG_init(void);
void _PG_fini(void);
static
void my_startup_hook (pid_t pid, Oid databaseOid,
const char * dbname, const char * username);
/*
* Module load callback
*/
void
_PG_init(void)
{
prev_backend_startup_hook = backend_startup_hook;
backend_startup_hook = &my_startup_hook;
}
void
_PG_fini(void)
{
backend_startup_hook = prev_backend_startup_hook;
}
static
void my_startup_hook (pid_t pid, Oid databaseOid,
const char * dbname, const char * username) {
if (! strcmp(dbname, "testdb")) {
elog(ERROR, "startup hook is failing");
} else {
elog(NOTICE, "startup hook finished OK");
}
}
--
Sent via pgsql-hackers mailing list ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers