diff options
author | Alexander Barkov <bar@mariadb.com> | 2021-11-20 21:49:25 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2021-11-20 21:49:25 +0400 |
commit | e9f171b4fe65399e9ebbb1660198b690582e2ef5 (patch) | |
tree | ad1e23e9dd8c256a79ee26620533611c6adf5f14 | |
parent | 7efcc2794d698f62074290232e0f71234c7a4b41 (diff) | |
download | mariadb-git-e9f171b4fe65399e9ebbb1660198b690582e2ef5.tar.gz |
MDEV-27098 Subquery using the ALL keyword on TIME columns produces a wrong resultbb-10.2-bar
-rw-r--r-- | mysql-test/r/type_time.result | 12 | ||||
-rw-r--r-- | mysql-test/t/type_time.test | 10 | ||||
-rw-r--r-- | sql/sql_class.cc | 25 | ||||
-rw-r--r-- | sql/sql_class.h | 1 |
4 files changed, 46 insertions, 2 deletions
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index 90d09ea595f..6e041236ff9 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1368,5 +1368,17 @@ Warning 1292 Incorrect datetime value: '1995.0000000' Note 1003 select `test`.`t1`.`f` AS `f` from `test`.`t1` where '00:00:00.000000' between `test`.`t1`.`f` and <cache>('23:59:59') DROP TABLE t1; # +# MDEV-27098 Subquery using the ALL keyword on TIME columns produces a wrong result +# +CREATE TABLE t1 (d TIME); +INSERT INTO t1 VALUES ('120:00:00'), ('20:00:00'), ('-120:00:00'), ('-220:00:00'); +SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1); +d +120:00:00 +SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1); +d +-220:00:00 +DROP TABLE t1; +# # End of 10.2 tests # diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 9ef80cf28fb..7c1a411df37 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -824,5 +824,15 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE 1995.0000000 BETWEEN f AND '23:59:59'; DROP TABLE t1; --echo # +--echo # MDEV-27098 Subquery using the ALL keyword on TIME columns produces a wrong result +--echo # + +CREATE TABLE t1 (d TIME); +INSERT INTO t1 VALUES ('120:00:00'), ('20:00:00'), ('-120:00:00'), ('-220:00:00'); +SELECT * FROM t1 WHERE d >= ALL (SELECT * FROM t1); +SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1); +DROP TABLE t1; + +--echo # --echo # End of 10.2 tests --echo # diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 21c06029787..479578679f1 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3394,7 +3394,7 @@ int select_max_min_finder_subselect::send_data(List<Item> &items) if (!cache) { cache= Item_cache::get_cache(thd, val_item); - switch (val_item->result_type()) { + switch (val_item->cmp_type()) { case REAL_RESULT: op= &select_max_min_finder_subselect::cmp_real; break; @@ -3407,8 +3407,13 @@ int select_max_min_finder_subselect::send_data(List<Item> &items) case DECIMAL_RESULT: op= &select_max_min_finder_subselect::cmp_decimal; break; - case ROW_RESULT: case TIME_RESULT: + if (val_item->field_type() == MYSQL_TYPE_TIME) + op= &select_max_min_finder_subselect::cmp_time; + else + op= &select_max_min_finder_subselect::cmp_str; + break; + case ROW_RESULT: // This case should never be choosen DBUG_ASSERT(0); op= 0; @@ -3453,6 +3458,22 @@ bool select_max_min_finder_subselect::cmp_int() return (val1 < val2); } +bool select_max_min_finder_subselect::cmp_time() +{ + Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); + longlong val1= cache->val_time_packed(), val2= maxmin->val_time_packed(); + + /* Ignore NULLs for ANY and keep them for ALL subqueries */ + if (cache->null_value) + return (is_all && !maxmin->null_value) || (!is_all && maxmin->null_value); + if (maxmin->null_value) + return !is_all; + + if (fmax) + return(val1 > val2); + return (val1 < val2); +} + bool select_max_min_finder_subselect::cmp_decimal() { Item *maxmin= ((Item_singlerow_subselect *)item)->element_index(0); diff --git a/sql/sql_class.h b/sql/sql_class.h index a767a34d869..9fff422684e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -5396,6 +5396,7 @@ public: bool cmp_int(); bool cmp_decimal(); bool cmp_str(); + bool cmp_time(); }; /* EXISTS subselect interface class */ |