Commit 035a5ac6 authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

MDEV-10713: signal 11 error on multi-table update - crash in...

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.
parent f988bcec
......@@ -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
......@@ -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
......@@ -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;
......
......@@ -817,31 +817,26 @@ class Item_func_quote :public Item_str_func
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 @@ class Item_func_conv_charset :public Item_str_func
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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment