Bug#31384 DATE_ADD() and DATE_SUB() return binary data

Problem: DATE_ADD() is a hybrid function and can return
DATE, DATETIME or VARCHAR data type depending on arguments.

In case of VARCHAR data type, DATE_ADD() reported "binary" character set,
which was wrong.

Fix: make DATE_ADD() return @character_set_connection in VARCHAR context.
 @ mysql-test/include/ctype_numconv.inc
   Adding tests
 @ mysql-test/r/ctype_binary.result
   Adding tests
 @ mysql-test/r/ctype_cp1251.result
   Adding tests
 @ mysql-test/r/ctype_latin1.result
   Adding tests
 @ mysql-test/r/ctype_ucs.result
   Adding tests
 @ mysql-test/r/ctype_utf8.result
   Adding tests
 @ sql/item_strfunc.cc
  - Moving code from Item_str_ascii_func::val_str() to
  Item_str_func::val_str_from_val_str_ascii(), as
  this code needs to be shared by Item_date_add_interval.
  - Adding str2 parameter to be used as a buffer, instead of
   using private ascii_buf member.
 @ sql/item_strfunc.h
  - Moving code from Item_str_ascii_func::val_str() to
  Item_str_func::val_str_from_val_str_ascii()
  - Removing "String *val_str_convert_from_ascii(String *str, String *ascii_buf)"
    prototype as it was neither used nor declared.
 @ sql/item_timefunc.h
  - Overwriting parent's charset_for_protocol() method,
    becase we need to behave differenlty in VARCHAR and DATE/DATETYPE context.
  - Adding ascii_buf for conversion.
  - Adding val_str_ascii() prototype.
  - Adding val_str() which uses newly added
    Item_str_func::val_str_from_val_str_ascii(),
    passing ascii_buf as a conversion buffer.
This commit is contained in:
Alexander Barkov 2011-02-10 11:18:08 +03:00
commit 7d88b552e2
10 changed files with 272 additions and 14 deletions

View file

@ -70,7 +70,7 @@ String my_empty_string("",default_charset_info);
Normally conversion does not happen, and val_str_ascii() is immediately
returned instead.
*/
String *Item_str_ascii_func::val_str(String *str)
String *Item_str_func::val_str_from_val_str_ascii(String *str, String *str2)
{
DBUG_ASSERT(fixed == 1);
@ -82,19 +82,19 @@ String *Item_str_ascii_func::val_str(String *str)
return res;
}
DBUG_ASSERT(str != &ascii_buf);
DBUG_ASSERT(str != str2);
uint errors;
String *res= val_str_ascii(&ascii_buf);
String *res= val_str_ascii(str);
if (!res)
return 0;
if ((null_value= str->copy(res->ptr(), res->length(),
&my_charset_latin1, collation.collation,
&errors)))
if ((null_value= str2->copy(res->ptr(), res->length(),
&my_charset_latin1, collation.collation,
&errors)))
return 0;
return str;
return str2;
}