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().
This commit is contained in:
parent
fdc2b921cc
commit
d027dd7c0d
@ -68,3 +68,10 @@ select 'a' union select concat('a', -0.0000);
|
|||||||
a
|
a
|
||||||
a
|
a
|
||||||
a0.0000
|
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);
|
select 'a' union select concat('a', -0.0000);
|
||||||
|
|
||||||
# End of 4.1 tests
|
# 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;
|
return;
|
||||||
|
|
||||||
for (uint i=0 ; i < arg_count ; i++)
|
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)
|
if (max_result_length >= MAX_BLOB_WIDTH)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user