Bug #41370 TIMESTAMP field does not accepts NULL from FROM_UNIXTIME()

Submitted: 10 Dec 2008 18:13 Modified: 11 Feb 2009 3:47
Reporter: Leandro Morgado Email Updates:
Status: Closed Impact on me:
None 
Category:MySQL Server: Data Types Severity:S2 (Serious)
Version:5.0.60sp1, 5.1.30 OS:Any
Assigned to: Tatiana Azundris Nuernberg CPU Architecture:Any

[10 Dec 2008 18:13] Leandro Morgado
Description:
When inserting a NULL value into a TIMESTAMP field it works as usual (ie, sets the current date) if the NULL is provided directly or via a function. However, if the NULL originates from a FROM_UNIXTIME() function, it will give an error and refuse to insert.

I have tested this on Ubuntu 8.04 (4.1.22-standard) and the insert works with FROM_UNIXTIME().

The test case attached has been executed on CentOS 5 (5.0.60sp1-enterprise, 5.1.30-enterpise) and Windows Vista (5.0.60sp1-enterprise).

How to repeat:
TEST CASE:

mysql> CREATE TABLE `test_timestamp` ( `pk` int(11) NOT NULL auto_increment, `test_field` timestamp NOT NULL default CURRENT_TIMESTAMP, PRIMARY KEY (`pk`) ) ENGINE=MyISAM;
Query OK, 0 rows affected (0.02 sec)

mysql> INSERT INTO test_timestamp (test_field) VALUES (NULL);
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO test_timestamp (test_field) VALUES (ASCII(NULL));
Query OK, 1 row affected (0.00 sec)

mysql> SELECT ASCII(NULL);
+-------------+
| ASCII(NULL) |
+-------------+
|        NULL | 
+-------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test_timestamp;
+----+---------------------+
| pk | test_field          |
+----+---------------------+
|  1 | 2008-12-10 17:28:12 | 
|  2 | 2008-12-10 17:28:20 | 
+----+---------------------+
2 rows in set (0.00 sec)

mysql> INSERT INTO test_timestamp (test_field) values (FROM_UNIXTIME('9999999999'));
ERROR 1048 (23000): Column 'test_field' cannot be null

mysql> SELECT FROM_UNIXTIME('9999999999');
+-----------------------------+
| FROM_UNIXTIME('9999999999') |
+-----------------------------+
| NULL                        | 
+-----------------------------+
1 row in set (0.00 sec)

mysql> SELECT * FROM test_timestamp;
+----+---------------------+
| pk | test_field          |
+----+---------------------+
|  1 | 2008-12-10 17:28:12 | 
|  2 | 2008-12-10 17:28:20 | 
+----+---------------------+

Suggested fix:
The FROM_UNIXTIME NULL value should be accepted by the insert on the TIMESTAMP field  and not differ from regular NULL and ASCII(NULL).
[10 Dec 2008 18:29] Valeriy Kravchuk
Verified just as described with 5.1.30 on Windows.
[11 Dec 2008 17:48] Sveta Smirnova
Workaround:  INSERT INTO test_timestamp (test_field) values (ascii(FROM_UNIXTIME('9999999999')));
[11 Dec 2008 19:50] Leandro Morgado
Sveta: the work around with ASCII only works if FROM_UNIXTIME returns NULL. If it returns a valid value then it will be converted to an ASCII value. The following should be the same.

ysql> SELECT FROM_UNIXTIME('123123');
+-------------------------+
| FROM_UNIXTIME('123123') |
+-------------------------+
| 1970-01-02 11:12:03     |
+-------------------------+
1 row in set (0.00 sec)

mysql> SELECT ASCII(FROM_UNIXTIME('123123'));
+--------------------------------+
| ASCII(FROM_UNIXTIME('123123')) |
+--------------------------------+
|                             49 |
+--------------------------------+
1 row in set (0.00 sec)

Here is a workaround that returns a proper timestamp fo
 
INSERT INTO test_timestamp (test_field) VALUES ( IF(ISNULL(FROM_UNIXTIME('123123')) , NULL, FROM_UNIXTIME('123123')) );

mysql> SELECT IF(ISNULL(FROM_UNIXTIME('123123')) , NULL, FROM_UNIXTIME('123123'));
+---------------------------------------------------------------------+
| IF(ISNULL(FROM_UNIXTIME('123123')) , NULL, FROM_UNIXTIME('123123')) |
+---------------------------------------------------------------------+
| 1970-01-02 11:12:03                                                 |
+---------------------------------------------------------------------+
1 row in set (0.00 sec)
[11 Dec 2008 20:42] Sveta Smirnova
Leandro,

right, but you can use ifnull():

INSERT INTO test_timestamp (test_field) values(ifnull(FROM_UNIXTIME('9999999999'),(ascii(FROM_UNIXTIME('9999999999')))));
[22 Jan 2009 7:52] Tatiana Azundris Nuernberg
completely different code paths for NULL and func.

#0  set_field_to_null (field=0x1171128) at field_conv.cc:118
#1  0x00000000005e695c in Item::save_date_in_field (this=0x116b290, field=0x1171128) at item.cc:346
#2  0x000000000064f2f8 in Item_date_func::save_in_field (this=0x116b290, field=0x1171128, no_conversions=false) at item_timefunc.h:390
#3  0x0000000000711e61 in fill_record (thd=0x7fc8b074f298, fields=@0x7fc8b07515d8, values=@0x116b170, ignore_errors=false) at sql_base.cc:8090
#4  0x0000000000711f6e in fill_record_n_invoke_before_triggers (thd=0x7fc8b074f298, fields=@0x7fc8b07515d8, values=@0x116b170, ignore_errors=false, triggers=0x0, event=TRG_EVENT_INSERT) at sql_base.cc:8135
#5  0x0000000000769520 in mysql_insert (thd=0x7fc8b074f298, table_list=0x116ad38, fields=@0x7fc8b07515d8, values_list=@0x7fc8b0751620, update_fields=@0x7fc8b0751608, update_values=@0x7fc8b07515f0, duplic=DUP_ERROR, ignore=false) at sql_insert.cc:747
#6  0x00000000006cc13d in mysql_execute_command (thd=0x7fc8b074f298) at sql_parse.cc:3088
#7  0x00000000006d1fd4 in mysql_parse (thd=0x7fc8b074f298, inBuf=0x116ac18 "INSERT INTO t1 (f2) VALUES (FROM_UNIXTIME('9999999999'))", length=56, found_semicolon=0x416aff00) at sql_parse.cc:5809
#8  0x00000000006d2e38 in dispatch_command (command=COM_QUERY, thd=0x7fc8b074f298, packet=0x7fc8b07a2eb9 "INSERT INTO t1 (f2) VALUES (FROM_UNIXTIME('9999999999'))", packet_length=56) at sql_parse.cc:1216

for the FROM_UNIXTIME(), we get a fail because our miracle-value 999... exceeds the allowed maximum.
item.cc:336 in 5.1

int Item::save_date_in_field(Field *field)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime, TIME_FUZZY_DATE))
    return set_field_to_null(field);
  ...

An error is then thrown in set_field_to_null(). (If we suppress the error, we just generate a "0000-00-00 ..." entry, which isn't really what we want.)

We can force the intended behaviour like so:
item.cc:336 in 5.1

int Item::save_date_in_field(Field *field)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime, TIME_FUZZY_DATE))
  {
    field->set_default();
    return 0;
  }
  ...

The ASCII(NULL) variant moves like this:

gdb) bt
#0  Item_func_ascii::val_int (this=0x116b1d8) at item_func.cc:2629
#1  0x00000000005e6d52 in Item::save_in_field (this=0x116b1d8, field=0x1171128, no_conversions=false) at item.cc:4889
#2  0x0000000000711e61 in fill_record (thd=0x7fc8b074f298, fields=@0x7fc8b07515d8, values=@0x116b150, ignore_errors=false) at sql_base.cc:8090
#3  0x0000000000711f6e in fill_record_n_invoke_before_triggers (thd=0x7fc8b074f298, fields=@0x7fc8b07515d8, values=@0x116b150, ignore_errors=false, triggers=0x0, event=TRG_EVENT_INSERT) at sql_base.cc:8135
#4  0x0000000000769520 in mysql_insert (thd=0x7fc8b074f298, table_list=0x116ad18, fields=@0x7fc8b07515d8, values_list=@0x7fc8b0751620, update_fields=@0x7fc8b0751608, update_values=@0x7fc8b07515f0, duplic=DUP_ERROR, ignore=false) at sql_insert.cc:747
#5  0x00000000006cc13d in mysql_execute_command (thd=0x7fc8b074f298) at sql_parse.cc:3088
#6  0x00000000006d1fd4 in mysql_parse (thd=0x7fc8b074f298, inBuf=0x116ac18 "INSERT INTO t1 (f2) VALUES (ASCII(NULL))", length=40, found_semicolon=0x416aff00) at sql_parse.cc:5809

So we'll do the same thing here:

int Item::save_date_in_field(Field *field)
{
  MYSQL_TIME ltime;
  if (get_date(&ltime, TIME_FUZZY_DATE))
    return set_field_to_null_with_conversions(field, 0);
[23 Jan 2009 6:23] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/63868

2734 Tatiana A. Nurnberg	2009-01-23
      Bug#41370: TIMESTAMP field does not accepts NULL from FROM_UNIXTIME()
      
      When storing a NULL to a TIMESTAMP NOT NULL DEFAULT ...,
      NULL returned from some functions threw a 'cannot be NULL error.'
      
      NULL-returns now correctly result in the timestamp-field being
      assigned its default value.
[30 Jan 2009 16:15] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/64673

2728 Tatiana A. Nurnberg	2009-01-30
      Bug#41370: TIMESTAMP field does not accepts NULL from FROM_UNIXTIME()
      
      When storing a NULL to a TIMESTAMP NOT NULL DEFAULT ...,
      NULL returned from some functions threw a 'cannot be NULL error.'
      
      NULL-returns now correctly result in the timestamp-field being
      assigned its default value.
[2 Feb 2009 16:22] Tatiana Azundris Nuernberg
queued for 5.0.78, 5.1.32, 6.0.10 in -bugteam
[3 Feb 2009 9:12] Bugs System
Pushed into 5.0.78 (revid:joro@sun.com-20090203090422-v91rh3gmx2ulhbu9) (version source revid:azundris@mysql.com-20090131010736-3jy0zq3q3lxvpb8c) (merge vers: 5.0.78) (pib:6)
[3 Feb 2009 9:40] Bugs System
Pushed into 5.1.32 (revid:joro@sun.com-20090203090549-gos3v4320vimrzg6) (version source revid:azundris@mysql.com-20090131010841-2tlg3da2ranivq04) (merge vers: 5.1.32) (pib:6)
[4 Feb 2009 11:16] Bugs System
Pushed into 6.0.10-alpha (revid:kostja@sun.com-20090204104420-mw1i2u9lum4bxjo6) (version source revid:aelkin@mysql.com-20090202205045-ibm2u4upsznckdmi) (merge vers: 6.0.10-alpha) (pib:6)
[11 Feb 2009 3:47] Paul DuBois
Noted in 5.0.72, 5.1.32, 6.0.10 changelog.

For a TIMESTAMP NOT NULL DEFAULT ... column, storing NULL as the 
return value from some functions caused a "cannot be NULL" error.
NULL returns now correctly cause the column default value to be
stored.
[17 Feb 2009 14:55] Bugs System
Pushed into 5.1.32-ndb-6.3.23 (revid:tomas.ulin@sun.com-20090217131017-6u8qz1edkjfiobef) (version source revid:tomas.ulin@sun.com-20090203133556-9rclp06ol19bmzs4) (merge vers: 5.1.32-ndb-6.3.22) (pib:6)
[17 Feb 2009 16:42] Bugs System
Pushed into 5.1.32-ndb-6.4.3 (revid:tomas.ulin@sun.com-20090217134419-5ha6xg4dpedrbmau) (version source revid:tomas.ulin@sun.com-20090203133556-9rclp06ol19bmzs4) (merge vers: 5.1.32-ndb-6.3.22) (pib:6)
[17 Feb 2009 18:18] Bugs System
Pushed into 5.1.32-ndb-6.2.17 (revid:tomas.ulin@sun.com-20090217134216-5699eq74ws4oxa0j) (version source revid:tomas.ulin@sun.com-20090203064601-uyuzm4mielj3fz76) (merge vers: 5.1.32-ndb-6.2.17) (pib:6)

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.072 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.