From 0fe16500d3ae68b8928a2b94dcab434e358480d5 Mon Sep 17 00:00:00 2001 From: Jan Wieck Date: Mon, 19 Mar 2007 23:38:32 +0000 Subject: Changes pg_trigger and extend pg_rewrite in order to allow triggers and rules to be defined with different, per session controllable, behaviors for replication purposes. This will allow replication systems like Slony-I and, as has been stated on pgsql-hackers, other products to control the firing mechanism of triggers and rewrite rules without modifying the system catalog directly. The firing mechanisms are controlled by a new superuser-only GUC variable, session_replication_role, together with a change to pg_trigger.tgenabled and a new column pg_rewrite.ev_enabled. Both columns are a single char data type now (tgenabled was a bool before). The possible values in these attributes are: 'O' - Trigger/Rule fires when session_replication_role is "origin" (default) or "local". This is the default behavior. 'D' - Trigger/Rule is disabled and fires never 'A' - Trigger/Rule fires always regardless of the setting of session_replication_role 'R' - Trigger/Rule fires when session_replication_role is "replica" The GUC variable can only be changed as long as the system does not have any cached query plans. This will prevent changing the session role and accidentally executing stored procedures or functions that have plans cached that expand to the wrong query set due to differences in the rule firing semantics. The SQL syntax for changing a triggers/rules firing semantics is ALTER TABLE TRIGGER|RULE ; ::= ENABLE | ENABLE ALWAYS | ENABLE REPLICA | DISABLE psql's \d command as well as pg_dump are extended in a backward compatible fashion. Jan --- src/backend/utils/misc/guc.c | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) (limited to 'src/backend/utils/misc/guc.c') diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 8088432bac8..f921c75a60b 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -10,7 +10,7 @@ * Written by Peter Eisentraut . * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.382 2007/03/13 14:32:25 petere Exp $ + * $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.383 2007/03/19 23:38:30 wieck Exp $ * *-------------------------------------------------------------------- */ @@ -34,6 +34,7 @@ #include "commands/async.h" #include "commands/vacuum.h" #include "commands/variable.h" +#include "commands/trigger.h" #include "funcapi.h" #include "libpq/auth.h" #include "libpq/pqformat.h" @@ -59,6 +60,7 @@ #include "utils/guc_tables.h" #include "utils/memutils.h" #include "utils/pg_locale.h" +#include "utils/plancache.h" #include "utils/ps_status.h" #include "utils/tzparser.h" #include "utils/xml.h" @@ -124,6 +126,8 @@ static const char *assign_syslog_ident(const char *ident, static const char *assign_defaultxactisolevel(const char *newval, bool doit, GucSource source); +static const char *assign_session_replication_role(const char *newval, bool doit, + GucSource source); static const char *assign_log_min_messages(const char *newval, bool doit, GucSource source); static const char *assign_client_min_messages(const char *newval, @@ -226,6 +230,7 @@ static char *backslash_quote_string; static char *client_encoding_string; static char *datestyle_string; static char *default_iso_level_string; +static char *session_replication_role_string; static char *locale_collate; static char *locale_ctype; static char *regex_flavor_string; @@ -1928,6 +1933,16 @@ static struct config_string ConfigureNamesString[] = "read committed", assign_defaultxactisolevel, NULL }, + { + {"session_replication_role", PGC_SUSET, CLIENT_CONN_STATEMENT, + gettext_noop("Sets the sessions behaviour for triggers and rewrite rules."), + gettext_noop("Each session can be either" + " \"origin\", \"replica\" or \"local\".") + }, + &session_replication_role_string, + "origin", assign_session_replication_role, NULL + }, + { {"dynamic_library_path", PGC_SUSET, CLIENT_CONN_OTHER, gettext_noop("Sets the path for dynamically loadable modules."), @@ -6115,6 +6130,33 @@ assign_defaultxactisolevel(const char *newval, bool doit, GucSource source) return newval; } +static const char * +assign_session_replication_role(const char *newval, bool doit, GucSource source) +{ + if (HaveCachedPlans()) + elog(ERROR, "session_replication_role cannot be changed " + "after prepared plans have been cached"); + + if (pg_strcasecmp(newval, "origin") == 0) + { + if (doit) + SessionReplicationRole = SESSION_REPLICATION_ROLE_ORIGIN; + } + else if (pg_strcasecmp(newval, "replica") == 0) + { + if (doit) + SessionReplicationRole = SESSION_REPLICATION_ROLE_REPLICA; + } + else if (pg_strcasecmp(newval, "local") == 0) + { + if (doit) + SessionReplicationRole = SESSION_REPLICATION_ROLE_LOCAL; + } + else + return NULL; + return newval; +} + static const char * assign_log_min_messages(const char *newval, bool doit, GucSource source) -- cgit v1.2.3