File fix2038.patch of Package mariadb
diff --git a/include/my_time.h b/include/my_time.h
index 9f3e61b944f..0ba675b99d9 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -46,7 +46,7 @@ extern uchar days_in_month[];
check for valid times only if the range of time_t is greater than
the range of my_time_t
*/
-#if SIZEOF_TIME_T > 4 || defined(TIME_T_UNSIGNED)
+#if SIZEOF_TIME_T <= 4 && ! defined(TIME_T_UNSIGNED)
# define IS_TIME_T_VALID_FOR_TIMESTAMP(x) \
((x) <= TIMESTAMP_MAX_VALUE && \
(x) >= TIMESTAMP_MIN_VALUE)
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 26adc4eddaa..362d7136962 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -54,6 +54,7 @@
#include "tztime.h" // struct Time_zone
#include "sql_class.h" // THD
#include <m_ctype.h>
+#include <stdint.h>
#include <time.h>
/** Day number for Dec 31st, 9999. */
@@ -1210,28 +1211,19 @@ longlong Item_func_year::val_int_endpoint(bool left_endp, bool *incl_endp)
}
-bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds,
+bool Item_func_unix_timestamp::get_timestamp_value(int64_t *seconds,
ulong *second_part)
{
DBUG_ASSERT(fixed());
- if (args[0]->type() == FIELD_ITEM)
- { // Optimize timestamp field
- Field *field=((Item_field*) args[0])->field;
- if (field->type() == MYSQL_TYPE_TIMESTAMP)
- {
- if ((null_value= field->is_null()))
- return 1;
- *seconds= field->get_timestamp(second_part);
- return 0;
- }
+ Datetime_from_temporal dt(current_thd, args[0], TIME_CONV_NONE);
+ if ((null_value = !dt.is_valid_datetime()))
+ {
+ return true;
}
- Timestamp_or_zero_datetime_native_null native(current_thd, args[0], true);
- if ((null_value= native.is_null() || native.is_zero_datetime()))
- return true;
- Timestamp tm(native);
- *seconds= tm.tv().tv_sec;
- *second_part= tm.tv().tv_usec;
+ *second_part = dt.fraction_remainder(TIME_SECOND_PART_DIGITS);
+ Datetime epoch(my_time_t(0), *second_part, current_thd->variables.time_zone);
+ *seconds = dt.to_seconds() - epoch.to_seconds();
return false;
}
@@ -1242,7 +1234,7 @@ longlong Item_func_unix_timestamp::int_op()
return (longlong) current_thd->query_start();
ulong second_part;
- my_time_t seconds;
+ int64_t seconds;
if (get_timestamp_value(&seconds, &second_part))
return 0;
@@ -1253,7 +1245,7 @@ longlong Item_func_unix_timestamp::int_op()
my_decimal *Item_func_unix_timestamp::decimal_op(my_decimal* buf)
{
ulong second_part;
- my_time_t seconds;
+ int64_t seconds;
if (get_timestamp_value(&seconds, &second_part))
return 0;
@@ -1303,7 +1295,7 @@ my_decimal *Item_func_time_to_sec::decimal_op(my_decimal* buf)
if ((null_value= !tm.is_valid_time()))
return 0;
const MYSQL_TIME *ltime= tm.get_mysql_time();
- longlong seconds= tm.to_seconds_abs();
+ int64_t seconds= tm.to_seconds_abs();
return seconds2my_decimal(ltime->neg, seconds, ltime->second_part, buf);
}
@@ -2749,14 +2741,14 @@ bool Item_func_from_unixtime::get_date(THD *thd, MYSQL_TIME *ltime,
bzero((char *)ltime, sizeof(*ltime));
ltime->time_type= MYSQL_TIMESTAMP_TIME;
- VSec9 sec(thd, args[0], "unixtime", TIMESTAMP_MAX_VALUE);
- DBUG_ASSERT(sec.is_null() || sec.sec() <= TIMESTAMP_MAX_VALUE);
+ VSec9 sec(thd, args[0], "unixtime", MY_TIME_T_MAX);
+ DBUG_ASSERT(sec.is_null() || sec.sec() <= MY_TIME_T_MAX);
if (sec.is_null() || sec.truncated() || sec.neg())
return (null_value= 1);
sec.round(MY_MIN(decimals, TIME_SECOND_PART_DIGITS), thd->temporal_round_mode());
- if (sec.sec() > TIMESTAMP_MAX_VALUE)
+ if (sec.sec() > MY_TIME_T_MAX)
return (null_value= true); // Went out of range after rounding
tz->gmt_sec_to_TIME(ltime, (my_time_t) sec.sec());
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index a5f6d9307c6..835eae2df43 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -572,7 +572,7 @@ class Item_func_seconds_hybrid: public Item_func_numhybrid
class Item_func_unix_timestamp :public Item_func_seconds_hybrid
{
- bool get_timestamp_value(my_time_t *seconds, ulong *second_part);
+ bool get_timestamp_value(int64_t *seconds, ulong *second_part);
public:
Item_func_unix_timestamp(THD *thd): Item_func_seconds_hybrid(thd) {}
Item_func_unix_timestamp(THD *thd, Item *a):