Commit 5fbc2904 authored by Sergey Glukhov's avatar Sergey Glukhov

Bug#46815 CONCAT_WS returning wrong data

The problem is that argument buffer can be used as result buffer
and it leads to argument value change.
The fix is to use 'old buffer' as result buffer only
if first argument is not constant item.
parent 54847eff
...@@ -2196,4 +2196,13 @@ SELECT LOAD_FILE(a) FROM t1; ...@@ -2196,4 +2196,13 @@ SELECT LOAD_FILE(a) FROM t1;
LOAD_FILE(a) LOAD_FILE(a)
NULL NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (f2 VARCHAR(20));
CREATE TABLE t2 (f2 VARCHAR(20));
INSERT INTO t1 VALUES ('MIN'),('MAX');
INSERT INTO t2 VALUES ('LOAD');
SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
concat_name
LOAD_MIN
LOAD_MAX
DROP TABLE t1, t2;
End of 5.0 tests End of 5.0 tests
...@@ -1177,5 +1177,18 @@ INSERT INTO t1 VALUES ('aaaaaaaa'); ...@@ -1177,5 +1177,18 @@ INSERT INTO t1 VALUES ('aaaaaaaa');
SELECT LOAD_FILE(a) FROM t1; SELECT LOAD_FILE(a) FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#46815 CONCAT_WS returning wrong data
#
CREATE TABLE t1 (f2 VARCHAR(20));
CREATE TABLE t2 (f2 VARCHAR(20));
INSERT INTO t1 VALUES ('MIN'),('MAX');
INSERT INTO t2 VALUES ('LOAD');
SELECT CONCAT_WS('_', (SELECT t2.f2 FROM t2), t1.f2) AS concat_name FROM t1;
DROP TABLE t1, t2;
--echo End of 5.0 tests --echo End of 5.0 tests
...@@ -600,6 +600,7 @@ String *Item_func_concat_ws::val_str(String *str) ...@@ -600,6 +600,7 @@ String *Item_func_concat_ws::val_str(String *str)
String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info), String tmp_sep_str(tmp_str_buff, sizeof(tmp_str_buff),default_charset_info),
*sep_str, *res, *res2,*use_as_buff; *sep_str, *res, *res2,*use_as_buff;
uint i; uint i;
bool is_const= 0;
null_value=0; null_value=0;
if (!(sep_str= args[0]->val_str(&tmp_sep_str))) if (!(sep_str= args[0]->val_str(&tmp_sep_str)))
...@@ -613,7 +614,11 @@ String *Item_func_concat_ws::val_str(String *str) ...@@ -613,7 +614,11 @@ String *Item_func_concat_ws::val_str(String *str)
// If not, return the empty string // If not, return the empty string
for (i=1; i < arg_count; i++) for (i=1; i < arg_count; i++)
if ((res= args[i]->val_str(str))) if ((res= args[i]->val_str(str)))
{
is_const= args[i]->const_item() || !args[i]->used_tables();
break; break;
}
if (i == arg_count) if (i == arg_count)
return &my_empty_string; return &my_empty_string;
...@@ -631,7 +636,7 @@ String *Item_func_concat_ws::val_str(String *str) ...@@ -631,7 +636,7 @@ String *Item_func_concat_ws::val_str(String *str)
current_thd->variables.max_allowed_packet); current_thd->variables.max_allowed_packet);
goto null; goto null;
} }
if (res->alloced_length() >= if (!is_const && res->alloced_length() >=
res->length() + sep_str->length() + res2->length()) res->length() + sep_str->length() + res2->length())
{ // Use old buffer { // Use old buffer
res->append(*sep_str); // res->length() > 0 always res->append(*sep_str); // res->length() > 0 always
......
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