summaryrefslogtreecommitdiff
path: root/sql/sql_class.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2022-03-15 14:27:04 +0400
committerDaniel Black <daniel@mariadb.org>2022-03-16 12:49:13 +1100
commit0e63023cb8f7e52506241723c105d31051a57820 (patch)
tree969877ac08280a24e683daf523f4bcc180abecac /sql/sql_class.cc
parenta9500860367c9ef4ac67c9c41c81dcfad13dc836 (diff)
parent03c3dc63655aabcfc309208188e44c200f680404 (diff)
downloadmariadb-git-0e63023cb8f7e52506241723c105d31051a57820.tar.gz
Merge branch 10.2 into 10.3
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 c808a2c997c..6203e5672fe 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -2307,6 +2307,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.
*/