From c5801dd67b86d2a3e27f05fcbdb01d20014019a2 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 27 Sep 2017 22:08:20 +0300 Subject: [PATCH] SQL: hide archive tables [closes #193] --- mysql-test/suite/versioning/r/ddl.result | 38 +++++------ mysql-test/suite/versioning/r/vtmd.result | 79 +++++++++++++++++++---- mysql-test/suite/versioning/t/ddl.test | 38 +++++------ mysql-test/suite/versioning/t/vtmd.test | 25 ++++++- sql/sql_show.cc | 61 +++++++++++++++++ sql/vtmd.cc | 25 +++---- sql/vtmd.h | 3 +- 7 files changed, 204 insertions(+), 65 deletions(-) diff --git a/mysql-test/suite/versioning/r/ddl.result b/mysql-test/suite/versioning/r/ddl.result index 0ba0b5de0d4..1bfca2da8f6 100644 --- a/mysql-test/suite/versioning/r/ddl.result +++ b/mysql-test/suite/versioning/r/ddl.result @@ -72,15 +72,15 @@ prepare stmt from concat(a, b, c); execute stmt; deallocate prepare stmt; end~~ -create function get_historical_table_name(table_name_arg varchar(255)) +create function get_archive_table_name() returns varchar(255) begin -return (select table_name from information_schema.tables -where table_schema='test' and table_name like concat(table_name_arg, '_%') limit 1); +return (select archive_name from t_vtmd for system_time all where archive_name is not NULL +order by start desc limit 1); end~~ -create procedure drop_last_historical(table_name_arg varchar(255)) +create procedure drop_last_archive() begin -call concat_exec2('drop table ', get_historical_table_name(table_name_arg)); +call concat_exec2('drop table ', get_archive_table_name()); end~~ set versioning_alter_history= survive; create or replace table t (a int) with system versioning; @@ -91,21 +91,21 @@ alter table t add column b int; select * from t; a b 2 NULL -call concat_exec3('select * from ', get_historical_table_name('t'), ' for system_time all'); +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); a 2 1 -call concat_exec3('select @tm=sys_trx_start from ', get_historical_table_name('t'), ' for system_time all where a=2'); +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); @tm=sys_trx_start 1 select @tm 0 and @start < @inf @@ -206,10 +208,6 @@ show tables; Tables_in_db1 other_name other_name_vtmd -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX call test.check_vtmd('db1.other_name_vtmd'); @start > 0 and @start < @inf 1 @@ -246,10 +244,6 @@ alter table t1 rename to test.t2, add column (y int); use test; show tables; Tables_in_test -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX -t0_TIMESTAMP_SUFFIX t2 t2_vtmd call check_vtmd('t2_vtmd'); @@ -279,6 +273,67 @@ A_start B_end name C_archive_name 1 0 t3 t3_ 1 0 t3 t3_ 1 1 t3 NULL +set versioning_hide = auto; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide = implicit; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide = full; +call show_tables(); +Tables_in_test +t2 +t2_vtmd +t3 +t3_vtmd +table_name table_schema +t2 test +t2_vtmd test +t3 test +t3_vtmd test +set versioning_hide = never; +call show_tables(); +Tables_in_test +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t0_TIMESTAMP_SUFFIX +t2 +t2_vtmd +t3 +t3_TIMESTAMP_SUFFIX +t3_TIMESTAMP_SUFFIX +t3_vtmd +table_name table_schema +t1_TIMESTAMP_SUFFIX db1 +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t0_TIMESTAMP_SUFFIX test +t2 test +t2_vtmd test +t3 test +t3_TIMESTAMP_SUFFIX test +t3_TIMESTAMP_SUFFIX test +t3_vtmd test drop database db0; drop database db1; drop database test; diff --git a/mysql-test/suite/versioning/t/ddl.test b/mysql-test/suite/versioning/t/ddl.test index e5b5a4c429a..5be62281a6d 100644 --- a/mysql-test/suite/versioning/t/ddl.test +++ b/mysql-test/suite/versioning/t/ddl.test @@ -1,16 +1,16 @@ -- source suite/versioning/common.inc delimiter ~~; -create function get_historical_table_name(table_name_arg varchar(255)) +create function get_archive_table_name() returns varchar(255) begin - return (select table_name from information_schema.tables - where table_schema='test' and table_name like concat(table_name_arg, '_%') limit 1); + return (select archive_name from t_vtmd for system_time all where archive_name is not NULL + order by start desc limit 1); end~~ -create procedure drop_last_historical(table_name_arg varchar(255)) +create procedure drop_last_archive() begin - call concat_exec2('drop table ', get_historical_table_name(table_name_arg)); + call concat_exec2('drop table ', get_archive_table_name()); end~~ delimiter ;~~ @@ -23,14 +23,14 @@ select sys_trx_start from t where a=2 into @tm; alter table t add column b int; select * from t; -call concat_exec3('select * from ', get_historical_table_name('t'), ' for system_time all'); +call concat_exec3('select * from ', get_archive_table_name(), ' for system_time all'); -call concat_exec3('select @tm=sys_trx_start from ', get_historical_table_name('t'), ' for system_time all where a=2'); +call concat_exec3('select @tm=sys_trx_start from ', get_archive_table_name(), ' for system_time all where a=2'); select @tm &all_archive_tables) +{ + if (thd->variables.vers_hide == VERS_HIDE_NEVER) + return false; + + Dynamic_array all_db; + LOOKUP_FIELD_VALUES lookup_field_values= { + *thd->make_lex_string(C_STRING_WITH_LEN("%")), {NULL, 0}, true, false}; + if (make_db_list(thd, &all_db, &lookup_field_values)) + return true; + + LEX_STRING information_schema= {C_STRING_WITH_LEN("information_schema")}; + for (size_t i= 0; i < all_db.elements(); i++) + { + LEX_STRING db= *all_db.at(i); + if (db.length == information_schema.length && + !memcmp(db.str, information_schema.str, db.length)) + { + all_db.del(i); + break; + } + } + + for (size_t i= 0; i < all_db.elements(); i++) + { + LEX_STRING db_name= *all_db.at(i); + Dynamic_array archive_tables; + if (VTMD_table::get_archive_tables(thd, db_name.str, db_name.length, + archive_tables)) + return true; + for (size_t i= 0; i < archive_tables.elements(); i++) + if (all_archive_tables.push(archive_tables.at(i))) + return true; + } + + return false; +} + +static bool is_archive_table(const Dynamic_array &all_archive_tables, + LEX_STRING candidate) +{ + for (size_t i= 0; i < all_archive_tables.elements(); i++) + { + const String &archive_table= all_archive_tables.at(i); + if (candidate.length == archive_table.length() && + !memcmp(candidate.str, archive_table.ptr(), candidate.length)) + { + return true; + } + } + return false; +} /** @brief Fill I_S tables whose data are retrieved @@ -4905,6 +4958,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) #endif uint table_open_method= tables->table_open_method; bool can_deadlock; + Dynamic_array all_archive_tables; DBUG_ENTER("get_all_tables"); /* @@ -4967,6 +5021,10 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) if (make_db_list(thd, &db_names, &plan->lookup_field_vals)) goto err; + + if (get_all_archive_tables(thd, all_archive_tables)) + goto err; + for (size_t i=0; i < db_names.elements(); i++) { LEX_STRING *db_name= db_names.at(i); @@ -4992,6 +5050,9 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) LEX_STRING *table_name= table_names.at(i); DBUG_ASSERT(table_name->length <= NAME_LEN); + if (is_archive_table(all_archive_tables, *table_name)) + continue; + #ifndef NO_EMBEDDED_ACCESS_CHECKS if (!(thd->col_access & TABLE_ACLS)) { diff --git a/sql/vtmd.cc b/sql/vtmd.cc index 6ba55679ec4..679a70e3e80 100644 --- a/sql/vtmd.cc +++ b/sql/vtmd.cc @@ -569,24 +569,26 @@ err: static bool -get_vtmd_tables(THD *thd, Dynamic_array &table_names) +get_vtmd_tables(THD *thd, const char *db, + size_t db_length, Dynamic_array &table_names) { - // Note function retrieves table names from current db only. LOOKUP_FIELD_VALUES lookup_field_values= { - *thd->make_lex_string(thd->db, strlen(thd->db)), + *thd->make_lex_string(db, db_length), *thd->make_lex_string(C_STRING_WITH_LEN("%_vtmd")), false, true}; - int res= make_table_name_list(thd, &table_names, thd->lex, &lookup_field_values, - &lookup_field_values.db_value); + int res= + make_table_name_list(thd, &table_names, thd->lex, &lookup_field_values, + &lookup_field_values.db_value); return res; } bool -VTMD_table::get_archive_tables(THD *thd, Dynamic_array &result) +VTMD_table::get_archive_tables(THD *thd, const char *db, size_t db_length, + Dynamic_array &result) { Dynamic_array vtmd_tables; - if (get_vtmd_tables(thd, vtmd_tables)) + if (get_vtmd_tables(thd, db, db_length, vtmd_tables)) return true; for (uint i= 0; i < vtmd_tables.elements(); i++) @@ -595,10 +597,8 @@ VTMD_table::get_archive_tables(THD *thd, Dynamic_array &result) Open_tables_backup open_tables_backup; TABLE_LIST table_list; - // Assume VTMD tables belongs to current db. - table_list.init_one_table(thd->db, strlen(thd->db), - LEX_STRING_WITH_LEN(table_name), table_name.str, - TL_READ); + table_list.init_one_table(db, db_length, LEX_STRING_WITH_LEN(table_name), + table_name.str, TL_READ); TABLE *table= open_log_table(thd, &table_list, &open_tables_backup); if (!table) @@ -633,6 +633,9 @@ VTMD_table::get_archive_tables(THD *thd, Dynamic_array &result) archive_name.length()); result.push(archive_name); } + // check for EOF + if (!thd->is_error()) + error= 0; end_read_record(&read_record); delete sql_select; diff --git a/sql/vtmd.h b/sql/vtmd.h index 5a987723a47..a2b010ece7d 100644 --- a/sql/vtmd.h +++ b/sql/vtmd.h @@ -92,7 +92,8 @@ public: } bool find_archive_name(THD *thd, String &out); - bool get_archive_tables(THD *thd, Dynamic_array &result); + static bool get_archive_tables(THD *thd, const char *db, size_t db_length, + Dynamic_array &result); }; class VTMD_exists : public VTMD_table