Commit 216fbe2a authored by Alexander Barkov's avatar Alexander Barkov

MDEV-6102 Comparison between TIME and DATETIME does not use CURRENT_DATE

MDEV-6101 Hybrid functions do not add CURRENT_DATE when converting TIME to DATETIME
parent d8edb88c
......@@ -1878,9 +1878,15 @@ least(1, f1)
Warnings:
Warning 1292 Incorrect datetime value: '1'
drop table t1;
SET timestamp=UNIX_TIMESTAMP('2014-04-14 10:10:10');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
now() > coalesce(time('21:43:24'), date('2010-05-03'))
0
SET timestamp=UNIX_TIMESTAMP('2014-04-14 22:22:22');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
now() > coalesce(time('21:43:24'), date('2010-05-03'))
1
SET timestamp=DEFAULT;
create table t1 (f1 timestamp);
select * from t1 where f1 > f1 and f1 <=> timestampadd(hour, 9 , '2010-01-01 16:55:35');
f1
......@@ -1918,15 +1924,20 @@ select cast(f1 AS time) from t1;
cast(f1 AS time)
00:00:00
drop table t1;
SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30');
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
greatest(cast("0-0-0" as date), cast("10:20:05" as time))
0000-00-00
2014-06-01
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00'
0
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01';
greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01'
1
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6))
0000-00-00 00:00:00.000000
2014-06-01 00:00:00.000000
SET timestamp=DEFAULT;
select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
microsecond('12:00:00.123456') microsecond('2009-12-31 23:59:59.000010')
123456 10
......@@ -2134,15 +2145,16 @@ DROP TABLE t1;
#
# MDEV-4870 Wrong values of CASE, COALESCE, IFNULL on a combination of different temporal types
#
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (dt2 DATETIME(2), t3 TIME(3), d DATE);
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.12', '00:00:00.567', '2002-01-01');
SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
CASE WHEN 0 THEN dt2 ELSE t3 END
0000-00-00 00:00:00.567
2001-01-01 00:00:00.567
CREATE TABLE t2 AS SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
SELECT * FROM t2;
CASE WHEN 0 THEN dt2 ELSE t3 END
0000-00-00 00:00:00.567
2001-01-01 00:00:00.567
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
CASE WHEN 0 THEN dt2 ELSE t3 END datetime(3) YES NULL
......@@ -2161,7 +2173,7 @@ CONCAT(CASE WHEN 1 THEN d ELSE t3 END)
2002-01-01 00:00:00.000
SELECT CASE WHEN 1 THEN t3 ELSE d END FROM t1;
CASE WHEN 1 THEN t3 ELSE d END
0000-00-00 00:00:00.567
2001-01-01 00:00:00.567
SELECT COALESCE(d, t3) FROM t1;
COALESCE(d, t3)
2002-01-01 00:00:00.000
......@@ -2181,6 +2193,7 @@ SELECT IFNULL(d, t3), CONCAT(IFNULL(d, t3)) FROM t1;
IFNULL(d, t3) CONCAT(IFNULL(d, t3))
2002-01-01 00:00:00.000 2002-01-01 00:00:00.000
DROP TABLE t1;
SET timestamp=DEFAULT;
#
# MDEV-4724 Some temporal functions do not preserve microseconds
#
......@@ -2570,3 +2583,20 @@ Warnings:
Warning 1441 Datetime function: datetime field overflow
Warning 1441 Datetime function: datetime field overflow
DROP TABLE t1;
#
# MDEV-6101 Hybrid functions do not add CURRENT_DATE when converting TIME to DATETIME
#
SET timestamp=UNIX_TIMESTAMP('2014-04-15 01:02:03');
SELECT IF(1,TIME'10:20:30',DATE'2001-01-01');
IF(1,TIME'10:20:30',DATE'2001-01-01')
2014-04-15 10:20:30
SELECT IFNULL(TIME'10:20:30',DATE'2001-01-01');
IFNULL(TIME'10:20:30',DATE'2001-01-01')
2014-04-15 10:20:30
SELECT CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END;
CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END
2014-04-15 10:20:30
SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
COALESCE(TIME'10:20:30',DATE'2001-01-01')
2014-04-15 10:20:30
SET timestamp=DEFAULT;
......@@ -95,8 +95,9 @@ INSERT INTO t1 VALUES (NULL, '00:20:12');
INSERT INTO t1 VALUES (NULL, '-00:20:12');
SELECT IF(1,ADDDATE(IFNULL(a,b),0),1) FROM t1;
IF(1,ADDDATE(IFNULL(a,b),0),1)
0000-00-00 00:20:12
NULL
NULL
Warnings:
Warning 1292 Incorrect datetime value: '0000-00-00 00:20:12'
Warning 1292 Truncated incorrect datetime value: '-00:20:12'
DROP TABLE t1;
......@@ -653,13 +653,15 @@ SELECT * FROM t1;
dt1
DROP TABLE t1;
End of 5.1 tests
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
create table t1 (d date, t time) engine=myisam;
insert into t1 values ('2000-12-03','22:55:23'),('2008-05-03','10:19:31');
select case when d = '2012-12-12' then d else t end as cond, group_concat( d ) from t1 group by cond;
cond group_concat( d )
0000-00-00 10:19:31 2008-05-03
0000-00-00 22:55:23 2000-12-03
2001-01-01 10:19:31 2008-05-03
2001-01-01 22:55:23 2000-12-03
drop table t1;
SET timestamp=DEFAULT;
#
# Semantics of the condition <non-nullable datetime field> IS NULL
# when the field belongs to an inner table of an outer join
......
......@@ -163,12 +163,26 @@ create table t1 (f1 time , f2 varchar(5), key(f1));
insert into t1 values ('00:20:01','a'),('00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
f1 f2
select * from t1 ignore key (f1) where f1 < curdate();
f1 f2
select * from t1 force key (f1) where f1 > curdate();
f1 f2
00:20:01 a
00:20:03 b
select * from t1 ignore key (f1) where f1 < curdate();
select * from t1 ignore key (f1) where f1 > curdate();
f1 f2
00:20:01 a
00:20:03 b
delete from t1;
insert into t1 values ('-00:20:01','a'),('-00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
f1 f2
-00:20:01 a
-00:20:03 b
select * from t1 ignore key (f1) where f1 < curdate();
f1 f2
-00:20:01 a
-00:20:03 b
drop table t1;
create table t1(f1 time);
insert into t1 values ('23:38:57');
......@@ -354,3 +368,17 @@ SELECT '-24:00:00' = (SELECT f1 FROM t1);
'-24:00:00' = (SELECT f1 FROM t1)
1
DROP TABLE t1;
#
# Start of 10.0 tests
#
#
# MDEV-6102 Comparison between TIME and DATETIME does not use CURRENT_DATE
#
SET timestamp=UNIX_TIMESTAMP('2014-04-14 01:02:03');
SELECT CAST(TIME'10:20:30' AS DATETIME), TIME'10:20:30'=TIMESTAMP'2014-04-14 10:20:30' AS cmp;
CAST(TIME'10:20:30' AS DATETIME) cmp
2014-04-14 10:20:30 1
SET timestamp=DEFAULT;
#
# End of 10.0 tests
#
......@@ -1126,7 +1126,11 @@ drop table t1;
#
# lp:737092 Assertion `item->null_value' failed in get_datetime_value in 5.1-micro
#
SET timestamp=UNIX_TIMESTAMP('2014-04-14 10:10:10');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
SET timestamp=UNIX_TIMESTAMP('2014-04-14 22:22:22');
select now() > coalesce(time('21:43:24'), date('2010-05-03'));
SET timestamp=DEFAULT;
#
# lp:737104 Crash in DTCollation::set in 5.1-micro
......@@ -1170,9 +1174,12 @@ insert into t1 values ('0000-00-00 00:00:00');
select cast(f1 AS time) from t1;
drop table t1;
SET timestamp=UNIX_TIMESTAMP('2014-06-01 10:20:30');
select greatest(cast("0-0-0" as date), cast("10:20:05" as time));
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '0000-00-00';
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01';
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
SET timestamp=DEFAULT;
select microsecond('12:00:00.123456'), microsecond('2009-12-31 23:59:59.000010');
......@@ -1340,6 +1347,7 @@ DROP TABLE t1;
--echo #
--echo # MDEV-4870 Wrong values of CASE, COALESCE, IFNULL on a combination of different temporal types
--echo #
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (dt2 DATETIME(2), t3 TIME(3), d DATE);
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.12', '00:00:00.567', '2002-01-01');
SELECT CASE WHEN 0 THEN dt2 ELSE t3 END FROM t1;
......@@ -1359,7 +1367,7 @@ SELECT CONCAT(COALESCE(dt2, t3)) FROM t1;
SELECT IFNULL(dt2, t3), CONCAT(IFNULL(dt2, t3)) FROM t1;
SELECT IFNULL(d, t3), CONCAT(IFNULL(d, t3)) FROM t1;
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
--echo # MDEV-4724 Some temporal functions do not preserve microseconds
......@@ -1571,3 +1579,13 @@ CREATE TABLE t1 (dt DATETIME);
INSERT INTO t1 VALUES ('2003-05-13 19:36:05'), ('2012-12-12 09:20:06');
SELECT COALESCE(ADDDATE(MAKEDATE(2011,121), dt), '2006-09-12' ) FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-6101 Hybrid functions do not add CURRENT_DATE when converting TIME to DATETIME
--echo #
SET timestamp=UNIX_TIMESTAMP('2014-04-15 01:02:03');
SELECT IF(1,TIME'10:20:30',DATE'2001-01-01');
SELECT IFNULL(TIME'10:20:30',DATE'2001-01-01');
SELECT CASE WHEN 1 THEN TIME'10:20:30' ELSE DATE'2001-01-01' END;
SELECT COALESCE(TIME'10:20:30',DATE'2001-01-01');
SET timestamp=DEFAULT;
......@@ -466,10 +466,12 @@ DROP TABLE t1;
#
# MDEV-4281 Assertion `maybe_null && item->null_value' fails in make_sortkey on CASE with different return types, GROUP_CONCAT, GROUP BY
#
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
create table t1 (d date, t time) engine=myisam;
insert into t1 values ('2000-12-03','22:55:23'),('2008-05-03','10:19:31');
select case when d = '2012-12-12' then d else t end as cond, group_concat( d ) from t1 group by cond;
drop table t1;
SET timestamp=DEFAULT;
--echo #
--echo # Semantics of the condition <non-nullable datetime field> IS NULL
......
......@@ -115,6 +115,12 @@ create table t1 (f1 time , f2 varchar(5), key(f1));
insert into t1 values ('00:20:01','a'),('00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
select * from t1 ignore key (f1) where f1 < curdate();
select * from t1 force key (f1) where f1 > curdate();
select * from t1 ignore key (f1) where f1 > curdate();
delete from t1;
insert into t1 values ('-00:20:01','a'),('-00:20:03','b');
select * from t1 force key (f1) where f1 < curdate();
select * from t1 ignore key (f1) where f1 < curdate();
drop table t1;
#
......@@ -243,3 +249,19 @@ SELECT CAST('-24:00:00' AS TIME) = (SELECT f1 FROM t1);
SELECT '-24:00:00' = (SELECT f1 FROM t1);
DROP TABLE t1;
--echo #
--echo # Start of 10.0 tests
--echo #
--echo #
--echo # MDEV-6102 Comparison between TIME and DATETIME does not use CURRENT_DATE
--echo #
SET timestamp=UNIX_TIMESTAMP('2014-04-14 01:02:03');
SELECT CAST(TIME'10:20:30' AS DATETIME), TIME'10:20:30'=TIMESTAMP'2014-04-14 10:20:30' AS cmp;
SET timestamp=DEFAULT;
--echo #
--echo # End of 10.0 tests
--echo #
......@@ -93,6 +93,31 @@ inline uint get_set_pack_length(int elements)
}
/**
Tests if field type is temporal and has date part,
i.e. represents DATE, DATETIME or TIMESTAMP types in SQL.
@param type Field type, as returned by field->type().
@retval true If field type is temporal type with date part.
@retval false If field type is not temporal type with date part.
*/
inline bool is_temporal_type_with_date(enum_field_types type)
{
switch (type)
{
case MYSQL_TYPE_DATE:
case MYSQL_TYPE_DATETIME:
case MYSQL_TYPE_TIMESTAMP:
return true;
case MYSQL_TYPE_DATETIME2:
case MYSQL_TYPE_TIMESTAMP2:
DBUG_ASSERT(0); // field->real_type() should not get to here.
default:
return false;
}
}
/**
Recognizer for concrete data type (called real_type for some reason),
returning true if it is one of the TIMESTAMP types.
......
......@@ -900,9 +900,11 @@ get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg,
{
MYSQL_TIME ltime;
uint fuzzydate= TIME_FUZZY_DATES | TIME_INVALID_DATES;
if (f_type == MYSQL_TYPE_TIME)
fuzzydate|= TIME_TIME_ONLY;
if (item->get_date(&ltime, fuzzydate))
if ((item->field_type() == MYSQL_TYPE_TIME &&
is_temporal_type_with_date(warn_item->field_type())) ?
item->get_date_with_conversion(&ltime, fuzzydate) :
item->get_date(&ltime, fuzzydate |
(f_type == MYSQL_TYPE_TIME ? TIME_TIME_ONLY : 0)))
value= 0; /* invalid date */
else
value= pack_time(&ltime);
......@@ -2559,9 +2561,9 @@ Item_func_ifnull::str_op(String *str)
bool Item_func_ifnull::date_op(MYSQL_TIME *ltime, uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
if (!args[0]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
if (!args[0]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
return (null_value= false);
if (!args[1]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES))
if (!args[1]->get_date_with_conversion(ltime, fuzzydate & ~TIME_FUZZY_DATES))
return (null_value= false);
bzero((char*) ltime,sizeof(*ltime));
return null_value= !(fuzzydate & TIME_FUZZY_DATES);
......@@ -2752,7 +2754,7 @@ bool Item_func_if::date_op(MYSQL_TIME *ltime, uint fuzzydate)
{
DBUG_ASSERT(fixed == 1);
Item *arg= args[0]->val_bool() ? args[1] : args[2];
return (null_value= arg->get_date(ltime, fuzzydate));
return (null_value= arg->get_date_with_conversion(ltime, fuzzydate));
}
......@@ -2997,7 +2999,7 @@ bool Item_func_case::date_op(MYSQL_TIME *ltime, uint fuzzydate)
Item *item= find_item(&dummy_str);
if (!item)
return (null_value= true);
return (null_value= item->get_date(ltime, fuzzydate));
return (null_value= item->get_date_with_conversion(ltime, fuzzydate));
}
......@@ -3315,7 +3317,8 @@ bool Item_func_coalesce::date_op(MYSQL_TIME *ltime,uint fuzzydate)
null_value= 0;
for (uint i= 0; i < arg_count; i++)
{
bool res= args[i]->get_date(ltime, fuzzydate & ~TIME_FUZZY_DATES);
bool res= args[i]->get_date_with_conversion(ltime,
fuzzydate & ~TIME_FUZZY_DATES);
if (!args[i]->null_value)
return res;
}
......
......@@ -1300,13 +1300,11 @@ bool get_interval_value(Item *args,interval_type int_type, INTERVAL *interval)
interval->neg= my_decimal2seconds(val, &second, &second_part);
if (second == LONGLONG_MAX)
{
char buff[DECIMAL_MAX_STR_LENGTH];
int length= sizeof(buff);
decimal2string(val, buff, &length, 0, 0, 0);
ErrConvDecimal err(val);
push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE), "DECIMAL",
buff);
err.ptr());
return true;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment