Skip to content

Commit 5a89046

Browse files
author
Alexander Barkov
committed
Merging WL#946 and WL#5885
2 parents c96f096 + f429adb commit 5a89046

File tree

188 files changed

+37448
-5590
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

188 files changed

+37448
-5590
lines changed

client/mysqlbinlog.cc

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -678,7 +678,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
678678
read them to be able to process the wanted events.
679679
*/
680680
if (((rec_count >= offset) &&
681-
((my_time_t)(ev->when) >= start_datetime)) ||
681+
((my_time_t) (ev->when.tv_sec) >= start_datetime)) ||
682682
(ev_type == FORMAT_DESCRIPTION_EVENT))
683683
{
684684
if (ev_type != FORMAT_DESCRIPTION_EVENT)
@@ -702,7 +702,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev,
702702
server_id && (server_id != ev->server_id))
703703
goto end;
704704
}
705-
if (((my_time_t)(ev->when) >= stop_datetime)
705+
if (((my_time_t) (ev->when.tv_sec) >= stop_datetime)
706706
|| (pos >= stop_position_mot))
707707
{
708708
/* end the program */
@@ -1292,13 +1292,13 @@ the mysql command line client.\n\n");
12921292

12931293
static my_time_t convert_str_to_timestamp(const char* str)
12941294
{
1295-
int was_cut;
1295+
MYSQL_TIME_STATUS status;
12961296
MYSQL_TIME l_time;
12971297
long dummy_my_timezone;
12981298
my_bool dummy_in_dst_time_gap;
12991299
/* We require a total specification (date AND time) */
1300-
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &was_cut) !=
1301-
MYSQL_TIMESTAMP_DATETIME || was_cut)
1300+
if (str_to_datetime(str, (uint) strlen(str), &l_time, 0, &status) ||
1301+
l_time.time_type != MYSQL_TIMESTAMP_DATETIME || status.warnings)
13021302
{
13031303
error("Incorrect date and time argument: %s", str);
13041304
exit(1);
@@ -1723,7 +1723,7 @@ static Exit_status dump_remote_log_entries(PRINT_EVENT_INFO *print_event_info,
17231723
}
17241724
}
17251725

1726-
if (rev->when == 0)
1726+
if (rev->when.tv_sec == 0)
17271727
{
17281728
if (!to_last_remote_log)
17291729
{

client/mysqltest.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7109,9 +7109,10 @@ void append_stmt_result(DYNAMIC_STRING *ds, MYSQL_STMT *stmt,
71097109
dynstr_append_mem(ds, "\n", 1);
71107110
}
71117111

7112-
if (mysql_stmt_fetch(stmt) != MYSQL_NO_DATA)
7113-
die("fetch didn't end with MYSQL_NO_DATA from statement: %d %s",
7114-
mysql_stmt_errno(stmt), mysql_stmt_error(stmt));
7112+
int rc;
7113+
if ((rc= mysql_stmt_fetch(stmt)) != MYSQL_NO_DATA)
7114+
die("fetch didn't end with MYSQL_NO_DATA from statement: %d: %s; rc=%d",
7115+
mysql_stmt_errno(stmt), mysql_stmt_error(stmt), rc);
71157116

71167117
for (i= 0; i < num_fields; i++)
71177118
{

include/decimal.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ int decimal_actual_fraction(decimal_t *from);
5151
int decimal2bin(decimal_t *from, uchar *to, int precision, int scale);
5252
int bin2decimal(const uchar *from, decimal_t *to, int precision, int scale);
5353

54+
/**
55+
Convert decimal to lldiv_t.
56+
The integer part is stored in to->quot.
57+
The fractional part is multiplied to 10^9 and stored to to->rem.
58+
@param from Decimal value
59+
@param to lldiv_t value
60+
@retval 0 on success
61+
@retval !0 in error
62+
*/
63+
int decimal2lldiv_t(const decimal_t *from, lldiv_t *to);
64+
65+
/**
66+
Convert doube to lldiv_t.
67+
The integer part is stored in to->quot.
68+
The fractional part is multiplied to 10^9 and stored to to->rem.
69+
@param from Decimal value
70+
@param to lldiv_t value
71+
@retval 0 on success
72+
@retval !0 in error
73+
*/
74+
75+
int double2lldiv_t(double from, lldiv_t *to);
5476
int decimal_size(int precision, int scale);
5577
int decimal_bin_size(int precision, int scale);
5678
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op,

include/my_global.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,5 +1480,12 @@ enum loglevel {
14801480
INFORMATION_LEVEL= 2
14811481
};
14821482

1483+
#ifdef _WIN32
1484+
typedef struct
1485+
{
1486+
long long int quot; /* Quotient. */
1487+
long long int rem; /* Remainder. */
1488+
} lldiv_t;
1489+
#endif
14831490

14841491
#endif // MY_GLOBAL_INCLUDED

include/my_time.h

Lines changed: 78 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ C_MODE_START
2727

2828
extern ulonglong log_10_int[20];
2929
extern uchar days_in_month[];
30+
extern const char my_zero_datetime6[]; /* "0000-00-00 00:00:00.000000" */
3031

3132
/*
3233
Portable time_t replacement.
@@ -41,6 +42,8 @@ typedef long my_time_t;
4142
#define MY_TIME_T_MAX LONG_MAX
4243
#define MY_TIME_T_MIN LONG_MIN
4344

45+
#define DATETIME_MAX_DECIMALS 6
46+
4447
/* Time handling defaults */
4548
#define TIMESTAMP_MAX_YEAR 2038
4649
#define TIMESTAMP_MIN_YEAR (1900 + YY_PART_YEAR - 1)
@@ -63,17 +66,27 @@ typedef long my_time_t;
6366
((x) >= TIMESTAMP_MIN_VALUE)
6467
#endif
6568

66-
/* Flags to str_to_datetime */
67-
#define TIME_FUZZY_DATE 1
68-
#define TIME_DATETIME_ONLY 2
69+
/* Flags to str_to_datetime and number_to_datetime */
70+
#define TIME_FUZZY_DATE 1
71+
#define TIME_DATETIME_ONLY 2
72+
#define TIME_NO_NSEC_ROUNDING 4
73+
#define TIME_NO_DATE_FRAC_WARN 8
74+
6975
/* Must be same as MODE_NO_ZERO_IN_DATE */
7076
#define TIME_NO_ZERO_IN_DATE (65536L*2*2*2*2*2*2*2)
7177
/* Must be same as MODE_NO_ZERO_DATE */
7278
#define TIME_NO_ZERO_DATE (TIME_NO_ZERO_IN_DATE*2)
7379
#define TIME_INVALID_DATES (TIME_NO_ZERO_DATE*2)
7480

75-
#define MYSQL_TIME_WARN_TRUNCATED 1
76-
#define MYSQL_TIME_WARN_OUT_OF_RANGE 2
81+
/* Conversion warnings */
82+
#define MYSQL_TIME_WARN_TRUNCATED 1
83+
#define MYSQL_TIME_WARN_OUT_OF_RANGE 2
84+
#define MYSQL_TIME_WARN_INVALID_TIMESTAMP 4
85+
#define MYSQL_TIME_WARN_ZERO_DATE 8
86+
#define MYSQL_TIME_NOTE_TRUNCATED 16
87+
88+
/* Usefull constants */
89+
#define SECONDS_IN_24H 86400L
7790

7891
/* Limits for the TIME data type */
7992
#define TIME_MAX_HOUR 838
@@ -84,23 +97,71 @@ typedef long my_time_t;
8497
#define TIME_MAX_VALUE_SECONDS (TIME_MAX_HOUR * 3600L + \
8598
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
8699

100+
/*
101+
Structure to return status from
102+
str_to_datetime(), str_to_time(), number_to_datetime(), number_to_time()
103+
*/
104+
typedef struct st_mysql_time_status
105+
{
106+
int warnings;
107+
uint fractional_digits;
108+
uint nanoseconds;
109+
} MYSQL_TIME_STATUS;
110+
111+
static inline void my_time_status_init(MYSQL_TIME_STATUS *status)
112+
{
113+
status->warnings= status->fractional_digits= status->nanoseconds= 0;
114+
}
115+
116+
87117
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
88118
ulonglong flags, int *was_cut);
89-
enum enum_mysql_timestamp_type
90-
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
91-
ulonglong flags, int *was_cut);
119+
my_bool str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
120+
ulonglong flags, MYSQL_TIME_STATUS *status);
92121
longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
93122
ulonglong flags, int *was_cut);
123+
my_bool number_to_time(longlong nr, MYSQL_TIME *ltime, int *warnings);
94124
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
95125
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
96126
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
97127
ulonglong TIME_to_ulonglong(const MYSQL_TIME *);
98128

129+
#define MY_PACKED_TIME_GET_INT_PART(x) ((x) >> 24)
130+
#define MY_PACKED_TIME_GET_FRAC_PART(x) ((x) % (1LL << 24))
131+
#define MY_PACKED_TIME_MAKE(i, f) ((((longlong) (i)) << 24) + (f))
132+
#define MY_PACKED_TIME_MAKE_INT(i) ((((longlong) (i)) << 24))
133+
134+
longlong year_to_longlong_datetime_packed(long year);
135+
longlong TIME_to_longlong_datetime_packed(const MYSQL_TIME *);
136+
longlong TIME_to_longlong_date_packed(const MYSQL_TIME *);
137+
longlong TIME_to_longlong_time_packed(const MYSQL_TIME *);
138+
longlong TIME_to_longlong_packed(const MYSQL_TIME *);
139+
140+
void TIME_from_longlong_datetime_packed(MYSQL_TIME *ltime, longlong nr);
141+
void TIME_from_longlong_time_packed(MYSQL_TIME *ltime, longlong nr);
142+
void TIME_from_longlong_date_packed(MYSQL_TIME *ltime, longlong nr);
143+
void TIME_set_yymmdd(MYSQL_TIME *ltime, uint yymmdd);
144+
void TIME_set_hhmmss(MYSQL_TIME *ltime, uint hhmmss);
145+
146+
void my_datetime_packed_to_binary(longlong nr, uchar *ptr, uint dec);
147+
longlong my_datetime_packed_from_binary(const uchar *ptr, uint dec);
148+
uint my_datetime_binary_length(uint dec);
149+
150+
void my_time_packed_to_binary(longlong nr, uchar *ptr, uint dec);
151+
longlong my_time_packed_from_binary(const uchar *ptr, uint dec);
152+
uint my_time_binary_length(uint dec);
153+
154+
void my_timestamp_to_binary(const struct timeval *tm, uchar *ptr, uint dec);
155+
void my_timestamp_from_binary(struct timeval *tm, const uchar *ptr, uint dec);
156+
uint my_timestamp_binary_length(uint dec);
99157

100158
my_bool str_to_time(const char *str,uint length, MYSQL_TIME *l_time,
101-
int *warning);
159+
MYSQL_TIME_STATUS *status);
102160

103-
int check_time_range(struct st_mysql_time *, int *warning);
161+
my_bool check_time_mmssff_range(const MYSQL_TIME *ltime);
162+
my_bool check_time_range_quick(const MYSQL_TIME *ltime);
163+
my_bool check_datetime_range(const MYSQL_TIME *ltime);
164+
void adjust_time_range(struct st_mysql_time *, int *warning);
104165

105166
long calc_daynr(uint year,uint month,uint day);
106167
uint calc_days_in_year(uint year);
@@ -137,6 +198,8 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone,
137198
my_bool *in_dst_time_gap);
138199

139200
void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
201+
void set_max_time(MYSQL_TIME *tm, my_bool neg);
202+
void set_max_hhmmss(MYSQL_TIME *tm);
140203

141204
/*
142205
Required buffer length for my_time_to_str, my_date_to_str,
@@ -148,10 +211,12 @@ void set_zero_time(MYSQL_TIME *tm, enum enum_mysql_timestamp_type time_type);
148211
*/
149212
#define MAX_DATE_STRING_REP_LENGTH 30
150213

151-
int my_time_to_str(const MYSQL_TIME *l_time, char *to);
214+
int my_time_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
152215
int my_date_to_str(const MYSQL_TIME *l_time, char *to);
153-
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to);
154-
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to);
216+
int my_datetime_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
217+
int my_TIME_to_str(const MYSQL_TIME *l_time, char *to, uint dec);
218+
219+
int my_timeval_to_str(const struct timeval *tm, char *to, uint dec);
155220

156221
/*
157222
Available interval types used in any statement.

include/mysql.h.pp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@
4949
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
5050
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
5151
MYSQL_TYPE_BIT,
52+
MYSQL_TYPE_TIMESTAMP2,
53+
MYSQL_TYPE_DATETIME2,
54+
MYSQL_TYPE_TIME2,
5255
MYSQL_TYPE_NEWDECIMAL=246,
5356
MYSQL_TYPE_ENUM=247,
5457
MYSQL_TYPE_SET=248,

include/mysql_com.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,9 @@ enum enum_field_types { MYSQL_TYPE_DECIMAL, MYSQL_TYPE_TINY,
346346
MYSQL_TYPE_DATETIME, MYSQL_TYPE_YEAR,
347347
MYSQL_TYPE_NEWDATE, MYSQL_TYPE_VARCHAR,
348348
MYSQL_TYPE_BIT,
349+
MYSQL_TYPE_TIMESTAMP2,
350+
MYSQL_TYPE_DATETIME2,
351+
MYSQL_TYPE_TIME2,
349352
MYSQL_TYPE_NEWDECIMAL=246,
350353
MYSQL_TYPE_ENUM=247,
351354
MYSQL_TYPE_SET=248,

include/mysql_time.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ enum enum_mysql_timestamp_type
4747
typedef struct st_mysql_time
4848
{
4949
unsigned int year, month, day, hour, minute, second;
50-
unsigned long second_part;
50+
unsigned long second_part; /**< microseconds */
5151
my_bool neg;
5252
enum enum_mysql_timestamp_type time_type;
5353
} MYSQL_TIME;

libmysql/libmysql.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3103,7 +3103,6 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31033103
uint length)
31043104
{
31053105
char *buffer= (char *)param->buffer;
3106-
int err= 0;
31073106
char *endptr= value + length;
31083107

31093108
/*
@@ -3115,6 +3114,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31153114
break;
31163115
case MYSQL_TYPE_TINY:
31173116
{
3117+
int err;
31183118
longlong data= my_strtoll10(value, &endptr, &err);
31193119
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
31203120
INT_MIN8, INT_MAX8, UINT_MAX8) || err > 0);
@@ -3123,6 +3123,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31233123
}
31243124
case MYSQL_TYPE_SHORT:
31253125
{
3126+
int err;
31263127
longlong data= my_strtoll10(value, &endptr, &err);
31273128
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
31283129
INT_MIN16, INT_MAX16, UINT_MAX16) || err > 0);
@@ -3131,6 +3132,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31313132
}
31323133
case MYSQL_TYPE_LONG:
31333134
{
3135+
int err;
31343136
longlong data= my_strtoll10(value, &endptr, &err);
31353137
*param->error= (IS_TRUNCATED(data, param->is_unsigned,
31363138
INT_MIN32, INT_MAX32, UINT_MAX32) || err > 0);
@@ -3139,6 +3141,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31393141
}
31403142
case MYSQL_TYPE_LONGLONG:
31413143
{
3144+
int err;
31423145
longlong data= my_strtoll10(value, &endptr, &err);
31433146
*param->error= param->is_unsigned ? err != 0 :
31443147
(err > 0 || (err == 0 && data < 0));
@@ -3147,6 +3150,7 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31473150
}
31483151
case MYSQL_TYPE_FLOAT:
31493152
{
3153+
int err;
31503154
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
31513155
float fdata= (float) data;
31523156
*param->error= (fdata != data) | test(err);
@@ -3155,26 +3159,30 @@ static void fetch_string_with_conversion(MYSQL_BIND *param, char *value,
31553159
}
31563160
case MYSQL_TYPE_DOUBLE:
31573161
{
3162+
int err;
31583163
double data= my_strntod(&my_charset_latin1, value, length, &endptr, &err);
31593164
*param->error= test(err);
31603165
doublestore(buffer, data);
31613166
break;
31623167
}
31633168
case MYSQL_TYPE_TIME:
31643169
{
3170+
MYSQL_TIME_STATUS status;
31653171
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3166-
str_to_time(value, length, tm, &err);
3167-
*param->error= test(err);
3172+
str_to_time(value, length, tm, &status);
3173+
*param->error= test(status.warnings);
31683174
break;
31693175
}
31703176
case MYSQL_TYPE_DATE:
31713177
case MYSQL_TYPE_DATETIME:
31723178
case MYSQL_TYPE_TIMESTAMP:
31733179
{
3180+
MYSQL_TIME_STATUS status;
31743181
MYSQL_TIME *tm= (MYSQL_TIME *)buffer;
3175-
(void) str_to_datetime(value, length, tm, TIME_FUZZY_DATE, &err);
3176-
*param->error= test(err) && (param->buffer_type == MYSQL_TYPE_DATE &&
3177-
tm->time_type != MYSQL_TIMESTAMP_DATE);
3182+
(void) str_to_datetime(value, length, tm, TIME_FUZZY_DATE, &status);
3183+
*param->error= test(status.warnings) &&
3184+
(param->buffer_type == MYSQL_TYPE_DATE &&
3185+
tm->time_type != MYSQL_TIMESTAMP_DATE);
31783186
break;
31793187
}
31803188
case MYSQL_TYPE_TINY_BLOB:
@@ -3501,7 +3509,7 @@ static void fetch_datetime_with_conversion(MYSQL_BIND *param,
35013509
fetch_string_with_conversion:
35023510
*/
35033511
char buff[MAX_DATE_STRING_REP_LENGTH];
3504-
uint length= my_TIME_to_str(my_time, buff);
3512+
uint length= my_TIME_to_str(my_time, buff, field->decimals);
35053513
/* Resort to string conversion */
35063514
fetch_string_with_conversion(param, (char *)buff, length);
35073515
break;
@@ -3978,7 +3986,7 @@ static my_bool setup_one_fetch_function(MYSQL_BIND *param, MYSQL_FIELD *field)
39783986
field->max_length= MAX_DOUBLE_STRING_REP_LENGTH;
39793987
break;
39803988
case MYSQL_TYPE_TIME:
3981-
field->max_length= 15; /* 19:23:48.123456 */
3989+
field->max_length= 17; /* -819:23:48.123456 */
39823990
param->skip_result= skip_result_with_length;
39833991
break;
39843992
case MYSQL_TYPE_DATE:

0 commit comments

Comments
 (0)