summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r--sql/item_strfunc.cc50
1 files changed, 49 insertions, 1 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 89c1e785c71..c71d8226f77 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1080,9 +1080,15 @@ String *Item_func_replace::val_str(String *str)
search=res2->ptr();
search_end=search+from_length;
redo:
+ DBUG_ASSERT(res->ptr() || !offset);
ptr=res->ptr()+offset;
strend=res->ptr()+res->length();
- end=strend-from_length+1;
+ /*
+ In some cases val_str() can return empty string
+ with ptr() == NULL and length() == 0.
+ Let's check strend to avoid overflow.
+ */
+ end= strend ? strend - from_length + 1 : NULL;
while (ptr < end)
{
if (*ptr == *search)
@@ -1184,6 +1190,20 @@ String *Item_func_insert::val_str(String *str)
if ((length < 0) || (length > res->length()))
length= res->length();
+ /*
+ There is one exception not handled (intentionaly) by the character set
+ aggregation code. If one string is strong side and is binary, and
+ another one is weak side and is a multi-byte character string,
+ then we need to operate on the second string in terms on bytes when
+ calling ::numchars() and ::charpos(), rather than in terms of characters.
+ Lets substitute its character set to binary.
+ */
+ if (collation.collation == &my_charset_bin)
+ {
+ res->set_charset(&my_charset_bin);
+ res2->set_charset(&my_charset_bin);
+ }
+
/* start and length are now sufficiently valid to pass to charpos function */
start= res->charpos((int) start);
length= res->charpos((int) length, (uint32) start);
@@ -2725,6 +2745,20 @@ String *Item_func_rpad::val_str(String *str)
/* Set here so that rest of code sees out-of-bound value as such. */
if ((ulonglong) count > INT_MAX32)
count= INT_MAX32;
+ /*
+ There is one exception not handled (intentionaly) by the character set
+ aggregation code. If one string is strong side and is binary, and
+ another one is weak side and is a multi-byte character string,
+ then we need to operate on the second string in terms on bytes when
+ calling ::numchars() and ::charpos(), rather than in terms of characters.
+ Lets substitute its character set to binary.
+ */
+ if (collation.collation == &my_charset_bin)
+ {
+ res->set_charset(&my_charset_bin);
+ rpad->set_charset(&my_charset_bin);
+ }
+
if (count <= (res_char_length= res->numchars()))
{ // String to pad is big enough
res->length(res->charpos((int) count)); // Shorten result if longer
@@ -2814,6 +2848,20 @@ String *Item_func_lpad::val_str(String *str)
if ((ulonglong) count > INT_MAX32)
count= INT_MAX32;
+ /*
+ There is one exception not handled (intentionaly) by the character set
+ aggregation code. If one string is strong side and is binary, and
+ another one is weak side and is a multi-byte character string,
+ then we need to operate on the second string in terms on bytes when
+ calling ::numchars() and ::charpos(), rather than in terms of characters.
+ Lets substitute its character set to binary.
+ */
+ if (collation.collation == &my_charset_bin)
+ {
+ res->set_charset(&my_charset_bin);
+ pad->set_charset(&my_charset_bin);
+ }
+
res_char_length= res->numchars();
if (count <= res_char_length)