# Bug#8785 Problem with nested concats and

character set conversion of a string constant.
This commit is contained in:
bar@mysql.com 2005-03-15 17:15:47 +04:00
parent 50a6dc4e71
commit c6c887b990
5 changed files with 33 additions and 2 deletions

View File

@ -861,6 +861,13 @@ user c
one <one>
two <two>
DROP TABLE t1;
create table t1 (f1 varchar(1) not null) default charset utf8;
insert into t1 values (''), ('');
select concat(concat(_latin1'->',f1),_latin1'<-') from t1;
concat(concat(_latin1'->',f1),_latin1'<-')
-><-
-><-
drop table t1;
select convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8);
convert(_koi8r'É' using utf8) < convert(_koi8r'Ê' using utf8)
1

View File

@ -694,6 +694,15 @@ SELECT CHARSET('a');
SELECT user, CONCAT('<', user, '>') AS c FROM t1;
DROP TABLE t1;
#
# Bug#8785
# the same problem with the above, but with nested CONCATs
#
create table t1 (f1 varchar(1) not null) default charset utf8;
insert into t1 values (''), ('');
select concat(concat(_latin1'->',f1),_latin1'<-') from t1;
drop table t1;
#
# Bug#8385: utf8_general_ci treats Cyrillic letters I and SHORT I as the same
#

View File

@ -236,6 +236,18 @@ Item *Item_string::safe_charset_converter(CHARSET_INFO *tocs)
return NULL;
}
conv->str_value.copy();
/*
The above line executes str_value.realloc() internally,
which alligns Alloced_length using ALLIGN_SIZE.
In the case of Item_string::str_value we don't want
Alloced_length to be longer than str_length.
Otherwise, some functions like Item_func_concat::val_str()
try to reuse str_value as a buffer for concatenation result
for optimization purposes, so our string constant become
corrupted. See bug#8785 for more details.
Let's shrink Alloced_length to str_length to avoid this problem.
*/
conv->str_value.shrink_to_length();
return conv;
}

View File

@ -277,8 +277,7 @@ String *Item_func_concat::val_str(String *str)
current_thd->variables.max_allowed_packet);
goto null;
}
if (!args[0]->const_item() &&
res->alloced_length() >= res->length()+res2->length())
if (res->alloced_length() >= res->length()+res2->length())
{ // Use old buffer
res->append(*res2);
}

View File

@ -177,6 +177,10 @@ public:
}
}
}
inline void shrink_to_length()
{
Alloced_length= str_length;
}
bool is_alloced() { return alloced; }
inline String& operator = (const String &s)
{