Browse Source

Bug#31990: MINUTE() and SECOND() return bogus results when used on a DATE

HOUR(), MINUTE(), ... returned spurious results when used on a DATE-cast.
This happened because DATE-cast object did not overload get_time() method
in superclass Item. The default method was inappropriate here and
misinterpreted the data.

Patch adds missing method; get_time() on DATE-casts now returns SQL-NULL
on NULL input, 0 otherwise. This coincides with the way DATE-columns
behave.

Also fixes similar bug in Date-Field now.
pull/73/head
tnurnberg@mysql.com/white.intern.koehntopp.de 18 years ago
parent
commit
3f0f275030
  1. 24
      mysql-test/r/cast.result
  2. 5
      mysql-test/r/type_date.result
  3. 22
      mysql-test/t/cast.test
  4. 8
      mysql-test/t/type_date.test
  5. 7
      sql/field.cc
  6. 1
      sql/field.h
  7. 7
      sql/item_timefunc.cc
  8. 1
      sql/item_timefunc.h

24
mysql-test/r/cast.result

@ -414,4 +414,28 @@ NULL
NULL
20070719
drop table t1;
CREATE TABLE t1 (f1 DATE);
INSERT INTO t1 VALUES ('2007-07-19'), (NULL);
SELECT HOUR(f1),
MINUTE(f1),
SECOND(f1) FROM t1;
HOUR(f1) MINUTE(f1) SECOND(f1)
0 0 0
NULL NULL NULL
SELECT HOUR(CAST('2007-07-19' AS DATE)),
MINUTE(CAST('2007-07-19' AS DATE)),
SECOND(CAST('2007-07-19' AS DATE));
HOUR(CAST('2007-07-19' AS DATE)) MINUTE(CAST('2007-07-19' AS DATE)) SECOND(CAST('2007-07-19' AS DATE))
0 0 0
SELECT HOUR(CAST(NULL AS DATE)),
MINUTE(CAST(NULL AS DATE)),
SECOND(CAST(NULL AS DATE));
HOUR(CAST(NULL AS DATE)) MINUTE(CAST(NULL AS DATE)) SECOND(CAST(NULL AS DATE))
NULL NULL NULL
SELECT HOUR(NULL),
MINUTE(NULL),
SECOND(NULL);
HOUR(NULL) MINUTE(NULL) SECOND(NULL)
NULL NULL NULL
DROP TABLE t1;
End of 5.0 tests

5
mysql-test/r/type_date.result

@ -214,4 +214,9 @@ INSERT INTO t1 VALUES ('0000-00-00');
ERROR 22007: Incorrect date value: '0000-00-00' for column 'a' at row 1
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
CREATE TABLE t1 SELECT curdate() AS f1;
SELECT hour(f1), minute(f1), second(f1) FROM t1;
hour(f1) minute(f1) second(f1)
0 0 0
DROP TABLE t1;
End of 5.0 tests

22
mysql-test/t/cast.test

@ -246,4 +246,26 @@ INSERT INTO t1(d1) VALUES ('2007-07-19 08:30:00'), (NULL),
SELECT cast(date(d1) as signed) FROM t1;
drop table t1;
#
# Bug #31990: MINUTE() and SECOND() return bogus results when used on a DATE
#
# Show that HH:MM:SS of a DATE are 0, and that it's the same for columns
# and typecasts (NULL in, NULL out).
CREATE TABLE t1 (f1 DATE);
INSERT INTO t1 VALUES ('2007-07-19'), (NULL);
SELECT HOUR(f1),
MINUTE(f1),
SECOND(f1) FROM t1;
SELECT HOUR(CAST('2007-07-19' AS DATE)),
MINUTE(CAST('2007-07-19' AS DATE)),
SECOND(CAST('2007-07-19' AS DATE));
SELECT HOUR(CAST(NULL AS DATE)),
MINUTE(CAST(NULL AS DATE)),
SECOND(CAST(NULL AS DATE));
SELECT HOUR(NULL),
MINUTE(NULL),
SECOND(NULL);
DROP TABLE t1;
--echo End of 5.0 tests

8
mysql-test/t/type_date.test

@ -190,4 +190,12 @@ INSERT INTO t1 VALUES ('0000-00-00');
SET SQL_MODE=DEFAULT;
DROP TABLE t1,t2;
#
# Bug #31990: MINUTE() and SECOND() return bogus results when used on a DATE
#
CREATE TABLE t1 SELECT curdate() AS f1;
SELECT hour(f1), minute(f1), second(f1) FROM t1;
DROP TABLE t1;
--echo End of 5.0 tests

7
sql/field.cc

@ -5194,6 +5194,13 @@ String *Field_date::val_str(String *val_buffer,
}
bool Field_date::get_time(MYSQL_TIME *ltime)
{
bzero((char *)ltime, sizeof(MYSQL_TIME));
return 0;
}
int Field_date::cmp(const char *a_ptr, const char *b_ptr)
{
int32 a,b;

1
sql/field.h

@ -933,6 +933,7 @@ public:
double val_real(void);
longlong val_int(void);
String *val_str(String*,String *);
bool get_time(MYSQL_TIME *ltime);
bool send_binary(Protocol *protocol);
int cmp(const char *,const char*);
void sort_string(char *buff,uint length);

7
sql/item_timefunc.cc

@ -2645,6 +2645,13 @@ bool Item_date_typecast::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
}
bool Item_date_typecast::get_time(MYSQL_TIME *ltime)
{
bzero((char *)ltime, sizeof(MYSQL_TIME));
return args[0]->null_value;
}
String *Item_date_typecast::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);

1
sql/item_timefunc.h

@ -779,6 +779,7 @@ public:
const char *func_name() const { return "cast_as_date"; }
String *val_str(String *str);
bool get_date(MYSQL_TIME *ltime, uint fuzzy_date);
bool get_time(MYSQL_TIME *ltime);
const char *cast_type() const { return "date"; }
enum_field_types field_type() const { return MYSQL_TYPE_DATE; }
Field *tmp_table_field(TABLE *t_arg)

Loading…
Cancel
Save