Bug#11753363 (bug#44793) CHARACTER SETS: CASE CLAUSE, UCS2 OR UTF32, FAILURE
Problem: in case of string CASE/WHEN arguments with different character sets, Item_func_case::find_item() called comparator cmp_items[x] on mixed character set Items, so a 8-bit value could be errouneously referenced to as being utf16/utf32 value, which led to crash on DBUG_ASSERT() because of wrong value length. This was wrong, as string comparator expects arguments in the same character set. Fix: modify Item_func_case's argument list after calling agg_arg_charsets_for_comparison() - put the Items in "agg" array back to "args", because some of the Items in the "agg" array might have been changed to character set converters: - to Item_func_conv_charset for non-constant items - to Item_string for constant items In other words, perform the same substitution which is done in all other operations string comparison or string result operations: Replace CASE latin1_item WHEN utf16_item THEN ... END to CASE CONVERT(latin1_item USING utf16) WHEN utf16_item THEN ... END Replace CASE utf16_item WHEN latin1_item THEN ... END to CASE utf16_item WHEN CONVERT(latin1_item USING utf16) THEN ... END @ mysql-test/r/ctype_utf16.result @ mysql-test/r/ctype_utf32.result @ mysql-test/t/ctype_utf16.test @ mysql-test/t/ctype_utf32.test Adding tests @ sql/item_cmpfunc.cc Put "agg" back to "args". @ sql/sql_string.cc Backporting a fix for String::set_or_copy_aligned() from 5.6, for better test coverage: "SELECT _utf16 0x61" should expand the string to 0x0061 rather than to 0x000061. This fix was made in 5.6 under terms of "WL#4616 Implement UTF16-LE".
Showing
Please register or sign in to comment