mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
MDEV-33772 Bad SEPARATOR value in GROUP_CONCAT on character set conversion
Item_func_group_concat::print() did not take into account that Item_func_group_concat::separator can be of a different character set than the "String *str" (when the printing is being done to). Therefore, printing did not work correctly for: - non-ASCII separators when GROUP_CONCAT is done on 8bit data or multi-byte data with mbminlen==1. - all separators (even including simple ones like comma) when GROUP_CONCAT is done on ucs2/utf16/utf32 data (mbminlen>1). Because of this problem, VIEW definitions did not print correctly to their FRM files. This later led to a wrong SELECT and SHOW CREATE output. Fix: - Adding new String methods: bool append_for_single_quote_using_mb_wc(const char *str, size_t length, CHARSET_INFO *cs); bool append_for_single_quote_opt_convert(const char *str, size_t length, CHARSET_INFO *cs) which perform both escaping and character set conversion at the same time. - Adding a new String method escaped_wc_for_single_quote(), to reuse the code between the old and the new methods. - Fixing Item_func_group_concat::print() to use the new method append_for_single_quote_opt_convert().
This commit is contained in:
@ -1134,6 +1134,42 @@ public:
|
||||
print_with_conversion(to, cs);
|
||||
}
|
||||
|
||||
static my_wc_t escaped_wc_for_single_quote(my_wc_t ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case '\\': return '\\';
|
||||
case '\0': return '0';
|
||||
case '\'': return '\'';
|
||||
case '\n': return 'n';
|
||||
case '\r': return 'r';
|
||||
case '\032': return 'Z';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Append for single quote using mb_wc/wc_mb Unicode conversion
|
||||
bool append_for_single_quote_using_mb_wc(const char *str, size_t length,
|
||||
CHARSET_INFO *cs);
|
||||
|
||||
// Append for single quote with optional mb_wc/wc_mb conversion
|
||||
bool append_for_single_quote_opt_convert(const char *str,
|
||||
size_t length,
|
||||
CHARSET_INFO *cs)
|
||||
{
|
||||
return charset() == &my_charset_bin || cs == &my_charset_bin ||
|
||||
my_charset_same(charset(), cs) ?
|
||||
append_for_single_quote(str, length) :
|
||||
append_for_single_quote_using_mb_wc(str, length, cs);
|
||||
}
|
||||
|
||||
bool append_for_single_quote_opt_convert(const String &str)
|
||||
{
|
||||
return append_for_single_quote_opt_convert(str.ptr(),
|
||||
str.length(),
|
||||
str.charset());
|
||||
}
|
||||
|
||||
bool append_for_single_quote(const char *st, size_t len);
|
||||
bool append_for_single_quote(const String *s)
|
||||
{
|
||||
|
Reference in New Issue
Block a user