+
+ event_triggers (boolean)
+
+ configuration parameter
+
+
+
+ Allow temporarily disabling execution of event triggers in order to
+ troubleshoot and repair faulty event triggers. All event triggers will
+ be disabled by setting it to false. Setting the value
+ to true allows all event triggers to fire, this
+ is the default value. Only superusers and users with the appropriate
+ SET privilege can change this setting.
+
+
+
+
Event triggers are disabled in single-user mode (see
- linkend="app-postgres"/>). If an erroneous event trigger disables the
- database so much that you can't even drop the trigger, restart in
- single-user mode and you'll be able to do that.
+ linkend="app-postgres"/>) as well as when
+ is set to false.
+ If an erroneous event trigger disables the database so much that you can't
+ even drop the trigger, restart with
+ set to false to temporarily disable event triggers, or
+ in single-user mode, and you'll be able to do that.
static EventTriggerQueryState *currentEventTriggerState = NULL;
+/* GUC parameter */
+bool event_triggers = true;
+
/* Support for dropped objects */
typedef struct SQLDropObject
{
* wherein event triggers are disabled. (Or we could implement
* heapscan-and-sort logic for that case, but having disaster recovery
* scenarios depend on code that's otherwise untested isn't appetizing.)
+ *
+ * Additionally, event triggers can be disabled with a superuser-only GUC
+ * to make fixing database easier as per 1 above.
*/
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster || !event_triggers)
return;
runlist = EventTriggerCommonSetup(parsetree,
/*
* See EventTriggerDDLCommandStart for a discussion about why event
- * triggers are disabled in single user mode.
+ * triggers are disabled in single user mode or via GUC.
*/
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster || !event_triggers)
return;
/*
/*
* See EventTriggerDDLCommandStart for a discussion about why event
- * triggers are disabled in single user mode.
+ * triggers are disabled in single user mode or via a GUC.
*/
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster || !event_triggers)
return;
/*
/*
* See EventTriggerDDLCommandStart for a discussion about why event
- * triggers are disabled in single user mode.
+ * triggers are disabled in single user mode or via a GUC.
*/
- if (!IsUnderPostmaster)
+ if (!IsUnderPostmaster || !event_triggers)
return;
/*
#include "catalog/namespace.h"
#include "catalog/storage.h"
#include "commands/async.h"
+#include "commands/event_trigger.h"
#include "commands/tablespace.h"
#include "commands/trigger.h"
#include "commands/user.h"
NULL, NULL, NULL
},
+ {
+ {"event_triggers", PGC_SUSET, CLIENT_CONN_STATEMENT,
+ gettext_noop("Enables event triggers."),
+ gettext_noop("When enabled, event triggers will fire for all applicable statements."),
+ },
+ &event_triggers,
+ true,
+ NULL, NULL, NULL
+ },
+
/* End-of-list marker */
{
{NULL, 0, 0, NULL, NULL}, NULL, false, NULL, NULL, NULL
#xmloption = 'content'
#gin_pending_list_limit = 4MB
#createrole_self_grant = '' # set and/or inherit
+#event_triggers = on
# - Locale and Formatting -
CommandTag tag;
} EventTriggerData;
+extern PGDLLIMPORT bool event_triggers;
+
#define AT_REWRITE_ALTER_PERSISTENCE 0x01
#define AT_REWRITE_DEFAULT_VAL 0x02
#define AT_REWRITE_COLUMN_REWRITE 0x04
DROP EVENT TRIGGER start_rls_command;
DROP EVENT TRIGGER end_rls_command;
DROP EVENT TRIGGER sql_drop_command;
+-- Check the GUC for disabling event triggers
+CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
+LANGUAGE plpgsql AS $$
+DECLARE
+ obj record;
+BEGIN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
+ END LOOP;
+END;
+$$;
+CREATE EVENT TRIGGER test_event_trigger_guc
+ ON sql_drop
+ WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
+SET event_triggers = 'on';
+CREATE POLICY pguc ON event_trigger_test USING (FALSE);
+DROP POLICY pguc ON event_trigger_test;
+NOTICE: DROP POLICY dropped policy
+CREATE POLICY pguc ON event_trigger_test USING (FALSE);
+SET event_triggers = 'off';
+DROP POLICY pguc ON event_trigger_test;
DROP EVENT TRIGGER start_rls_command;
DROP EVENT TRIGGER end_rls_command;
DROP EVENT TRIGGER sql_drop_command;
+
+-- Check the GUC for disabling event triggers
+CREATE FUNCTION test_event_trigger_guc() RETURNS event_trigger
+LANGUAGE plpgsql AS $$
+DECLARE
+ obj record;
+BEGIN
+ FOR obj IN SELECT * FROM pg_event_trigger_dropped_objects()
+ LOOP
+ RAISE NOTICE '% dropped %', tg_tag, obj.object_type;
+ END LOOP;
+END;
+$$;
+CREATE EVENT TRIGGER test_event_trigger_guc
+ ON sql_drop
+ WHEN TAG IN ('DROP POLICY') EXECUTE FUNCTION test_event_trigger_guc();
+
+SET event_triggers = 'on';
+CREATE POLICY pguc ON event_trigger_test USING (FALSE);
+DROP POLICY pguc ON event_trigger_test;
+
+CREATE POLICY pguc ON event_trigger_test USING (FALSE);
+SET event_triggers = 'off';
+DROP POLICY pguc ON event_trigger_test;