diff options
author | Daniel Black <daniel@mariadb.org> | 2022-03-25 15:06:56 +1100 |
---|---|---|
committer | Daniel Black <daniel@mariadb.org> | 2022-03-25 15:06:56 +1100 |
commit | 88ce8a3d8be0346b325bc4da75894cd15e255857 (patch) | |
tree | 1e827eb908eaa737225017627beafa2b6d8e9959 /sql/sql_class.cc | |
parent | f6fcf827b379fc069563d1896850fbfcebaa983e (diff) | |
parent | 13b97880bd8f6901225a1f8d6ff2eb6ba9303ceb (diff) | |
download | mariadb-git-88ce8a3d8be0346b325bc4da75894cd15e255857.tar.gz |
Merge 10.7 into 10.8
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r-- | sql/sql_class.cc | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 9737083e900..bf6efd9fd52 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2354,6 +2354,58 @@ bool THD::convert_string(LEX_STRING *to, CHARSET_INFO *to_cs, /* + Reinterpret a binary string to a character string + + @param[OUT] to The result will be written here, + either the original string as is, + or a newly alloced fixed string with + some zero bytes prepended. + @param cs The destination character set + @param str The binary string + @param length The length of the binary string + + @return false on success + @return true on error +*/ + +bool THD::reinterpret_string_from_binary(LEX_CSTRING *to, CHARSET_INFO *cs, + const char *str, size_t length) +{ + /* + When reinterpreting from binary to tricky character sets like + UCS2, UTF16, UTF32, we may need to prepend some zero bytes. + This is possible in scenarios like this: + SET COLLATION_CONNECTION=utf32_general_ci, CHARACTER_SET_CLIENT=binary; + This code is similar to String::copy_aligned(). + */ + size_t incomplete= length % cs->mbminlen; // Bytes in an incomplete character + if (incomplete) + { + size_t zeros= cs->mbminlen - incomplete; + size_t aligned_length= zeros + length; + char *dst= (char*) alloc(aligned_length + 1); + if (!dst) + { + to->str= NULL; // Safety + to->length= 0; + return true; + } + bzero(dst, zeros); + memcpy(dst + zeros, str, length); + dst[aligned_length]= '\0'; + to->str= dst; + to->length= aligned_length; + } + else + { + to->str= str; + to->length= length; + } + return check_string_for_wellformedness(to->str, to->length, cs); +} + + +/* Convert a string between two character sets. dstcs and srccs cannot be &my_charset_bin. */ |