summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc94
1 files changed, 56 insertions, 38 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 651fb4ce5b1..3ea6be95dda 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -101,16 +101,11 @@ TYPELIB binlog_checksum_typelib=
TODO: correct the constant when it has been determined
(which main tree to push and when)
*/
-const uchar checksum_version_split_mysql[3]= {5, 6, 1};
-const ulong checksum_version_product_mysql=
- (checksum_version_split_mysql[0] * 256 +
- checksum_version_split_mysql[1]) * 256 +
- checksum_version_split_mysql[2];
-const uchar checksum_version_split_mariadb[3]= {5, 3, 0};
-const ulong checksum_version_product_mariadb=
- (checksum_version_split_mariadb[0] * 256 +
- checksum_version_split_mariadb[1]) * 256 +
- checksum_version_split_mariadb[2];
+const Version checksum_version_split_mysql(5, 6, 1);
+const Version checksum_version_split_mariadb(5, 3, 0);
+
+// First MySQL version with fraction seconds
+const Version fsp_version_split_mysql(5, 6, 0);
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD* thd);
@@ -4541,6 +4536,7 @@ code_name(int code)
}
#endif
+
/**
Macro to check that there is enough space to read from memory.
@@ -4764,6 +4760,30 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
}
}
+#if !defined(MYSQL_CLIENT)
+ if (description_event->server_version_split.kind ==
+ Format_description_log_event::master_version_split::KIND_MYSQL)
+ {
+ // Handle MariaDB/MySQL incompatible sql_mode bits
+ sql_mode_t mysql_sql_mode= sql_mode;
+ sql_mode&= MODE_MASK_MYSQL_COMPATIBLE; // Unset MySQL specific bits
+
+ /*
+ sql_mode flags related to fraction second rounding/truncation
+ have opposite meaning in MySQL vs MariaDB.
+ MySQL:
+ - rounds fractional seconds by default
+ - truncates if TIME_TRUNCATE_FRACTIONAL is set
+ MariaDB:
+ - truncates fractional seconds by default
+ - rounds if TIME_ROUND_FRACTIONAL is set
+ */
+ if (description_event->server_version_split >= fsp_version_split_mysql &&
+ !(mysql_sql_mode & MODE_MYSQL80_TIME_TRUNCATE_FRACTIONAL))
+ sql_mode|= MODE_TIME_ROUND_FRACTIONAL;
+ }
+#endif
+
/**
Layout for the data buffer is as follows
+--------+-----------+------+------+---------+----+-------+
@@ -5581,7 +5601,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi,
gtid= rgi->current_gtid;
if (unlikely(rpl_global_gtid_slave_state->record_gtid(thd, &gtid,
sub_id,
- rgi, false,
+ true, false,
&hton)))
{
int errcode= thd->get_stmt_da()->sql_errno();
@@ -6549,26 +6569,24 @@ bool Format_description_log_event::start_decryption(Start_encryption_log_event*
return crypto_data.init(sele->crypto_scheme, sele->key_version);
}
-static inline void
-do_server_version_split(char* version,
- Format_description_log_event::master_version_split *split_versions)
+
+Version::Version(const char *version, const char **endptr)
{
- char *p= version, *r;
+ const char *p= version;
ulong number;
for (uint i= 0; i<=2; i++)
{
+ char *r;
number= strtoul(p, &r, 10);
/*
It is an invalid version if any version number greater than 255 or
first number is not followed by '.'.
*/
if (number < 256 && (*r == '.' || i != 0))
- split_versions->ver[i]= (uchar) number;
+ m_ver[i]= (uchar) number;
else
{
- split_versions->ver[0]= 0;
- split_versions->ver[1]= 0;
- split_versions->ver[2]= 0;
+ *this= Version();
break;
}
@@ -6576,12 +6594,19 @@ do_server_version_split(char* version,
if (*r == '.')
p++; // skip the dot
}
+ endptr[0]= p;
+}
+
+
+Format_description_log_event::
+ master_version_split::master_version_split(const char *version)
+{
+ const char *p;
+ static_cast<Version*>(this)[0]= Version(version, &p);
if (strstr(p, "MariaDB") != 0 || strstr(p, "-maria-") != 0)
- split_versions->kind=
- Format_description_log_event::master_version_split::KIND_MARIADB;
+ kind= KIND_MARIADB;
else
- split_versions->kind=
- Format_description_log_event::master_version_split::KIND_MYSQL;
+ kind= KIND_MYSQL;
}
@@ -6595,20 +6620,14 @@ do_server_version_split(char* version,
*/
void Format_description_log_event::calc_server_version_split()
{
- do_server_version_split(server_version, &server_version_split);
+ server_version_split= master_version_split(server_version);
DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
" '%s' %d %d %d", server_version,
- server_version_split.ver[0],
- server_version_split.ver[1], server_version_split.ver[2]));
+ server_version_split[0],
+ server_version_split[1], server_version_split[2]));
}
-static inline ulong
-version_product(const Format_description_log_event::master_version_split* version_split)
-{
- return ((version_split->ver[0] * 256 + version_split->ver[1]) * 256
- + version_split->ver[2]);
-}
/**
@return TRUE is the event's version is earlier than one that introduced
@@ -6618,9 +6637,9 @@ bool
Format_description_log_event::is_version_before_checksum(const master_version_split
*version_split)
{
- return version_product(version_split) <
+ return *version_split <
(version_split->kind == master_version_split::KIND_MARIADB ?
- checksum_version_product_mariadb : checksum_version_product_mysql);
+ checksum_version_split_mariadb : checksum_version_split_mysql);
}
/**
@@ -6636,7 +6655,6 @@ enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
{
enum enum_binlog_checksum_alg ret;
char version[ST_SERVER_VER_LEN];
- Format_description_log_event::master_version_split version_split;
DBUG_ENTER("get_checksum_alg");
DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
@@ -6646,7 +6664,7 @@ enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
ST_SERVER_VER_LEN);
version[ST_SERVER_VER_LEN - 1]= 0;
- do_server_version_split(version, &version_split);
+ Format_description_log_event::master_version_split version_split(version);
ret= Format_description_log_event::is_version_before_checksum(&version_split)
? BINLOG_CHECKSUM_ALG_UNDEF
: (enum_binlog_checksum_alg)buf[len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN];
@@ -8378,7 +8396,7 @@ Gtid_list_log_event::do_apply_event(rpl_group_info *rgi)
{
if ((ret= rpl_global_gtid_slave_state->record_gtid(thd, &list[i],
sub_id_list[i],
- NULL, false, &hton)))
+ false, false, &hton)))
return ret;
rpl_global_gtid_slave_state->update_state_hash(sub_id_list[i], &list[i],
hton, NULL);
@@ -8915,7 +8933,7 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
rgi->gtid_pending= false;
gtid= rgi->current_gtid;
- err= rpl_global_gtid_slave_state->record_gtid(thd, &gtid, sub_id, rgi,
+ err= rpl_global_gtid_slave_state->record_gtid(thd, &gtid, sub_id, true,
false, &hton);
if (unlikely(err))
{