Skip to content

Commit

Permalink
Fix a bug in the event trigger function that checks table rewrites. W…
Browse files Browse the repository at this point in the history
…hen 1) an application table has been removed from a logging tables group and then 2) an ALTER TABLE leads to a table rewrite, the event trigger erroneously blocked the statement, with a message telling that the application table belongs to a tables group. Aside the fix, a dedicated test case has been added to the regression test scenarios. As a workaround, event triggers can be disabled before and enabled after the faulting ALTER TABLE statement, using the emaj_disable_protection_by_event_triggers() and emaj_enable_protection_by_event_triggers() functions. Reported by Djamel Haddadi.
  • Loading branch information
beaud76 committed Jun 29, 2019
1 parent 576b216 commit 5e9c380
Show file tree
Hide file tree
Showing 16 changed files with 79 additions and 13 deletions.
6 changes: 4 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ E-Maj - Change log


###Bug fixes:###


* Fix a bug in the event trigger function that checks table rewrites. When
an application table has been removed from a logging tables group and an
ALTER TABLE leads then to a table rewrite, the event trigger erroneously
blocked the statement.

3.1.0 (2019-Jun-20)
------
Expand Down
39 changes: 39 additions & 0 deletions sql/emaj--3.1.0--devel.sql
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,45 @@ SELECT emaj._disable_event_triggers();
------------------------------------------------------------------
-- create new or modified functions --
------------------------------------------------------------------
CREATE OR REPLACE FUNCTION emaj._event_trigger_table_rewrite_fnct()
RETURNS EVENT_TRIGGER LANGUAGE plpgsql
SECURITY DEFINER SET search_path = pg_catalog, pg_temp AS
$_event_trigger_table_rewrite_fnct$
-- This function is called by the emaj_table_rewrite_trg event trigger.
-- The function blocks any ddl operation that leads to a table rewrite for:
-- - an application table registered into an active (not stopped) E-Maj group,
-- - an E-Maj log table.
-- The function is declared SECURITY DEFINER so that non emaj roles can access the emaj internal tables when altering their tables.
DECLARE
v_tableSchema TEXT;
v_tableName TEXT;
v_groupName TEXT;
BEGIN
-- get the schema and table names of the altered table
SELECT nspname, relname INTO v_tableSchema, v_tableName FROM pg_catalog.pg_class, pg_catalog.pg_namespace
WHERE relnamespace = pg_namespace.oid AND pg_class.oid = pg_event_trigger_table_rewrite_oid();
-- look at the emaj_relation table to verify that the table being rewritten does not belong to any active (not stopped) group
SELECT rel_group INTO v_groupName FROM emaj.emaj_relation, emaj.emaj_group
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName AND upper_inf(rel_time_range)
AND group_name = rel_group AND group_is_logging;
IF FOUND THEN
-- the table is an application table that belongs to a group, so raise an exception
RAISE EXCEPTION 'E-Maj event trigger: Attempting to change the application table "%.%" structure. But the table belongs to the'
' active tables group "%".', v_tableSchema, v_tableName , v_groupName;
END IF;
-- look at the emaj_relation table to verify that the table being rewritten is not a known log table
SELECT rel_group INTO v_groupName FROM emaj.emaj_relation
WHERE rel_log_schema = v_tableSchema AND rel_log_table = v_tableName;
IF FOUND THEN
-- the table is an E-Maj log table, so raise an exception
RAISE EXCEPTION 'E-Maj event trigger: Attempting to change the log table "%.%" structure. But the table belongs to the tables'
' group "%".', v_tableSchema, v_tableName , v_groupName;
END IF;
END;
$_event_trigger_table_rewrite_fnct$;
COMMENT ON FUNCTION emaj._event_trigger_table_rewrite_fnct() IS
$$E-Maj extension: support of the emaj_table_rewrite_trg event trigger.$$;

--<end_functions> pattern used by the tool that extracts and insert the functions definition
------------------------------------------
-- --
Expand Down
4 changes: 2 additions & 2 deletions sql/emaj--devel.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8008,8 +8008,8 @@ $_event_trigger_table_rewrite_fnct$
WHERE relnamespace = pg_namespace.oid AND pg_class.oid = pg_event_trigger_table_rewrite_oid();
-- look at the emaj_relation table to verify that the table being rewritten does not belong to any active (not stopped) group
SELECT rel_group INTO v_groupName FROM emaj.emaj_relation, emaj.emaj_group
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName
AND group_name = rel_group AND group_is_logging;
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName AND upper_inf(rel_time_range)
AND group_name = rel_group AND group_is_logging;
IF FOUND THEN
-- the table is an application table that belongs to a group, so raise an exception
RAISE EXCEPTION 'E-Maj event trigger: Attempting to change the application table "%.%" structure. But the table belongs to the'
Expand Down
4 changes: 2 additions & 2 deletions sql/emaj-devel.sql
Original file line number Diff line number Diff line change
Expand Up @@ -8015,8 +8015,8 @@ $_event_trigger_table_rewrite_fnct$
WHERE relnamespace = pg_namespace.oid AND pg_class.oid = pg_event_trigger_table_rewrite_oid();
-- look at the emaj_relation table to verify that the table being rewritten does not belong to any active (not stopped) group
SELECT rel_group INTO v_groupName FROM emaj.emaj_relation, emaj.emaj_group
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName
AND group_name = rel_group AND group_is_logging;
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName AND upper_inf(rel_time_range)
AND group_name = rel_group AND group_is_logging;
IF FOUND THEN
-- the table is an application table that belongs to a group, so raise an exception
RAISE EXCEPTION 'E-Maj event trigger: Attempting to change the application table "%.%" structure. But the table belongs to the'
Expand Down
4 changes: 4 additions & 0 deletions test/10/expected/alter_logging.out
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,10 @@ WARNING: _check_fk_groups: The foreign key "mytbl4_col44_fkey" on the table "my

drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down
2 changes: 1 addition & 1 deletion test/10/expected/check.out
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select funcname, calls from pg_stat_user_functions
_enable_event_triggers | 288
_estimate_rollback_groups | 13
_event_trigger_sql_drop_fnct | 113
_event_trigger_table_rewrite_fnct | 138
_event_trigger_table_rewrite_fnct | 139
_gen_sql_groups | 23
_gen_sql_tbl | 43
_get_current_sequence_state | 2308
Expand Down
4 changes: 4 additions & 0 deletions test/11/expected/alter_logging.out
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,10 @@ WARNING: _check_fk_groups: The foreign key "mytbl4_col44_fkey" on the table "my

drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down
2 changes: 1 addition & 1 deletion test/11/expected/check.out
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select funcname, calls from pg_stat_user_functions
_enable_event_triggers | 288
_estimate_rollback_groups | 13
_event_trigger_sql_drop_fnct | 115
_event_trigger_table_rewrite_fnct | 108
_event_trigger_table_rewrite_fnct | 109
_gen_sql_groups | 23
_gen_sql_tbl | 43
_get_current_sequence_state | 2308
Expand Down
4 changes: 2 additions & 2 deletions test/11/expected/install_psql.out
Original file line number Diff line number Diff line change
Expand Up @@ -7853,8 +7853,8 @@ $_event_trigger_table_rewrite_fnct$
WHERE relnamespace = pg_namespace.oid AND pg_class.oid = pg_event_trigger_table_rewrite_oid();
-- look at the emaj_relation table to verify that the table being rewritten does not belong to any active (not stopped) group
SELECT rel_group INTO v_groupName FROM emaj.emaj_relation, emaj.emaj_group
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName
AND group_name = rel_group AND group_is_logging;
WHERE rel_schema = v_tableSchema AND rel_tblseq = v_tableName AND upper_inf(rel_time_range)
AND group_name = rel_group AND group_is_logging;
IF FOUND THEN
-- the table is an application table that belongs to a group, so raise an exception
RAISE EXCEPTION 'E-Maj event trigger: Attempting to change the application table "%.%" structure. But the table belongs to the'
Expand Down
4 changes: 4 additions & 0 deletions test/12/expected/alter_logging.out
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,10 @@ WARNING: _check_fk_groups: The foreign key "mytbl4_col44_fkey" on the table "my

drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down
2 changes: 1 addition & 1 deletion test/12/expected/check.out
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select funcname, calls from pg_stat_user_functions
_enable_event_triggers | 288
_estimate_rollback_groups | 13
_event_trigger_sql_drop_fnct | 115
_event_trigger_table_rewrite_fnct | 108
_event_trigger_table_rewrite_fnct | 109
_gen_sql_groups | 23
_gen_sql_tbl | 43
_get_current_sequence_state | 2308
Expand Down
4 changes: 4 additions & 0 deletions test/95/expected/alter_logging.out
Original file line number Diff line number Diff line change
Expand Up @@ -1757,6 +1757,10 @@ PL/pgSQL function emaj.emaj_alter_group(text,text) line 6 at RETURN

drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down
2 changes: 1 addition & 1 deletion test/95/expected/check.out
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select funcname, calls from pg_stat_user_functions
_enable_event_triggers | 288
_estimate_rollback_groups | 13
_event_trigger_sql_drop_fnct | 111
_event_trigger_table_rewrite_fnct | 138
_event_trigger_table_rewrite_fnct | 139
_gen_sql_groups | 23
_gen_sql_tbl | 43
_get_current_sequence_state | 2308
Expand Down
4 changes: 4 additions & 0 deletions test/96/expected/alter_logging.out
Original file line number Diff line number Diff line change
Expand Up @@ -1541,6 +1541,10 @@ WARNING: _check_fk_groups: The foreign key "mytbl4_col44_fkey" on the table "my

drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down
2 changes: 1 addition & 1 deletion test/96/expected/check.out
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ select funcname, calls from pg_stat_user_functions
_enable_event_triggers | 288
_estimate_rollback_groups | 13
_event_trigger_sql_drop_fnct | 111
_event_trigger_table_rewrite_fnct | 138
_event_trigger_table_rewrite_fnct | 139
_gen_sql_groups | 23
_gen_sql_tbl | 43
_get_current_sequence_state | 2308
Expand Down
5 changes: 5 additions & 0 deletions test/sql/alter_logging.sql
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,11 @@ begin;
drop table mySchema1."myTbl3";
rollback;
-- testing an ALTER TABLE leading to a table rewrite
begin;
alter table mySchema1."myTbl3" alter column col33 type decimal (10,1);
rollback;
-- re-add all removed tables
update emaj.emaj_group_def set grpdef_group = 'myGroup1' where grpdef_group = 'temporarily_removed';
select emaj.emaj_alter_group('myGroup1', 'tables re-added to myGroup1');
Expand Down

0 comments on commit 5e9c380

Please sign in to comment.