summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOleksandr Byelkin <sanja@mariadb.com>2016-09-26 18:15:11 +0200
committerOleksandr Byelkin <sanja@mariadb.com>2016-12-06 18:53:46 +0100
commit035a5ac62a0215c2f6e3e363331e3e984d780138 (patch)
tree3c54ab29589306bac0624b94fec55f8ebde1fa69
parentf988bcecfde819d3d3d2d7227789491fcc0ee430 (diff)
downloadmariadb-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.result38
-rw-r--r--mysql-test/t/sp.test50
-rw-r--r--sql/item_strfunc.cc14
-rw-r--r--sql/item_strfunc.h28
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