Skip to content

Commit f071a12

Browse files
author
Alexander Barkov
committed
MDEV-8688 Wrong result for
SELECT..WHERE varchar_column IN (1,2,3) AND varchar_column=' 1';
1 parent 09fb512 commit f071a12

File tree

6 files changed

+108
-0
lines changed

6 files changed

+108
-0
lines changed

mysql-test/r/ctype_cp1251.result

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3334,3 +3334,34 @@ DROP TABLE t1;
33343334
#
33353335
# End of 5.5 tests
33363336
#
3337+
#
3338+
# Start of 10.1 tests
3339+
#
3340+
#
3341+
# MDEV-8688 Wrong result for SELECT..WHERE varchar_column IN (1,2,3) AND varchar_column=' 1';
3342+
#
3343+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci);
3344+
INSERT INTO t1 VALUES (' 1'),('`1');
3345+
SELECT * FROM t1 WHERE a IN (1,2,3);
3346+
a
3347+
1
3348+
SELECT * FROM t1 WHERE a IN (1,2,3) AND a=' 1';
3349+
a
3350+
1
3351+
SELECT * FROM t1 WHERE a IN (1,2,3,'4') AND a=' 1';
3352+
a
3353+
1
3354+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,3) AND a=' 1';
3355+
id select_type table type possible_keys key key_len ref rows filtered Extra
3356+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
3357+
Warnings:
3358+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 1') and (`test`.`t1`.`a` in (1,2,3)))
3359+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,3,'x') AND a=' 1';
3360+
id select_type table type possible_keys key key_len ref rows filtered Extra
3361+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
3362+
Warnings:
3363+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = ' 1') and (`test`.`t1`.`a` in (1,2,3,'x')))
3364+
DROP TABLE t1;
3365+
#
3366+
# End of 10.1 tests
3367+
#

mysql-test/r/ctype_utf8.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10166,5 +10166,31 @@ Warnings:
1016610166
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = 10) and (`test`.`t1`.`a` = '1e1'))
1016710167
DROP TABLE t1;
1016810168
#
10169+
# MDEV-8688 Wrong result for SELECT..WHERE varchar_column IN (1,2,3) AND varchar_column=' 1';
10170+
#
10171+
SET NAMES utf8;
10172+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
10173+
INSERT INTO t1 VALUES ('1e1'),('1ë1');
10174+
SELECT * FROM t1 WHERE a IN (1,2);
10175+
a
10176+
1ë1
10177+
SELECT * FROM t1 WHERE a IN (1,2) AND a='1ë1';
10178+
a
10179+
1ë1
10180+
SELECT * FROM t1 WHERE a IN (1,2,'x') AND a='1ë1';
10181+
a
10182+
1ë1
10183+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2) AND a='1ë1';
10184+
id select_type table type possible_keys key key_len ref rows filtered Extra
10185+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
10186+
Warnings:
10187+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '1ë1') and (`test`.`t1`.`a` in (1,2)))
10188+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,'x') AND a='1ë1';
10189+
id select_type table type possible_keys key key_len ref rows filtered Extra
10190+
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
10191+
Warnings:
10192+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where ((`test`.`t1`.`a` = '1ë1') and (`test`.`t1`.`a` in (1,2,'x')))
10193+
DROP TABLE IF EXISTS t1;
10194+
#
1016910195
# End of 10.1 tests
1017010196
#

mysql-test/t/ctype_cp1251.test

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,25 @@ DROP TABLE t1;
107107
--echo #
108108
--echo # End of 5.5 tests
109109
--echo #
110+
111+
--echo #
112+
--echo # Start of 10.1 tests
113+
--echo #
114+
115+
--echo #
116+
--echo # MDEV-8688 Wrong result for SELECT..WHERE varchar_column IN (1,2,3) AND varchar_column=' 1';
117+
--echo #
118+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET cp1251 COLLATE cp1251_ukrainian_ci);
119+
INSERT INTO t1 VALUES (' 1'),('`1');
120+
SELECT * FROM t1 WHERE a IN (1,2,3);
121+
SELECT * FROM t1 WHERE a IN (1,2,3) AND a=' 1';
122+
SELECT * FROM t1 WHERE a IN (1,2,3,'4') AND a=' 1';
123+
# Equality should not propagate ' 1' to IN: incompatible comparison context
124+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,3) AND a=' 1';
125+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,3,'x') AND a=' 1';
126+
DROP TABLE t1;
127+
128+
129+
--echo #
130+
--echo # End of 10.1 tests
131+
--echo #

mysql-test/t/ctype_utf8.test

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1818,6 +1818,20 @@ SELECT * FROM t1 WHERE (a,a)=(10,'1e1');
18181818
EXPLAIN EXTENDED SELECT * FROM t1 WHERE (a,a)=(10,'1e1');
18191819
DROP TABLE t1;
18201820

1821+
--echo #
1822+
--echo # MDEV-8688 Wrong result for SELECT..WHERE varchar_column IN (1,2,3) AND varchar_column=' 1';
1823+
--echo #
1824+
SET NAMES utf8;
1825+
CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET latin1);
1826+
INSERT INTO t1 VALUES ('1e1'),('1ë1');
1827+
SELECT * FROM t1 WHERE a IN (1,2);
1828+
SELECT * FROM t1 WHERE a IN (1,2) AND a='1ë1';
1829+
SELECT * FROM t1 WHERE a IN (1,2,'x') AND a='1ë1';
1830+
# Equality should not propagate '1ë1' to IN: incompatible comparison context
1831+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2) AND a='1ë1';
1832+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a IN (1,2,'x') AND a='1ë1';
1833+
DROP TABLE IF EXISTS t1;
1834+
18211835

18221836
--echo #
18231837
--echo # End of 10.1 tests

sql/item_cmpfunc.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3999,6 +3999,7 @@ void Item_func_in::fix_length_and_dec()
39993999
if (m_compare_type == STRING_RESULT &&
40004000
agg_arg_charsets_for_comparison(cmp_collation, args, arg_count))
40014001
return;
4002+
args[0]->cmp_context= m_compare_type;
40024003
arg_types_compatible= TRUE;
40034004

40044005
if (m_compare_type == ROW_RESULT)

sql/item_cmpfunc.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,20 @@ class Item_func_in :public Item_func_opt_neg
13921392
void add_key_fields(JOIN *join, KEY_FIELD **key_fields, uint *and_level,
13931393
table_map usable_tables, SARGABLE_PARAM **sargables);
13941394
SEL_TREE *get_mm_tree(RANGE_OPT_PARAM *param, Item **cond_ptr);
1395+
Item* propagate_equal_fields(THD *thd, const Context &ctx, COND_EQUAL *cond)
1396+
{
1397+
/*
1398+
In case when arg_types_compatible is false,
1399+
fix_length_and_dec() leaves args[0]->cmp_context equal to
1400+
IMPOSSIBLE_CONTEXT. In this case it's not safe to replace the field to an
1401+
equal constant, because Item_field::can_be_substituted_to_equal_item()
1402+
won't be able to check compatibility between
1403+
Item_equal->compare_collation() and this->compare_collation().
1404+
*/
1405+
return arg_types_compatible ?
1406+
Item_func_opt_neg::propagate_equal_fields(thd, ctx, cond) :
1407+
this;
1408+
}
13951409
virtual void print(String *str, enum_query_type query_type);
13961410
enum Functype functype() const { return IN_FUNC; }
13971411
const char *func_name() const { return " IN "; }

0 commit comments

Comments
 (0)