Commit d8cf7e01 authored by unknown's avatar unknown

Bug#9509 Optimizer: wrong result after AND with latin1_german2_ci

We cannot propagate constants with tricky collations.

parent b6317e3a
......@@ -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, &copyfl);
......
......@@ -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
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment