Skip to content

Commit 0aeb682

Browse files
committed
Bug#35115909: Wrong join result when one of the join columns is compared to a temporal literal
Bug#35080094: MySQL server crash - Assertion CompatibleTypesForIndexLookup failed This patch fixes two bugs: 1) Wrong results were seen in some case when one equality predicate compared two string columns and another equality predicate compared one of the string columns to a temporal constant. For example: SELECT * FROM t WHERE a = b AND b = DATE'2023-01-01' If a and b were VARCHAR columns with character set latin1, the optimizer would propagate the DATE constant into the a = b predicate and transform the query into: SELECT * FROM t WHERE a = DATE'2023-01-01' AND b = DATE'2023-01-01' The original a = b predicate would use string semantics for the comparison, whereas the new a = DATE'2023-01-01' predicate uses DATE semantics. The meaning of the query therefore changed, and wrong results could be returned. 2) The hypergraph optimizer got an assertion failure when analyzing which predicates were sargable. The assertion failure was seen if the WHERE clause compared an indexed string column with a constant TIME expression. It checked that all equality predicates that were part of a multiple equality had arguments that were compatible for index lookups. Both of these issues were fixed by disabling creation of multiple equalities from single equalities comparing a non-temporal string column to a temporal constant. Change-Id: Ibab64903eea83ce16ca4057154fa882a7e2b05f6
1 parent b626000 commit 0aeb682

File tree

7 files changed

+173
-0
lines changed

7 files changed

+173
-0
lines changed

mysql-test/r/type_date.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,3 +697,30 @@ d
697697
2021-10-11
698698
2021-10-11
699699
DROP TABLE d, dt;
700+
#
701+
# Bug#35080094: MySQL server crash -
702+
# Assertion CompatibleTypesForIndexLookup failed
703+
#
704+
CREATE TABLE t(a VARCHAR(100) CHARSET latin1, KEY(a));
705+
INSERT INTO t VALUES ('2023-1-1'), ('2023-01-01');
706+
SELECT * FROM t WHERE a = DATE'2023-01-01';
707+
a
708+
2023-01-01
709+
2023-1-1
710+
DROP TABLE t;
711+
#
712+
# Bug#35115909: Wrong join result when one of the join columns
713+
# is compared to a temporal literal
714+
#
715+
CREATE TABLE t (a VARCHAR(10) CHARSET latin1,
716+
b VARCHAR(10) CHARSET latin1);
717+
INSERT INTO t VALUES
718+
('2023-01-01', '2023-01-01'),
719+
('2023-01-01', '2023-1-1'),
720+
('2023-1-1', '2023-01-01'),
721+
('2023-1-1', '2023-1-1');
722+
SELECT * FROM t WHERE a = b and b = DATE'2023-01-01';
723+
a b
724+
2023-01-01 2023-01-01
725+
2023-1-1 2023-1-1
726+
DROP TABLE t;

mysql-test/r/type_datetime.result

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,3 +1116,30 @@ SELECT * FROM t1 wHERE pk = 5 AND
11161116
pk col_date col_datetime col_varchar
11171117
5 2022-02-25 2022-02-25 11:01:14 I
11181118
DROP TABLE t1;
1119+
#
1120+
# Bug#35080094: MySQL server crash -
1121+
# Assertion CompatibleTypesForIndexLookup failed
1122+
#
1123+
CREATE TABLE t(a VARCHAR(100) CHARSET latin1, KEY(a));
1124+
INSERT INTO t VALUES ('2023-1-1 1:2:3'), ('2023-01-01 01:02:03');
1125+
SELECT * FROM t WHERE a = TIMESTAMP'2023-01-01 01:02:03';
1126+
a
1127+
2023-01-01 01:02:03
1128+
2023-1-1 1:2:3
1129+
DROP TABLE t;
1130+
#
1131+
# Bug#35115909: Wrong join result when one of the join columns
1132+
# is compared to a temporal literal
1133+
#
1134+
CREATE TABLE t (a VARCHAR(30) CHARSET latin1,
1135+
b VARCHAR(30) CHARSET latin1);
1136+
INSERT INTO t VALUES
1137+
('2023-01-01 01:02:03', '2023-01-01 01:02:03'),
1138+
('2023-01-01 01:02:03', '2023-1-1 1:2:3'),
1139+
('2023-1-1 1:2:3', '2023-01-01 01:02:03'),
1140+
('2023-1-1 1:2:3', '2023-1-1 1:2:3');
1141+
SELECT * FROM t WHERE a = b and b = TIMESTAMP'2023-01-01 01:02:03';
1142+
a b
1143+
2023-01-01 01:02:03 2023-01-01 01:02:03
1144+
2023-1-1 1:2:3 2023-1-1 1:2:3
1145+
DROP TABLE t;

mysql-test/r/type_time.result

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,3 +2858,27 @@ t
28582858
02:00:00
28592859
02:00:00
28602860
DROP TABLE t, dt;
2861+
#
2862+
# Bug#35080094: MySQL server crash -
2863+
# Assertion CompatibleTypesForIndexLookup failed
2864+
#
2865+
CREATE TABLE t(a VARCHAR(100), KEY(a));
2866+
INSERT INTO t VALUES ('1:2:3'), ('01:02:03');
2867+
SELECT * FROM t WHERE a = TIME'01:02:03';
2868+
a
2869+
01:02:03
2870+
DROP TABLE t;
2871+
#
2872+
# Bug#35115909: Wrong join result when one of the join columns
2873+
# is compared to a temporal literal
2874+
#
2875+
CREATE TABLE t (a VARCHAR(10), b VARCHAR(10));
2876+
INSERT INTO t VALUES
2877+
('01:02:03', '01:02:03'),
2878+
('01:02:03', '1:2:3'),
2879+
('1:2:3', '01:02:03'),
2880+
('1:2:3', '1:2:3');
2881+
SELECT * FROM t WHERE a = b and b = TIME'01:02:03';
2882+
a b
2883+
01:02:03 01:02:03
2884+
DROP TABLE t;

mysql-test/t/type_date.test

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,3 +575,31 @@ SELECT * FROM d;
575575

576576
DROP TABLE d, dt;
577577

578+
--echo #
579+
--echo # Bug#35080094: MySQL server crash -
580+
--echo # Assertion CompatibleTypesForIndexLookup failed
581+
--echo #
582+
583+
CREATE TABLE t(a VARCHAR(100) CHARSET latin1, KEY(a));
584+
INSERT INTO t VALUES ('2023-1-1'), ('2023-01-01');
585+
--sorted_result
586+
SELECT * FROM t WHERE a = DATE'2023-01-01';
587+
DROP TABLE t;
588+
589+
--echo #
590+
--echo # Bug#35115909: Wrong join result when one of the join columns
591+
--echo # is compared to a temporal literal
592+
--echo #
593+
594+
CREATE TABLE t (a VARCHAR(10) CHARSET latin1,
595+
b VARCHAR(10) CHARSET latin1);
596+
INSERT INTO t VALUES
597+
('2023-01-01', '2023-01-01'),
598+
('2023-01-01', '2023-1-1'),
599+
('2023-1-1', '2023-01-01'),
600+
('2023-1-1', '2023-1-1');
601+
# Used to return four rows. Should return only those two rows that
602+
# satisfy the a=b predicate.
603+
--sorted_result
604+
SELECT * FROM t WHERE a = b and b = DATE'2023-01-01';
605+
DROP TABLE t;

mysql-test/t/type_datetime.test

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,3 +834,32 @@ SELECT * FROM t1 wHERE pk = 5 AND
834834
(col_varchar, col_date) IN (('I','2022-02-25'), ('I', '2022-02-25'));
835835

836836
DROP TABLE t1;
837+
838+
--echo #
839+
--echo # Bug#35080094: MySQL server crash -
840+
--echo # Assertion CompatibleTypesForIndexLookup failed
841+
--echo #
842+
843+
CREATE TABLE t(a VARCHAR(100) CHARSET latin1, KEY(a));
844+
INSERT INTO t VALUES ('2023-1-1 1:2:3'), ('2023-01-01 01:02:03');
845+
--sorted_result
846+
SELECT * FROM t WHERE a = TIMESTAMP'2023-01-01 01:02:03';
847+
DROP TABLE t;
848+
849+
--echo #
850+
--echo # Bug#35115909: Wrong join result when one of the join columns
851+
--echo # is compared to a temporal literal
852+
--echo #
853+
854+
CREATE TABLE t (a VARCHAR(30) CHARSET latin1,
855+
b VARCHAR(30) CHARSET latin1);
856+
INSERT INTO t VALUES
857+
('2023-01-01 01:02:03', '2023-01-01 01:02:03'),
858+
('2023-01-01 01:02:03', '2023-1-1 1:2:3'),
859+
('2023-1-1 1:2:3', '2023-01-01 01:02:03'),
860+
('2023-1-1 1:2:3', '2023-1-1 1:2:3');
861+
# Used to return four rows. Should return only those two rows that
862+
# satisfy the a=b predicate.
863+
--sorted_result
864+
SELECT * FROM t WHERE a = b and b = TIMESTAMP'2023-01-01 01:02:03';
865+
DROP TABLE t;

mysql-test/t/type_time.test

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,3 +540,36 @@ execute s using @dt;
540540
SELECT * FROM t;
541541

542542
DROP TABLE t, dt;
543+
544+
--echo #
545+
--echo # Bug#35080094: MySQL server crash -
546+
--echo # Assertion CompatibleTypesForIndexLookup failed
547+
--echo #
548+
549+
CREATE TABLE t(a VARCHAR(100), KEY(a));
550+
INSERT INTO t VALUES ('1:2:3'), ('01:02:03');
551+
SELECT * FROM t WHERE a = TIME'01:02:03';
552+
DROP TABLE t;
553+
554+
--echo #
555+
--echo # Bug#35115909: Wrong join result when one of the join columns
556+
--echo # is compared to a temporal literal
557+
--echo #
558+
559+
# This test case is provided for completeness, based on the test cases
560+
# for the same bug number in type_date and type_datetime, even though
561+
# the bug that was seen with DATE and DATETIME was not seen with TIME.
562+
CREATE TABLE t (a VARCHAR(10), b VARCHAR(10));
563+
INSERT INTO t VALUES
564+
('01:02:03', '01:02:03'),
565+
('01:02:03', '1:2:3'),
566+
('1:2:3', '01:02:03'),
567+
('1:2:3', '1:2:3');
568+
# The main point of this test case is to verify that the a=b predicate
569+
# uses string comparison and excludes the second and third row from
570+
# the result. The query currently returns the first row only. It would
571+
# have been more consistent with DATE and DATETIME if it had returned
572+
# both the first and the fourth row (see the test cases for the same
573+
# bug number in type_date and type_datetime).
574+
SELECT * FROM t WHERE a = b and b = TIME'01:02:03';
575+
DROP TABLE t;

sql/sql_optimizer.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3949,6 +3949,11 @@ static bool check_simple_equality(THD *thd, Item *left_item, Item *right_item,
39493949
(const_item->data_type() == MYSQL_TYPE_JSON)) {
39503950
return false;
39513951
}
3952+
// Similarly, strings and temporal types have different semantics for
3953+
// equality comparison.
3954+
if (const_item->is_temporal() && !field_item->is_temporal()) {
3955+
return false;
3956+
}
39523957
}
39533958

39543959
bool copyfl;

0 commit comments

Comments
 (0)