diff options
author | Alexander Barkov <alexander.barkov@oracle.com> | 2011-03-03 18:46:30 +0300 |
---|---|---|
committer | Alexander Barkov <alexander.barkov@oracle.com> | 2011-03-03 18:46:30 +0300 |
commit | 1a48afc1c64b165c1dc3b78480828367b7af4e69 (patch) | |
tree | 830a69da7cf587333ba50749c844eb350647a74f /sql/item_strfunc.cc | |
parent | cb018d83d758537694fbf1597657266e8f9cd517 (diff) | |
parent | a1e9be8e8b17e5f14be9edc558e69c4f68d01fab (diff) | |
download | mariadb-git-1a48afc1c64b165c1dc3b78480828367b7af4e69.tar.gz |
Merging from mysql-5.1
Diffstat (limited to 'sql/item_strfunc.cc')
-rw-r--r-- | sql/item_strfunc.cc | 62 |
1 files changed, 59 insertions, 3 deletions
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index d23e5af4e29..ad18d5dabbe 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -3450,14 +3450,68 @@ String *Item_func_quote::val_str(String *str) } arg_length= arg->length(); - new_length= arg_length+2; /* for beginning and ending ' signs */ - for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) - new_length+= get_esc_bit(escmask, (uchar) *from); + if (collation.collation->mbmaxlen == 1) + { + new_length= arg_length + 2; /* for beginning and ending ' signs */ + for (from= (char*) arg->ptr(), end= from + arg_length; from < end; from++) + new_length+= get_esc_bit(escmask, (uchar) *from); + } + else + { + new_length= (arg_length * 2) + /* For string characters */ + (2 * collation.collation->mbmaxlen); /* For quotes */ + } if (tmp_value.alloc(new_length)) goto null; + if (collation.collation->mbmaxlen > 1) + { + CHARSET_INFO *cs= collation.collation; + int mblen; + uchar *to_end; + to= (char*) tmp_value.ptr(); + to_end= (uchar*) to + new_length; + + /* Put leading quote */ + if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0) + goto null; + to+= mblen; + + for (start= (char*) arg->ptr(), end= start + arg_length; start < end; ) + { + my_wc_t wc; + bool escape; + if ((mblen= cs->cset->mb_wc(cs, &wc, (uchar*) start, (uchar*) end)) <= 0) + goto null; + start+= mblen; + switch (wc) { + case 0: escape= 1; wc= '0'; break; + case '\032': escape= 1; wc= 'Z'; break; + case '\'': escape= 1; break; + case '\\': escape= 1; break; + default: escape= 0; break; + } + if (escape) + { + if ((mblen= cs->cset->wc_mb(cs, '\\', (uchar*) to, to_end)) <= 0) + goto null; + to+= mblen; + } + if ((mblen= cs->cset->wc_mb(cs, wc, (uchar*) to, to_end)) <= 0) + goto null; + to+= mblen; + } + + /* Put trailing quote */ + if ((mblen= cs->cset->wc_mb(cs, '\'', (uchar *) to, to_end)) <= 0) + goto null; + to+= mblen; + new_length= to - tmp_value.ptr(); + goto ret; + } + /* We replace characters from the end to the beginning */ @@ -3489,6 +3543,8 @@ String *Item_func_quote::val_str(String *str) } } *to= '\''; + +ret: tmp_value.length(new_length); tmp_value.set_charset(collation.collation); null_value= 0; |