Bug #101059 Query result inconsistent for the year type in NOT IN expression
Submitted: 6 Oct 2020 2:47 Modified: 6 Oct 2020 5:22
Reporter: Yan Dong Email Updates:
Status: Verified Impact on me:
None 
Category:MySQL Server: Optimizer Severity:S3 (Non-critical)
Version:8.0.19, 8.0.21, 5.7.31, 5.6.49 OS:Any
Assigned to: CPU Architecture:x86

[6 Oct 2020 2:47] Yan Dong
Description:
The SELECT results are inconsistent when the year(4) type columns are used in NOT IN expression as index range conditions.

mysql> create table t (a year(4), key(a));
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> insert into t values (0), (1), (69), (70), (71);
Query OK, 5 rows affected (0.01 sec)
Records: 5  Duplicates: 0  Warnings: 0

mysql> select * from t where a not in (70);
+------+
| a    |
+------+
| 0000 |
| 1971 |
| 2001 |
| 2069 |
+------+
4 rows in set (0.00 sec)

mysql> select * from t where a not in (1, 70);
+------+
| a    |
+------+
| 0000 |
| 1970 |
| 1971 |
| 2001 |
| 2069 |
+------+
5 rows in set (0.00 sec)

mysql> select * from t where a not in (70, 71);
+------+
| a    |
+------+
| 0000 |
| 2001 |
| 2069 |
+------+
3 rows in set (0.00 sec)

How to repeat:
drop table if exists t;
create table t (a year(4), key(a));
insert into t values (0), (1), (69), (70), (71);
select * from t where a not in (70);
select * from t where a not in (1, 70);
select * from t where a not in (70, 71);

Suggested fix:
The results should either be: (mapping 70-99, 1-69 to 1970-2069)

mysql> select * from t where a not in (70);
+------+
| a    |
+------+
| 0000 |
| 1971 |
| 2001 |
| 2069 |
+------+
4 rows in set (0.00 sec)

mysql> select * from t where a not in (1, 70);
+------+
| a    |
+------+
| 0000 |
| 1971 |
| 2069 |
+------+
3 rows in set (0.00 sec)

mysql> select * from t where a not in (70, 71);
+------+
| a    |
+------+
| 0000 |
| 2001 |
| 2069 |
+------+
3 rows in set (0.00 sec)

Or: (without mapping)

mysql> select * from t where a not in (70);
+------+
| a    |
+------+
| 0000 |
| 1970 |
| 1971 |
| 2001 |
| 2069 |
+------+
5 rows in set (0.00 sec)

mysql> select * from t where a not in (1, 70);
+------+
| a    |
+------+
| 0000 |
| 1970 |
| 1971 |
| 2001 |
| 2069 |
+------+
5 rows in set (0.00 sec)

mysql> select * from t where a not in (70, 71);
+------+
| a    |
+------+
| 0000 |
| 1970 |
| 1971 |
| 2001 |
| 2069 |
+------+
5 rows in set (0.00 sec)
[6 Oct 2020 5:22] MySQL Verification Team
Hello Yan Dong,

Thank you for the report and test case.

regards,
Umesh