1 |
=== modified file 'mysql-test/r/information_schema.result' |
2 |
--- a/mysql-test/r/information_schema.result 2012-12-18 10:44:15 +0000 |
3 |
+++ b/mysql-test/r/information_schema.result 2013-01-16 13:49:47 +0000 |
4 |
@@ -1931,6 +1931,15 @@ |
5 |
# |
6 |
# Switching to connection 'default'. |
7 |
# |
8 |
+# |
9 |
+# MDEV-4029, Bug#58738: double locking mutex when querying i_s.session_status in query and it's subquery |
10 |
+# |
11 |
+SELECT * FROM information_schema.session_status |
12 |
+WHERE VARIABLE_NAME = ( |
13 |
+SELECT VARIABLE_NAME FROM information_schema.session_status WHERE VARIABLE_NAME = 'COM_BEGIN' |
14 |
+); |
15 |
+VARIABLE_NAME VARIABLE_VALUE |
16 |
+COM_BEGIN 0 |
17 |
# |
18 |
# Clean-up. |
19 |
drop database mysqltest; |
20 |
|
21 |
=== modified file 'mysql-test/t/information_schema.test' |
22 |
--- a/mysql-test/t/information_schema.test 2012-12-18 10:44:15 +0000 |
23 |
+++ b/mysql-test/t/information_schema.test 2013-01-16 13:45:49 +0000 |
24 |
@@ -1808,6 +1808,14 @@ |
25 |
disconnect con12828477_3; |
26 |
|
27 |
--echo # |
28 |
+--echo # MDEV-4029, Bug#58738: double locking mutex when querying i_s.session_status in query and it's subquery |
29 |
+--echo # |
30 |
+SELECT * FROM information_schema.session_status |
31 |
+WHERE VARIABLE_NAME = ( |
32 |
+ SELECT VARIABLE_NAME FROM information_schema.session_status WHERE VARIABLE_NAME = 'COM_BEGIN' |
33 |
+); |
34 |
+ |
35 |
+--echo # |
36 |
--echo # Clean-up. |
37 |
drop database mysqltest; |
38 |
|
39 |
|
40 |
=== modified file 'sql/sql_show.cc' |
41 |
--- a/sql/sql_show.cc 2013-01-15 18:13:32 +0000 |
42 |
+++ b/sql/sql_show.cc 2013-01-16 13:52:36 +0000 |
43 |
@@ -2584,8 +2584,7 @@ |
44 |
enum enum_var_type value_type, |
45 |
struct system_status_var *status_var, |
46 |
const char *prefix, TABLE *table, |
47 |
- bool ucase_names, |
48 |
- COND *cond) |
49 |
+ bool ucase_names, COND* partial_cond) |
50 |
{ |
51 |
my_aligned_storage<SHOW_VAR_FUNC_BUFF_SIZE, MY_ALIGNOF(long)> buffer; |
52 |
char * const buff= buffer.data; |
53 |
@@ -2595,7 +2594,6 @@ |
54 |
int len; |
55 |
LEX_STRING null_lex_str; |
56 |
SHOW_VAR tmp, *var; |
57 |
- COND *partial_cond= 0; |
58 |
enum_check_fields save_count_cuted_fields= thd->count_cuted_fields; |
59 |
bool res= FALSE; |
60 |
CHARSET_INFO *charset= system_charset_info; |
61 |
@@ -2609,7 +2607,6 @@ |
62 |
if (*prefix) |
63 |
*prefix_end++= '_'; |
64 |
len=name_buffer + sizeof(name_buffer) - prefix_end; |
65 |
- partial_cond= make_cond_for_info_schema(cond, table->pos_in_table_list); |
66 |
|
67 |
for (; variables->name; variables++) |
68 |
{ |
69 |
@@ -6893,6 +6890,12 @@ |
70 |
enum enum_var_type option_type= OPT_SESSION; |
71 |
bool upper_case_names= (schema_table_idx != SCH_VARIABLES); |
72 |
bool sorted_vars= (schema_table_idx == SCH_VARIABLES); |
73 |
+ COND* partial_cond= |
74 |
+ make_cond_for_info_schema(cond, tables->table->pos_in_table_list); |
75 |
+ // this can trigger subquery execution and entry into this function again |
76 |
+ // so we execute it before taking the lock to fill the table |
77 |
+ if (partial_cond) |
78 |
+ partial_cond->val_int(); |
79 |
|
80 |
if (lex->option_type == OPT_GLOBAL || |
81 |
schema_table_idx == SCH_GLOBAL_VARIABLES) |
82 |
@@ -6900,7 +6903,7 @@ |
83 |
|
84 |
mysql_rwlock_rdlock(&LOCK_system_variables_hash); |
85 |
res= show_status_array(thd, wild, enumerate_sys_vars(thd, sorted_vars, option_type), |
86 |
- option_type, NULL, "", tables->table, upper_case_names, cond); |
87 |
+ option_type, NULL, "", tables->table, upper_case_names, partial_cond); |
88 |
mysql_rwlock_unlock(&LOCK_system_variables_hash); |
89 |
DBUG_RETURN(res); |
90 |
} |
91 |
@@ -6917,6 +6920,12 @@ |
92 |
get_schema_table_idx(tables->schema_table); |
93 |
enum enum_var_type option_type; |
94 |
bool upper_case_names= (schema_table_idx != SCH_STATUS); |
95 |
+ COND* partial_cond= |
96 |
+ make_cond_for_info_schema(cond, tables->table->pos_in_table_list); |
97 |
+ // this can trigger subquery execution and reentrance into this function |
98 |
+ // so we execute it before taking the mutex to fill the table |
99 |
+ if (partial_cond) |
100 |
+ partial_cond->val_int(); |
101 |
|
102 |
if (schema_table_idx == SCH_STATUS) |
103 |
{ |
104 |
@@ -6943,7 +6952,7 @@ |
105 |
res= show_status_array(thd, wild, |
106 |
(SHOW_VAR *)all_status_vars.buffer, |
107 |
option_type, tmp1, "", tables->table, |
108 |
- upper_case_names, cond); |
109 |
+ upper_case_names, partial_cond); |
110 |
mysql_mutex_unlock(&LOCK_status); |
111 |
DBUG_RETURN(res); |
112 |
} |
113 |
|