=== modified file 'mysql-test/r/information_schema.result' --- mysql-test/r/information_schema.result 2012-12-18 10:44:15 +0000 +++ mysql-test/r/information_schema.result 2013-01-16 13:49:47 +0000 @@ -1954,6 +1954,15 @@ Note 1003 select `information_schema`.`columns`.`COLUMN_NAME` AS `column_name` from `information_schema`.`columns` where ((`information_schema`.`columns`.`TABLE_SCHEMA` = 'osm') and (`information_schema`.`columns`.`TABLE_NAME` = 'test')) drop view v1; # +# MDEV-4029, Bug#58738: double locking mutex when querying i_s.session_status in query and it's subquery +# +SELECT * FROM information_schema.session_status +WHERE VARIABLE_NAME = ( +SELECT VARIABLE_NAME FROM information_schema.session_status WHERE VARIABLE_NAME = 'COM_BEGIN' +); +VARIABLE_NAME VARIABLE_VALUE +COM_BEGIN 0 +# # Clean-up. drop database mysqltest; # === modified file 'mysql-test/t/information_schema.test' --- mysql-test/t/information_schema.test 2012-12-18 10:44:15 +0000 +++ mysql-test/t/information_schema.test 2013-01-16 13:45:49 +0000 @@ -1808,6 +1808,14 @@ drop view v1; --echo # +--echo # MDEV-4029, Bug#58738: double locking mutex when querying i_s.session_status in query and it's subquery +--echo # +SELECT * FROM information_schema.session_status +WHERE VARIABLE_NAME = ( + SELECT VARIABLE_NAME FROM information_schema.session_status WHERE VARIABLE_NAME = 'COM_BEGIN' +); + +--echo # --echo # Clean-up. drop database mysqltest; === modified file 'sql/sql_show.cc' --- sql/sql_show.cc 2013-01-15 18:13:32 +0000 +++ sql/sql_show.cc 2013-01-16 13:52:36 +0000 @@ -2584,8 +2584,7 @@ enum enum_var_type value_type, struct system_status_var *status_var, const char *prefix, TABLE *table, - bool ucase_names, - COND *cond) + bool ucase_names, COND* partial_cond) { my_aligned_storage buffer; char * const buff= buffer.data; @@ -2595,7 +2594,6 @@ int len; LEX_STRING null_lex_str; SHOW_VAR tmp, *var; - COND *partial_cond= 0; enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; bool res= FALSE; CHARSET_INFO *charset= system_charset_info; @@ -2609,7 +2607,6 @@ if (*prefix) *prefix_end++= '_'; len=name_buffer + sizeof(name_buffer) - prefix_end; - partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list); for (; variables->name; variables++) { @@ -6893,6 +6890,12 @@ enum enum_var_type option_type= OPT_SESSION; bool upper_case_names= (schema_table_idx != SCH_VARIABLES); bool sorted_vars= (schema_table_idx == SCH_VARIABLES); + COND* partial_cond= + make_cond_for_info_schema(cond, tables->table->pos_in_table_list); + // this can trigger subquery execution and entry into this function again + // so we execute it before taking the lock to fill the table + if (partial_cond) + partial_cond->val_int(); if (lex->option_type == OPT_GLOBAL || schema_table_idx == SCH_GLOBAL_VARIABLES) @@ -6900,7 +6903,7 @@ mysql_rwlock_rdlock(&LOCK_system_variables_hash); res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, option_type), - option_type, NULL, "", tables->table, upper_case_names, cond); + option_type, NULL, "", tables->table, upper_case_names, partial_cond); mysql_rwlock_unlock(&LOCK_system_variables_hash); DBUG_RETURN(res); } @@ -6917,6 +6920,12 @@ get_schema_table_idx(tables->schema_table); enum enum_var_type option_type; bool upper_case_names= (schema_table_idx != SCH_STATUS); + COND* partial_cond= + make_cond_for_info_schema(cond, tables->table->pos_in_table_list); + // this can trigger subquery execution and reentrance into this function + // so we execute it before taking the mutex to fill the table + if (partial_cond) + partial_cond->val_int(); if (schema_table_idx == SCH_STATUS) { @@ -6943,7 +6952,7 @@ res= show_status_array(thd, wild, (SHOW_VAR *)all_status_vars.buffer, option_type, tmp1, "", tables->table, - upper_case_names, cond); + upper_case_names, partial_cond); mysql_mutex_unlock(&LOCK_status); DBUG_RETURN(res); }