summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <bar@mysql.com>2005-09-07 16:32:15 +0500
committerunknown <bar@mysql.com>2005-09-07 16:32:15 +0500
commite8ba23fd0d1ca9b5f3a1366419f8351280b473bc (patch)
tree86be62125024f36215a902740ff80b67209bce8c
parentd9732be25a2baaa8820f44598dec15e23bddc3cf (diff)
parent4fdf0ce3803f42d20681ed332888b16042b33f8f (diff)
downloadmariadb-git-e8ba23fd0d1ca9b5f3a1366419f8351280b473bc.tar.gz
Merge mysql.com:/usr/home/bar/mysql-4.1.b12611
into mysql.com:/usr/home/bar/mysql-5.0 mysql-test/r/ctype_utf8.result: Auto merged mysql-test/r/func_like.result: Auto merged mysql-test/t/ctype_utf8.test: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged
-rw-r--r--mysql-test/r/ctype_utf8.result4
-rw-r--r--mysql-test/r/func_like.result7
-rw-r--r--mysql-test/t/ctype_utf8.test6
-rw-r--r--mysql-test/t/func_like.test17
-rw-r--r--sql/item_cmpfunc.cc37
-rw-r--r--sql/item_cmpfunc.h2
6 files changed, 71 insertions, 2 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 64c693a292a..48ff82aeeb2 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -955,6 +955,10 @@ char_length(a) length(a) a
2 4 ан
drop table t1;
set names utf8;
+select 'andre%' like 'andreñ%' escape 'ñ';
+'andre%' like 'andreñ%' escape 'ñ'
+1
+set names utf8;
select 'a\\' like 'a\\';
'a\\' like 'a\\'
1
diff --git a/mysql-test/r/func_like.result b/mysql-test/r/func_like.result
index ac8e5eda8e8..7e6fedb9403 100644
--- a/mysql-test/r/func_like.result
+++ b/mysql-test/r/func_like.result
@@ -158,3 +158,10 @@ DROP TABLE t1;
select _cp866'aaaaaaaaa' like _cp866'%aaaa%' collate cp866_bin;
_cp866'aaaaaaaaa' like _cp866'%aaaa%' collate cp866_bin
1
+set names koi8r;
+select 'andre%' like 'andreÊ%' escape 'Ê';
+'andre%' like 'andreÊ%' escape 'Ê'
+1
+select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê';
+_cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê'
+1
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index ce259f465d9..041451272d4 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -810,6 +810,12 @@ alter table t1 modify a char(2) character set utf8;
select char_length(a), length(a), a from t1 order by a;
drop table t1;
+#
+# Bugs#12611
+# ESCAPE + LIKE do not work when the escape char is a multibyte one
+#
+set names utf8;
+select 'andre%' like 'andreñ%' escape 'ñ';
#
# Bugs#11754: SET NAMES utf8 followed by SELECT "A\\" LIKE "A\\" returns 0
diff --git a/mysql-test/t/func_like.test b/mysql-test/t/func_like.test
index 684d7032038..4e1183afeff 100644
--- a/mysql-test/t/func_like.test
+++ b/mysql-test/t/func_like.test
@@ -96,4 +96,21 @@ DROP TABLE t1;
#
select _cp866'aaaaaaaaa' like _cp866'%aaaa%' collate cp866_bin;
+#
+# Check 8bit escape character
+#
+set names koi8r;
+select 'andre%' like 'andreÊ%' escape 'Ê';
+
+# Check 8bit escape character with charset conversion:
+# For "a LIKE b ESCAPE c" expressions,
+# escape character is converted into the operation character set,
+# which is result of aggregation of character sets of "a" and "b".
+# "c" itself doesn't take part in aggregation, because its collation
+# doesn't matter, escape character is always compared binary.
+# In the example below, escape character is converted from koi8r into cp1251:
+#
+select _cp1251'andre%' like convert('andreÊ%' using cp1251) escape 'Ê';
+
+#
# End of 4.1 tests
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index cc2849ff7e6..31bfa9ba3b7 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2811,7 +2811,42 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
/* If we are on execution stage */
String *escape_str= escape_item->val_str(&tmp_value1);
- escape= escape_str ? *(escape_str->ptr()) : '\\';
+ if (escape_str)
+ {
+ CHARSET_INFO *cs= cmp.cmp_collation.collation;
+ if (use_mb(cs))
+ {
+ my_wc_t wc;
+ int rc= cs->cset->mb_wc(cs, &wc,
+ (const uchar*) escape_str->ptr(),
+ (const uchar*) escape_str->ptr() +
+ escape_str->length());
+ escape= (int) (rc > 0 ? wc : '\\');
+ }
+ else
+ {
+ /*
+ In the case of 8bit character set, we pass native
+ code instead of Unicode code as "escape" argument.
+ Convert to "cs" if charset of escape differs.
+ */
+ uint32 unused;
+ if (escape_str->needs_conversion(escape_str->length(),
+ escape_str->charset(), cs, &unused))
+ {
+ char ch;
+ uint errors;
+ uint32 cnvlen= copy_and_convert(&ch, 1, cs, escape_str->ptr(),
+ escape_str->length(),
+ escape_str->charset(), &errors);
+ escape= cnvlen ? ch : '\\';
+ }
+ else
+ escape= *(escape_str->ptr());
+ }
+ }
+ else
+ escape= '\\';
/*
We could also do boyer-more for non-const items, but as we would have to
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 1915dbaabf6..0609adce7f0 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -966,7 +966,7 @@ class Item_func_like :public Item_bool_func2
Item *escape_item;
public:
- char escape;
+ int escape;
Item_func_like(Item *a,Item *b, Item *escape_arg)
:Item_bool_func2(a,b), canDoTurboBM(FALSE), pattern(0), pattern_len(0),