[MDEV-15765] BETWEEN not working in certain cases Created: 2018-04-03  Updated: 2018-06-04  Resolved: 2018-04-17

Status: Closed
Project: MariaDB Server
Component/s: Data Manipulation - Subquery
Affects Version/s: 10.2.14
Fix Version/s: 10.2.15

Type: Bug Priority: Blocker
Reporter: Toshko Andreev Assignee: Igor Babaev
Resolution: Fixed Votes: 2
Labels: None
Environment:

Ubuntu Server 16.04 LTS


Issue Links:
Duplicate
is duplicated by MDEV-15829 BETWEEN datetime not working with der... Closed
is duplicated by MDEV-15860 Datetime range search in subquery ret... Closed
is duplicated by MDEV-16195 MariaDB 10.2 Select Query Between Dat... Closed

 Description   

In MariaDB 10.2.14 the following SQLs do not work as intended, specifically BETWEEN seems to be broken. In 10.2.13 everything works as expected.

-- Not work
SELECT
  *
FROM (SELECT  date('2018-01-01') AS DAT
  UNION ALL
  SELECT  date('2018-01-01') AS DAT) AS t
WHERE t.DAT BETWEEN date ('2017-01-01') AND date ('2019-01-01');
 
-- not work
SELECT
  *
FROM (SELECT  date('2018-01-01') AS d) AS t
WHERE t.d BETWEEN date ('2017-01-01') AND date ('2019-01-01');
-- work
 SELECT 'aaaa' AS d FROM dual
 WHERE date('2018-01-01') BETWEEN date ('2017-01-01') AND date ('2019-01-01');



 Comments   
Comment by Alice Sherepa [ 2018-04-04 ]

after be3651b7005ed550be5a2a4b8bb2c600f9870cfa commit (10.2):

explain extended SELECT *
FROM (SELECT  date('2018-01-01') AS DAT
UNION ALL
SELECT  date('2018-01-01') AS DAT) AS t
WHERE t.DAT BETWEEN date ('2017-01-01') AND date ('2019-01-01');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
3	UNION	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
Warnings:
Note	1003	select `t`.`DAT` AS `DAT` from (select cast('2018-01-01' as date) AS `DAT` union all select cast('2018-01-01' as date) AS `DAT`) `t` where `t`.`DAT` between <cache>(cast('2017-01-01' as date)) and <cache>(cast('2019-01-01' as date))
explain extended SELECT *
FROM (SELECT  date('2018-01-01') AS d) AS t
WHERE t.d BETWEEN date ('2017-01-01') AND date ('2019-01-01');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE
Warnings:
Note	1003	select NULL AS `d` from (select cast('2018-01-01' as date) AS `d`) `t` where 0

before:

explain extended SELECT *
FROM (SELECT  date('2018-01-01') AS DAT
UNION ALL
SELECT  date('2018-01-01') AS DAT) AS t
WHERE t.DAT BETWEEN date ('2017-01-01') AND date ('2019-01-01');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	PRIMARY	<derived2>	ALL	NULL	NULL	NULL	NULL	2	100.00	Using where
2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
3	UNION	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
Warnings:
Note	1003	select `t`.`DAT` AS `DAT` from (select cast('2018-01-01' as date) AS `DAT` union all select cast('2018-01-01' as date) AS `DAT`) `t` where `t`.`DAT` between <cache>(cast('2017-01-01' as date)) and <cache>(cast('2019-01-01' as date))
explain extended SELECT *
FROM (SELECT  date('2018-01-01') AS d) AS t
WHERE t.d BETWEEN date ('2017-01-01') AND date ('2019-01-01');
id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
1	PRIMARY	<derived2>	system	NULL	NULL	NULL	NULL	1	100.00	
2	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
Warnings:
Note	1003	select '2018-01-01' AS `d` from dual where 1

Comment by Smail Mustafa [ 2018-04-08 ]

An extremely serious bug for us.
We expect you to fix it quickly!
Thanks!

Comment by Alexander Barkov [ 2018-04-09 ]

A smaller test script:

SELECT * FROM (SELECT date('2018-01-01') AS d) AS t WHERE t.d BETWEEN date ('2017-01-01') AND date ('2019-01-01');

It returns one row in 10.1, and empty set in 10.2.

Comment by Alexander Barkov [ 2018-04-09 ]

This patch fixes the problem:

diff --git a/sql/item.cc b/sql/item.cc
index 007b4f4..5fc68e4 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -9862,7 +9862,7 @@ Item *Item_cache_temporal::convert_to_basic_const_item(THD *thd)
 {
   Item *new_item;
   DBUG_ASSERT(value_cached || example != 0);
-  if (null_value)
+  if (!has_value())
     new_item= (Item*) new (thd->mem_root) Item_null(thd);
   else
   {

However:

  • I'm not sure if it's correct (for example, perhaps the value should be cached right at the cache creation time, instead of the convert_to_basic_const() time)
  • I guess it should be fixed the same way for all Item_cache_xxx::convert_to_basic_const_item(), but I could not make up covering scripts for Item_cache_int, Item_cache_real, Item_cache_decimal, Item_cache_str.

Reassigning to Igor who added Item_cache_temporal::convert_to_basic_const_item().

Comment by Oleksandr Byelkin [ 2018-04-11 ]

OK ti push

Comment by Igor Babaev [ 2018-04-17 ]

A fix for this bug was pushed into 10.2

Generated at Thu Feb 08 08:23:51 UTC 2024 using Jira 8.20.16#820016-sha1:9d11dbea5f4be3d4cc21f03a88dd11d8c8687422.