From 569143f9711a3ecea1825c7569042cc8ece60ef1 Mon Sep 17 00:00:00 2001 From: martsberger Date: Mon, 4 Oct 2021 17:04:51 -0400 Subject: [PATCH 1/3] Include trigger status (enable/disable/replica) in trigger create statement. --- schemainspect/pg/obj.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/schemainspect/pg/obj.py b/schemainspect/pg/obj.py index 0b60c8c..8c7df08 100644 --- a/schemainspect/pg/obj.py +++ b/schemainspect/pg/obj.py @@ -365,7 +365,18 @@ def drop_statement(self): @property def create_statement(self): - return self.full_definition + ";" + status_sql = { + 'O': 'ENABLE TRIGGER', + 'D': 'DISABLE TRIGGER', + 'R': 'ENABLE REPLICA TRIGGER', + 'A': 'ENABLE ALWAYS TRIGGER' + } + schema = quoted_identifier(self.schema) + table = quoted_identifier(self.table_name) + trigger_name = quoted_identifier(self.name) + table_alter = f'ALTER TABLE {schema}.{table} {status_sql[self.enabled]} {trigger_name}' + + return self.full_definition + ";\n" + table_alter + ";" def __eq__(self, other): """ From a2cbaf36d7d16ca8271946db3333faff0fe834cd Mon Sep 17 00:00:00 2001 From: martsberger Date: Mon, 4 Oct 2021 23:39:17 -0400 Subject: [PATCH 2/3] Table alter is not necessary for the default state. This will prevent it from being included with triggers on views. --- schemainspect/pg/obj.py | 8 +++++--- tests/test_triggers.py | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/schemainspect/pg/obj.py b/schemainspect/pg/obj.py index 8c7df08..8c73b47 100644 --- a/schemainspect/pg/obj.py +++ b/schemainspect/pg/obj.py @@ -374,9 +374,11 @@ def create_statement(self): schema = quoted_identifier(self.schema) table = quoted_identifier(self.table_name) trigger_name = quoted_identifier(self.name) - table_alter = f'ALTER TABLE {schema}.{table} {status_sql[self.enabled]} {trigger_name}' - - return self.full_definition + ";\n" + table_alter + ";" + if self.enabled in ('D', 'R', 'A'): + table_alter = f'ALTER TABLE {schema}.{table} {status_sql[self.enabled]} {trigger_name}' + return self.full_definition + ";\n" + table_alter + ";" + else: + return self.full_definition + ";" def __eq__(self, other): """ diff --git a/tests/test_triggers.py b/tests/test_triggers.py index 0a60b7a..70a231c 100644 --- a/tests/test_triggers.py +++ b/tests/test_triggers.py @@ -31,9 +31,37 @@ """ -def test_triggers(db): +def test_view_trigger(db): with S(db) as s: s.execute(BASE) i = get_inspector(s) - i.triggers['"public"."view_on_table"."trigger_on_view"'] + trigger = i.triggers['"public"."view_on_table"."trigger_on_view"'] + + # Triggers on views should not include the ALTER TABLE part of the create statement + assert 'ALTER TABLE' not in trigger.create_statement() + +def test_replica_trigger(db): + with S(db) as s: + s.execute(BASE) + function = ''' + CREATE OR REPLACE FUNCTION table_trigger_function() + RETURNS trigger + LANGUAGE plpgsql + AS $function$ + BEGIN + RETURN NEW; + END; + $function$ + ; + ''' + s.execute(function) + s.execute('CREATE TRIGGER table_trigger AFTER INSERT ON my_table FOR EACH ROW EXECUTE PROCEDURE table_trigger_function();') + s.execute('ALTER TABLLE my_table ENABLE REPLICA TRIGGER table_trigger;') + + i = get_inspector(s) + + trigger = i.triggers['"public"."my_table"."table_trigger"'] + + # Replica trigger needs the ALTER TABLE statement as well as the trigger definition + assert 'ALTER TABLE' not in trigger.create_statement() \ No newline at end of file From 0993a9b12300a8f72c3dea2c5015ec0cd6e6398f Mon Sep 17 00:00:00 2001 From: martsberger Date: Mon, 4 Oct 2021 23:56:28 -0400 Subject: [PATCH 3/3] Fix logic, "not in" should have been "in" --- tests/test_triggers.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test_triggers.py b/tests/test_triggers.py index 70a231c..d44a94e 100644 --- a/tests/test_triggers.py +++ b/tests/test_triggers.py @@ -41,6 +41,7 @@ def test_view_trigger(db): # Triggers on views should not include the ALTER TABLE part of the create statement assert 'ALTER TABLE' not in trigger.create_statement() + def test_replica_trigger(db): with S(db) as s: s.execute(BASE) @@ -64,4 +65,4 @@ def test_replica_trigger(db): trigger = i.triggers['"public"."my_table"."table_trigger"'] # Replica trigger needs the ALTER TABLE statement as well as the trigger definition - assert 'ALTER TABLE' not in trigger.create_statement() \ No newline at end of file + assert 'ALTER TABLE' in trigger.create_statement()