Commit 6e80e9a4 authored by unknown's avatar unknown

Fixed bug#15962: CONCAT() in UNION may lead to a data trucation.

To calculate its max_length the CONCAT() function is simply sums max_lengths
of its arguments but when the collation of an argument differs from the 
collation of the CONCAT() max_length will be wrong. This may lead to a data
truncation when a tmp table is used, in UNIONS for example.

The Item_func_concat::fix_length_and_dec() function now recalculates the 
max_length of an argument when the mbmaxlen of the argument differs from the
mbmaxlen of the CONCAT().


mysql-test/t/func_concat.test:
  Added test case for bug#15962:CONCAT() in UNION may lead to a data trucation.
mysql-test/r/func_concat.result:
  Added test case for bug#15962:CONCAT() in UNION may lead to a data trucation.
sql/item_strfunc.cc:
  Fixed bug#15962: CONCAT() in UNION may lead to a data trucation.
  The Item_func_concat::fix_length_and_dec() function now recalculates the 
  max_length of an argument when the mbmaxlen of the argument differs from the
  mbmaxlen of the CONCAT().
parent 63d63364
......@@ -68,3 +68,10 @@ select 'a' union select concat('a', -0.0000);
a
a
a0.0000
create table t1(f1 varchar(6)) charset=utf8;
insert into t1 values ("123456");
select concat(f1, 2) a from t1 union select 'x' a from t1;
a
1234562
x
drop table t1;
......@@ -53,3 +53,11 @@ select 'a' union select concat('a', -0.0);
select 'a' union select concat('a', -0.0000);
# End of 4.1 tests
#
# Bug#15962: CONCAT() in UNION may lead to a data trucation.
#
create table t1(f1 varchar(6)) charset=utf8;
insert into t1 values ("123456");
select concat(f1, 2) a from t1 union select 'x' a from t1;
drop table t1;
......@@ -389,7 +389,14 @@ void Item_func_concat::fix_length_and_dec()
return;
for (uint i=0 ; i < arg_count ; i++)
max_result_length+= args[i]->max_length;
{
if (args[i]->collation.collation->mbmaxlen != collation.collation->mbmaxlen)
max_result_length+= (args[i]->max_length /
args[i]->collation.collation->mbmaxlen) *
collation.collation->mbmaxlen;
else
max_result_length+= args[i]->max_length;
}
if (max_result_length >= MAX_BLOB_WIDTH)
{
......
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