summaryrefslogtreecommitdiff
path: root/sql/item_create.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mysql.com>2010-11-26 13:44:39 +0300
committerAlexander Barkov <bar@mysql.com>2010-11-26 13:44:39 +0300
commite3dee8a7fd3e16147145b877917d4aa85346dfcb (patch)
tree9eecf2ef41882c89b5d01222dd068af85b4121b2 /sql/item_create.cc
parentce441751ed12a80aed10b8e5d718dac34d4c68b7 (diff)
downloadmariadb-git-e3dee8a7fd3e16147145b877917d4aa85346dfcb.tar.gz
Bug#57737 Character sets: search fails with like, contraction, index
Problem: LIKE over an indexed column optimized away good results, because my_like_range_utf32/utf16 returned wrong ranges for contractions. Contraction related code was missing in my_like_range_utf32/utf16, but did exist in my_like_range_ucs2/utf8. It was forgotten in utf32/utf16 versions (during mysql-6.0 push/revert mess). Fix: The patch removes individual functions my_like_range_ucs2, my_like_range_utf16, my_like_range_utf32 and introduces a single function my_like_range_generic() instead. The new function handles contractions correctly. It can handle any character set with cs->min_sort_char and cs->max_sort_char represented in Unicode code points. added: @ mysql-test/include/ctype_czech.inc @ mysql-test/include/ctype_like_ignorable.inc @ mysql-test/r/ctype_like_range.result @ mysql-test/t/ctype_like_range.test Adding tests modified: @ include/m_ctype.h - Adding helper functions for contractions. - Prototypes: removing ucs2,utf16,utf32 functions, adding generic function. @ mysql-test/r/ctype_uca.result @ mysql-test/r/ctype_utf16_uca.result @ mysql-test/r/ctype_utf32_uca.result @ mysql-test/t/ctype_uca.test @ mysql-test/t/ctype_utf16_uca.test @ mysql-test/t/ctype_utf32_uca.test - Adding tests. @ strings/ctype-mb.c - Pad function did not put the last character. - Implementing my_like_range_generic() - an universal replacement for three separate functions my_like_range_ucs2(), my_like_range_utf16() and my_like_range_utf32(), with correct contraction handling. @ strings/ctype-ucs2.c - my_fill_mb2 did not put the high byte, as previously it was used to put only characters in ASCII range. Now it puts high byte as well (needed to pupulate cs->max_sort_char correctly). - Adding DBUG_ASSERT() - Removing character set specific functions: my_like_range_ucs2(), my_like_range_utf16() and my_like_range_utf32(). - Using my_like_range_generic() instead of the old functions. @ strings/ctype-uca.c - Using generic function instead of the old character set specific ones. @ sql/item_create.cc @ sql/item_strfunc.cc @ sql/item_strfunc.h - Adding SQL functions LIKE_RANGE_MIN and LIKE_RANGE_MAX, available only in debug build to make sure like_range() works correctly for all character sets and collations.
Diffstat (limited to 'sql/item_create.cc')
-rw-r--r--sql/item_create.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 672e59986d5..1ae65926013 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -1330,6 +1330,34 @@ protected:
};
+#ifndef DBUG_OFF
+class Create_func_like_range_min : public Create_func_arg2
+{
+public:
+ virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_like_range_min s_singleton;
+
+protected:
+ Create_func_like_range_min() {}
+ virtual ~Create_func_like_range_min() {}
+};
+
+
+class Create_func_like_range_max : public Create_func_arg2
+{
+public:
+ virtual Item *create(THD *thd, Item *arg1, Item *arg2);
+
+ static Create_func_like_range_max s_singleton;
+
+protected:
+ Create_func_like_range_max() {}
+ virtual ~Create_func_like_range_max() {}
+};
+#endif
+
+
class Create_func_ln : public Create_func_arg1
{
public:
@@ -3836,6 +3864,26 @@ Create_func_length::create(THD *thd, Item *arg1)
}
+#ifndef DBUG_OFF
+Create_func_like_range_min Create_func_like_range_min::s_singleton;
+
+Item*
+Create_func_like_range_min::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_like_range_min(arg1, arg2);
+}
+
+
+Create_func_like_range_max Create_func_like_range_max::s_singleton;
+
+Item*
+Create_func_like_range_max::create(THD *thd, Item *arg1, Item *arg2)
+{
+ return new (thd->mem_root) Item_func_like_range_max(arg1, arg2);
+}
+#endif
+
+
Create_func_ln Create_func_ln::s_singleton;
Item*
@@ -4924,6 +4972,10 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("LCASE") }, BUILDER(Create_func_lcase)},
{ { C_STRING_WITH_LEN("LEAST") }, BUILDER(Create_func_least)},
{ { C_STRING_WITH_LEN("LENGTH") }, BUILDER(Create_func_length)},
+#ifndef DBUG_OFF
+ { { C_STRING_WITH_LEN("LIKE_RANGE_MIN") }, BUILDER(Create_func_like_range_min)},
+ { { C_STRING_WITH_LEN("LIKE_RANGE_MAX") }, BUILDER(Create_func_like_range_max)},
+#endif
{ { C_STRING_WITH_LEN("LINEFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},
{ { C_STRING_WITH_LEN("LINEFROMWKB") }, GEOM_BUILDER(Create_func_geometry_from_wkb)},
{ { C_STRING_WITH_LEN("LINESTRINGFROMTEXT") }, GEOM_BUILDER(Create_func_geometry_from_text)},