summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorDaniel Black <daniel@mariadb.org>2022-03-25 15:06:56 +1100
committerDaniel Black <daniel@mariadb.org>2022-03-25 15:06:56 +1100
commit88ce8a3d8be0346b325bc4da75894cd15e255857 (patch)
tree1e827eb908eaa737225017627beafa2b6d8e9959 /sql/sql_class.cc
parentf6fcf827b379fc069563d1896850fbfcebaa983e (diff)
parent13b97880bd8f6901225a1f8d6ff2eb6ba9303ceb (diff)
downloadmariadb-git-88ce8a3d8be0346b325bc4da75894cd15e255857.tar.gz
Merge 10.7 into 10.8
Diffstat (limited to 'sql/sql_class.cc')
-rw-r--r--sql/sql_class.cc52
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.
*/