diff options
author | Alexander Barkov <bar@mariadb.com> | 2018-11-22 14:53:25 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2018-11-22 14:53:25 +0400 |
commit | 740ce108a52120fe6b2933ce8f3e82d8cf12ae8c (patch) | |
tree | 5ffdf0c29f4749c7cfcf67c2899edf3b1bf23820 | |
parent | 2ebb110c36b2671614af26f34b35ece58a9b9f6a (diff) | |
download | mariadb-git-740ce108a52120fe6b2933ce8f3e82d8cf12ae8c.tar.gz |
MDEV-17792 New class Timestamp and cleanups in Date, Datetime, Field for rounding
-rw-r--r-- | sql/field.cc | 67 | ||||
-rw-r--r-- | sql/field.h | 22 | ||||
-rw-r--r-- | sql/field_conv.cc | 33 | ||||
-rw-r--r-- | sql/item_timefunc.cc | 15 | ||||
-rw-r--r-- | sql/sql_class.h | 4 | ||||
-rw-r--r-- | sql/sql_show.cc | 14 | ||||
-rw-r--r-- | sql/sql_type.cc | 24 | ||||
-rw-r--r-- | sql/sql_type.h | 76 | ||||
-rw-r--r-- | sql/structs.h | 5 |
9 files changed, 184 insertions, 76 deletions
diff --git a/sql/field.cc b/sql/field.cc index 3fe2cee1220..cc95a8c8e84 100644 --- a/sql/field.cc +++ b/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) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; - static const timeval zero= {0, (uint) 0 }; + static const Timestamp zero(0, 0); // Handle totally bad values if (!dt->is_valid_datetime()) { set_datetime_warning(WARN_DATA_TRUNCATED, str, MYSQL_TIMESTAMP_DATETIME, 1); - store_TIMEVAL(zero); + store_TIMESTAMP(zero); 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.: 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, 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) { 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 } // Store the value 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 if (unlikely(conversion_error)) // e.g. DATETIME in the DST gap @@ -5116,7 +5116,7 @@ int Field_timestamp::store(double nr) int error; ErrConvDouble str(nr); 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); } @@ -5124,16 +5124,17 @@ int Field_timestamp::store(double nr) int Field_timestamp::store(longlong nr, bool unsigned_val) { int error; - ErrConvInteger str(Longlong_hybrid(nr, unsigned_val)); + Longlong_hybrid tmp(nr, unsigned_val); + ErrConvInteger str(tmp); 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); } 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 && 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() { set_notnull(); - store_TIME(get_thd()->query_start(), 0); + store_TIMESTAMP(Timestamp(get_thd()->query_start(), 0)); return 0; } @@ -5426,7 +5427,7 @@ int Field_timestamp::store_decimal(const my_decimal *d) int error; THD *thd= get_thd(); 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); } @@ -5435,7 +5436,8 @@ int Field_timestamp_with_dec::set_time() THD *thd= get_thd(); set_notnull(); // 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; } @@ -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); // Store the value DBUG_ASSERT(!dt->fraction_remainder(decimals())); - store_TIME(dt->get_mysql_time()); + store_datetime(*dt); // Caclulate return value and send warnings if needed return store_TIME_return_code_with_warnings(was_cut, str, MYSQL_TIMESTAMP_DATETIME); @@ -5576,7 +5578,7 @@ int Field_datetime::store(double nr) { int error; 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); } @@ -5584,8 +5586,9 @@ int Field_datetime::store(double nr) int Field_datetime::store(longlong nr, bool unsigned_val) { int error; - ErrConvInteger str(Longlong_hybrid(nr, unsigned_val)); - Datetime dt(&error, Sec6(nr, unsigned_val), sql_mode_for_dates(get_thd())); + Longlong_hybrid tmp(nr, unsigned_val); + ErrConvInteger str(tmp); + Datetime dt(&error, tmp, sql_mode_for_dates(get_thd())); return store_TIME_with_warning(&dt, &str, error); } @@ -5603,10 +5606,11 @@ int Field_datetime::store_decimal(const my_decimal *d) { int error; 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); } + bool Field_temporal_with_date::validate_value_in_record(THD *thd, 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); // Store the value DBUG_ASSERT(!t->fraction_remainder(decimals())); - store_TIME(t->get_mysql_time()); + store_TIME(*t); // Calculate return value and send warnings if needed 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); 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); } 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; // 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); } @@ -5906,7 +5911,7 @@ int Field_time::store_decimal(const my_decimal *d) { ErrConvDecimal str(d); 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); } @@ -6253,7 +6258,7 @@ int Field_date_common::store_TIME_with_warning(const Datetime *dt, // Store the value if (!dt->hhmmssff_is_zero()) was_cut|= MYSQL_TIME_NOTE_TRUNCATED; - store_TIME(dt->get_mysql_time()); + store_datetime(*dt); // Caclulate return value and send warnings if needed return store_TIME_return_code_with_warnings(was_cut, str, MYSQL_TIMESTAMP_DATE); @@ -6271,15 +6276,16 @@ int Field_date_common::store(double nr) { int error; 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); } int Field_date_common::store(longlong nr, bool unsigned_val) { int error; - ErrConvInteger str(Longlong_hybrid(nr, unsigned_val)); - Datetime dt(&error, Sec6(nr, unsigned_val), sql_mode_for_dates(get_thd())); + Longlong_hybrid tmp(nr, unsigned_val); + ErrConvInteger str(tmp); + Datetime dt(&error, tmp, sql_mode_for_dates(get_thd())); return store_TIME_with_warning(&dt, &str, error); } @@ -6296,7 +6302,7 @@ int Field_date_common::store_decimal(const my_decimal *d) { int error; 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); } @@ -6686,13 +6692,8 @@ void Field_datetime::sql_type(String &res) const int Field_datetime::set_time() { 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(); - my_time_trunc(&now_time, decimals()); - store_TIME(&now_time); - thd->time_zone_used= 1; + store_datetime(Datetime(thd, thd->query_start_timeval(), decimals())); return 0; } diff --git a/sql/field.h b/sql/field.h index d5cfe2faa86..7c5552ec13c 100644 --- a/sql/field.h +++ b/sql/field.h @@ -610,7 +610,9 @@ protected: static void do_field_int(Copy_field *copy); static void do_field_real(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_decimal(Copy_field *copy); public: @@ -2690,6 +2692,10 @@ public: class Field_temporal_with_date: public Field_temporal { protected: 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, date_mode_t fuzzydate) const = 0; bool validate_MMDD(bool not_zero_date, uint month, uint day, @@ -2722,6 +2728,10 @@ protected: { int4store(ptr, tv.tv_sec); } + void store_TIMESTAMP(const Timestamp &ts) + { + store_TIMEVAL(ts.tv()); + } public: Field_timestamp(uchar *ptr_arg, uint32 len_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -2761,9 +2771,10 @@ public: { return get_timestamp(ptr, sec_part); } + // This is used by storage/perfschema 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); uchar *pack(uchar *to, const uchar *from, @@ -2924,7 +2935,7 @@ public: return do_field_string; } case TIME_RESULT: - return do_field_temporal; + return do_field_date; case DECIMAL_RESULT: return do_field_decimal; case REAL_RESULT: @@ -2970,6 +2981,7 @@ public: null_ptr_arg, null_bit_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, const Item_bool_func *cond, scalar_comparison_op op, Item *value); @@ -3054,6 +3066,10 @@ class Field_time :public Field_temporal { long curdays; protected: 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); bool check_zero_in_date_with_warn(date_mode_t fuzzydate); static void do_field_time(Copy_field *copy); diff --git a/sql/field_conv.cc b/sql/field_conv.cc index 8b3d9c04656..7a064f64570 100644 --- a/sql/field_conv.cc +++ b/sql/field_conv.cc @@ -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; // 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(); else 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) { - MYSQL_TIME ltime; - 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()); + return do_field_temporal(copy, TIME_TIME_ONLY); } @@ -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 *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; else 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 { /* 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) || (table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE))) - return do_field_temporal; + return do_field_datetime; return get_identical_copy_func(); } diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 41a5798c3b5..df4dc8cb96d 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -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()) return (null_value= 1); - bzero(ltime, sizeof(*ltime)); - ltime->time_type= MYSQL_TIMESTAMP_TIME; - ltime->neg= hour.neg(); - - 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 + int warn; + new(ltime) Time(&warn, hour.neg(), hour.abs(), (uint) minute, sec); + if (warn) { // use check_time_range() to set ltime to the max value depending on dec int unused; diff --git a/sql/sql_class.h b/sql/sql_class.h index c0d1e3c8ce5..8174a8b313b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3415,6 +3415,10 @@ public: inline ulong query_start_sec_part() { query_start_sec_part_used=1; return start_time_sec_part; } MYSQL_TIME query_start_TIME(); + Timeval query_start_timeval() + { + return Timeval(query_start(), query_start_sec_part()); + } private: struct { diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 0ba06ab161a..a62603dbf1c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -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, const char *wild, bool full_access, const char *sp_user) { - MYSQL_TIME time; LEX *lex= thd->lex; CHARSET_INFO *cs= system_charset_info; 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], proc_table->field[MYSQL_PROC_FIELD_SECURITY_TYPE]); - bzero((char *)&time, sizeof(time)); - ((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_CREATED])-> - get_time(&time); - table->field[23]->store_time(&time); - bzero((char *)&time, sizeof(time)); - ((Field_timestamp *) proc_table->field[MYSQL_PROC_FIELD_MODIFIED])-> - get_time(&time); - table->field[24]->store_time(&time); + proc_table->field[MYSQL_PROC_FIELD_CREATED]-> + save_in_field(table->field[23]); + proc_table->field[MYSQL_PROC_FIELD_MODIFIED]-> + save_in_field(table->field[24]); + copy_field_as_string(table->field[25], proc_table->field[MYSQL_PROC_FIELD_SQL_MODE]); copy_field_as_string(table->field[26], diff --git a/sql/sql_type.cc b/sql/sql_type.cc index fd2487eca2b..60c3747f2ea 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -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) { 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, date_mode_t flags) { diff --git a/sql/sql_type.h b/sql/sql_type.h index e8af11764f5..273542c201c 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -1210,6 +1210,7 @@ public: All constructors that accept an "int *warn" parameter initialize *warn. The old value gets lost. */ + Time(int *warn, bool neg, ulonglong hour, uint minute, const Sec6 &second); Time() { time_type= MYSQL_TIMESTAMP_NONE; } Time(Item *item) :Time(current_thd, item, Options()) @@ -1233,14 +1234,24 @@ public: // The below call will optionally add notes to already collected warnings: xxx_to_time_result_to_valid_value(thd, &status->warnings, opt); } + +protected: Time(THD *thd, int *warn, const Sec6 &nr, const Options opt) { if (nr.to_datetime_or_time(this, warn, TIME_INVALID_DATES)) time_type= MYSQL_TIMESTAMP_NONE; 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) @@ -1260,8 +1271,23 @@ public: { trunc(dec); } - Time(THD *thd, int *warn, const Sec6 &nr, uint dec) - :Time(thd, warn, nr) + Time(THD *thd, int *warn, const Longlong_hybrid &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); } @@ -1615,6 +1641,8 @@ public: date_to_datetime_if_needed(); DBUG_ASSERT(is_valid_value_slow()); } + +protected: Datetime(int *warn, const Sec6 &nr, date_mode_t flags) :Temporal_with_date(warn, nr, flags) { @@ -1622,6 +1650,18 @@ public: 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, item, flags) { @@ -1634,17 +1674,28 @@ public: { 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) { 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, date_mode_t fuzzydate, uint dec) :Datetime(thd, warn, from, fuzzydate) { 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 { @@ -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(): diff --git a/sql/structs.h b/sql/structs.h index c9b973d351a..dec1e4de0c7 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -853,11 +853,6 @@ public: tv_sec= sec; tv_usec= usec; } - Timeval &trunc(uint dec) - { - my_timeval_trunc(this, dec); - return *this; - } }; |