diff --git a/include/my_time.h b/include/my_time.h index 4d92ee27349..fb328d71f8b 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -130,6 +130,13 @@ static inline void my_time_status_init(MYSQL_TIME_STATUS *status) status->nanoseconds= 0; } +struct my_timeval +{ + longlong tv_sec; + ulong tv_usec; +}; + + my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, ulonglong flags, int *was_cut); my_bool str_to_DDhhmmssff(const char *str, size_t length, MYSQL_TIME *l_time, @@ -227,7 +234,7 @@ int my_date_to_str(const MYSQL_TIME *l_time, char *to); int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint digits); int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits); -int my_timeval_to_str(const struct timeval *tm, char *to, uint dec); +int my_timeval_to_str(const struct my_timeval *tm, char *to, uint dec); static inline longlong sec_part_shift(longlong second_part, uint digits) { @@ -258,11 +265,6 @@ static inline void my_time_trunc(MYSQL_TIME *ltime, uint decimals) #ifdef _WIN32 #define suseconds_t long #endif -static inline void my_timeval_trunc(struct timeval *tv, uint decimals) -{ - tv->tv_usec-= (suseconds_t) my_time_fraction_remainder(tv->tv_usec, decimals); -} - #define hrtime_to_my_time(X) ((my_time_t)hrtime_to_time(X)) diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 6e9bac5e504..afba29e8982 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -1755,7 +1755,7 @@ int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint digits) @param dec Precision, in the range 0..6. @return The length of the result string. */ -int my_timeval_to_str(const struct timeval *tm, char *to, uint dec) +int my_timeval_to_str(const struct my_timeval *tm, char *to, uint dec) { char *pos= longlong10_to_str((longlong) tm->tv_sec, to, 10); if (dec) diff --git a/sql/compat56.cc b/sql/compat56.cc index 3d8574419d3..a72f37b0331 100644 --- a/sql/compat56.cc +++ b/sql/compat56.cc @@ -20,8 +20,7 @@ #include "myisampack.h" #include "my_time.h" - -static const int my_max_usec_value[7] +static const ulong my_max_usec_value[7] { 0, 900000, @@ -401,7 +400,7 @@ uint my_timestamp_binary_length(uint dec) @param ptr The pointer to read the value from. @param dec Precision. */ -void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec) +void my_timestamp_from_binary(struct my_timeval *tm, const uchar *ptr, uint dec) { DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); tm->tv_sec= mi_uint4korr(ptr); @@ -413,7 +412,7 @@ void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec) return; case 1: case 2: - tm->tv_usec= ((int) ptr[4]) * 10000; + tm->tv_usec= ((uint) ptr[4]) * 10000; break; case 3: case 4: @@ -427,6 +426,18 @@ void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec) set_if_smaller(tm->tv_usec, my_max_usec_value[dec]); } +/* + This is here mainly for ColumnStore until it is using my_timeval +*/ + +void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec) +{ + my_timeval tmp; + my_timestamp_from_binary(&tmp, ptr, dec); + tm->tv_sec= (ulong) tmp.tv_sec; + tm->tv_usec= tmp.tv_usec; +} + /** Convert MySQL56 in-memory timestamp representation to on-disk representation. @@ -435,7 +446,7 @@ void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec) @param OUT ptr The pointer to store the value to. @param dec Precision. */ -void my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uint dec) +void my_timestamp_to_binary(const struct my_timeval *tm, uchar *ptr, uint dec) { DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); /* Stored value must have been previously properly rounded or truncated */ diff --git a/sql/compat56.h b/sql/compat56.h index 65cd36dacfd..4edd55ef3bf 100644 --- a/sql/compat56.h +++ b/sql/compat56.h @@ -47,7 +47,9 @@ void my_time_packed_to_binary(longlong nr, uchar *ptr, uint dec); longlong my_time_packed_from_binary(const uchar *ptr, uint dec); uint my_time_binary_length(uint dec); -void my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uint dec); +void my_timestamp_to_binary(const struct my_timeval *tm, uchar *ptr, uint dec); +void my_timestamp_from_binary(struct my_timeval *tm, const uchar *ptr, uint dec); +/* For ColumnStore */ void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec); uint my_timestamp_binary_length(uint dec); /** End of MySQL routines and macros **/ diff --git a/sql/field.cc b/sql/field.cc index 9a906698bf5..1ab8a9ff18e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2048,7 +2048,7 @@ int Field::store_text(const char *to, size_t length, CHARSET_INFO *cs, } -int Field::store_timestamp_dec(const timeval &ts, uint dec) +int Field::store_timestamp_dec(const my_timeval &ts, uint dec) { return store_time_dec(Datetime(get_thd(), ts).get_mysql_time(), dec); } @@ -5403,13 +5403,13 @@ int Field_timestamp::store(longlong nr, bool unsigned_val) } -int Field_timestamp::store_timestamp_dec(const timeval &tv, uint dec) +int Field_timestamp::store_timestamp_dec(const my_timeval &tv, uint dec) { int warn= 0; time_round_mode_t mode= Datetime::default_round_mode(get_thd()); const Timestamp ts= Timestamp(tv).round(decimals(), mode, &warn); store_TIMESTAMP(ts); - if (ts.tv().tv_sec == 0 && ts.tv().tv_usec == 0) + if (ts.tv_sec == 0 && ts.tv_usec == 0) { /* The value {tv_sec==0, tv_usec==0} here means '1970-01-01 00:00:00 +00'. @@ -5474,7 +5474,7 @@ int Field_timestamp::store_native(const Native &value) Field_timestamp*::store_timestamp_dec() do not use the "dec" parameter. Passing TIME_SECOND_PART_DIGITS is OK. */ - return store_timestamp_dec(Timestamp(value).tv(), TIME_SECOND_PART_DIGITS); + return store_timestamp_dec(Timestamp(value), TIME_SECOND_PART_DIGITS); } @@ -5675,7 +5675,7 @@ static longlong read_native(const uchar *from, uint bytes) #endif -void Field_timestamp_hires::store_TIMEVAL(const timeval &tv) +void Field_timestamp_hires::store_TIMEVAL(const my_timeval &tv) { mi_int4store(ptr, tv.tv_sec); store_bigendian(sec_part_shift(tv.tv_usec, dec), ptr+4, sec_part_bytes(dec)); @@ -5693,7 +5693,7 @@ my_time_t Field_timestamp_hires::get_timestamp(const uchar *pos, bool Field_timestamp_hires::val_native(Native *to) { DBUG_ASSERT(marked_for_read()); - struct timeval tm; + struct my_timeval tm; tm.tv_sec= mi_uint4korr(ptr); tm.tv_usec= (ulong) sec_part_unshift(read_bigendian(ptr+4, sec_part_bytes(dec)), dec); return Timestamp_or_zero_datetime(Timestamp(tm), tm.tv_sec == 0). @@ -5770,7 +5770,7 @@ void Field_timestamp_with_dec::make_send_field(Send_field *field) ** MySQL-5.6 compatible TIMESTAMP(N) **************************************************************/ -void Field_timestampf::store_TIMEVAL(const timeval &tm) +void Field_timestampf::store_TIMEVAL(const my_timeval &tm) { my_timestamp_to_binary(&tm, ptr, dec); } @@ -5803,10 +5803,10 @@ bool Field_timestampf::is_max() my_time_t Field_timestampf::get_timestamp(const uchar *pos, ulong *sec_part) const { - struct timeval tm; + struct my_timeval tm; my_timestamp_from_binary(&tm, pos, dec); *sec_part= tm.tv_usec; - return tm.tv_sec; + return (my_time_t) tm.tv_sec; } diff --git a/sql/field.h b/sql/field.h index 187d152eb71..544ebca29e3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -969,11 +969,13 @@ public: virtual int store(longlong nr, bool unsigned_val)=0; virtual int store_decimal(const my_decimal *d)=0; virtual int store_time_dec(const MYSQL_TIME *ltime, uint dec); - virtual int store_timestamp_dec(const timeval &ts, uint dec); + virtual int store_timestamp_dec(const my_timeval &ts, uint dec); int store_timestamp(my_time_t timestamp, ulong sec_part) { - return store_timestamp_dec(Timeval(timestamp, sec_part), - TIME_SECOND_PART_DIGITS); + struct my_timeval tmp; + tmp.tv_sec= (longlong) timestamp; + tmp.tv_usec= (long) sec_part; + return store_timestamp_dec(tmp, TIME_SECOND_PART_DIGITS); } /** Store a value represented in native format @@ -3236,10 +3238,10 @@ class Field_timestamp :public Field_temporal { protected: int store_TIME_with_warning(THD *, const Datetime *, const ErrConv *, int warn); - virtual void store_TIMEVAL(const timeval &tv)= 0; + virtual void store_TIMEVAL(const my_timeval &tv)= 0; void store_TIMESTAMP(const Timestamp &ts) { - store_TIMEVAL(ts.tv()); + store_TIMEVAL(ts); } int zero_time_stored_return_code_with_warning(); public: @@ -3260,7 +3262,7 @@ public: int store(longlong nr, bool unsigned_val) override; int store_time_dec(const MYSQL_TIME *ltime, uint dec) override; int store_decimal(const my_decimal *) override; - int store_timestamp_dec(const timeval &ts, uint dec) override; + int store_timestamp_dec(const my_timeval &ts, uint dec) override; int save_in_field(Field *to) override; longlong val_int() override; String *val_str(String *, String *) override; @@ -3290,7 +3292,7 @@ public: class Field_timestamp0 :public Field_timestamp { - void store_TIMEVAL(const timeval &tv) override + void store_TIMEVAL(const my_timeval &tv) override { int4store(ptr, tv.tv_sec); } @@ -3382,7 +3384,7 @@ class Field_timestamp_hires :public Field_timestamp_with_dec { { return Type_handler_timestamp::sec_part_bytes(dec); } - void store_TIMEVAL(const timeval &tv) override; + void store_TIMEVAL(const my_timeval &tv) override; public: Field_timestamp_hires(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, @@ -3411,7 +3413,7 @@ public: TIMESTAMP(0..6) - MySQL56 version */ class Field_timestampf :public Field_timestamp_with_dec { - void store_TIMEVAL(const timeval &tv) override; + void store_TIMEVAL(const my_timeval &tv) override; public: Field_timestampf(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index f30ce5e2243..8b4202fe9a7 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1253,8 +1253,8 @@ bool Item_func_unix_timestamp::get_timestamp_value(my_time_t *seconds, 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; + *seconds= (my_time_t) tm.tv_sec; + *second_part= tm.tv_usec; return false; } diff --git a/sql/log_event_client.cc b/sql/log_event_client.cc index 83e900b177f..bbfc48af558 100644 --- a/sql/log_event_client.cc +++ b/sql/log_event_client.cc @@ -685,7 +685,7 @@ log_event_print_value(IO_CACHE *file, PRINT_EVENT_INFO *print_event_info, goto return_null; char buf[MAX_DATE_STRING_REP_LENGTH]; - struct timeval tm; + struct my_timeval tm; my_timestamp_from_binary(&tm, ptr, meta); int buflen= my_timeval_to_str(&tm, buf, meta); my_b_write(file, (uchar*)buf, buflen); diff --git a/sql/sql_class.h b/sql/sql_class.h index c9ab2a953e8..b7e7ade4b76 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -3388,7 +3388,7 @@ public: WT_THD wt; ///< for deadlock detection Rows_log_event *m_pending_rows_event; - struct st_trans_time : public timeval + struct st_trans_time : public my_timeval { void reset(THD *thd) { @@ -4299,7 +4299,7 @@ private: } public: - timeval transaction_time() + my_timeval transaction_time() { if (!in_multi_stmt_transaction_mode()) transaction->start_time.reset(this); diff --git a/sql/sql_type.cc b/sql/sql_type.cc index cab521d62e3..0c505c29503 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -390,7 +390,7 @@ bool Timestamp::to_native(Native *to, uint decimals) const bool Timestamp::to_TIME(THD *thd, MYSQL_TIME *to, date_mode_t fuzzydate) const { - return thd->timestamp_to_TIME(to, tv_sec, tv_usec, fuzzydate); + return thd->timestamp_to_TIME(to, (my_time_t) tv_sec, tv_usec, fuzzydate); } @@ -450,7 +450,7 @@ int Timestamp_or_zero_datetime_native::save_in_field(Field *field, static Datetime zero(Datetime::zero()); return field->store_time_dec(zero.get_mysql_time(), decimals); } - return field->store_timestamp_dec(Timestamp(*this).tv(), decimals); + return field->store_timestamp_dec(Timestamp(*this), decimals); } @@ -782,9 +782,9 @@ void Timestamp::round_or_set_max(uint dec, int *warn) { DBUG_ASSERT(dec <= TIME_SECOND_PART_DIGITS); if (add_nanoseconds_usec(msec_round_add[dec]) && - (ulonglong) tv_sec++ >= TIMESTAMP_MAX_VALUE) + tv_sec++ >= TIMESTAMP_MAX_VALUE) { - tv_sec= (time_t) TIMESTAMP_MAX_VALUE; + tv_sec= TIMESTAMP_MAX_VALUE; tv_usec= TIME_MAX_SECOND_PART; *warn|= MYSQL_TIME_WARN_OUT_OF_RANGE; } @@ -1053,9 +1053,9 @@ void Datetime::make_from_datetime(THD *thd, int *warn, const MYSQL_TIME *from, } -Datetime::Datetime(THD *thd, const timeval &tv) +Datetime::Datetime(THD *thd, const my_timeval &tv) { - thd->variables.time_zone->gmt_sec_to_TIME(this, tv.tv_sec); + thd->variables.time_zone->gmt_sec_to_TIME(this, (my_time_t) tv.tv_sec); second_part= tv.tv_usec; thd->used|= THD::TIME_ZONE_USED; DBUG_ASSERT(is_valid_value_slow()); diff --git a/sql/sql_type.h b/sql/sql_type.h index d41a5904f71..399362a316e 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -2480,7 +2480,7 @@ public: Datetime(THD *thd, int *warn, const my_decimal *d, date_mode_t fuzzydate) :Datetime(thd, warn, Sec9(d), fuzzydate) { } - Datetime(THD *thd, const timeval &tv); + Datetime(THD *thd, const my_timeval &tv); Datetime(THD *thd, Item *item, date_mode_t fuzzydate, uint dec) :Datetime(thd, item, fuzzydate) @@ -2765,7 +2765,7 @@ public: }; -class Timestamp: protected Timeval +class Timestamp: public Timeval { static uint binary_length_to_precision(uint length); protected: @@ -2798,12 +2798,11 @@ public: Timestamp(my_time_t timestamp, ulong sec_part) :Timeval(timestamp, sec_part) { } - explicit Timestamp(const timeval &tv) + explicit Timestamp(const my_timeval &tv) :Timeval(tv) { } explicit Timestamp(const Native &native); Timestamp(THD *thd, const MYSQL_TIME *ltime, uint *error_code); - const struct timeval &tv() const { return *this; } int cmp(const Timestamp &other) const { return tv_sec < other.tv_sec ? -1 : @@ -2934,7 +2933,7 @@ public: { return is_zero_datetime() ? Datetime::zero() : - Datetime(thd, Timestamp(*this).tv()); + Datetime(thd, Timestamp(*this)); } bool is_zero_datetime() const { diff --git a/sql/structs.h b/sql/structs.h index 3b2d4b58974..0546c5b23b7 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -1032,27 +1032,32 @@ public: }; -class Timeval: public timeval +class Timeval: public my_timeval { protected: Timeval() = default; public: Timeval(my_time_t sec, ulong usec) { - tv_sec= (time_t) sec; + tv_sec= (longlong) sec; /* Since tv_usec is not always of type ulong, cast usec parameter explicitly to uint to avoid compiler warnings about losing integer precision. */ DBUG_ASSERT(usec < 1000000); - tv_usec= (uint)usec; + tv_usec= usec; } - explicit Timeval(const timeval &tv) - :timeval(tv) - { } + explicit Timeval(const my_timeval &tv) + :my_timeval(tv) + {} }; +static inline void my_timeval_trunc(struct my_timeval *tv, uint decimals) +{ + tv->tv_usec-= (suseconds_t) my_time_fraction_remainder(tv->tv_usec, decimals); +} + /* A value that's either a Timeval or SQL NULL diff --git a/sql/table.cc b/sql/table.cc index fb11a81bc4e..3e3431f685e 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -10396,7 +10396,7 @@ void TR_table::store(uint field_id, ulonglong val) table->field[field_id]->set_notnull(); } -void TR_table::store(uint field_id, timeval ts) +void TR_table::store(uint field_id, my_timeval ts) { table->field[field_id]->store_timestamp(ts.tv_sec, ts.tv_usec); table->field[field_id]->set_notnull(); @@ -10416,7 +10416,7 @@ bool TR_table::update(ulonglong start_id, ulonglong end_id) store(FLD_BEGIN_TS, thd->transaction_time()); thd->set_time(); - timeval end_time= { (time_t) thd->query_start(), int(thd->query_start_sec_part())}; + my_timeval end_time= { thd->query_start(), thd->query_start_sec_part()}; store(FLD_TRX_ID, start_id); store(FLD_COMMIT_ID, end_id); store(FLD_COMMIT_TS, end_time); diff --git a/sql/table.h b/sql/table.h index c34ac17de4f..acb3eb1b0c4 100644 --- a/sql/table.h +++ b/sql/table.h @@ -3537,7 +3537,7 @@ public: @param[in] field number in a TABLE @param[in] value to store */ - void store(uint field_id, timeval ts); + void store(uint field_id, my_timeval ts); /** Update the transaction_registry right before commit. @param start_id transaction identifier at start diff --git a/sql/tztime.cc b/sql/tztime.cc index 03d0bbafc6c..830b7977099 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1075,7 +1075,7 @@ void Time_zone_system::gmt_sec_to_TIME(MYSQL_TIME *tmp, my_time_t t) const { struct tm tmp_tm; - time_t tmp_t= (time_t)t; + time_t tmp_t= (time_t) t; localtime_r(&tmp_t, &tmp_tm); localtime_to_TIME(tmp, &tmp_tm); diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp index 83661f96726..888a3d51bb0 100644 --- a/storage/mroonga/ha_mroonga.cpp +++ b/storage/mroonga/ha_mroonga.cpp @@ -11781,7 +11781,7 @@ int ha_mroonga::storage_encode_key_timestamp2(Field *field, const uchar *key, bool truncated = false; Field_timestampf *timestamp2_field = (Field_timestampf *)field; - struct timeval tm; + struct my_timeval tm; my_timestamp_from_binary(&tm, key, timestamp2_field->decimals()); MYSQL_TIME mysql_time; mrn_my_tz_UTC->gmt_sec_to_TIME(&mysql_time, (my_time_t)tm.tv_sec);