List:Commits« Previous MessageNext Message »
From:Alexander Barkov Date:November 18 2011 9:53am
Subject:bzr push into mysql-trunk branch (alexander.barkov:3565 to 3566)
Bug#13399082 WL#946
View as plain text  
 3566 Alexander Barkov	2011-11-18
      WL#946: Bug#13399082 ABARKOV ASSERTION `MON > 0 && MON < 13' FAILED IN TZTIME.CC:794 | SEC_SINCE_EPOCH

    modified:
      mysql-test/r/timezone2.result
      mysql-test/r/type_temporal_fractional.result
      mysql-test/t/timezone2.test
      mysql-test/t/type_temporal_fractional.test
      sql/field.cc
      sql/field.h
      sql/item.cc
      sql/item.h
      sql/item_timefunc.cc
      sql/sql_time.cc
      sql/sql_time.h
 3565 Alexander Barkov	2011-11-17
      WL#946: Bug#13401354 ITEM->FIELD_TYPE() == MYSQL_TYPE_TIME || ITEM->FIELD_TYPE() == MYSQL_TYPE_NULL

    modified:
      mysql-test/r/type_temporal_fractional.result
      mysql-test/t/type_temporal_fractional.test
      sql/item_cmpfunc.cc
=== modified file 'mysql-test/r/timezone2.result'
--- a/mysql-test/r/timezone2.result	2010-08-06 19:29:37 +0000
+++ b/mysql-test/r/timezone2.result	2011-11-18 09:52:00 +0000
@@ -309,3 +309,33 @@ CONVERT_TZ(1, 1, a)
 NULL
 DROP TABLE t1;
 End of 5.1 tests
+#
+# Start of 5.6 tests
+#
+SET time_zone='Europe/Moscow';
+CREATE TABLE t1 (a TIMESTAMP, b VARCHAR(30));
+INSERT INTO t1 VALUES
+('2003-03-30 01:59:59', 'Before the gap'),
+('2003-03-30 02:30:00', 'Inside the gap'),
+('2003-03-30 03:00:00',  'After the gap');
+Warnings:
+Warning	1299	Invalid TIMESTAMP value in column 'a' at row 2
+SELECT a, UNIX_TIMESTAMP(a), b FROM t1;
+a	UNIX_TIMESTAMP(a)	b
+2003-03-30 01:59:59	1048978799	Before the gap
+2003-03-30 03:00:00	1048978800	Inside the gap
+2003-03-30 03:00:00	1048978800	After the gap
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP('2003-03-30 01:59:59'), 'Before the gap' AS b;
+UNIX_TIMESTAMP('2003-03-30 01:59:59')	b
+1048978799	Before the gap
+SELECT UNIX_TIMESTAMP('2003-03-30 02:30:00'), 'Inside the gap' AS b;
+UNIX_TIMESTAMP('2003-03-30 02:30:00')	b
+1048978800	Inside the gap
+SELECT UNIX_TIMESTAMP('2003-03-30 03:00:00'), 'After the gap' AS b;
+UNIX_TIMESTAMP('2003-03-30 03:00:00')	b
+1048978800	After the gap
+SET time_zone=DEFAULT;
+#
+# End of 5.6 tests
+#

=== modified file 'mysql-test/r/type_temporal_fractional.result'
--- a/mysql-test/r/type_temporal_fractional.result	2011-11-17 18:31:32 +0000
+++ b/mysql-test/r/type_temporal_fractional.result	2011-11-18 09:52:00 +0000
@@ -16689,3 +16689,70 @@ Warnings:
 Warning	1411	Incorrect datetime value: '00-0' for function str_to_date
 Warning	1411	Incorrect datetime value: '00-0' for function str_to_date
 DROP TABLE t1;
+#
+# Bug#13399082 - ASSERTION `MON > 0 && MON < 13' FAILED IN TZTIME.CC | SEC_SINCE_EPOCH
+#
+SET TIME_ZONE='+02:00';
+SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
+UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'))
+0
+SET TIME_ZONE=DEFAULT;
+# This should return NULL
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES(NULL);
+SELECT UNIX_TIMESTAMP(a) FROM t1;
+UNIX_TIMESTAMP(a)
+NULL
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP(NULL);
+UNIX_TIMESTAMP(NULL)
+NULL
+SELECT UNIX_TIMESTAMP(DATE(NULL));
+UNIX_TIMESTAMP(DATE(NULL))
+NULL
+SELECT UNIX_TIMESTAMP(TIME(NULL));
+UNIX_TIMESTAMP(TIME(NULL))
+NULL
+SELECT UNIX_TIMESTAMP(TIMESTAMP(NULL));
+UNIX_TIMESTAMP(TIMESTAMP(NULL))
+NULL
+# This should return 0
+CREATE TABLE t1 (a VARCHAR(30));
+INSERT INTO t1 VALUES
+('0000-01-01 00:00:00'),('2001-00-01 00:00:01'),('2001-01-00 00:00:00'),
+('0000-00-00 00:00:01'),('0000-00-00 00:00:00.1');
+SELECT UNIX_TIMESTAMP(a) FROM t1;
+UNIX_TIMESTAMP(a)
+0.000000
+0.000000
+0.000000
+0.000000
+0.000000
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP('0000-01-01 00:00:00');
+UNIX_TIMESTAMP('0000-01-01 00:00:00')
+0
+SELECT UNIX_TIMESTAMP('2001-00-01 00:00:00');
+UNIX_TIMESTAMP('2001-00-01 00:00:00')
+0
+SELECT UNIX_TIMESTAMP('2001-01-00 00:00:00');
+UNIX_TIMESTAMP('2001-01-00 00:00:00')
+0
+SELECT UNIX_TIMESTAMP('0000-00-00 10:10:20');
+UNIX_TIMESTAMP('0000-00-00 10:10:20')
+0
+SELECT UNIX_TIMESTAMP('0000-00-00 00:00:00.1');
+UNIX_TIMESTAMP('0000-00-00 00:00:00.1')
+0.0
+SELECT UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 10:10:20');
+UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 10:10:20')
+0
+SELECT UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 00:00:00.1');
+UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 00:00:00.1')
+0.0
+SELECT UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 10:10:20'));
+UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 10:10:20'))
+0
+SELECT UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 00:00:00.1'));
+UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 00:00:00.1'))
+0.0

=== modified file 'mysql-test/t/timezone2.test'
--- a/mysql-test/t/timezone2.test	2010-08-06 19:29:37 +0000
+++ b/mysql-test/t/timezone2.test	2011-11-18 09:52:00 +0000
@@ -284,3 +284,25 @@ SELECT CONVERT_TZ(1, 1, a) FROM t1;
 DROP TABLE t1;
 
 --echo End of 5.1 tests
+
+--echo #
+--echo # Start of 5.6 tests
+--echo #
+SET time_zone='Europe/Moscow';
+CREATE TABLE t1 (a TIMESTAMP, b VARCHAR(30));
+# Testing values around winter/summer time change
+# Expect non-zero UNIX_TIMESTAMP value for all of them
+INSERT INTO t1 VALUES
+('2003-03-30 01:59:59', 'Before the gap'),
+('2003-03-30 02:30:00', 'Inside the gap'),
+('2003-03-30 03:00:00',  'After the gap');
+SELECT a, UNIX_TIMESTAMP(a), b FROM t1;
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP('2003-03-30 01:59:59'), 'Before the gap' AS b;
+SELECT UNIX_TIMESTAMP('2003-03-30 02:30:00'), 'Inside the gap' AS b;
+SELECT UNIX_TIMESTAMP('2003-03-30 03:00:00'), 'After the gap' AS b;
+SET time_zone=DEFAULT;
+
+--echo #
+--echo # End of 5.6 tests
+--echo #

=== modified file 'mysql-test/t/type_temporal_fractional.test'
--- a/mysql-test/t/type_temporal_fractional.test	2011-11-17 18:31:32 +0000
+++ b/mysql-test/t/type_temporal_fractional.test	2011-11-18 09:52:00 +0000
@@ -7261,6 +7261,41 @@ AND
   col_timestamp_3_not_null_key < col_datetime; 
 DROP TABLE t1;
 
+
+--echo #
+--echo # Bug#13399082 - ASSERTION `MON > 0 && MON < 13' FAILED IN TZTIME.CC | SEC_SINCE_EPOCH
+--echo #
+SET TIME_ZONE='+02:00';
+SELECT UNIX_TIMESTAMP(STR_TO_DATE('2020','%Y'));
+SET TIME_ZONE=DEFAULT;
+
+--echo # This should return NULL
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES(NULL);
+SELECT UNIX_TIMESTAMP(a) FROM t1;
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP(NULL);
+SELECT UNIX_TIMESTAMP(DATE(NULL));
+SELECT UNIX_TIMESTAMP(TIME(NULL));
+SELECT UNIX_TIMESTAMP(TIMESTAMP(NULL));
+
+--echo # This should return 0
+CREATE TABLE t1 (a VARCHAR(30));
+INSERT INTO t1 VALUES
+('0000-01-01 00:00:00'),('2001-00-01 00:00:01'),('2001-01-00 00:00:00'),
+('0000-00-00 00:00:01'),('0000-00-00 00:00:00.1');
+SELECT UNIX_TIMESTAMP(a) FROM t1;
+DROP TABLE t1;
+SELECT UNIX_TIMESTAMP('0000-01-01 00:00:00');
+SELECT UNIX_TIMESTAMP('2001-00-01 00:00:00');
+SELECT UNIX_TIMESTAMP('2001-01-00 00:00:00');
+SELECT UNIX_TIMESTAMP('0000-00-00 10:10:20');
+SELECT UNIX_TIMESTAMP('0000-00-00 00:00:00.1');
+SELECT UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 10:10:20');
+SELECT UNIX_TIMESTAMP(TIMESTAMP'0000-00-00 00:00:00.1');
+SELECT UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 10:10:20'));
+SELECT UNIX_TIMESTAMP(TIMESTAMP('0000-00-00 00:00:00.1'));
+
 ## TS-TODO: SELECT CAST('00:00:00' AS DATETIME) -> should it use curdate?
 
 ## TS-TODO: reuse count_datetime_length()/count_string_result_length()

=== modified file 'sql/field.cc'
--- a/sql/field.cc	2011-11-07 14:35:16 +0000
+++ b/sql/field.cc	2011-11-18 09:52:00 +0000
@@ -1794,15 +1794,12 @@ bool Field::get_time(MYSQL_TIME *ltime)
 }
 
 
-bool Field::get_timestamp(struct timeval *tm)
+bool Field::get_timestamp(struct timeval *tm, int *warnings)
 {
   MYSQL_TIME ltime;
-  if (get_date(&ltime, TIME_FUZZY_DATE))
-    return true;
-  my_bool not_used;
-  tm->tv_sec= TIME_to_timestamp(current_thd, &ltime, &not_used);
-  tm->tv_usec= ltime.second_part;
-  return false;
+  DBUG_ASSERT(!is_null());
+  return get_date(&ltime, TIME_FUZZY_DATE) ||
+         datetime_to_timeval(current_thd, &ltime, tm, warnings);
 }
 
 
@@ -5156,30 +5153,14 @@ Field_temporal_with_date_and_time::conve
                                                              struct timeval *tm,
                                                              int *warnings)
 {
-  my_bool in_dst_time_gap;
-  /* Only convert a correct date (not a zero date) */
-  if (!ltime->month)
+  /*
+    No needs to do check_date(TIME_NO_ZERO_IN_DATE),
+    because it has been done earlier in
+    store_time(), number_to_datetime() or str_to_datetime().
+  */
+  if (datetime_with_no_zero_in_date_to_timeval(thd, ltime, tm, warnings))
   {
     tm->tv_sec= tm->tv_usec= 0;
-    if (ltime->second_part)
-    {
-      /* Don't allow zero timestamp with microseconds */
-      *warnings|= MYSQL_TIME_WARN_TRUNCATED;
-      return true;    
-    }
-    return false;
-  }
-
-  tm->tv_usec= ltime->second_part;
-
-  if (!(tm->tv_sec= TIME_to_timestamp(thd, ltime, &in_dst_time_gap)))
-  {
-    *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
-    return true;    
-  }
-  else if (in_dst_time_gap)
-  {
-    *warnings|= MYSQL_TIME_WARN_INVALID_TIMESTAMP;
     return true;
   }
   return false;
@@ -5358,7 +5339,7 @@ bool Field_timestamp::get_date_internal(
 /**
    Get TIMESTAMP field value as seconds since begging of Unix Epoch
 */
-bool Field_timestamp::get_timestamp(struct timeval *tm)
+bool Field_timestamp::get_timestamp(struct timeval *tm, int *warnings)
 {
   if (is_null())
     return true;
@@ -5567,12 +5548,11 @@ Field_timestampf::get_date_internal(MYSQ
 }
 
 
-bool Field_timestampf::get_timestamp(struct timeval *tm)
+bool Field_timestampf::get_timestamp(struct timeval *tm, int *warnings)
 {
   THD *thd= table ? table->in_use : current_thd;
   thd->time_zone_used= 1;
-  if (is_null())
-    return true;
+  DBUG_ASSERT(!is_null());
   my_timestamp_from_binary(tm, ptr, dec);
   return false;
 }

=== modified file 'sql/field.h'
--- a/sql/field.h	2011-11-07 14:35:16 +0000
+++ b/sql/field.h	2011-11-18 09:52:00 +0000
@@ -535,7 +535,7 @@ public:
     This method is used in "SELECT UNIX_TIMESTAMP(field)"
     to avoid conversion from timestamp to MYSQL_TIME and back.
   */
-  virtual bool get_timestamp(struct timeval *tm);
+  virtual bool get_timestamp(struct timeval *tm, int *warnings);
   /**
     Stores a timestamp value in "struct timeval" format into a field.
     Note, store_timestamp(), get_timestamp() and store_time()
@@ -2170,7 +2170,7 @@ public:
       Field::set_default();
   }
   /* Get TIMESTAMP field value as seconds since begging of Unix Epoch */
-  bool get_timestamp(struct timeval *tm);
+  bool get_timestamp(struct timeval *tm, int *warnings);
   bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
   Field_timestamp *clone(MEM_ROOT *mem_root) const {
     DBUG_ASSERT(type() == MYSQL_TYPE_TIMESTAMP);
@@ -2265,7 +2265,7 @@ public:
     else
       Field::set_default();
   }
-  bool get_timestamp(struct timeval *tm);
+  bool get_timestamp(struct timeval *tm, int *warnings);
 };
 
 

=== modified file 'sql/item.cc'
--- a/sql/item.cc	2011-11-16 14:58:34 +0000
+++ b/sql/item.cc	2011-11-18 09:52:00 +0000
@@ -1372,17 +1372,14 @@ bool Item::get_time_from_non_temporal(MY
   }
   return (null_value= true); // Impossible result type
 }
- 
 
-bool Item::get_timeval(struct timeval *tm)
+
+bool Item::get_timeval(struct timeval *tm, int *warnings)
 {
   MYSQL_TIME ltime;
-  if (get_date(&ltime, 0))
-    return true;
-  my_bool not_used;
-  tm->tv_sec= TIME_to_timestamp(current_thd, &ltime, &not_used);
-  tm->tv_usec= ltime.second_part;
-  return false;
+  return (null_value=
+          (get_date(&ltime, TIME_FUZZY_DATE) ||
+           datetime_to_timeval(current_thd, &ltime, tm, warnings)));
 }
 
 
@@ -2674,9 +2671,10 @@ bool Item_field::get_time(MYSQL_TIME *lt
   return 0;
 }
 
-bool Item_field::get_timeval(struct timeval *tm)
+bool Item_field::get_timeval(struct timeval *tm, int *warnings)
 {
-  return ((null_value= field->get_timestamp(tm)));
+  return (null_value= (field->is_null() ||
+                       field->get_timestamp(tm, warnings)));
 }
 
 double Item_field::val_result()

=== modified file 'sql/item.h'
--- a/sql/item.h	2011-11-10 14:58:23 +0000
+++ b/sql/item.h	2011-11-18 09:52:00 +0000
@@ -1082,7 +1082,7 @@ public:
     @retval  false on success
     @retval  true  on error
   */
-  virtual bool get_timeval(struct timeval *tm);
+  virtual bool get_timeval(struct timeval *tm, int *warnings);
   virtual bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate)
   { return get_date(ltime,fuzzydate); }
   /*
@@ -1989,7 +1989,7 @@ public:
   bool get_date(MYSQL_TIME *ltime,uint fuzzydate);
   bool get_date_result(MYSQL_TIME *ltime,uint fuzzydate);
   bool get_time(MYSQL_TIME *ltime);
-  bool get_timeval(struct timeval *tm);
+  bool get_timeval(struct timeval *tm, int *warnings);
   bool is_null() { return field->is_null(); }
   void update_null_value();
   Item *get_tmp_table_item(THD *thd);

=== modified file 'sql/item_timefunc.cc'
--- a/sql/item_timefunc.cc	2011-11-16 13:45:51 +0000
+++ b/sql/item_timefunc.cc	2011-11-18 09:52:00 +0000
@@ -1471,14 +1471,19 @@ bool Item_func_unix_timestamp::val_timev
     tm->tv_usec= 0;
     return false; // no args: null_value is set in constructor and is always 0.
   }
-  if (args[0]->get_timeval(tm)) // Don't set null_value here
+  int warnings= 0;
+  if (args[0]->get_timeval(tm, &warnings)) // Don't set null_value here
   {
-    tm->tv_sec= tm->tv_usec= 0;
     /*
-      We set null_value only if args[0] returned null.
+      We set null_value only if args[0]->get_date() invoked
+      inside args[0]->get_timeval() returned null,
+      which is indicated by "warnings == 0".
       In case of wrong non-null datetime parameter we return 0.
+      "warnings" will not be equal to 0 in this case.
     */
-    return (null_value= args[0]->null_value);
+    if (warnings == 0)
+      return (null_value= true);
+    tm->tv_sec= tm->tv_usec= 0;
   }
   return (null_value= false);
 }
@@ -1499,10 +1504,9 @@ longlong Item_func_unix_timestamp::val_i
   DBUG_ASSERT(arg_count == 1 &&
               args[0]->type() == Item::FIELD_ITEM &&
               args[0]->field_type() == MYSQL_TYPE_TIMESTAMP);
-  Field *field=((Item_field*) args[0])->field;
   /* Leave the incl_endp intact */
   struct timeval tm;
-  return (null_value= field->get_timestamp(&tm)) ? 0 : tm.tv_sec;
+  return val_timeval(&tm) ?  0 : tm.tv_sec;
 }
 
 

=== modified file 'sql/sql_time.cc'
--- a/sql/sql_time.cc	2011-11-03 09:33:45 +0000
+++ b/sql/sql_time.cc	2011-11-18 09:52:00 +0000
@@ -637,6 +637,116 @@ my_time_t TIME_to_timestamp(THD *thd, co
 }
 
 
+/**
+  Convert a datetime MYSQL_TIME representation
+  to corresponding "struct timeval" value.
+
+  ltime must previously be checked for TIME_NO_ZERO_IN_DATE.
+  Things like '0000-01-01', '2000-00-01', '2000-01-00' are not allowed
+  and asserted.
+
+  Things like '0000-00-00 10:30:30' or '0000-00-00 00:00:00.123456'
+  (i.e. empty date with non-empty time) return error.
+
+  Zero datetime '0000-00-00 00:00:00.000000'
+  is allowed and is mapper to {tv_sec=0, tv_usec=0}.
+
+  Note: In case of error, tm value is not initialized.
+
+  Note: "warnings" is not initialized to zero,
+  so new warnings are added to the old ones.
+  Caller must make sure to initialize "warnings".
+
+  @param IN  thd       current thd
+  @param IN  ltime     datetime value
+  @param OUT tm        timeval value
+  @param OUT warnings  pointer to warnings vector
+  @return
+  @retval      false on success
+  @retval      true on error
+*/
+bool datetime_with_no_zero_in_date_to_timeval(THD *thd,
+                                              const MYSQL_TIME *ltime,
+                                              struct timeval *tm,
+                                              int *warnings)
+{
+  if (!ltime->month) /* Zero date */
+  {
+    DBUG_ASSERT(!ltime->year && !ltime->day);
+    if (non_zero_time(ltime))
+    {
+      /*
+        Return error for zero date with non-zero time, e.g.:
+        '0000-00-00 10:20:30' or '0000-00-00 00:00:00.123456'
+      */
+      *warnings|= MYSQL_TIME_WARN_TRUNCATED;
+      return true;
+    }
+    tm->tv_sec= tm->tv_usec= 0; // '0000-00-00 00:00:00.000000'
+    return false;
+  }
+
+  my_bool in_dst_time_gap;
+  if (!(tm->tv_sec= TIME_to_timestamp(current_thd, ltime, &in_dst_time_gap)))
+  {
+    /*
+      Date was outside of the supported timestamp range.
+      For example: '3001-01-01 00:00:00' or '1000-01-01 00:00:00'
+    */
+    *warnings|= MYSQL_TIME_WARN_OUT_OF_RANGE;
+    return true;
+  }
+  else if (in_dst_time_gap)
+  {
+    /*
+      Set MYSQL_TIME_WARN_INVALID_TIMESTAMP warning to indicate
+      that date was fine but pointed to winter/summer time switch gap.
+      In this case tm is set to the fist second after gap.
+      For example: '2003-03-30 02:30:00 MSK' -> '2003-03-30 03:00:00 MSK'
+    */
+    *warnings|= MYSQL_TIME_WARN_INVALID_TIMESTAMP;
+  }
+  tm->tv_usec= ltime->second_part;
+  return false;
+}
+
+
+/**
+  Convert a datetime MYSQL_TIME representation
+  to corresponding "struct timeval" value.
+
+  Things like '0000-01-01', '2000-00-01', '2000-01-00'
+  (i.e. incomplete date) return error.
+
+  Things like '0000-00-00 10:30:30' or '0000-00-00 00:00:00.123456'
+  (i.e. empty date with non-empty time) return error.
+
+  Zero datetime '0000-00-00 00:00:00.000000'
+  is allowed and is mapper to {tv_sec=0, tv_usec=0}.
+
+  Note: In case of error, tm value is not initialized.
+
+  Note: "warnings" is not initialized to zero,
+  so new warnings are added to the old ones.
+  Caller must make sure to initialize "warnings".
+
+  @param IN  thd       current thd
+  @param IN  ltime     datetime value
+  @param OUT tm        timeval value
+  @param OUT warnings  pointer to warnings vector
+  @return
+  @retval      false on success
+  @retval      true on error
+*/
+bool datetime_to_timeval(THD *thd, const MYSQL_TIME *ltime,
+                         struct timeval *tm, int *warnings)
+{
+  return
+    check_date(ltime, non_zero_date(ltime), TIME_NO_ZERO_IN_DATE, warnings) ||
+    datetime_with_no_zero_in_date_to_timeval(current_thd, ltime, tm, warnings);
+}
+
+
 /*
   Convert a time string to a MYSQL_TIME struct and produce a warning
   if string was cut during conversion.

=== modified file 'sql/sql_time.h'
--- a/sql/sql_time.h	2011-11-07 11:50:35 +0000
+++ b/sql/sql_time.h	2011-11-18 09:52:00 +0000
@@ -36,6 +36,11 @@ ulong convert_month_to_period(ulong mont
 void mix_date_and_time(MYSQL_TIME *ldate, const MYSQL_TIME *ltime);
 void get_date_from_daynr(long daynr,uint *year, uint *month, uint *day);
 my_time_t TIME_to_timestamp(THD *thd, const MYSQL_TIME *t, my_bool *not_exist);
+bool datetime_with_no_zero_in_date_to_timeval(THD *thd, const MYSQL_TIME *t,
+                                              struct timeval *tm,
+                                              int *warnings);
+bool datetime_to_timeval(THD *thd, const MYSQL_TIME *t,
+                         struct timeval *tm, int *warnings);
 bool str_to_datetime_with_warn(String *str,  MYSQL_TIME *l_time, uint flags);
 bool my_decimal_to_datetime_with_warn(const my_decimal *decimal,
                                       MYSQL_TIME *ltime, uint flags);

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (alexander.barkov:3565 to 3566)Bug#13399082 WL#946Alexander Barkov21 Nov