diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2016-09-26 18:15:11 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2016-12-06 18:53:46 +0100 |
commit | 035a5ac62a0215c2f6e3e363331e3e984d780138 (patch) | |
tree | 3c54ab29589306bac0624b94fec55f8ebde1fa69 | |
parent | f988bcecfde819d3d3d2d7227789491fcc0ee430 (diff) | |
download | mariadb-git-035a5ac62a0215c2f6e3e363331e3e984d780138.tar.gz |
MDEV-10713: signal 11 error on multi-table update - crash in handler::increment_statistics or in make_select or assertion failure pfs_thread == ((PFS_thread*) pthread_getspecific((THR_PFS)))
Move expression execution out of Item constructor.
-rw-r--r-- | mysql-test/r/sp.result | 38 | ||||
-rw-r--r-- | mysql-test/t/sp.test | 50 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 14 | ||||
-rw-r--r-- | sql/item_strfunc.h | 28 |
4 files changed, 113 insertions, 17 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 6214fbcde35..d15031989bf 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -8016,4 +8016,42 @@ Warnings: Error 1329 No data - zero rows fetched, selected, or processed DROP PROCEDURE p1; DROP TABLE t1; +# +# MDEV-10713: signal 11 error on multi-table update - crash in +# handler::increment_statistics or in make_select or assertion +# failure pfs_thread == ((PFS_thread*) pthread_getspecific((THR_PFS))) +# +CREATE TABLE `t1` ( +`CLOSE_YN` varchar(10) COLLATE utf8_bin DEFAULT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; +CREATE TABLE `t2` ( +`ap_close_to` varchar(8) COLLATE utf8_bin DEFAULT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; +CREATE FUNCTION `f1`(`P_DC_CD` VARBINARY(50), `P_SYS_DATE` DATETIME) RETURNS datetime +DETERMINISTIC +SQL SECURITY INVOKER +BEGIN +DECLARE V_SYS_DATE DATETIME; +SELECT now() AS LOC_DATE INTO V_SYS_DATE ; +RETURN v_sys_date ; +END $$ +update t1 S +JOIN +( +SELECT CASE +WHEN DATE_FORMAT( f1('F01', NOW()) , '%Y%m%d') <= CLOSE_YMD +THEN '99991231' + ELSE '' END ACCOUNT_APPLY_YYYYMMDD +FROM ( +select case +when 'AP'='AP' + then ap_close_to +end AS CLOSE_YMD +from t2 +) A +) X +SET S.CLOSE_YN = '' +where 1=1; +drop function if exists f1; +drop table t1,t2; # End of 5.5 test diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index ecb12408654..b56ab6c3b11 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -9302,4 +9302,54 @@ CALL p1; DROP PROCEDURE p1; DROP TABLE t1; +--echo # +--echo # MDEV-10713: signal 11 error on multi-table update - crash in +--echo # handler::increment_statistics or in make_select or assertion +--echo # failure pfs_thread == ((PFS_thread*) pthread_getspecific((THR_PFS))) +--echo # + +CREATE TABLE `t1` ( + `CLOSE_YN` varchar(10) COLLATE utf8_bin DEFAULT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; + + +CREATE TABLE `t2` ( + `ap_close_to` varchar(8) COLLATE utf8_bin DEFAULT NULL +) DEFAULT CHARSET=utf8 COLLATE=utf8_bin ; + + +--delimiter $$ + +CREATE FUNCTION `f1`(`P_DC_CD` VARBINARY(50), `P_SYS_DATE` DATETIME) RETURNS datetime + DETERMINISTIC + SQL SECURITY INVOKER +BEGIN + DECLARE V_SYS_DATE DATETIME; + SELECT now() AS LOC_DATE INTO V_SYS_DATE ; + RETURN v_sys_date ; +END $$ + +--delimiter ; + +update t1 S +JOIN +( + SELECT CASE + WHEN DATE_FORMAT( f1('F01', NOW()) , '%Y%m%d') <= CLOSE_YMD + THEN '99991231' + ELSE '' END ACCOUNT_APPLY_YYYYMMDD + FROM ( + select case + when 'AP'='AP' + then ap_close_to + end AS CLOSE_YMD + from t2 + ) A +) X +SET S.CLOSE_YN = '' +where 1=1; + +drop function if exists f1; +drop table t1,t2; + --echo # End of 5.5 test diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 94370d45cef..93e2edf9975 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2951,7 +2951,19 @@ String *Item_func_conv::val_str(String *str) String *Item_func_conv_charset::val_str(String *str) { DBUG_ASSERT(fixed == 1); - if (use_cached_value) + if (cached_value == CONST_WILL_BE_CACHED) + { + uint errors= 0; + String tmp, *str= args[0]->val_str(&tmp); + if (!str || str_value.copy(str->ptr(), str->length(), + str->charset(), conv_charset, &errors)) + null_value= 1; + cached_value= CACHED; + str_value.mark_as_const(); + safe= (errors == 0); + is_expensive_cache= 0; + } + if (cached_value == CACHED) return null_value ? 0 : &str_value; String *arg= args[0]->val_str(str); uint dummy_errors; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 7606c281548..459dc5af34e 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -817,31 +817,26 @@ public: class Item_func_conv_charset :public Item_str_func { - bool use_cached_value; String tmp_value; + enum state_of_cache { NOT_CONST, CONST_WILL_BE_CACHED, CACHED }; + enum state_of_cache cached_value; public: bool safe; CHARSET_INFO *conv_charset; // keep it public - Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a) - { conv_charset= cs; use_cached_value= 0; safe= 0; } - Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) - :Item_str_func(a) + Item_func_conv_charset(Item *a, CHARSET_INFO *cs) :Item_str_func(a), + cached_value(NOT_CONST), safe(0), conv_charset(cs) + {} + Item_func_conv_charset(Item *a, CHARSET_INFO *cs, bool cache_if_const) + :Item_str_func(a), conv_charset(cs) { - conv_charset= cs; - if (cache_if_const && args[0]->const_item() && !args[0]->is_expensive()) + if (cache_if_const && args[0]->const_item()) { - uint errors= 0; - String tmp, *str= args[0]->val_str(&tmp); - if (!str || str_value.copy(str->ptr(), str->length(), - str->charset(), conv_charset, &errors)) - null_value= 1; - use_cached_value= 1; - str_value.mark_as_const(); - safe= (errors == 0); + is_expensive_cache= MY_TEST(args[0]->is_expensive()); + cached_value= CONST_WILL_BE_CACHED; } else { - use_cached_value= 0; + cached_value= NOT_CONST; /* Conversion from and to "binary" is safe. Conversion to Unicode is safe. @@ -892,6 +887,7 @@ public: void fix_length_and_dec(); const char *func_name() const { return "convert"; } virtual void print(String *str, enum_query_type query_type); + virtual bool const_item() const { return cached_value != NOT_CONST; } }; class Item_func_set_collation :public Item_str_func |