diff options
author | Alexander Barkov <bar@mysql.com> | 2010-11-26 13:44:39 +0300 |
---|---|---|
committer | Alexander Barkov <bar@mysql.com> | 2010-11-26 13:44:39 +0300 |
commit | e3dee8a7fd3e16147145b877917d4aa85346dfcb (patch) | |
tree | 9eecf2ef41882c89b5d01222dd068af85b4121b2 /sql/item_create.cc | |
parent | ce441751ed12a80aed10b8e5d718dac34d4c68b7 (diff) | |
download | mariadb-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.cc | 52 |
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)}, |