Commit accf9b56 authored by Alexander Barkov's avatar Alexander Barkov

MDEV-5694 GREATEST(date, time) returns a wrong data type

parent a84fae27
This diff is collapsed.
......@@ -1919,16 +1919,19 @@ 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))
2014-06-01
2014-06-01 10:20:05
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'
0
select greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05';
greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05'
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))
2014-06-01 00:00:00.000000
2014-06-01 10:20:05.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')
......@@ -2563,18 +2566,12 @@ CREATE TABLE t1 (t TIME);
INSERT INTO t1 VALUES ('03:22:30'),('18:30:05');
SELECT CONVERT_TZ(GREATEST(t, CURRENT_DATE()), '+02:00', '+10:00') FROM t1;
CONVERT_TZ(GREATEST(t, CURRENT_DATE()), '+02:00', '+10:00')
2014-02-26 06:59:59
2014-02-26 06:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '1296:00:00'
Warning 1292 Truncated incorrect time value: '1296:00:00'
2014-01-22 11:22:30
2014-01-23 02:30:05
SELECT GREATEST(t, CURRENT_DATE()) FROM t1;
GREATEST(t, CURRENT_DATE())
838:59:59
838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '1296:00:00'
Warning 1292 Truncated incorrect time value: '1296:00:00'
2014-01-22 03:22:30
2014-01-22 18:30:05
DROP TABLE t1;
SET TIMESTAMP=DEFAULT;
#
......@@ -2695,18 +2692,15 @@ SET timestamp=DEFAULT;
#
# MDEV-5750 Assertion `ltime->year == 0' fails on a query with EXTRACT DAY_MINUTE and TIME column
#
SET timestamp=UNIX_TIMESTAMP('2010-01-01 00:00:00');
CREATE TABLE t1 ( d DATE, t TIME );
INSERT INTO t1 VALUES ('2008-12-05','22:34:09'),('2005-03-27','14:26:02');
SELECT EXTRACT(DAY_MINUTE FROM GREATEST(t,d)), GREATEST(t,d) FROM t1;
EXTRACT(DAY_MINUTE FROM GREATEST(t,d)) GREATEST(t,d)
342259 838:59:59
342259 838:59:59
Warnings:
Warning 1292 Truncated incorrect time value: '9336:00:00'
Warning 1292 Truncated incorrect time value: '9336:00:00'
Warning 1292 Truncated incorrect time value: '2952:00:00'
Warning 1292 Truncated incorrect time value: '2952:00:00'
12234 2010-01-01 22:34:09
11426 2010-01-01 14:26:02
DROP TABLE t1;
SET timestamp=DEFAULT;
#
# MDEV-7221 from_days fails after null value
#
......
......@@ -81,6 +81,38 @@ INSERT INTO t1 VALUES (4294967295,2015);
--source include/func_hybrid_type.inc
DROP TABLE t1;
--echo #
SET timestamp=UNIX_TIMESTAMP('2001-01-01 01:02:03');
CREATE TABLE t1 (a DATE, b TIME);
INSERT INTO t1 VALUES ('2010-01-01','10:20:30');
--source include/func_hybrid_type.inc
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
SET timestamp=UNIX_TIMESTAMP('2001-01-01 01:02:03');
CREATE TABLE t1 (a TIMESTAMP, b TIME);
INSERT INTO t1 VALUES ('2010-01-01 00:00:00','10:20:30');
--source include/func_hybrid_type.inc
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
SET timestamp=UNIX_TIMESTAMP('2001-01-01 01:02:03');
CREATE TABLE t1 (a DATETIME, b TIME);
INSERT INTO t1 VALUES ('2010-01-01 00:00:00','10:20:30');
--source include/func_hybrid_type.inc
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
SET timestamp=UNIX_TIMESTAMP('2001-01-01 01:02:03');
CREATE TABLE t1 (a DATETIME, b DATE);
INSERT INTO t1 VALUES ('2010-01-01 10:20:30','2001-01-02');
--source include/func_hybrid_type.inc
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
--echo # MDEV-8873 Wrong field type or metadata for LEAST(int_column,string_column)
......@@ -111,6 +143,28 @@ INSERT INTO t1 (a) VALUES (13836376518955650385) ON DUPLICATE KEY UPDATE a=GREAT
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-5694 GREATEST(date, time) returns a wrong data type
--echo #
SET timestamp=UNIX_TIMESTAMP('2010-01-01 01:02:03');
--disable_ps_protocol
--enable_metadata
# Expect DATETIME type (12) in metadata
SELECT GREATEST(CURRENT_TIME, CURRENT_DATE), COALESCE(CURRENT_TIME, CURRENT_DATE);
CREATE TABLE t1 (a TIMESTAMP);
INSERT INTO t1 VALUES ('2010-01-01 10:20:30');
# Expect TIMESTAMP type (7) in metadata
SELECT GREATEST(a,a) FROM t1;
DROP TABLE t1;
--disable_metadata
--enable_ps_protocol
CREATE TABLE t1 (a TIMESTAMP, b DATETIME);
CREATE TABLE t2 AS SELECT LEAST(a,a),LEAST(b,b),LEAST(a,b) FROM t1;
SHOW CREATE TABLE t2;
DROP TABLE t2;
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
--echo # End of 10.1 tests
--echo #
......@@ -1180,6 +1180,7 @@ 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 greatest(cast("0-0-0" as date), cast("10:20:05" as time)) = '2014-06-01 10:20:05';
select cast(greatest(cast("0-0-0" as date), cast("10:20:05" as time)) as datetime(6));
SET timestamp=DEFAULT;
......@@ -1629,11 +1630,12 @@ SET timestamp=DEFAULT;
--echo #
--echo # MDEV-5750 Assertion `ltime->year == 0' fails on a query with EXTRACT DAY_MINUTE and TIME column
--echo #
SET timestamp=UNIX_TIMESTAMP('2010-01-01 00:00:00');
CREATE TABLE t1 ( d DATE, t TIME );
INSERT INTO t1 VALUES ('2008-12-05','22:34:09'),('2005-03-27','14:26:02');
SELECT EXTRACT(DAY_MINUTE FROM GREATEST(t,d)), GREATEST(t,d) FROM t1;
DROP TABLE t1;
SET timestamp=DEFAULT;
--echo #
--echo # MDEV-7221 from_days fails after null value
......
......@@ -2832,9 +2832,10 @@ void Item_func_min_max::fix_length_and_dec()
max_length=0;
maybe_null=0;
thd= current_thd;
compare_as_dates= find_date_time_item(args, arg_count, 0);
Item_result tmp_cmp_type= args[0]->cmp_type();
uint string_type_count= 0;
uint temporal_type_count= 0;
enum_field_types temporal_field_type= MYSQL_TYPE_DATETIME;
for (uint i=0 ; i < arg_count ; i++)
{
......@@ -2846,6 +2847,15 @@ void Item_func_min_max::fix_length_and_dec()
maybe_null= 1;
tmp_cmp_type= item_cmp_type(tmp_cmp_type, args[i]->cmp_type());
string_type_count+= args[i]->cmp_type() == STRING_RESULT;
if (args[i]->cmp_type() == TIME_RESULT)
{
if (!temporal_type_count)
temporal_field_type= args[i]->field_type();
else
temporal_field_type= Field::field_type_merge(temporal_field_type,
args[i]->field_type());
temporal_type_count++;
}
}
unsigned_flag= unsigned_count == arg_count; // if all args are unsigned
......@@ -2853,12 +2863,11 @@ void Item_func_min_max::fix_length_and_dec()
case TIME_RESULT:
// At least one temporal argument was found.
collation.set_numeric();
set_handler_by_field_type(compare_as_dates->field_type());
if (mysql_type_to_time_type(Item_func_min_max::field_type()) ==
MYSQL_TIMESTAMP_DATE)
decimals= 0;
else
set_handler_by_field_type(temporal_field_type);
if (is_temporal_type_with_time(temporal_field_type))
set_if_smaller(decimals, TIME_SECOND_PART_DIGITS);
else
decimals= 0;
break;
case STRING_RESULT:
......@@ -2956,12 +2965,12 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
for example, SELECT MONTH(GREATEST("2011-11-21", "2010-10-09"))
*/
if (!compare_as_dates)
if (Item_func_min_max::cmp_type() != TIME_RESULT)
return Item_func::get_date(ltime, fuzzy_date);
for (uint i=0; i < arg_count ; i++)
{
longlong res= args[i]->val_temporal_packed(compare_as_dates);
longlong res= args[i]->val_temporal_packed(Item_func_min_max::field_type());
/* Check if we need to stop (because of error or KILL) and stop the loop */
if (thd->is_error() || args[i]->null_value)
......@@ -2974,12 +2983,12 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
}
unpack_time(min_max, ltime);
if (compare_as_dates->field_type() == MYSQL_TYPE_DATE)
if (Item_func_min_max::field_type() == MYSQL_TYPE_DATE)
{
ltime->time_type= MYSQL_TIMESTAMP_DATE;
ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
}
else if (compare_as_dates->field_type() == MYSQL_TYPE_TIME)
else if (Item_func_min_max::field_type() == MYSQL_TYPE_TIME)
{
ltime->time_type= MYSQL_TIMESTAMP_TIME;
ltime->hour+= (ltime->month * 32 + ltime->day) * 24;
......@@ -3001,7 +3010,7 @@ bool Item_func_min_max::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
String *Item_func_min_max::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
if (compare_as_dates)
if (Item_func_min_max::cmp_type() == TIME_RESULT)
return val_string_from_date(str);
switch (Item_func_min_max::result_type()) {
case INT_RESULT:
......@@ -3047,7 +3056,7 @@ double Item_func_min_max::val_real()
{
DBUG_ASSERT(fixed == 1);
double value=0.0;
if (compare_as_dates)
if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
......@@ -3076,7 +3085,7 @@ longlong Item_func_min_max::val_int()
{
DBUG_ASSERT(fixed == 1);
longlong value=0;
if (compare_as_dates)
if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
......@@ -3106,7 +3115,7 @@ my_decimal *Item_func_min_max::val_decimal(my_decimal *dec)
DBUG_ASSERT(fixed == 1);
my_decimal tmp_buf, *tmp, *UNINIT_VAR(res);
if (compare_as_dates)
if (Item_func_min_max::cmp_type() == TIME_RESULT)
{
MYSQL_TIME ltime;
if (get_date(&ltime, 0))
......
......@@ -1002,13 +1002,11 @@ class Item_func_min_max :public Item_func,
{
String tmp_value;
int cmp_sign;
/* An item used for issuing warnings while string to DATETIME conversion. */
Item *compare_as_dates;
THD *thd;
public:
Item_func_min_max(THD *thd, List<Item> &list, int cmp_sign_arg):
Item_func(thd, list), cmp_sign(cmp_sign_arg),
compare_as_dates(0) {}
Item_func(thd, list), cmp_sign(cmp_sign_arg)
{}
double val_real();
longlong val_int();
String *val_str(String *);
......
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