Skip to content

Commit 0c37712

Browse files
author
Bharathy Satish
committed
Bug#27489026: PERSIST_ONLY DOESN'T RESPECT DEFAULT INSTEAD COPIES GLOBAL VALUE
Problem: When a variables default value is persisted using PERSIST_ONLY syntax, instead of persisting default value, variable current global value is persisted. Fix: Fix it to introduce a new function sys_var::saved_value_to_string() which will convert the default value present in sys_var::save_result to string.
1 parent 0ac7a57 commit 0c37712

8 files changed

+311
-15
lines changed

mysql-test/r/persisted_variables_bugs.result

+93
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,97 @@ COUNT(DISTINCT MICROSECOND(set_time))
153153
# Cleanup
154154
SET GLOBAL max_join_size=DEFAULT, init_connect=DEFAULT;
155155
RESET PERSIST;
156+
#
157+
# Bug #27489026: PERSIST_ONLY DOESN'T RESPECT DEFAULT INSTEAD COPIES GLOBAL VALUE
158+
#
159+
SELECT @@global.binlog_cache_size;
160+
@@global.binlog_cache_size
161+
32768
162+
SELECT @@global.disabled_storage_engines;
163+
@@global.disabled_storage_engines
164+
165+
SELECT @@global.collation_database;
166+
@@global.collation_database
167+
utf8mb4_0900_ai_ci
168+
SELECT @@global.innodb_flush_method;
169+
@@global.innodb_flush_method
170+
fsync
171+
SELECT @@global.innodb_open_files;
172+
@@global.innodb_open_files
173+
4000
174+
SELECT @@global.optimizer_trace_offset;
175+
@@global.optimizer_trace_offset
176+
-1
177+
SELECT @@global.optimizer_switch;
178+
@@global.optimizer_switch
179+
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off
180+
SELECT @@global.enforce_gtid_consistency;
181+
@@global.enforce_gtid_consistency
182+
OFF
183+
SELECT @@global.sql_mode;
184+
@@global.sql_mode
185+
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
186+
SET @@global.binlog_cache_size= 4096;
187+
SET @@persist_only.binlog_cache_size= default,
188+
@@persist_only.collation_database= default,
189+
@@persist_only.disabled_storage_engines= default,
190+
@@persist_only.innodb_flush_method= default,
191+
@@persist_only.innodb_open_files= default,
192+
@@persist_only.optimizer_trace_offset= default,
193+
@@persist_only.optimizer_switch= default,
194+
@@persist_only.enforce_gtid_consistency= default,
195+
@@persist_only.sql_mode= default;
196+
SELECT * FROM performance_schema.persisted_variables ORDER BY 1;
197+
VARIABLE_NAME VARIABLE_VALUE
198+
binlog_cache_size 32768
199+
collation_database utf8mb4_0900_ai_ci
200+
disabled_storage_engines
201+
enforce_gtid_consistency 0
202+
innodb_flush_method 0
203+
innodb_open_files 0
204+
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off
205+
optimizer_trace_offset -1
206+
sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
207+
# Restart server
208+
# restart
209+
SELECT @@global.binlog_cache_size;
210+
@@global.binlog_cache_size
211+
32768
212+
SELECT @@global.disabled_storage_engines;
213+
@@global.disabled_storage_engines
214+
215+
SELECT @@global.collation_database;
216+
@@global.collation_database
217+
utf8mb4_0900_ai_ci
218+
SELECT @@global.innodb_flush_method;
219+
@@global.innodb_flush_method
220+
fsync
221+
SELECT @@global.innodb_open_files;
222+
@@global.innodb_open_files
223+
4000
224+
SELECT @@global.optimizer_trace_offset;
225+
@@global.optimizer_trace_offset
226+
-1
227+
SELECT @@global.optimizer_switch;
228+
@@global.optimizer_switch
229+
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off
230+
SELECT @@global.enforce_gtid_consistency;
231+
@@global.enforce_gtid_consistency
232+
OFF
233+
SELECT @@global.sql_mode;
234+
@@global.sql_mode
235+
ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
236+
SELECT * FROM performance_schema.persisted_variables ORDER BY 1;
237+
VARIABLE_NAME VARIABLE_VALUE
238+
binlog_cache_size 32768
239+
collation_database utf8mb4_0900_ai_ci
240+
disabled_storage_engines
241+
enforce_gtid_consistency 0
242+
innodb_flush_method 0
243+
innodb_open_files 0
244+
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,engine_condition_pushdown=on,index_condition_pushdown=on,mrr=on,mrr_cost_based=on,block_nested_loop=on,batched_key_access=off,materialization=on,semijoin=on,loosescan=on,firstmatch=on,duplicateweedout=on,subquery_materialization_cost_based=on,use_index_extensions=on,condition_fanout_filter=on,derived_merge=on,use_invisible_indexes=off
245+
optimizer_trace_offset -1
246+
sql_mode ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
247+
# Cleanup
248+
RESET PERSIST;
156249
# End of the 8.0 tests

mysql-test/r/read_only_persisted_variables.result

+2-2
Original file line numberDiff line numberDiff line change
@@ -243,9 +243,9 @@ SET PERSIST_ONLY ft_query_expansion_limit= DEFAULT;
243243
SELECT * FROM performance_schema.persisted_variables ORDER BY 1;
244244
VARIABLE_NAME VARIABLE_VALUE
245245
auto_increment_increment 10
246-
ft_query_expansion_limit 200
246+
ft_query_expansion_limit 20
247247
innodb_checksum_algorithm strict_crc32
248-
innodb_log_file_size 4194304
248+
innodb_log_file_size 50331648
249249
slave_type_conversions ALL_UNSIGNED
250250
# reset slave_type_conversions
251251
RESET PERSIST slave_type_conversions;

mysql-test/t/persisted_variables_bugs.test

+51
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,57 @@ SELECT COUNT(DISTINCT MICROSECOND(set_time)) FROM performance_schema.variables_i
155155
SET GLOBAL max_join_size=DEFAULT, init_connect=DEFAULT;
156156
RESET PERSIST;
157157

158+
--echo #
159+
--echo # Bug #27489026: PERSIST_ONLY DOESN'T RESPECT DEFAULT INSTEAD COPIES GLOBAL VALUE
160+
--echo #
161+
162+
SELECT @@global.binlog_cache_size;
163+
SELECT @@global.disabled_storage_engines;
164+
SELECT @@global.collation_database;
165+
SELECT @@global.innodb_flush_method;
166+
SELECT @@global.innodb_open_files;
167+
# test SIGNED long value
168+
SELECT @@global.optimizer_trace_offset;
169+
# test Sys_var_flagset type
170+
SELECT @@global.optimizer_switch;
171+
# test Sys_var_multi_enum type
172+
SELECT @@global.enforce_gtid_consistency;
173+
# test Sys_var_set type
174+
SELECT @@global.sql_mode;
175+
# set value different from default
176+
SET @@global.binlog_cache_size= 4096;
177+
178+
# persist default values
179+
SET @@persist_only.binlog_cache_size= default,
180+
@@persist_only.collation_database= default,
181+
@@persist_only.disabled_storage_engines= default,
182+
@@persist_only.innodb_flush_method= default,
183+
@@persist_only.innodb_open_files= default,
184+
@@persist_only.optimizer_trace_offset= default,
185+
@@persist_only.optimizer_switch= default,
186+
@@persist_only.enforce_gtid_consistency= default,
187+
@@persist_only.sql_mode= default;
188+
189+
SELECT * FROM performance_schema.persisted_variables ORDER BY 1;
190+
191+
--echo # Restart server
192+
--source include/restart_mysqld.inc
193+
194+
# must have default values.
195+
SELECT @@global.binlog_cache_size;
196+
SELECT @@global.disabled_storage_engines;
197+
SELECT @@global.collation_database;
198+
SELECT @@global.innodb_flush_method;
199+
SELECT @@global.innodb_open_files;
200+
SELECT @@global.optimizer_trace_offset;
201+
SELECT @@global.optimizer_switch;
202+
SELECT @@global.enforce_gtid_consistency;
203+
SELECT @@global.sql_mode;
204+
205+
SELECT * FROM performance_schema.persisted_variables ORDER BY 1;
206+
207+
--echo # Cleanup
208+
RESET PERSIST;
158209

159210
--echo # End of the 8.0 tests
160211

sql/persisted_variable.cc

+19-11
Original file line numberDiff line numberDiff line change
@@ -292,17 +292,25 @@ void Persisted_variables_cache::set_variable(THD *thd, set_var *setvar) {
292292
const char *var_name =
293293
Persisted_variables_cache::get_variable_name(system_var);
294294
const char *var_value = val_buf;
295-
if (setvar->type == OPT_PERSIST_ONLY && setvar->value) {
296-
res = setvar->value->val_str(&str);
297-
if (res && res->length()) {
298-
/*
299-
value held by Item class can be of different charset,
300-
so convert to utf8mb4
301-
*/
302-
const CHARSET_INFO *tocs = &my_charset_utf8mb4_bin;
303-
uint dummy_err;
304-
utf8_str.copy(res->ptr(), res->length(), res->charset(), tocs,
305-
&dummy_err);
295+
if (setvar->type == OPT_PERSIST_ONLY) {
296+
const CHARSET_INFO *tocs = &my_charset_utf8mb4_bin;
297+
uint dummy_err;
298+
if (setvar->value) {
299+
res = setvar->value->val_str(&str);
300+
if (res && res->length()) {
301+
/*
302+
value held by Item class can be of different charset,
303+
so convert to utf8mb4
304+
*/
305+
utf8_str.copy(res->ptr(), res->length(), res->charset(), tocs,
306+
&dummy_err);
307+
var_value = utf8_str.c_ptr_quick();
308+
}
309+
} else {
310+
/* persist default value */
311+
setvar->var->save_default(thd, setvar);
312+
setvar->var->saved_value_to_string(thd, setvar, (char *)str.ptr());
313+
utf8_str.copy(str.ptr(), str.length(), str.charset(), tocs, &dummy_err);
306314
var_value = utf8_str.c_ptr_quick();
307315
}
308316
} else {

sql/set_var.h

+9
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,13 @@ class sys_var {
222222
bool set_default(THD *thd, set_var *var);
223223
bool update(THD *thd, set_var *var);
224224

225+
/**
226+
This function converts value stored in save_result to string. This
227+
function must ba called after calling save_default() as save_default() will
228+
store default value to save_result.
229+
*/
230+
virtual void saved_value_to_string(THD *thd, set_var *var, char *def_val) = 0;
231+
225232
SHOW_TYPE show_type() { return show_val_type; }
226233
int scope() const { return flags & SCOPE_MASK; }
227234
const CHARSET_INFO *charset(THD *thd);
@@ -284,6 +291,8 @@ class sys_var {
284291
*/
285292
Item *copy_value(THD *thd);
286293

294+
void save_default(THD *thd, set_var *var) { global_save_default(thd, var); }
295+
287296
private:
288297
virtual bool do_check(THD *thd, set_var *var) = 0;
289298
/**

sql/sql_plugin_var.cc

+77-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
1+
/* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
22
33
This program is free software; you can redistribute it and/or modify
44
it under the terms of the GNU General Public License, version 2.0,
@@ -537,6 +537,82 @@ bool sys_var_pluginvar::on_check_pluginvar(sys_var *self MY_ATTRIBUTE((unused)),
537537
return (!var->value);
538538
}
539539

540+
void sys_var_pluginvar::saved_value_to_string(THD *, set_var *var,
541+
char *def_val) {
542+
if (!var->value) {
543+
switch (plugin_var->flags & (PLUGIN_VAR_TYPEMASK | PLUGIN_VAR_THDLOCAL)) {
544+
case PLUGIN_VAR_INT:
545+
var->save_result.ulonglong_value =
546+
((sysvar_uint_t *)plugin_var)->def_val;
547+
longlong10_to_str(var->save_result.ulonglong_value, def_val, -10);
548+
return;
549+
case PLUGIN_VAR_LONG:
550+
var->save_result.ulonglong_value =
551+
((sysvar_ulong_t *)plugin_var)->def_val;
552+
longlong10_to_str(var->save_result.ulonglong_value, def_val, -10);
553+
return;
554+
case PLUGIN_VAR_LONGLONG:
555+
var->save_result.ulonglong_value =
556+
((sysvar_ulonglong_t *)plugin_var)->def_val;
557+
longlong10_to_str(var->save_result.ulonglong_value, def_val, 10);
558+
return;
559+
case PLUGIN_VAR_ENUM:
560+
var->save_result.ulonglong_value =
561+
((sysvar_enum_t *)plugin_var)->def_val;
562+
longlong10_to_str(var->save_result.ulonglong_value, def_val, 10);
563+
return;
564+
case PLUGIN_VAR_BOOL:
565+
var->save_result.ulonglong_value =
566+
((sysvar_bool_t *)plugin_var)->def_val;
567+
longlong10_to_str(var->save_result.ulonglong_value, def_val, 10);
568+
return;
569+
case PLUGIN_VAR_STR:
570+
strcpy(def_val, ((sysvar_str_t *)plugin_var)->def_val);
571+
return;
572+
case PLUGIN_VAR_DOUBLE:
573+
var->save_result.double_value =
574+
((sysvar_double_t *)plugin_var)->def_val;
575+
my_fcvt(var->save_result.double_value, 6, def_val, NULL);
576+
return;
577+
case PLUGIN_VAR_INT | PLUGIN_VAR_THDLOCAL:
578+
var->save_result.ulonglong_value =
579+
((thdvar_uint_t *)plugin_var)->def_val;
580+
longlong10_to_str(var->save_result.ulonglong_value, def_val, -10);
581+
return;
582+
case PLUGIN_VAR_LONG | PLUGIN_VAR_THDLOCAL:
583+
var->save_result.ulonglong_value =
584+
((thdvar_ulong_t *)plugin_var)->def_val;
585+
longlong10_to_str(var->save_result.ulonglong_value, def_val, -10);
586+
return;
587+
case PLUGIN_VAR_LONGLONG | PLUGIN_VAR_THDLOCAL:
588+
var->save_result.ulonglong_value =
589+
((thdvar_ulonglong_t *)plugin_var)->def_val;
590+
longlong10_to_str(var->save_result.ulonglong_value, def_val, -10);
591+
return;
592+
case PLUGIN_VAR_ENUM | PLUGIN_VAR_THDLOCAL:
593+
var->save_result.ulonglong_value =
594+
((thdvar_enum_t *)plugin_var)->def_val;
595+
longlong10_to_str(var->save_result.ulonglong_value, def_val, 10);
596+
return;
597+
case PLUGIN_VAR_BOOL | PLUGIN_VAR_THDLOCAL:
598+
var->save_result.ulonglong_value =
599+
((thdvar_bool_t *)plugin_var)->def_val;
600+
longlong10_to_str(var->save_result.ulonglong_value, def_val, 10);
601+
return;
602+
case PLUGIN_VAR_STR | PLUGIN_VAR_THDLOCAL:
603+
strcpy(def_val, ((thdvar_str_t *)plugin_var)->def_val);
604+
return;
605+
case PLUGIN_VAR_DOUBLE | PLUGIN_VAR_THDLOCAL:
606+
var->save_result.double_value =
607+
((thdvar_double_t *)plugin_var)->def_val;
608+
my_fcvt(var->save_result.double_value, 6, def_val, NULL);
609+
return;
610+
default:
611+
DBUG_ASSERT(0);
612+
}
613+
}
614+
}
615+
540616
/****************************************************************************
541617
default variable data check and update functions
542618
****************************************************************************/

sql/sql_plugin_var.h

+1
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,7 @@ class sys_var_pluginvar : public sys_var {
264264
}
265265
bool do_check(THD *thd, set_var *var);
266266
virtual void session_save_default(THD *, set_var *) {}
267+
virtual void saved_value_to_string(THD *thd, set_var *var, char *def_val);
267268
virtual void global_save_default(THD *, set_var *) {}
268269
bool session_update(THD *thd, set_var *var);
269270
bool global_update(THD *thd, set_var *var);

0 commit comments

Comments
 (0)