mirror of
https://github.com/MariaDB/server.git
synced 2026-04-20 15:25:33 +02:00
Bug#9509 Optimizer: wrong result after AND with latin1_german2_ci
We cannot propagate constants with tricky collations.
This commit is contained in:
parent
b6317e3ac0
commit
d8cf7e0133
22 changed files with 115 additions and 17 deletions
|
|
@ -132,6 +132,7 @@ typedef struct my_collation_handler_st
|
|||
/* Hash calculation */
|
||||
void (*hash_sort)(struct charset_info_st *cs, const uchar *key, uint len,
|
||||
ulong *nr1, ulong *nr2);
|
||||
my_bool (*propagate)(struct charset_info_st *cs, const uchar *str, uint len);
|
||||
} MY_COLLATION_HANDLER;
|
||||
|
||||
extern MY_COLLATION_HANDLER my_collation_mb_bin_handler;
|
||||
|
|
@ -385,6 +386,10 @@ int my_wildcmp_unicode(CHARSET_INFO *cs,
|
|||
extern my_bool my_parse_charset_xml(const char *bug, uint len,
|
||||
int (*add)(CHARSET_INFO *cs));
|
||||
|
||||
my_bool my_propagate_simple(CHARSET_INFO *cs, const uchar *str, uint len);
|
||||
my_bool my_propagate_complex(CHARSET_INFO *cs, const uchar *str, uint len);
|
||||
|
||||
|
||||
#define _MY_U 01 /* Upper case */
|
||||
#define _MY_L 02 /* Lower case */
|
||||
#define _MY_NMR 04 /* Numeral (digit) */
|
||||
|
|
|
|||
|
|
@ -338,3 +338,9 @@ ss
|
|||
ss
|
||||
ß
|
||||
DROP TABLE t1;
|
||||
create table t1 (s1 char(5) character set latin1 collate latin1_german2_ci);
|
||||
insert into t1 values (0xf6) /* this is o-umlaut */;
|
||||
select * from t1 where length(s1)=1 and s1='oe';
|
||||
s1
|
||||
ö
|
||||
drop table t1;
|
||||
|
|
|
|||
|
|
@ -132,3 +132,11 @@ INSERT INTO t1 VALUES ('
|
|||
ALTER TABLE t1 ADD KEY ifword(col1);
|
||||
SELECT * FROM t1 WHERE col1='ß' ORDER BY col1, BINARY col1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug#9509
|
||||
#
|
||||
create table t1 (s1 char(5) character set latin1 collate latin1_german2_ci);
|
||||
insert into t1 values (0xf6) /* this is o-umlaut */;
|
||||
select * from t1 where length(s1)=1 and s1='oe';
|
||||
drop table t1;
|
||||
|
|
|
|||
|
|
@ -6435,10 +6435,13 @@ static bool check_equality(Item *item, COND_EQUAL *cond_equal)
|
|||
{
|
||||
bool copyfl;
|
||||
|
||||
if (field_item->result_type() == STRING_RESULT &&
|
||||
((Field_str *) field_item->field)->charset() !=
|
||||
((Item_cond *) item)->compare_collation())
|
||||
return FALSE;
|
||||
if (field_item->result_type() == STRING_RESULT)
|
||||
{
|
||||
CHARSET_INFO *cs= ((Field_str*) field_item->field)->charset();
|
||||
if ((cs != ((Item_cond *) item)->compare_collation()) ||
|
||||
!cs->coll->propagate(cs, 0, 0))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Item_equal *item_equal = find_item_equal(cond_equal,
|
||||
field_item->field, ©fl);
|
||||
|
|
|
|||
|
|
@ -6335,7 +6335,8 @@ static MY_COLLATION_HANDLER my_collation_big5_chinese_ci_handler =
|
|||
my_wildcmp_mb,
|
||||
my_strcasecmp_mb,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_big5_handler=
|
||||
|
|
|
|||
|
|
@ -459,7 +459,8 @@ MY_COLLATION_HANDLER my_collation_8bit_bin_handler =
|
|||
my_wildcmp_bin,
|
||||
my_strcasecmp_bin,
|
||||
my_instr_bin,
|
||||
my_hash_sort_bin
|
||||
my_hash_sort_bin,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -474,7 +475,8 @@ static MY_COLLATION_HANDLER my_collation_binary_handler =
|
|||
my_wildcmp_bin,
|
||||
my_strcasecmp_bin,
|
||||
my_instr_bin,
|
||||
my_hash_sort_bin
|
||||
my_hash_sort_bin,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -5462,6 +5462,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_8bit,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -599,6 +599,7 @@ static MY_COLLATION_HANDLER my_collation_latin2_czech_ci_handler =
|
|||
my_strcasecmp_8bit,
|
||||
my_instr_simple,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
CHARSET_INFO my_charset_latin2_czech_ci =
|
||||
|
|
|
|||
|
|
@ -8647,6 +8647,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_mb,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -8648,6 +8648,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_mb,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -5698,6 +5698,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_mb, /* instr */
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -9945,6 +9945,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_mb,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -698,7 +698,8 @@ static MY_COLLATION_HANDLER my_collation_german2_ci_handler=
|
|||
my_wildcmp_8bit,
|
||||
my_strcasecmp_8bit,
|
||||
my_instr_simple,
|
||||
my_hash_sort_latin1_de
|
||||
my_hash_sort_latin1_de,
|
||||
my_propagate_complex
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -920,7 +920,8 @@ MY_COLLATION_HANDLER my_collation_mb_bin_handler =
|
|||
my_wildcmp_mb_bin,
|
||||
my_strcasecmp_mb_bin,
|
||||
my_instr_mb,
|
||||
my_hash_sort_mb_bin
|
||||
my_hash_sort_mb_bin,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1340,6 +1340,60 @@ longlong my_strtoll10_8bit(CHARSET_INFO *cs __attribute__((unused)),
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Check if a constant can be propagated
|
||||
|
||||
SYNOPSIS:
|
||||
my_propagate_simple()
|
||||
cs Character set information
|
||||
str String to convert to double
|
||||
length Optional length for string.
|
||||
|
||||
NOTES:
|
||||
Takes the string in the given charset and check
|
||||
if it can be safely propagated in the optimizer.
|
||||
|
||||
create table t1 (
|
||||
s char(5) character set latin1 collate latin1_german2_ci);
|
||||
insert into t1 values (0xf6); -- o-umlaut
|
||||
select * from t1 where length(s)=1 and s='oe';
|
||||
|
||||
The above query should return one row.
|
||||
We cannot convert this query into:
|
||||
select * from t1 where length('oe')=1 and s='oe';
|
||||
|
||||
Currently we don't check the constant itself,
|
||||
and decide not to propagate a constant
|
||||
just if the collation itself allows tricky things
|
||||
like expansions and contractions. In the future
|
||||
we can write a more sophisticated functions to
|
||||
check the constants. For example, 'oa' can always
|
||||
be safety propagated in German2 because unlike
|
||||
'oe' it does not have any special meaning.
|
||||
|
||||
RETURN
|
||||
1 if constant can be safely propagated
|
||||
0 if it is not safe to propagate the constant
|
||||
*/
|
||||
|
||||
|
||||
|
||||
my_bool my_propagate_simple(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar *str __attribute__((unused)),
|
||||
uint length __attribute__((unused)))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
my_bool my_propagate_complex(CHARSET_INFO *cs __attribute__((unused)),
|
||||
const uchar *str __attribute__((unused)),
|
||||
uint length __attribute__((unused)))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
MY_CHARSET_HANDLER my_charset_8bit_handler=
|
||||
{
|
||||
my_cset_init_8bit,
|
||||
|
|
@ -1380,5 +1434,6 @@ MY_COLLATION_HANDLER my_collation_8bit_simple_ci_handler =
|
|||
my_wildcmp_8bit,
|
||||
my_strcasecmp_8bit,
|
||||
my_instr_simple,
|
||||
my_hash_sort_simple
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
|
|
|||
|
|
@ -4631,6 +4631,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_8bit,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -933,6 +933,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_8bit,
|
||||
my_instr_simple, /* QQ: To be fixed */
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -8029,7 +8029,8 @@ MY_COLLATION_HANDLER my_collation_ucs2_uca_handler =
|
|||
my_wildcmp_uca,
|
||||
NULL,
|
||||
my_instr_mb,
|
||||
my_hash_sort_ucs2_uca
|
||||
my_hash_sort_ucs2_uca,
|
||||
my_propagate_complex
|
||||
};
|
||||
|
||||
CHARSET_INFO my_charset_ucs2_general_uca=
|
||||
|
|
@ -8510,7 +8511,8 @@ MY_COLLATION_HANDLER my_collation_any_uca_handler =
|
|||
my_wildcmp_uca,
|
||||
NULL,
|
||||
my_instr_mb,
|
||||
my_hash_sort_any_uca
|
||||
my_hash_sort_any_uca,
|
||||
my_propagate_complex
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -1527,7 +1527,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_general_ci_handler =
|
|||
my_wildcmp_ucs2_ci,
|
||||
my_strcasecmp_ucs2,
|
||||
my_instr_mb,
|
||||
my_hash_sort_ucs2
|
||||
my_hash_sort_ucs2,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -1542,7 +1543,8 @@ static MY_COLLATION_HANDLER my_collation_ucs2_bin_handler =
|
|||
my_wildcmp_ucs2_bin,
|
||||
my_strcasecmp_ucs2_bin,
|
||||
my_instr_mb,
|
||||
my_hash_sort_ucs2_bin
|
||||
my_hash_sort_ucs2_bin,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -8516,6 +8516,7 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_strcasecmp_mb,
|
||||
my_instr_mb,
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
static MY_CHARSET_HANDLER my_charset_handler=
|
||||
|
|
|
|||
|
|
@ -2316,7 +2316,8 @@ static MY_COLLATION_HANDLER my_collation_ci_handler =
|
|||
my_wildcmp_utf8,
|
||||
my_strcasecmp_utf8,
|
||||
my_instr_mb,
|
||||
my_hash_sort_utf8
|
||||
my_hash_sort_utf8,
|
||||
my_propagate_complex
|
||||
};
|
||||
|
||||
MY_CHARSET_HANDLER my_charset_utf8_handler=
|
||||
|
|
@ -2540,7 +2541,8 @@ static MY_COLLATION_HANDLER my_collation_cs_handler =
|
|||
my_wildcmp_mb,
|
||||
my_strcasecmp_utf8,
|
||||
my_instr_mb,
|
||||
my_hash_sort_utf8
|
||||
my_hash_sort_utf8,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
CHARSET_INFO my_charset_utf8_general_cs=
|
||||
|
|
|
|||
|
|
@ -631,7 +631,8 @@ static MY_COLLATION_HANDLER my_collation_czech_ci_handler =
|
|||
my_wildcmp_8bit,
|
||||
my_strcasecmp_8bit,
|
||||
my_instr_simple,
|
||||
my_hash_sort_simple
|
||||
my_hash_sort_simple,
|
||||
my_propagate_simple
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue