Skip to content

Commit

Permalink
Refactor a bit the emaj_alter_group() function. This simplifies and o…
Browse files Browse the repository at this point in the history
…ptimizes the code. This also prepares future evolutions.
  • Loading branch information
beaud76 committed Mar 7, 2017
1 parent 04349a9 commit 9a76ad0
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 241 deletions.
63 changes: 27 additions & 36 deletions sql/emaj--2.0.1--next_version.sql
Original file line number Diff line number Diff line change
Expand Up @@ -866,7 +866,7 @@ $emaj_alter_group$
SELECT DISTINCT rel_log_schema FROM emaj.emaj_relation -- minus those already created
ORDER BY 1
) AS t;
-- list all relations that do not belong to the tables group any more
-- drop all relations that do not belong to the tables group any more
FOR r_rel IN
SELECT * FROM emaj.emaj_relation
WHERE rel_group = v_groupName
Expand Down Expand Up @@ -894,53 +894,44 @@ $emaj_alter_group$
v_nbDrop = v_nbDrop + 1;
END LOOP;
--
-- list relations that still belong to the tables group
-- cleanup all remaining log tables
PERFORM emaj._reset_group(v_groupName);
--
-- list tables that still belong to the tables group but have their attributes changed in the emaj_group_def table
FOR r_tblsq IN
SELECT rel_priority, rel_schema, rel_tblseq, rel_kind, rel_log_schema, rel_log_table, rel_log_dat_tsp, rel_log_idx_tsp,
grpdef_priority, grpdef_schema, grpdef_tblseq, grpdef_log_schema_suffix, grpdef_emaj_names_prefix, grpdef_log_dat_tsp, grpdef_log_idx_tsp
SELECT rel_schema, rel_tblseq
FROM emaj.emaj_relation, emaj.emaj_group_def
WHERE rel_schema = grpdef_schema AND rel_tblseq = grpdef_tblseq
AND rel_group = v_groupName
AND grpdef_group = v_groupName
ORDER BY rel_priority, rel_schema, rel_tblseq
LOOP
-- now detect other changes that justify to drop and recreate the relation
AND rel_kind = 'r'
AND (
-- detect if the log data tablespace in emaj_group_def has changed
IF (r_tblsq.rel_kind = 'r' AND coalesce(r_tblsq.rel_log_dat_tsp,'') <> coalesce(r_tblsq.grpdef_log_dat_tsp, v_defTsp,''))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_dat_tsp IS NOT NULL)
coalesce(rel_log_dat_tsp,'') <> coalesce(grpdef_log_dat_tsp, v_defTsp,'')
-- or if the log index tablespace in emaj_group_def has changed
OR (r_tblsq.rel_kind = 'r' AND coalesce(r_tblsq.rel_log_idx_tsp,'') <> coalesce(r_tblsq.grpdef_log_idx_tsp, v_defTsp,''))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_idx_tsp IS NOT NULL)
OR coalesce(rel_log_idx_tsp,'') <> coalesce(grpdef_log_idx_tsp, v_defTsp,'')
-- or if the log schema in emaj_group_def has changed
OR (r_tblsq.rel_kind = 'r' AND r_tblsq.rel_log_schema <> (v_schemaPrefix || coalesce(r_tblsq.grpdef_log_schema_suffix, '')))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_schema_suffix IS NOT NULL)
OR rel_log_schema <> (v_schemaPrefix || coalesce(grpdef_log_schema_suffix, ''))
-- or if the emaj names prefix in emaj_group_def has changed (detected with the log table name)
OR (r_tblsq.rel_kind = 'r' AND
r_tblsq.rel_log_table <> (coalesce(r_tblsq.grpdef_emaj_names_prefix, r_tblsq.grpdef_schema || '_' || r_tblsq.grpdef_tblseq) || '_log'))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_emaj_names_prefix IS NOT NULL) THEN
-- then drop the relation (it will be recreated later)
OR rel_log_table <> (coalesce(grpdef_emaj_names_prefix, grpdef_schema || '_' || grpdef_tblseq) || '_log'))
ORDER BY rel_priority, rel_schema, rel_tblseq
LOOP
-- get the related row in emaj_relation
SELECT * FROM emaj.emaj_relation WHERE rel_schema = r_tblsq.rel_schema AND rel_tblseq = r_tblsq.rel_tblseq INTO r_rel;
IF r_tblsq.rel_kind = 'r' THEN
-- if it is a table, delete the related emaj objects
PERFORM emaj._drop_tbl (r_rel);
ELSEIF r_tblsq.rel_kind = 'S' THEN
-- if it is a sequence, delete all related data from emaj_sequence table
PERFORM emaj._drop_seq (r_rel);
END IF;
v_nbDrop = v_nbDrop + 1;
-- other case ?
-- has the priority changed in emaj_group_def ? If yes, just report the change into emaj_relation
ELSEIF (r_tblsq.rel_priority IS NULL AND r_tblsq.grpdef_priority IS NOT NULL) OR
(r_tblsq.rel_priority IS NOT NULL AND r_tblsq.grpdef_priority IS NULL) OR
(r_tblsq.rel_priority <> r_tblsq.grpdef_priority) THEN
UPDATE emaj.emaj_relation SET rel_priority = r_tblsq.grpdef_priority
WHERE rel_schema = r_tblsq.grpdef_schema AND rel_tblseq = r_tblsq.grpdef_tblseq;
END IF;
SELECT * FROM emaj.emaj_relation WHERE rel_schema = r_tblsq.rel_schema AND rel_tblseq = r_tblsq.rel_tblseq INTO r_rel;
-- then drop the relation (it will be recreated later)
PERFORM emaj._drop_tbl (r_rel);
v_nbDrop = v_nbDrop + 1;
END LOOP;
-- update the emaj_relation table to report the priorities that have ben changed in the emaj_group_def table
UPDATE emaj.emaj_relation SET rel_priority = grpdef_priority
FROM emaj.emaj_group_def
WHERE rel_schema = grpdef_schema AND rel_tblseq = grpdef_tblseq
AND rel_group = v_groupName
AND grpdef_group = v_groupName
AND ( (rel_priority IS NULL AND grpdef_priority IS NOT NULL) OR
(rel_priority IS NOT NULL AND grpdef_priority IS NULL) OR
(rel_priority <> grpdef_priority) );
--
-- cleanup all remaining log tables
PERFORM emaj._reset_group(v_groupName);
-- drop useless log schemas, using the list of schemas to drop built previously
IF v_logSchemasToDrop IS NOT NULL THEN
FOREACH v_aLogSchema IN ARRAY v_logSchemasToDrop LOOP
Expand Down
63 changes: 27 additions & 36 deletions sql/emaj--next_version.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2258,7 +2258,7 @@ $emaj_alter_group$
SELECT DISTINCT rel_log_schema FROM emaj.emaj_relation -- minus those already created
ORDER BY 1
) AS t;
-- list all relations that do not belong to the tables group any more
-- drop all relations that do not belong to the tables group any more
FOR r_rel IN
SELECT * FROM emaj.emaj_relation
WHERE rel_group = v_groupName
Expand Down Expand Up @@ -2286,53 +2286,44 @@ $emaj_alter_group$
v_nbDrop = v_nbDrop + 1;
END LOOP;
--
-- list relations that still belong to the tables group
-- cleanup all remaining log tables
PERFORM emaj._reset_group(v_groupName);
--
-- list tables that still belong to the tables group but have their attributes changed in the emaj_group_def table
FOR r_tblsq IN
SELECT rel_priority, rel_schema, rel_tblseq, rel_kind, rel_log_schema, rel_log_table, rel_log_dat_tsp, rel_log_idx_tsp,
grpdef_priority, grpdef_schema, grpdef_tblseq, grpdef_log_schema_suffix, grpdef_emaj_names_prefix, grpdef_log_dat_tsp, grpdef_log_idx_tsp
SELECT rel_schema, rel_tblseq
FROM emaj.emaj_relation, emaj.emaj_group_def
WHERE rel_schema = grpdef_schema AND rel_tblseq = grpdef_tblseq
AND rel_group = v_groupName
AND grpdef_group = v_groupName
ORDER BY rel_priority, rel_schema, rel_tblseq
LOOP
-- now detect other changes that justify to drop and recreate the relation
AND rel_kind = 'r'
AND (
-- detect if the log data tablespace in emaj_group_def has changed
IF (r_tblsq.rel_kind = 'r' AND coalesce(r_tblsq.rel_log_dat_tsp,'') <> coalesce(r_tblsq.grpdef_log_dat_tsp, v_defTsp,''))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_dat_tsp IS NOT NULL)
coalesce(rel_log_dat_tsp,'') <> coalesce(grpdef_log_dat_tsp, v_defTsp,'')
-- or if the log index tablespace in emaj_group_def has changed
OR (r_tblsq.rel_kind = 'r' AND coalesce(r_tblsq.rel_log_idx_tsp,'') <> coalesce(r_tblsq.grpdef_log_idx_tsp, v_defTsp,''))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_idx_tsp IS NOT NULL)
OR coalesce(rel_log_idx_tsp,'') <> coalesce(grpdef_log_idx_tsp, v_defTsp,'')
-- or if the log schema in emaj_group_def has changed
OR (r_tblsq.rel_kind = 'r' AND r_tblsq.rel_log_schema <> (v_schemaPrefix || coalesce(r_tblsq.grpdef_log_schema_suffix, '')))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_log_schema_suffix IS NOT NULL)
OR rel_log_schema <> (v_schemaPrefix || coalesce(grpdef_log_schema_suffix, ''))
-- or if the emaj names prefix in emaj_group_def has changed (detected with the log table name)
OR (r_tblsq.rel_kind = 'r' AND
r_tblsq.rel_log_table <> (coalesce(r_tblsq.grpdef_emaj_names_prefix, r_tblsq.grpdef_schema || '_' || r_tblsq.grpdef_tblseq) || '_log'))
OR (r_tblsq.rel_kind = 'S' AND r_tblsq.grpdef_emaj_names_prefix IS NOT NULL) THEN
-- then drop the relation (it will be recreated later)
OR rel_log_table <> (coalesce(grpdef_emaj_names_prefix, grpdef_schema || '_' || grpdef_tblseq) || '_log'))
ORDER BY rel_priority, rel_schema, rel_tblseq
LOOP
-- get the related row in emaj_relation
SELECT * FROM emaj.emaj_relation WHERE rel_schema = r_tblsq.rel_schema AND rel_tblseq = r_tblsq.rel_tblseq INTO r_rel;
IF r_tblsq.rel_kind = 'r' THEN
-- if it is a table, delete the related emaj objects
PERFORM emaj._drop_tbl (r_rel);
ELSEIF r_tblsq.rel_kind = 'S' THEN
-- if it is a sequence, delete all related data from emaj_sequence table
PERFORM emaj._drop_seq (r_rel);
END IF;
v_nbDrop = v_nbDrop + 1;
-- other case ?
-- has the priority changed in emaj_group_def ? If yes, just report the change into emaj_relation
ELSEIF (r_tblsq.rel_priority IS NULL AND r_tblsq.grpdef_priority IS NOT NULL) OR
(r_tblsq.rel_priority IS NOT NULL AND r_tblsq.grpdef_priority IS NULL) OR
(r_tblsq.rel_priority <> r_tblsq.grpdef_priority) THEN
UPDATE emaj.emaj_relation SET rel_priority = r_tblsq.grpdef_priority
WHERE rel_schema = r_tblsq.grpdef_schema AND rel_tblseq = r_tblsq.grpdef_tblseq;
END IF;
SELECT * FROM emaj.emaj_relation WHERE rel_schema = r_tblsq.rel_schema AND rel_tblseq = r_tblsq.rel_tblseq INTO r_rel;
-- then drop the relation (it will be recreated later)
PERFORM emaj._drop_tbl (r_rel);
v_nbDrop = v_nbDrop + 1;
END LOOP;
-- update the emaj_relation table to report the priorities that have ben changed in the emaj_group_def table
UPDATE emaj.emaj_relation SET rel_priority = grpdef_priority
FROM emaj.emaj_group_def
WHERE rel_schema = grpdef_schema AND rel_tblseq = grpdef_tblseq
AND rel_group = v_groupName
AND grpdef_group = v_groupName
AND ( (rel_priority IS NULL AND grpdef_priority IS NOT NULL) OR
(rel_priority IS NOT NULL AND grpdef_priority IS NULL) OR
(rel_priority <> grpdef_priority) );
--
-- cleanup all remaining log tables
PERFORM emaj._reset_group(v_groupName);
-- drop useless log schemas, using the list of schemas to drop built previously
IF v_logSchemasToDrop IS NOT NULL THEN
FOREACH v_aLogSchema IN ARRAY v_logSchemasToDrop LOOP
Expand Down
20 changes: 10 additions & 10 deletions test/91/expected/adm2.out
Original file line number Diff line number Diff line change
Expand Up @@ -519,17 +519,17 @@ NOTICE: table "phil's schema3_phil's tbl1_log" does not exist, skipping
CONTEXT: SQL statement "DROP TABLE IF EXISTS "emaj #'3"."phil's schema3_phil's tbl1_log""
PL/pgSQL function "_create_tbl" line 70 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
NOTICE: trigger "emaj_log_trg" for table "phil's tbl1" does not exist, skipping
CONTEXT: SQL statement "DROP TRIGGER IF EXISTS emaj_log_trg ON "phil's schema3"."phil's tbl1""
PL/pgSQL function "_create_tbl" line 124 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
NOTICE: trigger "emaj_trunc_trg" for table "phil's tbl1" does not exist, skipping
CONTEXT: SQL statement "DROP TRIGGER IF EXISTS emaj_trunc_trg ON "phil's schema3"."phil's tbl1""
PL/pgSQL function "_create_tbl" line 131 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
emaj_alter_group
------------------
4
Expand All @@ -556,17 +556,17 @@ NOTICE: table "phil's schema3_phil's tbl1_log" does not exist, skipping
CONTEXT: SQL statement "DROP TABLE IF EXISTS "emaj #'3"."phil's schema3_phil's tbl1_log""
PL/pgSQL function "_create_tbl" line 70 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
NOTICE: trigger "emaj_log_trg" for table "phil's tbl1" does not exist, skipping
CONTEXT: SQL statement "DROP TRIGGER IF EXISTS emaj_log_trg ON "phil's schema3"."phil's tbl1""
PL/pgSQL function "_create_tbl" line 124 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
NOTICE: trigger "emaj_trunc_trg" for table "phil's tbl1" does not exist, skipping
CONTEXT: SQL statement "DROP TRIGGER IF EXISTS emaj_trunc_trg ON "phil's schema3"."phil's tbl1""
PL/pgSQL function "_create_tbl" line 131 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
emaj_alter_group
------------------
4
Expand Down Expand Up @@ -1520,18 +1520,18 @@ NOTICE: table "short_log" does not exist, skipping
CONTEXT: SQL statement "DROP TABLE IF EXISTS "emaj #'3".short_log"
PL/pgSQL function "_create_tbl" line 70 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
NOTICE: trigger "emaj_log_trg" for table "table_with_very_looooooooooooooooooooooooooooooooooooooong_name" does not exist, skipping
CONTEXT: SQL statement "DROP TRIGGER IF EXISTS emaj_log_trg ON "phil's schema3".table_with_very_looooooooooooooooooooooooooooooooooooooong_name"
PL/pgSQL function "_create_tbl" line 124 at EXECUTE statement
SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
WARNING: _check_fk_groups: Foreign key "mytbl2_col21_fkey", from table "phil's schema3.myTbl2\", references "phil's schema3.mytbl4" that is outside groups (phil's group#3",).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
WARNING: _check_fk_groups: table "phil's schema3.table_with_very_looooooooooooooooooooooooooooooooooooooong_name" is referenced by foreign key "mytbl4_col44_fkey" from table "phil's schema3.mytbl4" that is outside groups (phil's group#3",).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
emaj_alter_group
------------------
4
Expand Down
12 changes: 6 additions & 6 deletions test/91/expected/create_drop.out
Original file line number Diff line number Diff line change
Expand Up @@ -719,10 +719,10 @@ delete from emaj.emaj_group_def where grpdef_schema = 'myschema1' and grpdef_tbl
select emaj.emaj_alter_group('myGroup1');
WARNING: _check_fk_groups: table "myschema1.mytbl2" is referenced by foreign key "mytbl4_col43_fkey" from table "myschema1.mytbl4" that is outside groups (myGroup1).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
WARNING: _check_fk_groups: table "myschema1.mytbl1" is referenced by foreign key "mytbl4_col44_fkey" from table "myschema1.mytbl4" that is outside groups (myGroup1).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
emaj_alter_group
------------------
3
Expand All @@ -746,10 +746,10 @@ delete from emaj.emaj_group_def where grpdef_schema = 'myschema1' and grpdef_tbl
select emaj.emaj_alter_group('myGroup1');
WARNING: _check_fk_groups: table "myschema1.mytbl2" is referenced by foreign key "mytbl4_col43_fkey" from table "myschema1.mytbl4" that is outside groups (myGroup1).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
WARNING: _check_fk_groups: table "myschema1.mytbl1" is referenced by foreign key "mytbl4_col44_fkey" from table "myschema1.mytbl4" that is outside groups (myGroup1).
CONTEXT: SQL statement "SELECT emaj._check_fk_groups(array[v_groupName])"
PL/pgSQL function "emaj_alter_group" line 221 at PERFORM
PL/pgSQL function "emaj_alter_group" line 212 at PERFORM
emaj_alter_group
------------------
2
Expand Down Expand Up @@ -883,7 +883,7 @@ update emaj.emaj_group_def set grpdef_log_dat_tsp = case when grpdef_log_dat_tsp
select emaj.emaj_alter_group('myGroup1');
WARNING: _create_tbl: table "myschema1.mytbl2" has triggers (mytbl2trg). Verify the compatibility with emaj rollback operations (in particular if triggers update one or several other tables). Triggers may have to be manualy disabled before rollback.
CONTEXT: SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
emaj_alter_group
------------------
6
Expand All @@ -893,7 +893,7 @@ update emaj.emaj_group_def set grpdef_log_dat_tsp = case when grpdef_log_dat_tsp
select emaj.emaj_alter_group('myGroup1');
WARNING: _create_tbl: table "myschema1.mytbl2" has triggers (mytbl2trg). Verify the compatibility with emaj rollback operations (in particular if triggers update one or several other tables). Triggers may have to be manualy disabled before rollback.
CONTEXT: SQL statement "SELECT emaj._create_tbl(r_grpdef, v_groupName, v_isRollbackable, v_defTsp)"
PL/pgSQL function "emaj_alter_group" line 192 at PERFORM
PL/pgSQL function "emaj_alter_group" line 183 at PERFORM
emaj_alter_group
------------------
6
Expand Down

0 comments on commit 9a76ad0

Please sign in to comment.