Skip to content

Commit edd919d

Browse files
committed
MDEV-38199 Optimizer Error with = SOME on UNIQUE Column Using Decimal/Integer Types
return 2 (= value was truncated) when a decimal or float number was modified when stored in Field_long (= fractional part was lost). This tells the optimizer that a number with a non-zero fractional part cannot be found in an index over an integer field.
1 parent e2b5e1f commit edd919d

File tree

8 files changed

+50
-37
lines changed

8 files changed

+50
-37
lines changed

mysql-test/main/null.result

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1647,18 +1647,18 @@ DROP TABLE t1;
16471647
#
16481648
CREATE TABLE t1 (a YEAR);
16491649
INSERT INTO t1 VALUES (2010),(2020);
1650-
SELECT * FROM t1 WHERE a=2010 AND NULLIF(10.1,a) IS NULL;
1650+
SELECT * FROM t1 WHERE a=2010 AND NULLIF(10,a) IS NULL;
16511651
a
16521652
2010
1653-
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND NULLIF(10.1,a) IS NULL;
1653+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND NULLIF(10,a) IS NULL;
16541654
id select_type table type possible_keys key key_len ref rows filtered Extra
16551655
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
16561656
Warnings:
16571657
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2010
1658-
SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10.1=a THEN NULL ELSE 10.1 END IS NULL;
1658+
SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10=a THEN NULL ELSE 10 END IS NULL;
16591659
a
16601660
2010
1661-
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10.1=a THEN NULL ELSE 10.1 END IS NULL;
1661+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10=a THEN NULL ELSE 10 END IS NULL;
16621662
id select_type table type possible_keys key key_len ref rows filtered Extra
16631663
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
16641664
Warnings:
@@ -1708,20 +1708,21 @@ a
17081708
2010
17091709
SELECT * FROM t1 WHERE NULLIF(a,2011.1)='2011';
17101710
a
1711+
2011
17111712
SELECT * FROM t1 WHERE a=10 AND NULLIF(a,2011.1)='2011';
17121713
a
17131714
EXPLAIN EXTENDED
17141715
SELECT * FROM t1 WHERE a=10 AND NULLIF(a,2011.1)='2011';
17151716
id select_type table type possible_keys key key_len ref rows filtered Extra
17161717
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
17171718
Warnings:
1718-
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2010 and (case when 2010 = 2011 then NULL else `test`.`t1`.`a` end) = '2011'
1719+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2010 and nullif(`test`.`t1`.`a`,2011.1) = '2011'
17191720
EXPLAIN EXTENDED
17201721
SELECT * FROM t1 WHERE a=10 AND NULLIF(a,2011.1)=CONCAT('2011',RAND());
17211722
id select_type table type possible_keys key key_len ref rows filtered Extra
17221723
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
17231724
Warnings:
1724-
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2010 and (case when 2010 = 2011 then NULL else `test`.`t1`.`a` end) = concat('2011',rand())
1725+
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 2010 and nullif(`test`.`t1`.`a`,2011.1) = concat('2011',rand())
17251726
DROP TABLE t1;
17261727
#
17271728
# MDEV-8754 Wrong result for SELECT..WHERE year_field=2020 AND NULLIF(year_field,2010)='2020'

mysql-test/main/null.test

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -998,10 +998,10 @@ DROP TABLE t1;
998998
--echo #
999999
CREATE TABLE t1 (a YEAR);
10001000
INSERT INTO t1 VALUES (2010),(2020);
1001-
SELECT * FROM t1 WHERE a=2010 AND NULLIF(10.1,a) IS NULL;
1002-
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND NULLIF(10.1,a) IS NULL;
1003-
SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10.1=a THEN NULL ELSE 10.1 END IS NULL;
1004-
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10.1=a THEN NULL ELSE 10.1 END IS NULL;
1001+
SELECT * FROM t1 WHERE a=2010 AND NULLIF(10,a) IS NULL;
1002+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND NULLIF(10,a) IS NULL;
1003+
SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10=a THEN NULL ELSE 10 END IS NULL;
1004+
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=2010 AND CASE WHEN 10=a THEN NULL ELSE 10 END IS NULL;
10051005
DROP TABLE t1;
10061006

10071007
--echo # Two warnings expected

mysql-test/main/table_elim.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -345,7 +345,7 @@ id select_type table type possible_keys key key_len ref rows Extra
345345
explain select t1.a from t1 left join t2 on t2.pk between 0.5 and 1.5;
346346
id select_type table type possible_keys key key_len ref rows Extra
347347
1 SIMPLE t1 ALL NULL NULL NULL NULL 4
348-
1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index
348+
1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
349349
explain select t1.a from t1 left join t2 on t2.pk between 10 and 10;
350350
id select_type table type possible_keys key key_len ref rows Extra
351351
1 SIMPLE t1 ALL NULL NULL NULL NULL 4

mysql-test/main/type_decimal.result

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,6 @@ Warning 1264 Out of range value for column 'a' at row 3
349349
insert ignore into t1 values (1e+100),(1e-100),(-1e+100);
350350
Warnings:
351351
Warning 1264 Out of range value for column 'a' at row 1
352-
Note 1265 Data truncated for column 'a' at row 2
353352
Warning 1264 Out of range value for column 'a' at row 3
354353
insert into t1 values (123.4e0),(123.4e+2),(123.4e-2),(123e1),(123e+0);
355354
Warnings:
@@ -1700,6 +1699,19 @@ a
17001699
123.47
17011700
DROP TABLE t1;
17021701
DROP PROCEDURE show_table;
1703-
#
17041702
# End of 10.11 tests
17051703
#
1704+
# MDEV-38199 Optimizer Error with = SOME on UNIQUE Column Using Decimal/Integer Types
1705+
#
1706+
create table t1 (i int, key (i));
1707+
insert into t1 values(1),(1),(1);
1708+
select i from t1 where i=0.6;
1709+
i
1710+
select i from t1 ignore index(i) where i=0.6;
1711+
i
1712+
select i from t1 where i=0.6e0;
1713+
i
1714+
select i from t1 ignore index(i) where i=0.6e0;
1715+
i
1716+
drop table t1;
1717+
# End of 12.3 tests

mysql-test/main/type_decimal.test

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -930,7 +930,17 @@ DROP TABLE t1;
930930

931931
DROP PROCEDURE show_table;
932932

933+
--echo # End of 10.11 tests
933934

934935
--echo #
935-
--echo # End of 10.11 tests
936+
--echo # MDEV-38199 Optimizer Error with = SOME on UNIQUE Column Using Decimal/Integer Types
936937
--echo #
938+
create table t1 (i int, key (i));
939+
insert into t1 values(1),(1),(1);
940+
select i from t1 where i=0.6;
941+
select i from t1 ignore index(i) where i=0.6;
942+
select i from t1 where i=0.6e0;
943+
select i from t1 ignore index(i) where i=0.6e0;
944+
drop table t1;
945+
946+
--echo # End of 12.3 tests

mysql-test/main/type_year.result

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -229,16 +229,12 @@ yyyy c4
229229
1999 1999
230230
SELECT * FROM t2 WHERE yy = 1999.1;
231231
yy c2
232-
99 1999
233232
SELECT * FROM t4 WHERE yyyy = 1999.1;
234233
yyyy c4
235-
1999 1999
236234
SELECT * FROM t2 WHERE yy = 1998.9;
237235
yy c2
238-
99 1999
239236
SELECT * FROM t4 WHERE yyyy = 1998.9;
240237
yyyy c4
241-
1999 1999
242238
# Coverage tests for YEAR with zero/2000 constants:
243239
SELECT * FROM t2 WHERE yy = 0;
244240
yy c2

mysql-test/suite/innodb/r/innodb-isolation.result

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -973,7 +973,7 @@ id select_type table type possible_keys key key_len ref rows Extra
973973
2 SUBQUERY t1 index NULL k2 5 NULL # Using index
974974
EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1);
975975
id select_type table type possible_keys key key_len ref rows Extra
976-
1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL # Using where
976+
1 PRIMARY t1 index PRIMARY k2 5 NULL # Using where; Using index
977977
2 SUBQUERY t1 index NULL k2 5 NULL # Using index
978978
#
979979
# Make all indexes in t2 obsolete to the active repeatable read transaction

sql/field.cc

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1897,11 +1897,6 @@ int Field::warn_if_overflow(int op_result)
18971897
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
18981898
return 1;
18991899
}
1900-
if (op_result == E_DEC_TRUNCATED)
1901-
{
1902-
set_note(WARN_DATA_TRUNCATED, 1);
1903-
/* We return 0 here as this is not a critical issue */
1904-
}
19051900
return 0;
19061901
}
19071902

@@ -2254,31 +2249,28 @@ longlong Field::convert_decimal2longlong(const my_decimal *val,
22542249
bool unsigned_flag, int *err)
22552250
{
22562251
longlong i;
2252+
int res= E_DEC_OVERFLOW;
22572253
if (unsigned_flag)
22582254
{
22592255
if (val->sign())
22602256
{
22612257
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
22622258
i= 0;
2263-
*err= 1;
22642259
}
2265-
else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR &
2266-
~E_DEC_OVERFLOW &
2267-
~E_DEC_TRUNCATED),
2268-
val, TRUE, &i)))
2260+
else if (warn_if_overflow(res= my_decimal2int(E_DEC_FATAL_ERROR &
2261+
~E_DEC_OVERFLOW,
2262+
val, TRUE, &i)))
22692263
{
22702264
i= ~(longlong) 0;
2271-
*err= 1;
22722265
}
22732266
}
2274-
else if (warn_if_overflow(my_decimal2int((E_DEC_ERROR &
2275-
~E_DEC_OVERFLOW &
2276-
~E_DEC_TRUNCATED),
2277-
val, FALSE, &i)))
2267+
else if (warn_if_overflow(res= my_decimal2int(E_DEC_FATAL_ERROR &
2268+
~E_DEC_OVERFLOW,
2269+
val, FALSE, &i)))
22782270
{
22792271
i= (val->sign() ? LONGLONG_MIN : LONGLONG_MAX);
2280-
*err= 1;
22812272
}
2273+
*err= res == E_DEC_TRUNCATED ? 2 : res != 0;
22822274
return i;
22832275
}
22842276

@@ -4519,12 +4511,12 @@ int Field_long::store(const char *from,size_t len,CHARSET_INFO *cs)
45194511
}
45204512

45214513

4522-
int Field_long::store(double nr)
4514+
int Field_long::store(double val)
45234515
{
45244516
DBUG_ASSERT(marked_for_write_or_computed());
45254517
int error= 0;
45264518
int32 res;
4527-
nr=rint(nr);
4519+
double nr= rint(val);
45284520
if (unsigned_flag)
45294521
{
45304522
if (nr < 0)
@@ -4558,6 +4550,8 @@ int Field_long::store(double nr)
45584550
}
45594551
if (unlikely(error))
45604552
set_warning(ER_WARN_DATA_OUT_OF_RANGE, 1);
4553+
else if (nr != val)
4554+
error= 2;
45614555

45624556
int4store(ptr,res);
45634557
return error;

0 commit comments

Comments
 (0)