summaryrefslogtreecommitdiff
path: root/sql/item.cc
diff options
context:
space:
mode:
authorSreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com>2016-01-29 08:29:06 +0530
committerSreeharsha Ramanavarapu <sreeharsha.ramanavarapu@oracle.com>2016-01-29 08:29:06 +0530
commit718c787912e0d498c167e7436d840b2c837e90f9 (patch)
tree4bfe82566b5440efa40ab51746f457bc34dd8d60 /sql/item.cc
parent01d41f68b7a6e6cc12565056661f1f28876beff5 (diff)
downloadmariadb-git-718c787912e0d498c167e7436d840b2c837e90f9.tar.gz
Bug #18823979: PS: UCS2 + CASE WHEN THEN ELSE CRASH IN
ITEM_PARAM::SAFE_CHARSET_CONVERTER ISSUE: ------ Charset conversion on a null parameter is not handled correctly. SOLUTION: --------- Item_param's charset converter does not handle the case where it might have to deal with a null value. This is fine for other charset converters since the value is not supplied to them at runtime. The fix is to check if the parameter is now set to null and return an Item_null object. Also, there is no need to initialize Item_param's cnvitem in the constructor to a string. This can be done in ITEM_PARAM::SAFE_CHARSET_CONVERTER itself. Members of Item_param, cnvbuf and cnvstr, have been removed and cnvitem has been made a local variable in ITEM_PARAM::SAFE_CHARSET_CONVERTER.
Diffstat (limited to 'sql/item.cc')
-rw-r--r--sql/item.cc35
1 files changed, 25 insertions, 10 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 5f02b96e59f..c482f0e1a04 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -926,14 +926,31 @@ Item *Item_param::safe_charset_converter(CHARSET_INFO *tocs)
{
if (const_item())
{
- uint cnv_errors;
- String *ostr= val_str(&cnvstr);
- cnvitem->str_value.copy(ostr->ptr(), ostr->length(),
- ostr->charset(), tocs, &cnv_errors);
- if (cnv_errors)
- return NULL;
- cnvitem->str_value.mark_as_const();
- cnvitem->max_length= cnvitem->str_value.numchars() * tocs->mbmaxlen;
+ Item *cnvitem;
+ String tmp, cstr, *ostr= val_str(&tmp);
+
+ if (null_value)
+ {
+ cnvitem= new Item_null();
+ if (cnvitem == NULL)
+ return NULL;
+
+ cnvitem->collation.set(tocs);
+ }
+ else
+ {
+ uint conv_errors;
+ cstr.copy(ostr->ptr(), ostr->length(), ostr->charset(), tocs,
+ &conv_errors);
+
+ if (conv_errors || !(cnvitem= new Item_string(cstr.ptr(), cstr.length(),
+ cstr.charset(),
+ collation.derivation)))
+ return NULL;
+
+ cnvitem->str_value.copy();
+ cnvitem->str_value.mark_as_const();
+ }
return cnvitem;
}
return Item::safe_charset_converter(tocs);
@@ -2795,8 +2812,6 @@ Item_param::Item_param(uint pos_in_query_arg) :
value is set.
*/
maybe_null= 1;
- cnvitem= new Item_string("", 0, &my_charset_bin, DERIVATION_COERCIBLE);
- cnvstr.set(cnvbuf, sizeof(cnvbuf), &my_charset_bin);
}