summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2014-06-06 10:29:52 +0400
committerAlexander Barkov <bar@mariadb.org>2014-06-06 10:29:52 +0400
commit216fbe2af3c8dc81f492af79dee61d6a3d333678 (patch)
tree8fc7a2b00b5fe229d79d2b4216d236debd201fa1
parentd8edb88cb15c3341a7686eb5909dde6deac16674 (diff)
downloadmariadb-git-216fbe2af3c8dc81f492af79dee61d6a3d333678.tar.gz
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
-rw-r--r--mysql-test/r/func_time.result40
-rw-r--r--mysql-test/r/old-mode.result3
-rw-r--r--mysql-test/r/type_datetime.result6
-rw-r--r--mysql-test/r/type_time.result30
-rw-r--r--mysql-test/t/func_time.test20
-rw-r--r--mysql-test/t/type_datetime.test2
-rw-r--r--mysql-test/t/type_time.test22
-rw-r--r--sql/field.h25
-rw-r--r--sql/item_cmpfunc.cc19
-rw-r--r--sql/item_timefunc.cc6
10 files changed, 151 insertions, 22 deletions
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index c7643f79779..db68f08cbba 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -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;
diff --git a/mysql-test/r/old-mode.result b/mysql-test/r/old-mode.result
index b7e1ee26391..7f3339e7ce4 100644
--- a/mysql-test/r/old-mode.result
+++ b/mysql-test/r/old-mode.result
@@ -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;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 2ba7606b663..82b64d30d96 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -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
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index aaf9819d79a..55b3ca1a1f4 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -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
+#
diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test
index ed2f0e86bb7..6bea1aab392 100644
--- a/mysql-test/t/func_time.test
+++ b/mysql-test/t/func_time.test
@@ -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;
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index e2ac9122a10..e44b190def0 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -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
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 3b839905848..4f23f7b1bb8 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -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 #
+
diff --git a/sql/field.h b/sql/field.h
index cbd9175f26c..46ec491270b 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -94,6 +94,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.
*/
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 2c4218279d7..289668f24ca 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -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;
}
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index bd1dd6d89fb..5fddad56028 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -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;
}