mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
Extends 64 bit windows to support timestamps up to year 2106.
MDEV-32188 make TIMESTAMP use whole 32-bit unsigned range This is done by changing my_time_t from long to unsigned long. The effect of this is that on windows compling old clients may get warnings of if they compare my_time_t with as signed variable. Other things - Removed my_time_t from include/*.pp files as it is different on windows and linux. - Changed do_abi_check.cmake to first print abi_check and then the conflicting file (this makes it easier to find the cause of the error).
This commit is contained in:
parent
dfdedd46e4
commit
b8ffd99cee
14 changed files with 60 additions and 46 deletions
|
@ -82,7 +82,7 @@ FOREACH(file ${ABI_HEADERS})
|
|||
EXECUTE_PROCESS(COMMAND mv -v ${abi_check_out} ${file}.pp)
|
||||
ELSE(ABI_UPDATE)
|
||||
MESSAGE(FATAL_ERROR
|
||||
"ABI check found difference between ${file}.pp and ${abi_check_out}")
|
||||
"ABI check found difference between ${abi_check_out} and ${file}.pp")
|
||||
ENDIF(ABI_UPDATE)
|
||||
ENDIF()
|
||||
FILE(REMOVE ${abi_check_out})
|
||||
|
|
|
@ -30,7 +30,8 @@ C_MODE_START
|
|||
extern MYSQL_PLUGIN_IMPORT ulonglong log_10_int[20];
|
||||
extern uchar days_in_month[];
|
||||
|
||||
#if SIZEOF_LONG == 4
|
||||
#if SIZEOF_VOIDP == 4
|
||||
/* 32 bit system, using old timestamp */
|
||||
#define MY_TIME_T_MAX LONG_MAX
|
||||
#define MY_TIME_T_MIN LONG_MIN
|
||||
#define TIMESTAMP_MAX_YEAR 2038
|
||||
|
@ -39,7 +40,7 @@ extern uchar days_in_month[];
|
|||
#define TIMESTAMP_MAX_VALUE INT_MAX32
|
||||
#define TIMESTAMP_MIN_VALUE 0
|
||||
#else
|
||||
/* Use 4 byte unsigned timestamp */
|
||||
/* 64 bit system. Use 4 byte unsigned timestamp */
|
||||
#define MY_TIME_T_MAX ((longlong) UINT_MAX32)
|
||||
#define MY_TIME_T_MIN 0
|
||||
#define TIMESTAMP_MAX_YEAR 2106
|
||||
|
@ -47,7 +48,7 @@ extern uchar days_in_month[];
|
|||
#define TIMESTAMP_MAX_VALUE ((longlong) UINT_MAX32)
|
||||
#define TIMESTAMP_MAX_MONTH 2
|
||||
#define TIMESTAMP_MAX_DAY 7
|
||||
#endif /* SIZEOF_LONG */
|
||||
#endif /* SIZEOF_VOIDP */
|
||||
|
||||
#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
|
||||
/* two-digit years < this are 20..; >= this are 19.. */
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -385,7 +385,6 @@ void thd_key_delete(MYSQL_THD_KEY_T *key);
|
|||
void* thd_getspecific(THD* thd, MYSQL_THD_KEY_T key);
|
||||
int thd_setspecific(THD* thd, MYSQL_THD_KEY_T key, void *value);
|
||||
}
|
||||
typedef long my_time_t;
|
||||
enum enum_mysql_timestamp_type
|
||||
{
|
||||
MYSQL_TIMESTAMP_NONE= -2, MYSQL_TIMESTAMP_ERROR= -1,
|
||||
|
|
|
@ -19,13 +19,26 @@
|
|||
|
||||
/*
|
||||
Portable time_t replacement.
|
||||
For 32 bit systems holds seconds for 1970 - 2038-01-19 range
|
||||
For 64 bit systems (where long is 64 bit) holds seconds for 1970 - 2106
|
||||
For 32 bit systems holds seconds for 1970 - 2038-01-19
|
||||
For 64 bit systems holds seconds for 1970 - 2106-02-07
|
||||
|
||||
Using the system built in time_t is not an option as
|
||||
we rely on the above requirements in the time functions
|
||||
*/
|
||||
|
||||
#ifndef MYSQL_ABI_CHECK
|
||||
/*
|
||||
long is 64bit on all 64bit systems, except Windows where it is 32 bit.
|
||||
long is 32bit on all 32bit systems.
|
||||
The following code ensures that my_time_t is 64 bit on all 64 bit
|
||||
systems.
|
||||
*/
|
||||
#ifdef _WIN64
|
||||
typedef long long my_time_t;
|
||||
#else
|
||||
typedef long my_time_t;
|
||||
#endif
|
||||
#endif /* MYSQL_ABI_CHECK */
|
||||
|
||||
/*
|
||||
Time declarations shared between the server and client API:
|
||||
|
|
|
@ -829,7 +829,7 @@ int Log_event_writer::write_footer()
|
|||
bool Log_event::write_header(Log_event_writer *writer, size_t event_data_length)
|
||||
{
|
||||
uchar header[LOG_EVENT_HEADER_LEN];
|
||||
ulong now;
|
||||
my_time_t now;
|
||||
DBUG_ENTER("Log_event::write_header");
|
||||
DBUG_PRINT("enter", ("filepos: %lld length: %zu type: %d",
|
||||
(longlong) writer->pos(), event_data_length,
|
||||
|
|
|
@ -784,7 +784,7 @@ void Timestamp::round_or_set_max(uint dec, int *warn)
|
|||
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_usec= TIME_MAX_SECOND_PART;
|
||||
*warn|= MYSQL_TIME_WARN_OUT_OF_RANGE;
|
||||
}
|
||||
|
|
|
@ -1039,7 +1039,7 @@ protected:
|
|||
public:
|
||||
Timeval(my_time_t sec, ulong usec)
|
||||
{
|
||||
tv_sec= sec;
|
||||
tv_sec= (time_t) sec;
|
||||
/*
|
||||
Since tv_usec is not always of type ulong, cast usec parameter
|
||||
explicitly to uint to avoid compiler warnings about losing
|
||||
|
|
|
@ -52,6 +52,13 @@
|
|||
#include <mysql/psi/mysql_file.h>
|
||||
#include "lock.h" // MYSQL_LOCK_IGNORE_FLUSH,
|
||||
// MYSQL_LOCK_IGNORE_TIMEOUT
|
||||
/*
|
||||
Internal server time. Needed to interface with my_time_t, which can
|
||||
be either long, ulong or long long depending on hardware or os.
|
||||
*/
|
||||
|
||||
typedef longlong my_int_time_t;
|
||||
|
||||
/* Structure describing local time type (e.g. Moscow summer time (MSD)) */
|
||||
typedef struct ttinfo
|
||||
{
|
||||
|
@ -67,7 +74,7 @@ typedef struct ttinfo
|
|||
/* Structure describing leap-second corrections. */
|
||||
typedef struct lsinfo
|
||||
{
|
||||
my_time_t ls_trans; // Transition time
|
||||
my_int_time_t ls_trans; // Transition time
|
||||
long ls_corr; // Correction to apply
|
||||
} LS_INFO;
|
||||
|
||||
|
@ -101,7 +108,7 @@ typedef struct st_time_zone_info
|
|||
uint charcnt; // Number of characters used for abbreviations
|
||||
uint revcnt; // Number of transition descr. for TIME->my_time_t conversion
|
||||
/* The following are dynamical arrays are allocated in MEM_ROOT */
|
||||
my_time_t *ats; // Times of transitions between time types
|
||||
my_int_time_t *ats; // Times of transitions between time types
|
||||
uchar *types; // Local time types for transitions
|
||||
TRAN_TYPE_INFO *ttis; // Local time types descriptions
|
||||
/* Storage for local time types abbreviations. They are stored as ASCIIZ */
|
||||
|
@ -116,7 +123,7 @@ typedef struct st_time_zone_info
|
|||
ranges on which shifted my_time_t -> my_time_t mapping is linear or undefined.
|
||||
Used for tm -> my_time_t conversion.
|
||||
*/
|
||||
my_time_t *revts;
|
||||
my_int_time_t *revts;
|
||||
REVT_INFO *revtis;
|
||||
/*
|
||||
Time type which is used for times smaller than first transition or if
|
||||
|
@ -159,7 +166,7 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
union
|
||||
{
|
||||
struct tzhead tzhead;
|
||||
uchar buf[sizeof(struct tzhead) + sizeof(my_time_t) * TZ_MAX_TIMES +
|
||||
uchar buf[sizeof(struct tzhead) + sizeof(my_int_time_t) * TZ_MAX_TIMES +
|
||||
TZ_MAX_TIMES + sizeof(TRAN_TYPE_INFO) * TZ_MAX_TYPES +
|
||||
MY_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1))) +
|
||||
sizeof(LS_INFO) * TZ_MAX_LEAPS];
|
||||
|
@ -210,8 +217,8 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
sp->leapcnt * sizeof(LS_INFO))))
|
||||
return 1;
|
||||
|
||||
sp->ats= (my_time_t *)tzinfo_buf;
|
||||
tzinfo_buf+= ALIGN_SIZE(sp->timecnt * sizeof(my_time_t));
|
||||
sp->ats= (my_int_time_t*) tzinfo_buf;
|
||||
tzinfo_buf+= ALIGN_SIZE(sp->timecnt * sizeof(sp->ats[0]));
|
||||
sp->types= (uchar *)tzinfo_buf;
|
||||
tzinfo_buf+= ALIGN_SIZE(sp->timecnt);
|
||||
sp->ttis= (TRAN_TYPE_INFO *)tzinfo_buf;
|
||||
|
@ -302,9 +309,9 @@ tz_load(const char *name, TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
static my_bool
|
||||
prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
||||
{
|
||||
my_time_t cur_t= MY_TIME_T_MIN;
|
||||
my_time_t cur_l, end_t, UNINIT_VAR(end_l);
|
||||
my_time_t cur_max_seen_l= MY_TIME_T_MIN;
|
||||
my_int_time_t cur_t= MY_TIME_T_MIN;
|
||||
my_int_time_t cur_l, end_t, UNINIT_VAR(end_l);
|
||||
my_int_time_t cur_max_seen_l= MY_TIME_T_MIN;
|
||||
long cur_offset, cur_corr, cur_off_and_corr;
|
||||
uint next_trans_idx, next_leap_idx;
|
||||
uint i;
|
||||
|
@ -313,7 +320,7 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
we don't know table sizes ahead. (Well we can estimate their
|
||||
upper bound but this will take extra space.)
|
||||
*/
|
||||
my_time_t revts[TZ_MAX_REV_RANGES];
|
||||
my_int_time_t revts[TZ_MAX_REV_RANGES];
|
||||
REVT_INFO revtis[TZ_MAX_REV_RANGES];
|
||||
|
||||
/*
|
||||
|
@ -472,15 +479,15 @@ prepare_tz_info(TIME_ZONE_INFO *sp, MEM_ROOT *storage)
|
|||
revts[sp->revcnt]= end_l;
|
||||
|
||||
/* Allocate arrays of proper size in sp and copy result there */
|
||||
if (!(sp->revts= (my_time_t *)alloc_root(storage,
|
||||
sizeof(*sp->revts) *
|
||||
(sp->revcnt + 1))) ||
|
||||
if (!(sp->revts= (my_int_time_t*) alloc_root(storage,
|
||||
sizeof(*sp->revts) *
|
||||
(sp->revcnt + 1))) ||
|
||||
!(sp->revtis= (REVT_INFO *)alloc_root(storage,
|
||||
sizeof(REVT_INFO) * sp->revcnt)))
|
||||
return 1;
|
||||
|
||||
memcpy(sp->revts, revts, sizeof(my_time_t) * (sp->revcnt + 1));
|
||||
memcpy(sp->revtis, revtis, sizeof(REVT_INFO) * sp->revcnt);
|
||||
memcpy(sp->revts, revts, sizeof(sp->revts[0]) * (sp->revcnt + 1));
|
||||
memcpy(sp->revtis, revtis, sizeof(sp->revtis[0]) * sp->revcnt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -610,7 +617,7 @@ sec_to_TIME(MYSQL_TIME * tmp, my_time_t t, long offset)
|
|||
Index of range to which t belongs
|
||||
*/
|
||||
static uint
|
||||
find_time_range(my_time_t t, const my_time_t *range_boundaries,
|
||||
find_time_range(my_int_time_t t, const my_int_time_t *range_boundaries,
|
||||
uint higher_bound)
|
||||
{
|
||||
uint i, lower_bound= 0;
|
||||
|
@ -875,7 +882,7 @@ sec_since_epoch(int year, int mon, int mday, int hour, int min ,int sec)
|
|||
static my_time_t
|
||||
TIME_to_gmt_sec(const MYSQL_TIME *t, const TIME_ZONE_INFO *sp, uint *error_code)
|
||||
{
|
||||
longlong local_t;
|
||||
my_int_time_t local_t;
|
||||
uint saved_seconds;
|
||||
uint i;
|
||||
int shift= 0;
|
||||
|
@ -1375,7 +1382,7 @@ Time_zone_offset::Time_zone_offset(long tz_offset_arg):
|
|||
my_time_t
|
||||
Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
|
||||
{
|
||||
my_time_t local_t;
|
||||
my_int_time_t local_t;
|
||||
int shift= 0;
|
||||
|
||||
/*
|
||||
|
@ -1408,7 +1415,7 @@ Time_zone_offset::TIME_to_gmt_sec(const MYSQL_TIME *t, uint *error_code) const
|
|||
}
|
||||
|
||||
if (local_t >= TIMESTAMP_MIN_VALUE && local_t <= TIMESTAMP_MAX_VALUE)
|
||||
return local_t;
|
||||
return (my_time_t) local_t;
|
||||
|
||||
/* range error*/
|
||||
*error_code= ER_WARN_DATA_OUT_OF_RANGE;
|
||||
|
@ -1880,7 +1887,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||
Time_zone *return_val= 0;
|
||||
int res;
|
||||
uint tzid, ttid;
|
||||
my_time_t ttime;
|
||||
my_int_time_t ttime;
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
uchar keybuff[32];
|
||||
Field *field;
|
||||
|
@ -1891,7 +1898,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||
Temporary arrays that are used for loading of data for filling
|
||||
TIME_ZONE_INFO structure
|
||||
*/
|
||||
my_time_t ats[TZ_MAX_TIMES];
|
||||
my_int_time_t ats[TZ_MAX_TIMES];
|
||||
uchar types[TZ_MAX_TIMES];
|
||||
TRAN_TYPE_INFO ttis[TZ_MAX_TYPES];
|
||||
char chars[MY_MAX(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))];
|
||||
|
@ -2056,7 +2063,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||
(key_part_map)1, HA_READ_KEY_EXACT);
|
||||
while (!res)
|
||||
{
|
||||
ttime= (my_time_t)table->field[1]->val_int();
|
||||
ttime= (my_int_time_t) table->field[1]->val_int();
|
||||
ttid= (uint)table->field[2]->val_int();
|
||||
|
||||
if (tmp_tz_info.timecnt + 1 > TZ_MAX_TIMES)
|
||||
|
@ -2131,7 +2138,7 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||
Now we will allocate memory and init TIME_ZONE_INFO structure.
|
||||
*/
|
||||
if (!(alloc_buff= (char*) alloc_root(&tz_storage,
|
||||
ALIGN_SIZE(sizeof(my_time_t) *
|
||||
ALIGN_SIZE(sizeof(my_int_time_t) *
|
||||
tz_info->timecnt) +
|
||||
ALIGN_SIZE(tz_info->timecnt) +
|
||||
ALIGN_SIZE(tz_info->charcnt) +
|
||||
|
@ -2142,9 +2149,9 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables)
|
|||
goto end;
|
||||
}
|
||||
|
||||
tz_info->ats= (my_time_t *) alloc_buff;
|
||||
memcpy(tz_info->ats, ats, tz_info->timecnt * sizeof(my_time_t));
|
||||
alloc_buff+= ALIGN_SIZE(sizeof(my_time_t) * tz_info->timecnt);
|
||||
tz_info->ats= (my_int_time_t *) alloc_buff;
|
||||
memcpy(tz_info->ats, ats, tz_info->timecnt * sizeof(tz_info->ats[0]));
|
||||
alloc_buff+= ALIGN_SIZE(sizeof(tz_info->ats[0]) * tz_info->timecnt);
|
||||
tz_info->types= (uchar *)alloc_buff;
|
||||
memcpy(tz_info->types, types, tz_info->timecnt);
|
||||
alloc_buff+= ALIGN_SIZE(tz_info->timecnt);
|
||||
|
@ -2482,8 +2489,8 @@ print_tz_as_sql(const char* tz_name, const TIME_ZONE_INFO *sp)
|
|||
printf("INSERT INTO time_zone_transition \
|
||||
(Time_zone_id, Transition_time, Transition_type_id) VALUES\n");
|
||||
for (i= 0; i < sp->timecnt; i++)
|
||||
printf("%s(@time_zone_id, %ld, %u)\n", (i == 0 ? " " : ","), sp->ats[i],
|
||||
(uint)sp->types[i]);
|
||||
printf("%s(@time_zone_id, %lld, %u)\n", (i == 0 ? " " : ","),
|
||||
(longlong) sp->ats[i], (uint)sp->types[i]);
|
||||
printf(";\n");
|
||||
}
|
||||
|
||||
|
@ -2534,8 +2541,8 @@ print_tz_leaps_as_sql(const TIME_ZONE_INFO *sp)
|
|||
printf("INSERT INTO time_zone_leap_second \
|
||||
(Transition_time, Correction) VALUES\n");
|
||||
for (i= 0; i < sp->leapcnt; i++)
|
||||
printf("%s(%ld, %ld)\n", (i == 0 ? " " : ","),
|
||||
sp->lsis[i].ls_trans, sp->lsis[i].ls_corr);
|
||||
printf("%s(%lld, %ld)\n", (i == 0 ? " " : ","),
|
||||
(longlong) sp->lsis[i].ls_trans, sp->lsis[i].ls_corr);
|
||||
printf(";\n");
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue