summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/main/timezone2.result23
-rw-r--r--mysql-test/main/timezone2.test19
-rw-r--r--sql/item_timefunc.cc37
-rw-r--r--sql/sql_time.cc30
-rw-r--r--sql/sql_time.h2
-rw-r--r--sql/sql_type.h16
6 files changed, 68 insertions, 59 deletions
diff --git a/mysql-test/main/timezone2.result b/mysql-test/main/timezone2.result
index 096e996bffb..6de62d7ea30 100644
--- a/mysql-test/main/timezone2.result
+++ b/mysql-test/main/timezone2.result
@@ -332,3 +332,26 @@ NULL
#
# End of 5.3 tests
#
+#
+# Start of 10.4 tests
+#
+#
+# MDEV-17203 Move fractional second truncation from Item_xxx_typecast::get_date() to Time and Datetime constructors
+# (an addition for the test for MDEV-4653)
+SET timestamp=unix_timestamp('2001-02-03 10:20:30');
+SET old_mode=ZERO_DATE_TIME_CAST;
+SELECT CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5');
+CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '00:00:00'
+SELECT CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5');
+CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5')
+NULL
+Warnings:
+Warning 1292 Truncated incorrect datetime value: '00:00:00'
+SET old_mode=DEFAULT;
+SET timestamp=DEFAULT;
+#
+# End of 10.4 tests
+#
diff --git a/mysql-test/main/timezone2.test b/mysql-test/main/timezone2.test
index 7a38610ad95..773b40ec86c 100644
--- a/mysql-test/main/timezone2.test
+++ b/mysql-test/main/timezone2.test
@@ -308,3 +308,22 @@ SELECT CONVERT_TZ('2001-10-08 00:00:00', MAKE_SET(0,'+01:00'), '+00:00' );
--echo #
--echo # End of 5.3 tests
--echo #
+
+--echo #
+--echo # Start of 10.4 tests
+--echo #
+
+--echo #
+--echo # MDEV-17203 Move fractional second truncation from Item_xxx_typecast::get_date() to Time and Datetime constructors
+--echo # (an addition for the test for MDEV-4653)
+
+SET timestamp=unix_timestamp('2001-02-03 10:20:30');
+SET old_mode=ZERO_DATE_TIME_CAST;
+SELECT CONVERT_TZ(TIME('00:00:00'),'+00:00','+7:5');
+SELECT CONVERT_TZ(TIME('2010-01-01 00:00:00'),'+00:00','+7:5');
+SET old_mode=DEFAULT;
+SET timestamp=DEFAULT;
+
+--echo #
+--echo # End of 10.4 tests
+--echo #
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 84db154566a..1cc0d0bb2e1 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -2474,43 +2474,26 @@ void Item_char_typecast::fix_length_and_dec_internal(CHARSET_INFO *from_cs)
bool Item_time_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- Time tm(args[0], Time::Options_for_cast());
- if ((null_value= !tm.is_valid_time()))
- return true;
- tm.copy_to_mysql_time(ltime);
- if (decimals < TIME_SECOND_PART_DIGITS)
- my_time_trunc(ltime, decimals);
- return (fuzzy_date & TIME_TIME_ONLY) ? 0 :
- (null_value= check_date_with_warn(ltime, fuzzy_date,
- MYSQL_TIMESTAMP_ERROR));
+ Time *tm= new(ltime) Time(args[0], Time::Options_for_cast(),
+ MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
+ return (null_value= !tm->is_valid_time());
}
bool Item_date_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- fuzzy_date |= sql_mode_for_dates(current_thd);
- if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY))
- return 1;
-
- if (make_date_with_warn(ltime, fuzzy_date, MYSQL_TIMESTAMP_DATE))
- return (null_value= 1);
-
- return 0;
+ fuzzy_date= (fuzzy_date | sql_mode_for_dates(current_thd)) & ~TIME_TIME_ONLY;
+ Date *d= new(ltime) Date(current_thd, args[0], fuzzy_date);
+ return (null_value= !d->is_valid_date());
}
bool Item_datetime_typecast::get_date(MYSQL_TIME *ltime, ulonglong fuzzy_date)
{
- fuzzy_date |= sql_mode_for_dates(current_thd);
- if (get_arg0_date(ltime, fuzzy_date & ~TIME_TIME_ONLY))
- return 1;
-
- if (decimals < TIME_SECOND_PART_DIGITS)
- my_time_trunc(ltime, decimals);
-
- DBUG_ASSERT(ltime->time_type != MYSQL_TIMESTAMP_TIME);
- ltime->time_type= MYSQL_TIMESTAMP_DATETIME;
- return 0;
+ fuzzy_date= (fuzzy_date | sql_mode_for_dates(current_thd)) & ~TIME_TIME_ONLY;
+ Datetime *dt= new(ltime) Datetime(current_thd, args[0], fuzzy_date,
+ MY_MIN(decimals, TIME_SECOND_PART_DIGITS));
+ return (null_value= !dt->is_valid_datetime());
}
diff --git a/sql/sql_time.cc b/sql/sql_time.cc
index 7b1cb504f08..ee56022a868 100644
--- a/sql/sql_time.cc
+++ b/sql/sql_time.cc
@@ -1185,36 +1185,6 @@ bool time_to_datetime(MYSQL_TIME *ltime)
}
-/**
- Return a valid DATE or DATETIME value from an arbitrary MYSQL_TIME.
- If ltime is TIME, it's first converted to DATETIME.
- If ts_type is DATE, hhmmss is set to zero.
- The date part of the result is checked against fuzzy_date.
-
- @param ltime The value to convert.
- @param fuzzy_date Flags to check date.
- @param ts_type The type to convert to.
- @return false on success, true of error (negative time).*/
-bool
-make_date_with_warn(MYSQL_TIME *ltime, ulonglong fuzzy_date,
- timestamp_type ts_type)
-{
- DBUG_ASSERT(ts_type == MYSQL_TIMESTAMP_DATE ||
- ts_type == MYSQL_TIMESTAMP_DATETIME);
- if (ltime->time_type == MYSQL_TIMESTAMP_TIME && time_to_datetime(ltime))
- {
- /* e.g. negative time */
- ErrConvTime str(ltime);
- make_truncated_value_warning(current_thd, Sql_condition::WARN_LEVEL_WARN,
- &str, ts_type, 0);
- return true;
- }
- if ((ltime->time_type= ts_type) == MYSQL_TIMESTAMP_DATE)
- ltime->hour= ltime->minute= ltime->second= ltime->second_part= 0;
- return check_date_with_warn(ltime, fuzzy_date, ts_type);
-}
-
-
/*
Convert a TIME value to DAY-TIME interval, e.g. for extraction:
EXTRACT(DAY FROM x), EXTRACT(HOUR FROM x), etc.
diff --git a/sql/sql_time.h b/sql/sql_time.h
index 862289ffdf1..47c057cd9b5 100644
--- a/sql/sql_time.h
+++ b/sql/sql_time.h
@@ -168,8 +168,6 @@ check_date(const MYSQL_TIME *ltime, ulonglong flags, int *was_cut)
}
bool check_date_with_warn(const MYSQL_TIME *ltime, ulonglong fuzzy_date,
timestamp_type ts_type);
-bool make_date_with_warn(MYSQL_TIME *ltime,
- ulonglong fuzzy_date, timestamp_type ts_type);
bool adjust_time_range_with_warn(MYSQL_TIME *ltime, uint dec);
longlong pack_time(const MYSQL_TIME *my_time);
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 4eaf578fac1..c497e041ea0 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -471,6 +471,12 @@ protected:
bool str_to_datetime(MYSQL_TIME_STATUS *st, const char *str, size_t length,
CHARSET_INFO *cs, sql_mode_t fuzzydate);
public:
+ static void *operator new(size_t size, MYSQL_TIME *ltime) throw()
+ {
+ DBUG_ASSERT(size == sizeof(MYSQL_TIME));
+ return ltime;
+ }
+
long fraction_remainder(uint dec) const
{
return my_time_fraction_remainder(second_part, dec);
@@ -772,6 +778,11 @@ public:
:Temporal(Time(warn, Sec6(d), Options()))
{ }
+ Time(Item *item, const Options opt, uint dec)
+ :Temporal(Time(item, opt))
+ {
+ trunc(dec);
+ }
Time(int *warn, const MYSQL_TIME *from, long curdays, uint dec)
:Temporal(Time(warn, from, curdays))
{
@@ -1125,6 +1136,11 @@ public:
DBUG_ASSERT(is_valid_value_slow());
}
+ Datetime(THD *thd, Item *item, sql_mode_t flags, uint dec)
+ :Temporal_with_date(Datetime(thd, item, flags))
+ {
+ trunc(dec);
+ }
Datetime(MYSQL_TIME_STATUS *status,
const char *str, size_t len, CHARSET_INFO *cs,
sql_mode_t fuzzydate, uint dec)