Commit ebda548d authored by unknown's avatar unknown

Fix for BUG#7716: in in_string::set() take into account that the value returned

by item->val_str() may be a substring of the passed string. 
Disallow string=its_substring assignment in String::operator=().


mysql-test/r/func_misc.result:
  Testcase for BUG#7716
mysql-test/t/func_misc.test:
  Testcase for BUG#7716
sql/item_cmpfunc.cc:
  Fix for BUG#7716: in in_string::set() take into account that the string returned 
  by item->val_str(S) may be not S but use the buffer owned by S.
sql/sql_string.h:
  * Added assert: String& String::operator=(const String&) may not be used to do 
    assignments like str = string_that_uses_buffer_owned_by_str
  * Added String::uses_buffer_owned_by().
parent bd556f0d
...@@ -28,3 +28,24 @@ length(format('nan', 2)) > 0 ...@@ -28,3 +28,24 @@ length(format('nan', 2)) > 0
select concat("$",format(2500,2)); select concat("$",format(2500,2));
concat("$",format(2500,2)) concat("$",format(2500,2))
$2,500.00 $2,500.00
create table t1 ( a timestamp );
insert into t1 values ( '2004-01-06 12:34' );
select a from t1 where left(a+0,6) in ( left(20040106,6) );
a
2004-01-06 12:34:00
select a from t1 where left(a+0,6) = ( left(20040106,6) );
a
2004-01-06 12:34:00
select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
a
2004-01-06 12:34:00
select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
a
2004-01-06 12:34:00
select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
a
2004-01-06 12:34:00
select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
a
2004-01-06 12:34:00
drop table t1;
...@@ -23,3 +23,18 @@ select length(format('nan', 2)) > 0; ...@@ -23,3 +23,18 @@ select length(format('nan', 2)) > 0;
# Test for bug #628 # Test for bug #628
# #
select concat("$",format(2500,2)); select concat("$",format(2500,2));
# Test for BUG#7716
create table t1 ( a timestamp );
insert into t1 values ( '2004-01-06 12:34' );
select a from t1 where left(a+0,6) in ( left(20040106,6) );
select a from t1 where left(a+0,6) = ( left(20040106,6) );
select a from t1 where right(a+0,6) in ( right(20040106123400,6) );
select a from t1 where right(a+0,6) = ( right(20040106123400,6) );
select a from t1 where mid(a+0,6,3) in ( mid(20040106123400,6,3) );
select a from t1 where mid(a+0,6,3) = ( mid(20040106123400,6,3) );
drop table t1;
...@@ -1503,7 +1503,11 @@ void in_string::set(uint pos,Item *item) ...@@ -1503,7 +1503,11 @@ void in_string::set(uint pos,Item *item)
String *str=((String*) base)+pos; String *str=((String*) base)+pos;
String *res=item->val_str(str); String *res=item->val_str(str);
if (res && res != str) if (res && res != str)
{
if (res->uses_buffer_owned_by(str))
res->copy();
*str= *res; *str= *res;
}
if (!str->charset()) if (!str->charset())
{ {
CHARSET_INFO *cs; CHARSET_INFO *cs;
......
...@@ -182,6 +182,11 @@ public: ...@@ -182,6 +182,11 @@ public:
{ {
if (&s != this) if (&s != this)
{ {
/*
It is forbidden to do assignments like
some_string = substring_of_that_string
*/
DBUG_ASSERT(!s.uses_buffer_owned_by(this));
free(); free();
Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length; Ptr=s.Ptr ; str_length=s.str_length ; Alloced_length=s.Alloced_length;
alloced=0; alloced=0;
...@@ -313,4 +318,9 @@ public: ...@@ -313,4 +318,9 @@ public:
/* Swap two string objects. Efficient way to exchange data without memcpy. */ /* Swap two string objects. Efficient way to exchange data without memcpy. */
void swap(String &s); void swap(String &s);
inline bool uses_buffer_owned_by(const String *s) const
{
return (s->alloced && Ptr >= s->Ptr && Ptr < s->Ptr + s->str_length);
}
}; };
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