MDEV-17792 New class Timestamp and cleanups in Date, Datetime, Field for rounding
This commit is contained in:
parent
2ebb110c36
commit
740ce108a5
67
sql/field.cc
67
sql/field.cc
@ -5035,13 +5035,13 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
|
|||||||
const ErrConv *str, int was_cut)
|
const ErrConv *str, int was_cut)
|
||||||
{
|
{
|
||||||
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED;
|
||||||
static const timeval zero= {0, (uint) 0 };
|
static const Timestamp zero(0, 0);
|
||||||
|
|
||||||
// Handle totally bad values
|
// Handle totally bad values
|
||||||
if (!dt->is_valid_datetime())
|
if (!dt->is_valid_datetime())
|
||||||
{
|
{
|
||||||
set_datetime_warning(WARN_DATA_TRUNCATED, str, MYSQL_TIMESTAMP_DATETIME, 1);
|
set_datetime_warning(WARN_DATA_TRUNCATED, str, MYSQL_TIMESTAMP_DATETIME, 1);
|
||||||
store_TIMEVAL(zero);
|
store_TIMESTAMP(zero);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5053,7 +5053,7 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
|
|||||||
Return success or a warning about non-fatal truncation, e.g.:
|
Return success or a warning about non-fatal truncation, e.g.:
|
||||||
INSERT INTO t1 (ts) VALUES ('0000-00-00 00:00:00 some tail');
|
INSERT INTO t1 (ts) VALUES ('0000-00-00 00:00:00 some tail');
|
||||||
*/
|
*/
|
||||||
store_TIMEVAL(zero);
|
store_TIMESTAMP(zero);
|
||||||
return store_TIME_return_code_with_warnings(was_cut, str,
|
return store_TIME_return_code_with_warnings(was_cut, str,
|
||||||
MYSQL_TIMESTAMP_DATETIME);
|
MYSQL_TIMESTAMP_DATETIME);
|
||||||
}
|
}
|
||||||
@ -5065,13 +5065,13 @@ int Field_timestamp::store_TIME_with_warning(THD *thd, const Datetime *dt,
|
|||||||
if (timestamp == 0 && l_time->second_part == 0)
|
if (timestamp == 0 && l_time->second_part == 0)
|
||||||
{
|
{
|
||||||
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, MYSQL_TIMESTAMP_DATETIME, 1);
|
set_datetime_warning(ER_WARN_DATA_OUT_OF_RANGE, str, MYSQL_TIMESTAMP_DATETIME, 1);
|
||||||
store_TIMEVAL(zero);
|
store_TIMESTAMP(zero);
|
||||||
return 1; // date was fine but pointed to a DST gap
|
return 1; // date was fine but pointed to a DST gap
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store the value
|
// Store the value
|
||||||
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
|
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
|
||||||
store_TIMEVAL(Timeval(timestamp, l_time->second_part));
|
store_TIMESTAMP(Timestamp(timestamp, l_time->second_part));
|
||||||
|
|
||||||
// Calculate return value and send warnings if needed
|
// Calculate return value and send warnings if needed
|
||||||
if (unlikely(conversion_error)) // e.g. DATETIME in the DST gap
|
if (unlikely(conversion_error)) // e.g. DATETIME in the DST gap
|
||||||
@ -5116,7 +5116,7 @@ int Field_timestamp::store(double nr)
|
|||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(&error, Sec6(nr), sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(&error, nr, sql_mode_for_timestamp(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5124,16 +5124,17 @@ int Field_timestamp::store(double nr)
|
|||||||
int Field_timestamp::store(longlong nr, bool unsigned_val)
|
int Field_timestamp::store(longlong nr, bool unsigned_val)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvInteger str(Longlong_hybrid(nr, unsigned_val));
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
|
ErrConvInteger str(tmp);
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
Datetime dt(&error, Sec6(nr, unsigned_val), sql_mode_for_timestamp(thd));
|
Datetime dt(&error, tmp, sql_mode_for_timestamp(thd));
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
int Field_timestamp::store_timestamp(my_time_t ts, ulong sec_part)
|
||||||
{
|
{
|
||||||
store_TIME(ts, sec_part);
|
store_TIMESTAMP(Timestamp(ts, sec_part).trunc(decimals()));
|
||||||
if (ts == 0 && sec_part == 0 &&
|
if (ts == 0 && sec_part == 0 &&
|
||||||
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
get_thd()->variables.sql_mode & (ulonglong) TIME_NO_ZERO_DATE)
|
||||||
{
|
{
|
||||||
@ -5298,7 +5299,7 @@ void Field_timestamp::sql_type(String &res) const
|
|||||||
int Field_timestamp::set_time()
|
int Field_timestamp::set_time()
|
||||||
{
|
{
|
||||||
set_notnull();
|
set_notnull();
|
||||||
store_TIME(get_thd()->query_start(), 0);
|
store_TIMESTAMP(Timestamp(get_thd()->query_start(), 0));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5426,7 +5427,7 @@ int Field_timestamp::store_decimal(const my_decimal *d)
|
|||||||
int error;
|
int error;
|
||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime dt(&error, Sec6(d), sql_mode_for_timestamp(thd), decimals());
|
Datetime dt(&error, d, sql_mode_for_timestamp(thd), decimals());
|
||||||
return store_TIME_with_warning(thd, &dt, &str, error);
|
return store_TIME_with_warning(thd, &dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5435,7 +5436,8 @@ int Field_timestamp_with_dec::set_time()
|
|||||||
THD *thd= get_thd();
|
THD *thd= get_thd();
|
||||||
set_notnull();
|
set_notnull();
|
||||||
// Avoid writing microseconds into binlog for FSP=0
|
// Avoid writing microseconds into binlog for FSP=0
|
||||||
store_TIME(thd->query_start(), decimals() ? thd->query_start_sec_part() : 0);
|
ulong msec= decimals() ? thd->query_start_sec_part() : 0;
|
||||||
|
store_TIMESTAMP(Timestamp(thd->query_start(), msec).trunc(decimals()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5557,7 +5559,7 @@ int Field_datetime::store_TIME_with_warning(const Datetime *dt,
|
|||||||
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATETIME);
|
return store_invalid_with_warning(str, was_cut, MYSQL_TIMESTAMP_DATETIME);
|
||||||
// Store the value
|
// Store the value
|
||||||
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
|
DBUG_ASSERT(!dt->fraction_remainder(decimals()));
|
||||||
store_TIME(dt->get_mysql_time());
|
store_datetime(*dt);
|
||||||
// Caclulate return value and send warnings if needed
|
// Caclulate return value and send warnings if needed
|
||||||
return store_TIME_return_code_with_warnings(was_cut, str,
|
return store_TIME_return_code_with_warnings(was_cut, str,
|
||||||
MYSQL_TIMESTAMP_DATETIME);
|
MYSQL_TIMESTAMP_DATETIME);
|
||||||
@ -5576,7 +5578,7 @@ int Field_datetime::store(double nr)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
Datetime dt(&error, Sec6(nr), sql_mode_for_dates(get_thd()), decimals());
|
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()), decimals());
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5584,8 +5586,9 @@ int Field_datetime::store(double nr)
|
|||||||
int Field_datetime::store(longlong nr, bool unsigned_val)
|
int Field_datetime::store(longlong nr, bool unsigned_val)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvInteger str(Longlong_hybrid(nr, unsigned_val));
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
Datetime dt(&error, Sec6(nr, unsigned_val), sql_mode_for_dates(get_thd()));
|
ErrConvInteger str(tmp);
|
||||||
|
Datetime dt(&error, tmp, sql_mode_for_dates(get_thd()));
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5603,10 +5606,11 @@ int Field_datetime::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime tm(&error, Sec6(d), sql_mode_for_dates(get_thd()), decimals());
|
Datetime tm(&error, d, sql_mode_for_dates(get_thd()), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, error);
|
return store_TIME_with_warning(&tm, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Field_temporal_with_date::validate_value_in_record(THD *thd,
|
Field_temporal_with_date::validate_value_in_record(THD *thd,
|
||||||
const uchar *record) const
|
const uchar *record) const
|
||||||
@ -5698,7 +5702,7 @@ int Field_time::store_TIME_with_warning(const Time *t,
|
|||||||
return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_TIME);
|
return store_invalid_with_warning(str, warn, MYSQL_TIMESTAMP_TIME);
|
||||||
// Store the value
|
// Store the value
|
||||||
DBUG_ASSERT(!t->fraction_remainder(decimals()));
|
DBUG_ASSERT(!t->fraction_remainder(decimals()));
|
||||||
store_TIME(t->get_mysql_time());
|
store_TIME(*t);
|
||||||
// Calculate return value and send warnings if needed
|
// Calculate return value and send warnings if needed
|
||||||
return store_TIME_return_code_with_warnings(warn, str, MYSQL_TIMESTAMP_TIME);
|
return store_TIME_return_code_with_warnings(warn, str, MYSQL_TIMESTAMP_TIME);
|
||||||
}
|
}
|
||||||
@ -5738,17 +5742,18 @@ int Field_time::store(double nr)
|
|||||||
{
|
{
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
Time tm(get_thd(), &was_cut, Sec6(nr), decimals());
|
Time tm(get_thd(), &was_cut, nr, Time::Options(), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Field_time::store(longlong nr, bool unsigned_val)
|
int Field_time::store(longlong nr, bool unsigned_val)
|
||||||
{
|
{
|
||||||
ErrConvInteger str(Longlong_hybrid(nr, unsigned_val));
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
|
ErrConvInteger str(tmp);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
// Need fractional digit truncation if nr overflows to '838:59:59.999999'
|
// Need fractional digit truncation if nr overflows to '838:59:59.999999'
|
||||||
Time tm(get_thd(), &was_cut, Sec6(nr, unsigned_val), decimals());
|
Time tm(get_thd(), &was_cut, tmp, Time::Options(), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5906,7 +5911,7 @@ int Field_time::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
int was_cut;
|
int was_cut;
|
||||||
Time tm(get_thd(), &was_cut, Sec6(d), decimals());
|
Time tm(get_thd(), &was_cut, d, Time::Options(), decimals());
|
||||||
return store_TIME_with_warning(&tm, &str, was_cut);
|
return store_TIME_with_warning(&tm, &str, was_cut);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6253,7 +6258,7 @@ int Field_date_common::store_TIME_with_warning(const Datetime *dt,
|
|||||||
// Store the value
|
// Store the value
|
||||||
if (!dt->hhmmssff_is_zero())
|
if (!dt->hhmmssff_is_zero())
|
||||||
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
|
was_cut|= MYSQL_TIME_NOTE_TRUNCATED;
|
||||||
store_TIME(dt->get_mysql_time());
|
store_datetime(*dt);
|
||||||
// Caclulate return value and send warnings if needed
|
// Caclulate return value and send warnings if needed
|
||||||
return store_TIME_return_code_with_warnings(was_cut, str,
|
return store_TIME_return_code_with_warnings(was_cut, str,
|
||||||
MYSQL_TIMESTAMP_DATE);
|
MYSQL_TIMESTAMP_DATE);
|
||||||
@ -6271,15 +6276,16 @@ int Field_date_common::store(double nr)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDouble str(nr);
|
ErrConvDouble str(nr);
|
||||||
Datetime dt(&error, Sec6(nr), sql_mode_for_dates(get_thd()));
|
Datetime dt(&error, nr, sql_mode_for_dates(get_thd()));
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
int Field_date_common::store(longlong nr, bool unsigned_val)
|
int Field_date_common::store(longlong nr, bool unsigned_val)
|
||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvInteger str(Longlong_hybrid(nr, unsigned_val));
|
Longlong_hybrid tmp(nr, unsigned_val);
|
||||||
Datetime dt(&error, Sec6(nr, unsigned_val), sql_mode_for_dates(get_thd()));
|
ErrConvInteger str(tmp);
|
||||||
|
Datetime dt(&error, tmp, sql_mode_for_dates(get_thd()));
|
||||||
return store_TIME_with_warning(&dt, &str, error);
|
return store_TIME_with_warning(&dt, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6296,7 +6302,7 @@ int Field_date_common::store_decimal(const my_decimal *d)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
ErrConvDecimal str(d);
|
ErrConvDecimal str(d);
|
||||||
Datetime tm(&error, Sec6(d), sql_mode_for_dates(get_thd()));
|
Datetime tm(&error, d, sql_mode_for_dates(get_thd()));
|
||||||
return store_TIME_with_warning(&tm, &str, error);
|
return store_TIME_with_warning(&tm, &str, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -6686,13 +6692,8 @@ void Field_datetime::sql_type(String &res) const
|
|||||||
int Field_datetime::set_time()
|
int Field_datetime::set_time()
|
||||||
{
|
{
|
||||||
THD *thd= table->in_use;
|
THD *thd= table->in_use;
|
||||||
MYSQL_TIME now_time;
|
|
||||||
thd->variables.time_zone->gmt_sec_to_TIME(&now_time, thd->query_start());
|
|
||||||
now_time.second_part= thd->query_start_sec_part();
|
|
||||||
set_notnull();
|
set_notnull();
|
||||||
my_time_trunc(&now_time, decimals());
|
store_datetime(Datetime(thd, thd->query_start_timeval(), decimals()));
|
||||||
store_TIME(&now_time);
|
|
||||||
thd->time_zone_used= 1;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
22
sql/field.h
22
sql/field.h
@ -610,7 +610,9 @@ protected:
|
|||||||
static void do_field_int(Copy_field *copy);
|
static void do_field_int(Copy_field *copy);
|
||||||
static void do_field_real(Copy_field *copy);
|
static void do_field_real(Copy_field *copy);
|
||||||
static void do_field_string(Copy_field *copy);
|
static void do_field_string(Copy_field *copy);
|
||||||
static void do_field_temporal(Copy_field *copy);
|
static void do_field_date(Copy_field *copy);
|
||||||
|
static void do_field_temporal(Copy_field *copy, date_mode_t fuzzydate);
|
||||||
|
static void do_field_datetime(Copy_field *copy);
|
||||||
static void do_field_timestamp(Copy_field *copy);
|
static void do_field_timestamp(Copy_field *copy);
|
||||||
static void do_field_decimal(Copy_field *copy);
|
static void do_field_decimal(Copy_field *copy);
|
||||||
public:
|
public:
|
||||||
@ -2690,6 +2692,10 @@ public:
|
|||||||
class Field_temporal_with_date: public Field_temporal {
|
class Field_temporal_with_date: public Field_temporal {
|
||||||
protected:
|
protected:
|
||||||
virtual void store_TIME(const MYSQL_TIME *ltime) = 0;
|
virtual void store_TIME(const MYSQL_TIME *ltime) = 0;
|
||||||
|
void store_datetime(const Datetime &dt)
|
||||||
|
{
|
||||||
|
return store_TIME(dt.get_mysql_time());
|
||||||
|
}
|
||||||
virtual bool get_TIME(MYSQL_TIME *ltime, const uchar *pos,
|
virtual bool get_TIME(MYSQL_TIME *ltime, const uchar *pos,
|
||||||
date_mode_t fuzzydate) const = 0;
|
date_mode_t fuzzydate) const = 0;
|
||||||
bool validate_MMDD(bool not_zero_date, uint month, uint day,
|
bool validate_MMDD(bool not_zero_date, uint month, uint day,
|
||||||
@ -2722,6 +2728,10 @@ protected:
|
|||||||
{
|
{
|
||||||
int4store(ptr, tv.tv_sec);
|
int4store(ptr, tv.tv_sec);
|
||||||
}
|
}
|
||||||
|
void store_TIMESTAMP(const Timestamp &ts)
|
||||||
|
{
|
||||||
|
store_TIMEVAL(ts.tv());
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
Field_timestamp(uchar *ptr_arg, uint32 len_arg,
|
Field_timestamp(uchar *ptr_arg, uint32 len_arg,
|
||||||
uchar *null_ptr_arg, uchar null_bit_arg,
|
uchar *null_ptr_arg, uchar null_bit_arg,
|
||||||
@ -2761,9 +2771,10 @@ public:
|
|||||||
{
|
{
|
||||||
return get_timestamp(ptr, sec_part);
|
return get_timestamp(ptr, sec_part);
|
||||||
}
|
}
|
||||||
|
// This is used by storage/perfschema
|
||||||
void store_TIME(my_time_t timestamp, ulong sec_part)
|
void store_TIME(my_time_t timestamp, ulong sec_part)
|
||||||
{
|
{
|
||||||
store_TIMEVAL(Timeval(timestamp, sec_part).trunc(decimals()));
|
store_TIMESTAMP(Timestamp(timestamp, sec_part).trunc(decimals()));
|
||||||
}
|
}
|
||||||
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
bool get_date(MYSQL_TIME *ltime, date_mode_t fuzzydate);
|
||||||
uchar *pack(uchar *to, const uchar *from,
|
uchar *pack(uchar *to, const uchar *from,
|
||||||
@ -2924,7 +2935,7 @@ public:
|
|||||||
return do_field_string;
|
return do_field_string;
|
||||||
}
|
}
|
||||||
case TIME_RESULT:
|
case TIME_RESULT:
|
||||||
return do_field_temporal;
|
return do_field_date;
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
return do_field_decimal;
|
return do_field_decimal;
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
@ -2970,6 +2981,7 @@ public:
|
|||||||
null_ptr_arg, null_bit_arg,
|
null_ptr_arg, null_bit_arg,
|
||||||
unireg_check_arg, field_name_arg)
|
unireg_check_arg, field_name_arg)
|
||||||
{}
|
{}
|
||||||
|
Copy_func *get_copy_func(const Field *from) const;
|
||||||
SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, KEY_PART *key_part,
|
SEL_ARG *get_mm_leaf(RANGE_OPT_PARAM *param, KEY_PART *key_part,
|
||||||
const Item_bool_func *cond,
|
const Item_bool_func *cond,
|
||||||
scalar_comparison_op op, Item *value);
|
scalar_comparison_op op, Item *value);
|
||||||
@ -3054,6 +3066,10 @@ class Field_time :public Field_temporal {
|
|||||||
long curdays;
|
long curdays;
|
||||||
protected:
|
protected:
|
||||||
virtual void store_TIME(const MYSQL_TIME *ltime);
|
virtual void store_TIME(const MYSQL_TIME *ltime);
|
||||||
|
void store_TIME(const Time &t)
|
||||||
|
{
|
||||||
|
return store_TIME(t.get_mysql_time());
|
||||||
|
}
|
||||||
int store_TIME_with_warning(const Time *ltime, const ErrConv *str, int warn);
|
int store_TIME_with_warning(const Time *ltime, const ErrConv *str, int warn);
|
||||||
bool check_zero_in_date_with_warn(date_mode_t fuzzydate);
|
bool check_zero_in_date_with_warn(date_mode_t fuzzydate);
|
||||||
static void do_field_time(Copy_field *copy);
|
static void do_field_time(Copy_field *copy);
|
||||||
|
@ -425,24 +425,32 @@ void Field::do_field_timestamp(Copy_field *copy)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field::do_field_temporal(Copy_field *copy)
|
void Field::do_field_temporal(Copy_field *copy, date_mode_t fuzzydate)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
MYSQL_TIME ltime;
|
||||||
// TODO: we now need to check result
|
// TODO: we now need to check result
|
||||||
if (copy->from_field->get_date(<ime, date_mode_t(0)))
|
if (copy->from_field->get_date(<ime, fuzzydate))
|
||||||
copy->to_field->reset();
|
copy->to_field->reset();
|
||||||
else
|
else
|
||||||
copy->to_field->store_time_dec(<ime, copy->from_field->decimals());
|
copy->to_field->store_time_dec(<ime, copy->from_field->decimals());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Field::do_field_datetime(Copy_field *copy)
|
||||||
|
{
|
||||||
|
return do_field_temporal(copy, date_mode_t(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Field::do_field_date(Copy_field *copy)
|
||||||
|
{
|
||||||
|
return do_field_temporal(copy, date_mode_t(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Field_time::do_field_time(Copy_field *copy)
|
void Field_time::do_field_time(Copy_field *copy)
|
||||||
{
|
{
|
||||||
MYSQL_TIME ltime;
|
return do_field_temporal(copy, TIME_TIME_ONLY);
|
||||||
if (copy->from_field->get_date(<ime, TIME_TIME_ONLY))
|
|
||||||
copy->to_field->reset();
|
|
||||||
else
|
|
||||||
copy->to_field->store_time_dec(<ime, copy->from_field->decimals());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -720,13 +728,20 @@ void Copy_field::set(Field *to,Field *from,bool save)
|
|||||||
Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
|
Field::Copy_func *Field_timestamp::get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
Field::Copy_func *copy= Field_temporal::get_copy_func(from);
|
Field::Copy_func *copy= Field_temporal::get_copy_func(from);
|
||||||
if (copy == do_field_temporal && from->type() == MYSQL_TYPE_TIMESTAMP)
|
if (copy == do_field_datetime && from->type() == MYSQL_TYPE_TIMESTAMP)
|
||||||
return do_field_timestamp;
|
return do_field_timestamp;
|
||||||
else
|
else
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Field::Copy_func *Field_date_common::get_copy_func(const Field *from) const
|
||||||
|
{
|
||||||
|
Field::Copy_func *copy= Field_temporal::get_copy_func(from);
|
||||||
|
return copy == do_field_datetime ? do_field_date : copy;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
|
Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
|
||||||
{
|
{
|
||||||
/* If types are not 100 % identical then convert trough get_date() */
|
/* If types are not 100 % identical then convert trough get_date() */
|
||||||
@ -739,7 +754,7 @@ Field::Copy_func *Field_temporal::get_copy_func(const Field *from) const
|
|||||||
if (!eq_def(from) ||
|
if (!eq_def(from) ||
|
||||||
(table->in_use->variables.sql_mode &
|
(table->in_use->variables.sql_mode &
|
||||||
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)))
|
(MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)))
|
||||||
return do_field_temporal;
|
return do_field_datetime;
|
||||||
return get_identical_copy_func();
|
return get_identical_copy_func();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2576,18 +2576,9 @@ bool Item_func_maketime::get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzy
|
|||||||
minute < 0 || minute > 59 || sec.neg() || sec.truncated())
|
minute < 0 || minute > 59 || sec.neg() || sec.truncated())
|
||||||
return (null_value= 1);
|
return (null_value= 1);
|
||||||
|
|
||||||
bzero(ltime, sizeof(*ltime));
|
int warn;
|
||||||
ltime->time_type= MYSQL_TIMESTAMP_TIME;
|
new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, sec);
|
||||||
ltime->neg= hour.neg();
|
if (warn)
|
||||||
|
|
||||||
if (hour.abs() <= TIME_MAX_HOUR)
|
|
||||||
{
|
|
||||||
ltime->hour= (uint) hour.abs();
|
|
||||||
ltime->minute= (uint) minute;
|
|
||||||
ltime->second= (uint) sec.sec();
|
|
||||||
ltime->second_part= sec.usec();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// use check_time_range() to set ltime to the max value depending on dec
|
// use check_time_range() to set ltime to the max value depending on dec
|
||||||
int unused;
|
int unused;
|
||||||
|
@ -3415,6 +3415,10 @@ public:
|
|||||||
inline ulong query_start_sec_part()
|
inline ulong query_start_sec_part()
|
||||||
{ query_start_sec_part_used=1; return start_time_sec_part; }
|
{ query_start_sec_part_used=1; return start_time_sec_part; }
|
||||||
MYSQL_TIME query_start_TIME();
|
MYSQL_TIME query_start_TIME();
|
||||||
|
Timeval query_start_timeval()
|
||||||
|
{
|
||||||
|
return Timeval(query_start(), query_start_sec_part());
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct {
|
struct {
|
||||||
|
@ -6332,7 +6332,6 @@ bool store_schema_params(THD *thd, TABLE *table, TABLE *proc_table,
|
|||||||
bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
|
bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
|
||||||
const char *wild, bool full_access, const char *sp_user)
|
const char *wild, bool full_access, const char *sp_user)
|
||||||
{
|
{
|
||||||
MYSQL_TIME time;
|
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
CHARSET_INFO *cs= system_charset_info;
|
CHARSET_INFO *cs= system_charset_info;
|
||||||
const Sp_handler *sph;
|
const Sp_handler *sph;
|
||||||
@ -6420,14 +6419,11 @@ bool store_schema_proc(THD *thd, TABLE *table, TABLE *proc_table,
|
|||||||
copy_field_as_string(table->field[22],
|
copy_field_as_string(table->field[22],
|
||||||
proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]);
|
proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]);
|
||||||
|
|
||||||
bzero((char *)&time, sizeof(time));
|
proc_table->field[MYSQL_PROC_FIELD_CREATED]->
|
||||||
((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_CREATED])->
|
save_in_field(table->field[23]);
|
||||||
get_time(&time);
|
proc_table->field[MYSQL_PROC_FIELD_MODIFIED]->
|
||||||
table->field[23]->store_time(&time);
|
save_in_field(table->field[24]);
|
||||||
bzero((char *)&time, sizeof(time));
|
|
||||||
((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_MODIFIED])->
|
|
||||||
get_time(&time);
|
|
||||||
table->field[24]->store_time(&time);
|
|
||||||
copy_field_as_string(table->field[25],
|
copy_field_as_string(table->field[25],
|
||||||
proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]);
|
proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]);
|
||||||
copy_field_as_string(table->field[26],
|
copy_field_as_string(table->field[26],
|
||||||
|
@ -571,6 +571,21 @@ Time::Time(int *warn, const MYSQL_TIME *from, long curdays)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Time::Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(second.sec() <= 59);
|
||||||
|
*warn= 0;
|
||||||
|
set_zero_time(this, MYSQL_TIMESTAMP_TIME);
|
||||||
|
MYSQL_TIME::neg= neg;
|
||||||
|
MYSQL_TIME::hour= hour > TIME_MAX_HOUR ? (uint) (TIME_MAX_HOUR + 1) :
|
||||||
|
(uint) hour;
|
||||||
|
MYSQL_TIME::minute= minute;
|
||||||
|
MYSQL_TIME::second= (uint) second.sec();
|
||||||
|
MYSQL_TIME::second_part= second.usec();
|
||||||
|
adjust_time_range_or_invalidate(warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Temporal_with_date::make_from_item(THD *thd, Item *item, date_mode_t flags)
|
void Temporal_with_date::make_from_item(THD *thd, Item *item, date_mode_t flags)
|
||||||
{
|
{
|
||||||
flags&= ~TIME_TIME_ONLY;
|
flags&= ~TIME_TIME_ONLY;
|
||||||
@ -642,6 +657,15 @@ void Datetime::make_from_datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Datetime::Datetime(THD *thd, const timeval &tv)
|
||||||
|
{
|
||||||
|
thd->variables.time_zone->gmt_sec_to_TIME(this, tv.tv_sec);
|
||||||
|
second_part= tv.tv_usec;
|
||||||
|
thd->time_zone_used= 1;
|
||||||
|
DBUG_ASSERT(is_valid_value_slow());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
Datetime::Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||||
date_mode_t flags)
|
date_mode_t flags)
|
||||||
{
|
{
|
||||||
|
@ -1210,6 +1210,7 @@ public:
|
|||||||
All constructors that accept an "int *warn" parameter initialize *warn.
|
All constructors that accept an "int *warn" parameter initialize *warn.
|
||||||
The old value gets lost.
|
The old value gets lost.
|
||||||
*/
|
*/
|
||||||
|
Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second);
|
||||||
Time() { time_type= MYSQL_TIMESTAMP_NONE; }
|
Time() { time_type= MYSQL_TIMESTAMP_NONE; }
|
||||||
Time(Item *item)
|
Time(Item *item)
|
||||||
:Time(current_thd, item, Options())
|
:Time(current_thd, item, Options())
|
||||||
@ -1233,14 +1234,24 @@ public:
|
|||||||
// The below call will optionally add notes to already collected warnings:
|
// The below call will optionally add notes to already collected warnings:
|
||||||
xxx_to_time_result_to_valid_value(thd, &status->warnings, opt);
|
xxx_to_time_result_to_valid_value(thd, &status->warnings, opt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
Time(THD *thd, int *warn, const Sec6 &nr, const Options opt)
|
Time(THD *thd, int *warn, const Sec6 &nr, const Options opt)
|
||||||
{
|
{
|
||||||
if (nr.to_datetime_or_time(this, warn, TIME_INVALID_DATES))
|
if (nr.to_datetime_or_time(this, warn, TIME_INVALID_DATES))
|
||||||
time_type= MYSQL_TIMESTAMP_NONE;
|
time_type= MYSQL_TIMESTAMP_NONE;
|
||||||
xxx_to_time_result_to_valid_value(thd, warn, opt);
|
xxx_to_time_result_to_valid_value(thd, warn, opt);
|
||||||
}
|
}
|
||||||
Time(THD *thd, int *warn, const Sec6 &nr)
|
|
||||||
:Time(thd, warn, nr, Options())
|
public:
|
||||||
|
Time(THD *thd, int *warn, const Longlong_hybrid &nr, const Options &opt)
|
||||||
|
:Time(thd, warn, Sec6(nr), opt)
|
||||||
|
{ }
|
||||||
|
Time(THD *thd, int *warn, double nr, const Options &opt)
|
||||||
|
:Time(thd, warn, Sec6(nr), opt)
|
||||||
|
{ }
|
||||||
|
Time(THD *thd, int *warn, const my_decimal *d, const Options &opt)
|
||||||
|
:Time(thd, warn, Sec6(d), opt)
|
||||||
{ }
|
{ }
|
||||||
|
|
||||||
Time(THD *thd, Item *item, const Options opt, uint dec)
|
Time(THD *thd, Item *item, const Options opt, uint dec)
|
||||||
@ -1260,8 +1271,23 @@ public:
|
|||||||
{
|
{
|
||||||
trunc(dec);
|
trunc(dec);
|
||||||
}
|
}
|
||||||
Time(THD *thd, int *warn, const Sec6 &nr, uint dec)
|
Time(THD *thd, int *warn, const Longlong_hybrid &nr,
|
||||||
:Time(thd, warn, nr)
|
const Options &opt, uint dec)
|
||||||
|
:Time(thd, warn, nr, opt)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Decimal digit truncation is needed here in case if nr was out
|
||||||
|
of the supported TIME range, so "this" was set to '838:59:59.999999'.
|
||||||
|
*/
|
||||||
|
trunc(dec);
|
||||||
|
}
|
||||||
|
Time(THD *thd, int *warn, double nr, const Options &opt, uint dec)
|
||||||
|
:Time(thd, warn, nr, opt)
|
||||||
|
{
|
||||||
|
trunc(dec);
|
||||||
|
}
|
||||||
|
Time(THD *thd, int *warn, const my_decimal *d, const Options &opt, uint dec)
|
||||||
|
:Time(thd, warn, d, opt)
|
||||||
{
|
{
|
||||||
trunc(dec);
|
trunc(dec);
|
||||||
}
|
}
|
||||||
@ -1615,6 +1641,8 @@ public:
|
|||||||
date_to_datetime_if_needed();
|
date_to_datetime_if_needed();
|
||||||
DBUG_ASSERT(is_valid_value_slow());
|
DBUG_ASSERT(is_valid_value_slow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
Datetime(int *warn, const Sec6 &nr, date_mode_t flags)
|
Datetime(int *warn, const Sec6 &nr, date_mode_t flags)
|
||||||
:Temporal_with_date(warn, nr, flags)
|
:Temporal_with_date(warn, nr, flags)
|
||||||
{
|
{
|
||||||
@ -1622,6 +1650,18 @@ public:
|
|||||||
DBUG_ASSERT(is_valid_value_slow());
|
DBUG_ASSERT(is_valid_value_slow());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
Datetime(int *warn, const Longlong_hybrid &nr, date_mode_t mode)
|
||||||
|
:Datetime(warn, Sec6(nr), mode)
|
||||||
|
{ }
|
||||||
|
Datetime(int *warn, double nr, date_mode_t fuzzydate)
|
||||||
|
:Datetime(warn, Sec6(nr), fuzzydate)
|
||||||
|
{ }
|
||||||
|
Datetime(int *warn, const my_decimal *d, date_mode_t fuzzydate)
|
||||||
|
:Datetime(warn, Sec6(d), fuzzydate)
|
||||||
|
{ }
|
||||||
|
Datetime(THD *thd, const timeval &tv);
|
||||||
|
|
||||||
Datetime(THD *thd, Item *item, date_mode_t flags, uint dec)
|
Datetime(THD *thd, Item *item, date_mode_t flags, uint dec)
|
||||||
:Datetime(thd, item, flags)
|
:Datetime(thd, item, flags)
|
||||||
{
|
{
|
||||||
@ -1634,17 +1674,28 @@ public:
|
|||||||
{
|
{
|
||||||
trunc(dec);
|
trunc(dec);
|
||||||
}
|
}
|
||||||
Datetime(int *warn, const Sec6 &nr, date_mode_t fuzzydate, uint dec)
|
Datetime(int *warn, double nr, date_mode_t fuzzydate, uint dec)
|
||||||
:Datetime(warn, nr, fuzzydate)
|
:Datetime(warn, nr, fuzzydate)
|
||||||
{
|
{
|
||||||
trunc(dec);
|
trunc(dec);
|
||||||
}
|
}
|
||||||
|
Datetime(int *warn, const my_decimal *d, date_mode_t fuzzydate, uint dec)
|
||||||
|
:Datetime(warn, d, fuzzydate)
|
||||||
|
{
|
||||||
|
trunc(dec);
|
||||||
|
}
|
||||||
Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
Datetime(THD *thd, int *warn, const MYSQL_TIME *from,
|
||||||
date_mode_t fuzzydate, uint dec)
|
date_mode_t fuzzydate, uint dec)
|
||||||
:Datetime(thd, warn, from, fuzzydate)
|
:Datetime(thd, warn, from, fuzzydate)
|
||||||
{
|
{
|
||||||
trunc(dec);
|
trunc(dec);
|
||||||
}
|
}
|
||||||
|
Datetime(THD *thd, const timeval &tv, uint dec)
|
||||||
|
:Datetime(thd, tv)
|
||||||
|
{
|
||||||
|
DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS);
|
||||||
|
trunc(dec);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_valid_datetime() const
|
bool is_valid_datetime() const
|
||||||
{
|
{
|
||||||
@ -1759,6 +1810,21 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Timestamp: protected Timeval
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Timestamp(my_time_t timestamp, ulong sec_part)
|
||||||
|
:Timeval(timestamp, sec_part)
|
||||||
|
{ }
|
||||||
|
const struct timeval &tv() const { return *this; }
|
||||||
|
Timestamp &trunc(uint dec)
|
||||||
|
{
|
||||||
|
my_timeval_trunc(this, dec);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Flags for collation aggregation modes, used in TDCollation::agg():
|
Flags for collation aggregation modes, used in TDCollation::agg():
|
||||||
|
|
||||||
|
@ -853,11 +853,6 @@ public:
|
|||||||
tv_sec= sec;
|
tv_sec= sec;
|
||||||
tv_usec= usec;
|
tv_usec= usec;
|
||||||
}
|
}
|
||||||
Timeval &trunc(uint dec)
|
|
||||||
{
|
|
||||||
my_timeval_trunc(this, dec);
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user