summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-09-12 21:53:02 +0400
committerAlexander Barkov <bar@mariadb.com>2018-09-12 21:53:02 +0400
commit61e8d21c774dcf3a778694e5a56b04dae65b8995 (patch)
tree4108b0f643b11434cec6c316cd07be0fb90cd4bc
parent2fe51a6fdda7eb91ddac1e24bc3f972e57067fd2 (diff)
downloadmariadb-git-61e8d21c774dcf3a778694e5a56b04dae65b8995.tar.gz
MDEV-17182 Move fractional second truncation outside of Field_xxx::store_TIME_with_warn()
-rw-r--r--sql/field.cc59
-rw-r--r--sql/sql_type.h65
2 files changed, 80 insertions, 44 deletions
diff --git a/sql/field.cc b/sql/field.cc
index d695be4feff..a8ee5696aaa 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -5058,8 +5058,9 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
return 1; // date was fine but pointed to a DST gap
}
- // Adjust and store the value
- store_TIMEVAL(Timeval(timestamp, l_time->second_part).trunc(decimals()));
+ // Store the value
+ DBUG_ASSERT(!dt->fraction_remainder(decimals()));
+ store_TIMEVAL(Timeval(timestamp, l_time->second_part));
// Calculate return value and send warnings if needed
if (unlikely(conversion_error)) // e.g. DATETIME in the DST gap
@@ -5084,7 +5085,7 @@ int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec)
int warn;
ErrConvTime str(ltime);
THD *thd= get_thd();
- Datetime dt(thd, &warn, ltime, sql_mode_for_timestamp(thd));
+ Datetime dt(thd, &warn, ltime, sql_mode_for_timestamp(thd), decimals());
return store_TIME_with_warning(thd, &dt, &str, warn);
}
@@ -5094,7 +5095,7 @@ int Field_timestamp::store(const char *from,size_t len,CHARSET_INFO *cs)
ErrConvString str(from, len, cs);
THD *thd= get_thd();
MYSQL_TIME_STATUS st;
- Datetime dt(&st, from, len, cs, sql_mode_for_timestamp(thd));
+ Datetime dt(&st, from, len, cs, sql_mode_for_timestamp(thd), decimals());
return store_TIME_with_warning(thd, &dt, &str, st.warnings);
}
@@ -5104,7 +5105,7 @@ int Field_timestamp::store(double nr)
int error;
ErrConvDouble str(nr);
THD *thd= get_thd();
- Datetime dt(&error, nr, sql_mode_for_timestamp(thd));
+ Datetime dt(&error, nr, sql_mode_for_timestamp(thd), decimals());
return store_TIME_with_warning(thd, &dt, &str, error);
}
@@ -5414,7 +5415,7 @@ int Field_timestamp::store_decimal(const my_decimal *d)
int error;
THD *thd= get_thd();
ErrConvDecimal str(d);
- Datetime dt(&error, d, sql_mode_for_timestamp(thd));
+ Datetime dt(&error, d, sql_mode_for_timestamp(thd), decimals());
return store_TIME_with_warning(thd, &dt, &str, error);
}
@@ -5556,20 +5557,11 @@ int Field_temporal_with_date::store_TIME_with_warning(const Datetime *dt,
set_warnings(trunc_level, str, MYSQL_TIME_WARN_TRUNCATED, ts_type);
return 1;
}
- // Adjust and store the value
- if (ts_type == MYSQL_TIMESTAMP_DATE)
- {
- if (!dt->hhmmssff_is_zero())
- was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
- store_TIME(dt->get_mysql_time());
- }
- else if (dt->fraction_remainder(decimals()))
- {
- Datetime truncated(dt->trunc(decimals()));
- store_TIME(truncated.get_mysql_time());
- }
- else
- store_TIME(dt->get_mysql_time());
+ // Store the value
+ DBUG_ASSERT(!dt->fraction_remainder(decimals()));
+ if (ts_type == MYSQL_TIMESTAMP_DATE && !dt->hhmmssff_is_zero())
+ was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
+ store_TIME(dt->get_mysql_time());
// Caclulate return value and send warnings if needed
return store_TIME_return_code_with_warnings(was_cut, str, ts_type);
}
@@ -5579,7 +5571,7 @@ int Field_temporal_with_date::store(const char *from, size_t len, CHARSET_INFO *
{
MYSQL_TIME_STATUS st;
ErrConvString str(from, len, cs);
- Datetime dt(&st, from, len, cs, sql_mode_for_dates(get_thd()));
+ Datetime dt(&st, from, len, cs, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&dt, &str, st.warnings);
}
@@ -5587,7 +5579,7 @@ int Field_temporal_with_date::store(double nr)
{
int error;
ErrConvDouble str(nr);
- Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
+ Datetime dt(&error, nr, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&dt, &str, error);
}
@@ -5605,7 +5597,7 @@ int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec)
int error;
ErrConvTime str(ltime);
THD *thd= get_thd();
- Datetime dt(thd, &error, ltime, sql_mode_for_dates(thd));
+ Datetime dt(thd, &error, ltime, sql_mode_for_dates(thd), decimals());
return store_TIME_with_warning(&dt, &str, error);
}
@@ -5704,14 +5696,9 @@ int Field_time::store_TIME_with_warning(const Time *t,
set_warnings(Sql_condition::WARN_LEVEL_WARN, str, MYSQL_TIME_WARN_TRUNCATED);
return 1;
}
- // Adjust and store the value
- if (t->fraction_remainder(decimals()))
- {
- Time truncated(t->trunc(decimals()));
- store_TIME(truncated.get_mysql_time());
- }
- else
- store_TIME(t->get_mysql_time());
+ // Store the value
+ DBUG_ASSERT(!t->fraction_remainder(decimals()));
+ store_TIME(t->get_mysql_time());
// Calculate return value and send warnings if needed
return store_TIME_return_code_with_warnings(warn, str, MYSQL_TIMESTAMP_TIME);
}
@@ -5732,7 +5719,7 @@ int Field_time::store(const char *from,size_t len,CHARSET_INFO *cs)
{
ErrConvString str(from, len, cs);
MYSQL_TIME_STATUS st;
- Time tm(&st, from, len, cs, sql_mode_for_dates(get_thd()));
+ Time tm(&st, from, len, cs, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&tm, &str, st.warnings);
}
@@ -5741,7 +5728,7 @@ int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec)
{
ErrConvTime str(ltime);
int warn;
- Time tm(&warn, ltime, curdays);
+ Time tm(&warn, ltime, curdays, decimals());
return store_TIME_with_warning(&tm, &str, warn);
}
@@ -5750,7 +5737,7 @@ int Field_time::store(double nr)
{
ErrConvDouble str(nr);
int was_cut;
- Time tm(&was_cut, nr);
+ Time tm(&was_cut, nr, decimals());
return store_TIME_with_warning(&tm, &str, was_cut);
}
@@ -5917,7 +5904,7 @@ int Field_time::store_decimal(const my_decimal *d)
{
ErrConvDecimal str(d);
int was_cut;
- Time tm(&was_cut, d);
+ Time tm(&was_cut, d, decimals());
return store_TIME_with_warning(&tm, &str, was_cut);
}
@@ -6655,7 +6642,7 @@ int Field_temporal_with_date::store_decimal(const my_decimal *d)
{
int error;
ErrConvDecimal str(d);
- Datetime tm(&error, d, sql_mode_for_dates(get_thd()));
+ Datetime tm(&error, d, sql_mode_for_dates(get_thd()), decimals());
return store_TIME_with_warning(&tm, &str, error);
}
diff --git a/sql/sql_type.h b/sql/sql_type.h
index 29a0db9ed53..4eaf578fac1 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -771,6 +771,29 @@ public:
Time(int *warn, const my_decimal *d)
:Temporal(Time(warn, Sec6(d), Options()))
{ }
+
+ Time(int *warn, const MYSQL_TIME *from, long curdays, uint dec)
+ :Temporal(Time(warn, from, curdays))
+ {
+ trunc(dec);
+ }
+ Time(MYSQL_TIME_STATUS *status, const char *str, size_t len, CHARSET_INFO *cs,
+ const Options &opt, uint dec)
+ :Temporal(Time(status, str, len, cs, opt))
+ {
+ trunc(dec);
+ }
+ Time(int *warn, double nr, uint dec)
+ :Temporal(Time(warn, nr))
+ {
+ trunc(dec);
+ }
+ Time(int *warn, const my_decimal *d, uint dec)
+ :Temporal(Time(warn, d))
+ {
+ trunc(dec);
+ }
+
static sql_mode_t flags_for_get_date()
{ return TIME_TIME_ONLY | TIME_INVALID_DATES; }
static sql_mode_t comparison_flags_for_get_date()
@@ -846,11 +869,12 @@ public:
{
return is_valid_time() ? Temporal::to_packed() : 0;
}
- Time trunc(uint dec) const
+ Time &trunc(uint dec)
{
- Time tm(*this);
- my_time_trunc(&tm, dec);
- return tm;
+ if (is_valid_time())
+ my_time_trunc(this, dec);
+ DBUG_ASSERT(is_valid_value_slow());
+ return *this;
}
};
@@ -1101,6 +1125,30 @@ public:
DBUG_ASSERT(is_valid_value_slow());
}
+ Datetime(MYSQL_TIME_STATUS *status,
+ const char *str, size_t len, CHARSET_INFO *cs,
+ sql_mode_t fuzzydate, uint dec)
+ :Temporal_with_date(Datetime(status, str, len, cs, fuzzydate))
+ {
+ trunc(dec);
+ }
+ Datetime(int *warn, double nr, sql_mode_t fuzzydate, uint dec)
+ :Temporal_with_date(Datetime(warn, nr, fuzzydate))
+ {
+ trunc(dec);
+ }
+ Datetime(int *warn, const my_decimal *d, sql_mode_t fuzzydate, uint dec)
+ :Temporal_with_date(Datetime(warn, d, fuzzydate))
+ {
+ trunc(dec);
+ }
+ Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
+ sql_mode_t fuzzydate, uint dec)
+ :Temporal_with_date(Datetime(thd, warn, from, fuzzydate))
+ {
+ trunc(dec);
+ }
+
bool is_valid_datetime() const
{
/*
@@ -1173,11 +1221,12 @@ public:
{
return is_valid_datetime() ? Temporal::to_packed() : 0;
}
- Datetime trunc(uint dec) const
+ Datetime &trunc(uint dec)
{
- Datetime tm(*this);
- my_time_trunc(&tm, dec);
- return tm;
+ if (is_valid_datetime())
+ my_time_trunc(this, dec);
+ DBUG_ASSERT(is_valid_value_slow());
+ return *this;
}
};