diff --git a/mysql-test/suite/period/r/create.result b/mysql-test/suite/period/r/create.result index ff97296b95e..8ba5ce31ff2 100644 --- a/mysql-test/suite/period/r/create.result +++ b/mysql-test/suite/period/r/create.result @@ -10,9 +10,21 @@ t CREATE TABLE `t` ( PERIOD FOR `mytime` (`s`, `e`), PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +create view v as select * from t; select * from information_schema.periods; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD START_COLUMN_NAME END_COLUMN_NAME def test t mytime s e +Warnings: +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +select * from information_schema.key_period_usage; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warnings: +drop view v; create or replace table t (id int primary key, s timestamp(6), e timestamp(6), period for mytime(s,e)); show create table t; @@ -114,3 +126,40 @@ create table t2 (s date, e date, period for `abcd123456789012345678901234567890123456789012345678901234567890` (s,e)); drop table t2; +# MDEV-32205 Server crashes in get_schema_key_period_usage_record on +# server without InnoDB +# Make sure innodb id disabled, but there's at least one innodb table +select "yes" from information_schema.tables where engine="innodb" limit 1; +yes +yes +select plugin_status from information_schema.all_plugins where plugin_name = "innodb"; +plugin_status +DISABLED +select * from information_schema.periods; +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD START_COLUMN_NAME END_COLUMN_NAME +select * from information_schema.key_period_usage; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME +# [DUPLICATE] MDEV-32204 Server crashes in +# get_schema_key_period_usage_record +create table t (a date) engine=myisam; +create table t1 (a int) engine=merge union = (t) ; +select 1 from information_schema.key_period_usage; +1 +Warning 1168 Unable to open underlying table which is differently defined or of non-MyISAM type or doesn't exist +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warnings: +drop table t1; +drop table t; +create view v1 as select 1; +create view v2 as select * from v1; +drop view v1; +select * from information_schema.key_period_usage; +CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them +Warnings: +drop view v2; diff --git a/mysql-test/suite/period/r/i_s_notembedded.result b/mysql-test/suite/period/r/i_s_notembedded.result index ff96e817b37..832d4ec6b04 100644 --- a/mysql-test/suite/period/r/i_s_notembedded.result +++ b/mysql-test/suite/period/r/i_s_notembedded.result @@ -1,5 +1,9 @@ select * from information_schema.periods; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD START_COLUMN_NAME END_COLUMN_NAME +Warnings: +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' +Warning 1286 Unknown storage engine 'InnoDB' create or replace table t1 (id int primary key, s timestamp(6), e timestamp(6), period for mytime(s,e)); create or replace table t2 (id int primary key, s timestamp(6), e timestamp(6), @@ -15,9 +19,9 @@ s timestamp(6) NO NULL e timestamp(6) NO NULL select * from information_schema.periods where table_schema = 'test'; TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD START_COLUMN_NAME END_COLUMN_NAME +def test t1 mytime s e def test t2 SYSTEM_TIME vs ve def test t2 mytime s e -def test t1 mytime s e create user periods_hidden@localhost; grant create on test.nonexist to periods_hidden@localhost; connect chopped,localhost,periods_hidden,,test; diff --git a/mysql-test/suite/period/r/overlaps.result b/mysql-test/suite/period/r/overlaps.result index a94bd6bd62d..f7a19752b99 100644 --- a/mysql-test/suite/period/r/overlaps.result +++ b/mysql-test/suite/period/r/overlaps.result @@ -22,9 +22,9 @@ unique(id2, very_interesting_period without overlaps) ); select * from information_schema.key_period_usage; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PERIOD_NAME +def test PRIMARY def test t p def test PRIMARY def test t_multi very_interesting_period def test id2 def test t_multi very_interesting_period -def test PRIMARY def test t p drop table t_multi; insert into t values (1, '2003-01-01', '2003-03-01'), (1, '2003-05-01', '2003-07-01'); diff --git a/mysql-test/suite/period/t/create.test b/mysql-test/suite/period/t/create.test index 9fb50a36995..537a1dc05c3 100644 --- a/mysql-test/suite/period/t/create.test +++ b/mysql-test/suite/period/t/create.test @@ -2,7 +2,11 @@ create table t (id int primary key, s date, e date, period for mytime(s,e)); --echo # CONSTRAINT CHECK (s < e) is added implicitly, and shouldn't be shown --echo # this is important for correct command-based replication show create table t; +create view v as select * from t; select * from information_schema.periods; +--sorted_result +select * from information_schema.key_period_usage; +drop view v; create or replace table t (id int primary key, s timestamp(6), e timestamp(6), period for mytime(s,e)); @@ -101,3 +105,33 @@ create table t2 (s date, e date, period for `abcd123456789012345678901234567890123456789012345678901234567890` (s,e)); drop table t2; + + +--echo # MDEV-32205 Server crashes in get_schema_key_period_usage_record on +--echo # server without InnoDB + +--echo # Make sure innodb id disabled, but there's at least one innodb table +--disable_warnings +select "yes" from information_schema.tables where engine="innodb" limit 1; +select plugin_status from information_schema.all_plugins where plugin_name = "innodb"; +select * from information_schema.periods; +select * from information_schema.key_period_usage; +--enable_warnings + +--echo # [DUPLICATE] MDEV-32204 Server crashes in +--echo # get_schema_key_period_usage_record + +create table t (a date) engine=myisam; +create table t1 (a int) engine=merge union = (t) ; + +--sorted_result +select 1 from information_schema.key_period_usage; +drop table t1; +drop table t; + +create view v1 as select 1; +create view v2 as select * from v1; +drop view v1; +--sorted_result +select * from information_schema.key_period_usage; +drop view v2; diff --git a/mysql-test/suite/period/t/i_s_notembedded.test b/mysql-test/suite/period/t/i_s_notembedded.test index 519b682315d..7450ac0818f 100644 --- a/mysql-test/suite/period/t/i_s_notembedded.test +++ b/mysql-test/suite/period/t/i_s_notembedded.test @@ -14,6 +14,7 @@ create or replace table t2 (id int primary key, s timestamp(6), e timestamp(6), show columns from t1; +--sorted_result select * from information_schema.periods where table_schema = 'test'; create user periods_hidden@localhost; @@ -21,14 +22,17 @@ create user periods_hidden@localhost; grant create on test.nonexist to periods_hidden@localhost; --connect (chopped,localhost,periods_hidden,,test) +--sorted_result select * from information_schema.periods where table_schema = 'test'; --connection default grant select(id) on test.t1 to periods_hidden@localhost; --connection chopped +--sorted_result select * from information_schema.periods where table_schema = 'test'; --connection default grant select(s) on test.t1 to periods_hidden@localhost; --connection chopped +--sorted_result select * from information_schema.periods where table_schema = 'test'; --connection default grant select(e) on test.t2 to periods_hidden@localhost; diff --git a/mysql-test/suite/period/t/overlaps.test b/mysql-test/suite/period/t/overlaps.test index 0cd70e84d14..b7aa531faa3 100644 --- a/mysql-test/suite/period/t/overlaps.test +++ b/mysql-test/suite/period/t/overlaps.test @@ -13,12 +13,14 @@ create or replace table t(id int, s date, e date, --replace_result $default_engine DEFAULT_ENGINE show create table t; +--sorted_result select * from information_schema.key_period_usage; create or replace table t_multi(id int, id2 int, s date, e date, period for very_interesting_period(s,e), primary key(id, very_interesting_period without overlaps), unique(id2, very_interesting_period without overlaps) ); +--sorted_result select * from information_schema.key_period_usage; drop table t_multi; diff --git a/plugin/type_geom/plugin.cc b/plugin/type_geom/plugin.cc index b462a34cef9..1b740ebb799 100644 --- a/plugin/type_geom/plugin.cc +++ b/plugin/type_geom/plugin.cc @@ -158,17 +158,6 @@ static int get_geometry_column_record(THD *thd, TABLE_LIST *tables, Field **ptr, *field; DBUG_ENTER("get_geometry_column_record"); - if (res) - { - /* - open_table() failed with an error. - Convert the error to a warning and let the caller - continue with the next table. - */ - convert_error_to_warning(thd); - DBUG_RETURN(0); - } - // Skip INFORMATION_SCHEMA tables. They don't have geometry columns. if (tables->schema_table) DBUG_RETURN(0); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 29796048335..688495b60cf 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4685,7 +4685,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, LEX *old_lex= thd->lex, temp_lex, *lex; LEX_CSTRING db_name, table_name; TABLE_LIST *table_list; - bool result= true; + bool result= true, open_result, run, ext_error_handling; DBUG_ENTER("fill_schema_table_by_open"); /* @@ -4762,7 +4762,7 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, } DBUG_ASSERT(thd->lex == lex); - result= open_tables_only_view_structure(thd, table_list, can_deadlock); + open_result= open_tables_only_view_structure(thd, table_list, can_deadlock); DEBUG_SYNC(thd, "after_open_table_ignore_flush"); @@ -4777,28 +4777,41 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, Again we don't do this for SHOW COLUMNS/KEYS because of backward compatibility. */ - if (!is_show_fields_or_keys && result && thd->is_error() && - (thd->get_stmt_da()->sql_errno() == ER_NO_SUCH_TABLE || - thd->get_stmt_da()->sql_errno() == ER_WRONG_OBJECT || - thd->get_stmt_da()->sql_errno() == ER_NOT_SEQUENCE)) + result= open_result; + run= true; + ext_error_handling= schema_table->i_s_requested_object + & I_S_EXTENDED_ERROR_HANDLING; + if (result && thd->is_error()) { - /* - Hide error for a non-existing table. - For example, this error can occur when we use a where condition - with a db name and table, but the table does not exist or - there is a view with the same name. - */ - result= false; - thd->clear_error(); + if (!is_show_fields_or_keys) + { + /* + Hide error for a non-existing table and skip processing. + For example, this error can occur when we use a where condition + with a db name and table, but the table does not exist or + there is a view with the same name. + Some errors, like ER_UNKNOWN_STORAGE_ENGINE, can still allow table + processing, if the information schema table supports that. + */ + run= run && thd->get_stmt_da()->sql_errno() != ER_NO_SUCH_TABLE + && thd->get_stmt_da()->sql_errno() != ER_WRONG_OBJECT + && thd->get_stmt_da()->sql_errno() != ER_NOT_SEQUENCE; + if (!run) + thd->clear_error(); + else if (!ext_error_handling) + convert_error_to_warning(thd); + result= false; + } } - else + + if (run && (!open_result || ext_error_handling)) { char buf[NAME_CHAR_LEN + 1]; if (unlikely(thd->is_error())) get_table_engine_for_i_s(thd, buf, table_list, &db_name, &table_name); result= schema_table->process_table(thd, table_list, - table, result, + table, open_result, orig_db_name, orig_table_name); } @@ -5122,7 +5135,7 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, { res= 0; } - else + else if (schema_table->i_s_requested_object & I_S_EXTENDED_ERROR_HANDLING) { char buf[NAME_CHAR_LEN + 1]; get_table_engine_for_i_s(thd, buf, &table_list, db_name, table_name); @@ -5130,6 +5143,11 @@ static int fill_schema_table_from_frm(THD *thd, MEM_ROOT *mem_root, res= schema_table->process_table(thd, &table_list, table, true, db_name, table_name); } + else + { + if (thd->is_error()) + convert_error_to_warning(thd); + } goto end; } @@ -5350,6 +5368,7 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) */ if (lsel && lsel->table_list.first) { + DBUG_ASSERT(thd->sql_command_flags() & CF_STATUS_COMMAND); error= fill_schema_table_by_open(thd, thd->mem_root, TRUE, table, schema_table, &lsel->table_list.first->db, @@ -6315,20 +6334,6 @@ int get_schema_column_record(THD *thd, TABLE_LIST *tables, bool quoted_defaults= lex->sql_command != SQLCOM_SHOW_FIELDS; DBUG_ENTER("get_schema_column_record"); - if (res) - { - if (lex->sql_command != SQLCOM_SHOW_FIELDS) - { - /* - I.e. we are in SELECT FROM INFORMATION_SCHEMA.COLUMS - rather than in SHOW COLUMNS - */ - if (thd->is_error()) - convert_error_to_warning(thd); - res= 0; - } - DBUG_RETURN(res); - } show_table= tables->table; count= 0; ptr= show_table->field; @@ -7146,24 +7151,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, { CHARSET_INFO *cs= system_charset_info; DBUG_ENTER("get_schema_stat_record"); - if (res) - { - if (thd->lex->sql_command != SQLCOM_SHOW_KEYS) - { - /* - I.e. we are in SELECT FROM INFORMATION_SCHEMA.STATISTICS - rather than in SHOW KEYS - */ - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - res= 0; - } - DBUG_RETURN(res); - } - else if (!tables->view) + if (!tables->view) { TABLE *show_table= tables->table; KEY *key_info=show_table->s->key_info; @@ -7453,15 +7441,6 @@ static int get_check_constraints_record(THD *thd, TABLE_LIST *tables, const LEX_CSTRING *table_name) { DBUG_ENTER("get_check_constraints_record"); - if (res) - { - if (thd->is_error()) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } if (!tables->view) { StringBuffer str(system_charset_info); @@ -7505,16 +7484,7 @@ static int get_schema_constraints_record(THD *thd, TABLE_LIST *tables, const LEX_CSTRING *table_name) { DBUG_ENTER("get_schema_constraints_record"); - if (res) - { - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } - else if (!tables->view) + if (!tables->view) { /* need any non-SELECT privilege on the table or any of its columns */ if (!get_schema_privileges_for_show(thd, tables, TABLE_ACLS & ~SELECT_ACL, @@ -7632,19 +7602,6 @@ static int get_schema_triggers_record(THD *thd, TABLE_LIST *tables, const LEX_CSTRING *table_name) { DBUG_ENTER("get_schema_triggers_record"); - /* - res can be non zero value when processed table is a view or - error happened during opening of processed table. - */ - if (res) - { - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } if (!tables->view && tables->table->triggers) { Table_triggers_list *triggers= tables->table->triggers; @@ -7710,16 +7667,7 @@ get_schema_key_column_usage_record(THD *thd, TABLE_LIST *tables, const LEX_CSTRING *table_name) { DBUG_ENTER("get_schema_key_column_usage_record"); - if (res) - { - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } - else if (!tables->view) + if (!tables->view) { List f_key_list; TABLE *show_table= tables->table; @@ -7837,8 +7785,6 @@ int get_schema_key_period_usage_record(THD *thd, TABLE_LIST *tables, { const uint keys_total= tables->table->s->keys; const KEY *keys= tables->table->s->key_info; - if (!tables->table) - return 0; const Lex_ident &period_name= tables->table->s->period.name; if (!period_name) return 0; @@ -7990,15 +7936,6 @@ static int get_schema_partitions_record(THD *thd, TABLE_LIST *tables, #endif DBUG_ENTER("get_schema_partitions_record"); - if (res) - { - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } file= show_table->file; #ifdef WITH_PARTITION_STORAGE_ENGINE part_info= show_table->part_info; @@ -8583,15 +8520,6 @@ get_referential_constraints_record(THD *thd, TABLE_LIST *tables, LEX_CSTRING *s; DBUG_ENTER("get_referential_constraints_record"); - if (res) - { - if (unlikely(thd->is_error())) - push_warning(thd, Sql_condition::WARN_LEVEL_WARN, - thd->get_stmt_da()->sql_errno(), - thd->get_stmt_da()->message()); - thd->clear_error(); - DBUG_RETURN(0); - } if (!tables->view) { List f_key_list; @@ -10447,7 +10375,7 @@ ST_SCHEMA_TABLE schema_tables[]= OPTIMIZE_I_S_TABLE|OPEN_TABLE_ONLY}, {"PERIODS", Show::periods_fields_info, 0, get_all_tables, 0, get_schema_period_records, 1, 2, 0, - OPTIMIZE_I_S_TABLE | OPEN_FRM_FILE_ONLY}, + OPTIMIZE_I_S_TABLE | OPEN_TABLE_ONLY}, {"PLUGINS", Show::plugin_fields_info, 0, fill_plugins, make_old_format, 0, -1, -1, 0, 0}, {"PROCESSLIST", Show::processlist_fields_info, 0, @@ -10477,7 +10405,7 @@ ST_SCHEMA_TABLE schema_tables[]= fill_sysvars, make_old_format, 0, 0, -1, 0, 0}, {"TABLES", Show::tables_fields_info, 0, get_all_tables, make_old_format, get_schema_tables_record, 1, 2, 0, - OPTIMIZE_I_S_TABLE}, + OPTIMIZE_I_S_TABLE|I_S_EXTENDED_ERROR_HANDLING}, {"TABLESPACES", Show::tablespaces_fields_info, 0, hton_fill_schema_table, 0, 0, -1, -1, 0, 0}, {"TABLE_CONSTRAINTS", Show::table_constraints_fields_info, 0, @@ -10494,7 +10422,7 @@ ST_SCHEMA_TABLE schema_tables[]= fill_schema_user_privileges, 0, 0, -1, -1, 0, 0}, {"VIEWS", Show::view_fields_info, 0, get_all_tables, 0, get_schema_views_record, 1, 2, 0, - OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE}, + OPEN_VIEW_ONLY|OPTIMIZE_I_S_TABLE|I_S_EXTENDED_ERROR_HANDLING}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; diff --git a/sql/unireg.h b/sql/unireg.h index 1eec3585acc..f730faf665a 100644 --- a/sql/unireg.h +++ b/sql/unireg.h @@ -130,6 +130,13 @@ */ #define OPEN_TRIGGER_ONLY (1 << 21) +/** + This flag is used in information schema to determine if handling funciton + can treat open result extensively and provide some user output even if + table open fails. +*/ +#define I_S_EXTENDED_ERROR_HANDLING (1 << 22) + /* Minimum length pattern before Turbo Boyer-Moore is used for SELECT "text" LIKE "%pattern%", excluding the two