summaryrefslogtreecommitdiff
path: root/sql/item_strfunc.cc
diff options
context:
space:
mode:
authorJonathan Perkin <jonathan.perkin@oracle.com>2010-12-16 11:13:58 +0100
committerJonathan Perkin <jonathan.perkin@oracle.com>2010-12-16 11:13:58 +0100
commit3d799bdffd04beba3dad4f1ece915104b0284157 (patch)
tree83c2beab0fb52424ab77dcb1449a3f394f0d0fe1 /sql/item_strfunc.cc
parentc7e273b5313fb71c20444e8ee70423b44fbd02c3 (diff)
parent93efc7e2c4bc8cffa235f2406db3bdaf4180189d (diff)
downloadmariadb-git-3d799bdffd04beba3dad4f1ece915104b0284157.tar.gz
Merge from mysql-5.5.8-release
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)