aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/libmysql_r/libbinlogevents
diff options
context:
space:
mode:
authorhcpp <hcpp@ydb.tech>2023-11-08 12:09:41 +0300
committerhcpp <hcpp@ydb.tech>2023-11-08 12:56:14 +0300
commita361f5b98b98b44ea510d274f6769164640dd5e1 (patch)
treec47c80962c6e2e7b06798238752fd3da0191a3f6 /contrib/libs/libmysql_r/libbinlogevents
parent9478806fde1f4d40bd5a45e7cbe77237dab613e9 (diff)
downloadydb-a361f5b98b98b44ea510d274f6769164640dd5e1.tar.gz
metrics have been added
Diffstat (limited to 'contrib/libs/libmysql_r/libbinlogevents')
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-linux.h34
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-osx.h34
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-win.h34
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/binlog_config.h13
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/binlog_event.h940
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/byteorder.h121
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/control_events.h1292
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/debug_vars.h43
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/event_reader.h535
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/load_data_events.h396
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/rows_event.h1165
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/statement_events.h1074
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/table_id.h74
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/uuid.h173
-rw-r--r--contrib/libs/libmysql_r/libbinlogevents/include/wrapper_functions.h193
15 files changed, 6121 insertions, 0 deletions
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-linux.h b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-linux.h
new file mode 100644
index 0000000000..f490623d4e
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-linux.h
@@ -0,0 +1,34 @@
+/**
+ Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef BAPI_CONFIG_INCLUDED
+#define BAPI_CONFIG_INCLUDED
+/* Symbols we may use */
+/* #undef IS_BIG_ENDIAN */
+#define HAVE_LE64TOH 1
+#define HAVE_LE32TOH 1
+#define HAVE_LE16TOH 1
+#define HAVE_STRNDUP 1
+#define HAVE_ENDIAN_CONVERSION_MACROS 1
+
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-osx.h b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-osx.h
new file mode 100644
index 0000000000..d6aea3ef00
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-osx.h
@@ -0,0 +1,34 @@
+/**
+ Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef BAPI_CONFIG_INCLUDED
+#define BAPI_CONFIG_INCLUDED
+/* Symbols we may use */
+/* #undef IS_BIG_ENDIAN */
+/* #undef HAVE_LE64TOH */
+/* #undef HAVE_LE32TOH */
+/* #undef HAVE_LE16TOH */
+#define HAVE_STRNDUP 1
+/* #undef HAVE_ENDIAN_CONVERSION_MACROS */
+
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-win.h b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-win.h
new file mode 100644
index 0000000000..346f370ebd
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config-win.h
@@ -0,0 +1,34 @@
+/**
+ Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef BAPI_CONFIG_INCLUDED
+#define BAPI_CONFIG_INCLUDED
+/* Symbols we may use */
+/* #undef IS_BIG_ENDIAN */
+/* #undef HAVE_LE64TOH */
+/* #undef HAVE_LE32TOH */
+/* #undef HAVE_LE16TOH */
+/* #undef HAVE_STRNDUP */
+/* #undef HAVE_ENDIAN_CONVERSION_MACROS */
+
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config.h b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config.h
new file mode 100644
index 0000000000..eef995ed74
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_config.h
@@ -0,0 +1,13 @@
+#pragma once
+
+#if defined(__linux__)
+#include "binlog_config-linux.h"
+#endif
+
+#if defined(__APPLE__)
+#include "binlog_config-osx.h"
+#endif
+
+#if defined(_MSC_VER)
+#include "binlog_config-win.h"
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/binlog_event.h b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_event.h
new file mode 100644
index 0000000000..e14a08ef3d
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/binlog_event.h
@@ -0,0 +1,940 @@
+/* Copyright (c) 2011, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file binlog_event.h
+
+ @brief Contains the classes representing events occurring in the replication
+ stream. Each event is represented as a byte sequence with logical divisions
+ as event header, event specific data and event footer. The header and footer
+ are common to all the events and are represented as two different subclasses.
+*/
+
+#ifndef BINLOG_EVENT_INCLUDED
+#define BINLOG_EVENT_INCLUDED
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <zlib.h> //for checksum calculations
+#include <climits>
+#include <cstdio>
+#include <iostream>
+
+#include "debug_vars.h"
+#include "event_reader.h"
+#include "my_io.h"
+
+#if defined(_WIN32)
+#include <Winsock2.h>
+#else
+#include <sys/times.h>
+#endif
+/*
+ The symbols below are a part of the common definitions between
+ the MySQL server and the client. Since they should not be a part of
+ this library but the server, these should be placed in a header file
+ common to the library and the MySQL server code, so that if they are
+ updated in the server code, it is reflected in the libbinlogevent also.
+
+ TODO(WL#7984): Moving the binlog constant in library libbinlogevents into a
+ separate file and make them const variables
+*/
+#ifndef SYSTEM_CHARSET_MBMAXLEN
+#define SYSTEM_CHARSET_MBMAXLEN 3
+#endif
+#ifndef NAME_CHAR_LEN
+#define NAME_CHAR_LEN 64 /* Field/table name length */
+#endif
+#ifndef NAME_LEN
+#define NAME_LEN (NAME_CHAR_LEN * SYSTEM_CHARSET_MBMAXLEN)
+#endif
+/* Length of the server_version_split array in FDE class */
+#ifndef ST_SERVER_VER_SPLIT_LEN
+#define ST_SERVER_VER_SPLIT_LEN 3
+#endif
+
+/*
+ Do not decrease the value of BIN_LOG_HEADER_SIZE.
+ Do not even increase it before checking code.
+*/
+#ifndef BIN_LOG_HEADER_SIZE
+#define BIN_LOG_HEADER_SIZE 4U
+#endif
+
+/**
+ binlog_version 3 is MySQL 4.x; 4 is MySQL 5.0.0.
+ Compared to version 3, version 4 has:
+ - a different Start_event, which includes info about the binary log
+ (sizes of headers); this info is included for better compatibility if the
+ master's MySQL version is different from the slave's.
+*/
+#define BINLOG_VERSION 4
+
+/*
+ Constants used by Query_event.
+*/
+
+/**
+ The maximum number of updated databases that a status of
+ Query-log-event can carry. It can be redefined within a range
+ [1.. OVER_MAX_DBS_IN_EVENT_MTS].
+*/
+#define MAX_DBS_IN_EVENT_MTS 16
+
+/**
+ When the actual number of databases exceeds MAX_DBS_IN_EVENT_MTS
+ the value of OVER_MAX_DBS_IN_EVENT_MTS is is put into the
+ mts_accessed_dbs status.
+*/
+#define OVER_MAX_DBS_IN_EVENT_MTS 254
+
+/**
+ Max number of possible extra bytes in a replication event compared to a
+ packet (i.e. a query) sent from client to master;
+ First, an auxiliary log_event status vars estimation:
+*/
+#define MAX_SIZE_LOG_EVENT_STATUS \
+ (1U + 4 /* type, flags2 */ + 1U + 8 /* type, sql_mode */ + 1U + 1 + \
+ 255 /* type, length, catalog */ + 1U + 4 /* type, auto_increment */ + 1U + \
+ 6 /* type, charset */ + 1U + 1 + 255 /* type, length, time_zone */ + 1U + \
+ 2 /* type, lc_time_names_number */ + 1U + \
+ 2 /* type, charset_database_number */ + 1U + \
+ 8 /* type, table_map_for_update */ + 1U + \
+ 4 /* type, master_data_written */ + /* type, db_1, db_2, ... */ \
+ 1U + (MAX_DBS_IN_EVENT_MTS * (1 + NAME_LEN)) + 3U + \
+ /* type, microseconds */ +1U + 32 * 3 + /* type, user_len, user */ \
+ 1 + 255 /* host_len, host */ + 1U + 1 /* type, explicit_def..ts*/ + 1U + \
+ 8 /* type, xid of DDL */ + 1U + \
+ 2 /* type, default_collation_for_utf8mb4_number */ + \
+ 1 /* sql_require_primary_key */ + 1 /* type, default_table_encryption */)
+
+/**
+ Uninitialized timestamp value (for either last committed or sequence number).
+ Often carries meaning of the minimum value in the logical timestamp domain.
+*/
+const int64_t SEQ_UNINIT = 0;
+
+/** We use 7 bytes, 1 bit being used as a flag. */
+#define MAX_COMMIT_TIMESTAMP_VALUE (1ULL << 55)
+/**
+ Used to determine whether the original_commit_timestamp is already known or if
+ it still needs to be determined when computing it.
+*/
+const int64_t UNDEFINED_COMMIT_TIMESTAMP = MAX_COMMIT_TIMESTAMP_VALUE;
+
+const uint32_t UNDEFINED_SERVER_VERSION = 999999;
+const uint32_t UNKNOWN_SERVER_VERSION = 0;
+
+/** Setting this flag will mark an event as Ignorable */
+#define LOG_EVENT_IGNORABLE_F 0x80
+
+/**
+ In case the variable is updated,
+ make sure to update it in $MYSQL_SOURCE_DIR/my_io.h.
+*/
+#ifndef FN_REFLEN
+#define FN_REFLEN 512 /* Max length of full path-name */
+#endif
+
+/**
+ Splits server 'version' string into three numeric pieces stored
+ into 'split_versions':
+ X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
+ X.Yabc -> {X,Y,0}
+
+ @param version String representing server version
+ @param split_versions Array with each element containing one split of the
+ input version string
+*/
+inline void do_server_version_split(const char *version,
+ unsigned char split_versions[3]) {
+ const char *p = version;
+ char *r;
+ unsigned long number;
+ for (unsigned int i = 0; i <= 2; i++) {
+ 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[i] = static_cast<unsigned char>(number);
+ else {
+ split_versions[0] = 0;
+ split_versions[1] = 0;
+ split_versions[2] = 0;
+ break;
+ }
+
+ p = r;
+ if (*r == '.') p++; // skip the dot
+ }
+}
+
+/**
+ Transforms the server version from 'XX.YY.ZZ-suffix' into an integer in the
+ format XXYYZZ.
+
+ @param version String representing server version
+ @return The server version in the format XXYYZZ
+*/
+inline uint32_t do_server_version_int(const char *version) {
+ unsigned char version_split[3];
+ do_server_version_split(version, version_split);
+ uint32_t ret = static_cast<uint32_t>(version_split[0]) * 10000 +
+ static_cast<uint32_t>(version_split[1]) * 100 +
+ static_cast<uint32_t>(version_split[2]);
+ return ret;
+}
+
+/**
+ Calculate the version product from the numeric pieces representing the server
+ version:
+ For a server version X.Y.Zabc (X,Y,Z numbers, a not a digit), the input is
+ {X,Y,Z}. This is converted to XYZ in bit representation.
+
+ @param version_split Array containing the version information of the server
+ @return The version product of the server
+*/
+inline unsigned long version_product(const unsigned char *version_split) {
+ return ((version_split[0] * 256 + version_split[1]) * 256 + version_split[2]);
+}
+
+/**
+ Replication event checksum is introduced in the following "checksum-home"
+ version. The checksum-aware servers extract FD's version to decide whether
+ the FD event carries checksum info.
+*/
+extern const unsigned char checksum_version_split[3];
+extern const unsigned long checksum_version_product;
+/**
+ @namespace binary_log
+
+ The namespace contains classes representing events that can occur in a
+ replication stream.
+*/
+namespace binary_log {
+/*
+ This flag only makes sense for Format_description_event. It is set
+ when the event is written, and *reset* when a binlog file is
+ closed (yes, it's the only case when MySQL modifies an already written
+ part of the binlog). Thus it is a reliable indicator that the binlog was
+ closed correctly. (Stop_event is not enough, there's always a
+ small chance that mysqld crashes in the middle of insert and end of
+ the binlog would look like a Stop_event).
+
+ This flag is used to detect a restart after a crash, and to provide
+ "unbreakable" binlog. The problem is that on a crash storage engines
+ rollback automatically, while binlog does not. To solve this we use this
+ flag and automatically append ROLLBACK to every non-closed binlog (append
+ virtually, on reading, file itself is not changed). If this flag is found,
+ mysqlbinlog simply prints "ROLLBACK". Replication master does not abort on
+ binlog corruption, but takes it as EOF, and replication slave forces a
+ rollback in this case.
+
+ Note, that old binlogs does not have this flag set, so we get a
+ a backward-compatible behaviour.
+*/
+#define LOG_EVENT_BINLOG_IN_USE_F 0x1
+
+/**
+ Enumeration type for the different types of log events.
+*/
+enum Log_event_type {
+ /**
+ Every time you add a type, you have to
+ - Assign it a number explicitly. Otherwise it will cause trouble
+ if a event type before is deprecated and removed directly from
+ the enum.
+ - Fix Format_description_event::Format_description_event().
+ */
+ UNKNOWN_EVENT = 0,
+ /*
+ Deprecated since mysql 8.0.2. It is just a placeholder,
+ should not be used anywhere else.
+ */
+ START_EVENT_V3 = 1,
+ QUERY_EVENT = 2,
+ STOP_EVENT = 3,
+ ROTATE_EVENT = 4,
+ INTVAR_EVENT = 5,
+
+ SLAVE_EVENT = 7,
+
+ APPEND_BLOCK_EVENT = 9,
+ DELETE_FILE_EVENT = 11,
+
+ RAND_EVENT = 13,
+ USER_VAR_EVENT = 14,
+ FORMAT_DESCRIPTION_EVENT = 15,
+ XID_EVENT = 16,
+ BEGIN_LOAD_QUERY_EVENT = 17,
+ EXECUTE_LOAD_QUERY_EVENT = 18,
+
+ TABLE_MAP_EVENT = 19,
+
+ /**
+ The V1 event numbers are used from 5.1.16 until mysql-5.6.
+ */
+ WRITE_ROWS_EVENT_V1 = 23,
+ UPDATE_ROWS_EVENT_V1 = 24,
+ DELETE_ROWS_EVENT_V1 = 25,
+
+ /**
+ Something out of the ordinary happened on the master
+ */
+ INCIDENT_EVENT = 26,
+
+ /**
+ Heartbeat event to be send by master at its idle time
+ to ensure master's online status to slave
+ */
+ HEARTBEAT_LOG_EVENT = 27,
+
+ /**
+ In some situations, it is necessary to send over ignorable
+ data to the slave: data that a slave can handle in case there
+ is code for handling it, but which can be ignored if it is not
+ recognized.
+ */
+ IGNORABLE_LOG_EVENT = 28,
+ ROWS_QUERY_LOG_EVENT = 29,
+
+ /** Version 2 of the Row events */
+ WRITE_ROWS_EVENT = 30,
+ UPDATE_ROWS_EVENT = 31,
+ DELETE_ROWS_EVENT = 32,
+
+ GTID_LOG_EVENT = 33,
+ ANONYMOUS_GTID_LOG_EVENT = 34,
+
+ PREVIOUS_GTIDS_LOG_EVENT = 35,
+
+ TRANSACTION_CONTEXT_EVENT = 36,
+
+ VIEW_CHANGE_EVENT = 37,
+
+ /* Prepared XA transaction terminal event similar to Xid */
+ XA_PREPARE_LOG_EVENT = 38,
+
+ /**
+ Extension of UPDATE_ROWS_EVENT, allowing partial values according
+ to binlog_row_value_options.
+ */
+ PARTIAL_UPDATE_ROWS_EVENT = 39,
+
+ /**
+ Add new events here - right above this comment!
+ Existing events (except ENUM_END_EVENT) should never change their numbers
+ */
+ ENUM_END_EVENT /* end marker */
+};
+
+/**
+ The length of the array server_version, which is used to store the version
+ of MySQL server.
+ We could have used SERVER_VERSION_LENGTH, but this introduces an
+ obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
+ this would break the replication protocol
+ both of these are used to initialize the array server_version
+ SERVER_VERSION_LENGTH is used for global array server_version
+ and ST_SERVER_VER_LEN for the Start_event_v3 member server_version
+*/
+
+#define ST_SERVER_VER_LEN 50
+
+/*
+ Event header offsets;
+ these point to places inside the fixed header.
+*/
+#define EVENT_TYPE_OFFSET 4
+#define SERVER_ID_OFFSET 5
+#define EVENT_LEN_OFFSET 9
+#define LOG_POS_OFFSET 13
+#define FLAGS_OFFSET 17
+
+/** start event post-header (for v3 and v4) */
+#define ST_BINLOG_VER_OFFSET 0
+#define ST_SERVER_VER_OFFSET 2
+#define ST_CREATED_OFFSET (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
+#define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4)
+
+#define LOG_EVENT_HEADER_LEN 19U /* the fixed header length */
+
+/**
+ Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer
+ header (it will for sure when we have the unique event's ID), but at least
+ the first 19 bytes are the same in 4.x and 5.0. So when we have the unique
+ event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but
+ LOG_EVENT_MINIMAL_HEADER_LEN will remain 19.
+*/
+#define LOG_EVENT_MINIMAL_HEADER_LEN 19U
+
+/**
+ Enumeration spcifying checksum algorithm used to encode a binary log event
+*/
+enum enum_binlog_checksum_alg {
+ /**
+ Events are without checksum though its generator is checksum-capable
+ New Master (NM).
+ */
+ BINLOG_CHECKSUM_ALG_OFF = 0,
+ /** CRC32 of zlib algorithm */
+ BINLOG_CHECKSUM_ALG_CRC32 = 1,
+ /** the cut line: valid alg range is [1, 0x7f] */
+ BINLOG_CHECKSUM_ALG_ENUM_END,
+ /**
+ Special value to tag undetermined yet checksum or events from
+ checksum-unaware servers
+ */
+ BINLOG_CHECKSUM_ALG_UNDEF = 255
+};
+
+#define CHECKSUM_CRC32_SIGNATURE_LEN 4
+
+/**
+ defined statically while there is just one alg implemented
+*/
+#define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
+#define BINLOG_CHECKSUM_ALG_DESC_LEN 1 /* 1 byte checksum alg descriptor */
+#define LOG_EVENT_HEADER_SIZE 20
+
+/**
+ Calculate a long checksum for a memoryblock.
+
+ @param crc start value for crc
+ @param pos pointer to memory block
+ @param length length of the block
+
+ @return checksum for a memory block
+*/
+inline uint32_t checksum_crc32(uint32_t crc, const unsigned char *pos,
+ size_t length) {
+ BAPI_ASSERT(length <= UINT_MAX);
+ return static_cast<uint32_t>(crc32(static_cast<unsigned int>(crc), pos,
+ static_cast<unsigned int>(length)));
+}
+
+/*
+ Forward declaration of Format_description_event class to be used in class
+ Log_event_header
+*/
+class Format_description_event;
+
+/**
+ @class Log_event_footer
+
+ The footer, in the current version of the MySQL server, only contains
+ the checksum algorithm descriptor. The descriptor is contained in the
+ FDE of the binary log. This is common for all the events contained in
+ that binary log, and defines the algorithm used to checksum
+ the events contained in the binary log.
+
+ @anchor Table_common_footer
+ The footer contains the following:
+ <table>
+ <caption>Common-Footer</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>checkusm_alg</td>
+ <td>enum_checksum_alg</td>
+ <td>Algorithm used to checksum the events contained in the binary log</td>
+ </tr>
+
+ </table>
+
+ @note checksum *value* is not generated with the event. On master's side, it
+ is calculated right before writing the event into the binary log. The
+ data_written field of the event is adjusted (+BINLOG_CHECKSUM_LEN) to
+ consider the checksum value as part of the event. On reading the event,
+ if the Format Description Event (FDE) used when serializing the event
+ tells that the events have checksum information, the checksum value can
+ be retrieved from a particular offset of the serialized event buffer
+ (event length - BINLOG_CHECKSUM_LEN) and checked for corruption by
+ computing a new value over the event buffer. It is not required after
+ that. Therefore, the checksum value is not required to be stored in the
+ instance as a class member.
+*/
+class Log_event_footer {
+ public:
+ /**
+ Wrapper to call get_checksum_alg(const char *, ulong) function based on the
+ event reader object (which knows both buffer and buffer length).
+
+ @param[in] reader The Event_reader object associated to the event buffer
+ of the FD event.
+
+ @retval BINLOG_CHECKSUM_ALG_UNDEF originator is checksum-unaware
+ (effectively no checksum).
+ @retval BINLOG_CHECKSUM_ALG_OFF no checksum.
+ @retval other the actual checksum algorithm descriptor.
+ */
+ static enum_binlog_checksum_alg get_checksum_alg(Event_reader &reader);
+
+ /**
+ The method returns the checksum algorithm used to checksum the binary log
+ from a Format Description Event serialized buffer.
+
+ For MySQL server versions < 5.6, the algorithm is undefined.
+
+ @param buf buffer holding serialized FD event.
+ @param len length of the event buffer.
+
+ @retval BINLOG_CHECKSUM_ALG_UNDEF originator is checksum-unaware
+ (effectively no checksum).
+ @retval BINLOG_CHECKSUM_ALG_OFF no checksum.
+ @retval other the actual checksum algorithm descriptor.
+ */
+ static enum_binlog_checksum_alg get_checksum_alg(const char *buf,
+ unsigned long len);
+
+ static bool event_checksum_test(unsigned char *buf, unsigned long event_len,
+ enum_binlog_checksum_alg alg);
+
+ /* Constructors */
+ Log_event_footer() : checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF) {}
+
+ /**
+ This ctor will create a new object of Log_event_footer, and will adjust
+ the event reader buffer size with respect to CRC usage.
+
+ @param reader the Event_reader containing the serialized event (including
+ header, event data and optional checksum information).
+ @param event_type the type of the event the footer belongs to.
+ @param fde An FDE event, used to get information about CRC.
+ */
+ Log_event_footer(Event_reader &reader, Log_event_type event_type,
+ const Format_description_event *fde);
+
+ explicit Log_event_footer(enum_binlog_checksum_alg checksum_alg_arg)
+ : checksum_alg(checksum_alg_arg) {}
+
+ /**
+ @verbatim
+ Master side:
+ The value is set by caller of FD(Format Description) constructor
+ In the FD case it's propagated into the last byte
+ of post_header_len[].
+ Slave side:
+ On the slave side the value is assigned from post_header_len[last]
+ of the last seen FD event.
+ @endverbatim
+ TODO(WL#7546): Revisit this comment when encoder is moved in libbinlogevent
+ */
+ enum_binlog_checksum_alg checksum_alg;
+};
+
+/**
+ @class Log_event_header
+
+ The Common-Header always has the same form and length within one
+ version of MySQL. Each event type specifies a format and length
+ of the Post-Header. The length of the Common-Header is the same
+ for all events of the same type.
+
+ @anchor Table_common_header
+ The binary format of Common-Header is as follows:
+ <table>
+ <caption>Common-Header</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>when</td>
+ <td>4 byte unsigned integer, represented by type struct timeval</td>
+ <td>The time when the query started, in seconds since 1970.
+ </td>
+ </tr>
+
+ <tr>
+ <td>type_code</td>
+ <td>1 byte enumeration</td>
+ <td>See enum #Log_event_type.</td>
+ </tr>
+
+ <tr>
+ <td>unmasked_server_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>Server ID of the server that created the event.</td>
+ </tr>
+
+ <tr>
+ <td>data_written</td>
+ <td>4 byte unsigned integer</td>
+ <td>The total size of this event, in bytes. In other words, this
+ is the sum of the sizes of Common-Header, Post-Header, and Body.
+ </td>
+ </tr>
+
+ <tr>
+ <td>log_pos</td>
+ <td>4 byte unsigned integer</td>
+ <td>The position of the next event in the master binary log, in
+ bytes from the beginning of the file. In a binlog that is not a
+ relay log, this is just the position of the next event, in bytes
+ from the beginning of the file. In a relay log, this is
+ the position of the next event in the master's binlog.
+ </td>
+ </tr>
+
+ <tr>
+ <td>flags</td>
+ <td>2 byte bitfield</td>
+ <td>16 or less flags depending on the version of the binary log.</td>
+ </tr>
+ </table>
+
+ Summing up the numbers above, we see that the total size of the
+ common header is 19 bytes.
+*/
+class Log_event_header {
+ public:
+ /*
+ Timestamp on the master(for debugging and replication of
+ NOW()/TIMESTAMP). It is important for queries and LOAD DATA
+ INFILE. This is set at the event's creation time, except for Query
+ and Load (and other events) events where this is set at the query's
+ execution time, which guarantees good replication (otherwise, we
+ could have a query and its event with different timestamps).
+ */
+ struct timeval when;
+
+ /**
+ Event type extracted from the header. In the server, it is decoded
+ by read_log_event(), but adding here for complete decoding.
+ */
+ Log_event_type type_code;
+
+ /*
+ The server id read from the Binlog.
+ */
+ unsigned int unmasked_server_id;
+
+ /* Length of an event, which will be written by write() function */
+ size_t data_written;
+
+ /*
+ The offset in the log where this event originally appeared (it is
+ preserved in relay logs, making SHOW SLAVE STATUS able to print
+ coordinates of the event in the master's binlog).
+ */
+ unsigned long long log_pos;
+
+ /*
+ 16 or less flags depending on the version of the binary log.
+ See the definitions above for LOG_EVENT_TIME_F,
+ LOG_EVENT_FORCED_ROTATE_F, LOG_EVENT_THREAD_SPECIFIC_F, and
+ LOG_EVENT_SUPPRESS_USE_F for notes.
+ */
+ uint16_t flags;
+
+ /**
+ The following type definition is to be used whenever data is placed
+ and manipulated in a common buffer. Use this typedef for buffers
+ that contain data containing binary and character data.
+ */
+ typedef unsigned char Byte;
+
+ explicit Log_event_header(Log_event_type type_code_arg = ENUM_END_EVENT)
+ : type_code(type_code_arg), data_written(0), log_pos(0), flags(0) {
+ when.tv_sec = 0;
+ when.tv_usec = 0;
+ }
+ /**
+ Log_event_header constructor.
+
+ @param reader the Event_reader containing the serialized event (including
+ header, event data and optional checksum information).
+ */
+ Log_event_header(Event_reader &reader);
+
+ /**
+ The get_is_valid function is related to event specific sanity checks to
+ determine that the object was initialized without errors.
+
+ Note that a given event object may be valid at some point (ancestor
+ event type initialization was fine) but be turned invalid in a later
+ stage.
+
+ @return True if the event object is valid, false otherwise.
+ */
+
+ bool get_is_valid() { return m_is_valid; }
+
+ /**
+ Set if the event object shall be considered valid or not.
+
+ @param is_valid if the event object shall be considered valid.
+ */
+
+ void set_is_valid(bool is_valid) { m_is_valid = is_valid; }
+
+ private:
+ /*
+ As errors might happen when de-serializing events, the m_is_valid variable
+ will hold information about the validity of the event.
+
+ An invalid event shall never be applied/dumped/displayed, as its
+ interpretation (accessing its contents) might lead to using invalid
+ memory pointers.
+ */
+ bool m_is_valid;
+};
+
+/**
+ This is the abstract base class for binary log events.
+
+ @section Binary_log_event_binary_format Binary Format
+
+ @anchor Binary_log_event_format
+ Any @c Binary_log_event saved on disk consists of the following four
+ components.
+
+ - Common-Header
+ - Post-Header
+ - Body
+ - Footer
+
+ Common header has the same format and length in a given MySQL version. It is
+ documented @ref Table_common_header "here".
+
+ The Body may be of different format and length even for different events of
+ the same type. The binary formats of Post-Header and Body are documented
+ separately in each subclass.
+
+ Footer is common to all the events in a given MySQL version. It is documented
+ @ref Table_common_footer "here".
+
+ @anchor packed_integer
+ - Some events, used for RBR use a special format for efficient representation
+ of unsigned integers, called Packed Integer. A Packed Integer has the
+ capacity of storing up to 8-byte integers, while small integers
+ still can use 1, 3, or 4 bytes. The value of the first byte
+ determines how to read the number, according to the following table:
+
+ <table>
+ <caption>Format of Packed Integer</caption>
+
+ <tr>
+ <th>First byte</th>
+ <th>Format</th>
+ </tr>
+
+ <tr>
+ <td>0-250</td>
+ <td>The first byte is the number (in the range 0-250), and no more
+ bytes are used.</td>
+ </tr>
+
+ <tr>
+ <td>252</td>
+ <td>Two more bytes are used. The number is in the range
+ 251-0xffff.</td>
+ </tr>
+
+ <tr>
+ <td>253</td>
+ <td>Three more bytes are used. The number is in the range
+ 0xffff-0xffffff.</td>
+ </tr>
+
+ <tr>
+ <td>254</td>
+ <td>Eight more bytes are used. The number is in the range
+ 0xffffff-0xffffffffffffffff.</td>
+ </tr>
+
+ </table>
+
+ - Strings are stored in various formats. The format of each string
+ is documented separately.
+
+*/
+class Binary_log_event {
+ public:
+ /*
+ The number of types we handle in Format_description_event (UNKNOWN_EVENT
+ is not to be handled, it does not exist in binlogs, it does not have a
+ format).
+ */
+ static const int LOG_EVENT_TYPES = (ENUM_END_EVENT - 1);
+
+ /**
+ The lengths for the fixed data part of each event.
+ This is an enum that provides post-header lengths for all events.
+ */
+ enum enum_post_header_length {
+ // where 3.23, 4.x and 5.0 agree
+ QUERY_HEADER_MINIMAL_LEN = (4 + 4 + 1 + 2),
+ // where 5.0 differs: 2 for length of N-bytes vars.
+ QUERY_HEADER_LEN = (QUERY_HEADER_MINIMAL_LEN + 2),
+ STOP_HEADER_LEN = 0,
+ START_V3_HEADER_LEN = (2 + ST_SERVER_VER_LEN + 4),
+ // this is FROZEN (the Rotate post-header is frozen)
+ ROTATE_HEADER_LEN = 8,
+ INTVAR_HEADER_LEN = 0,
+ APPEND_BLOCK_HEADER_LEN = 4,
+ DELETE_FILE_HEADER_LEN = 4,
+ RAND_HEADER_LEN = 0,
+ USER_VAR_HEADER_LEN = 0,
+ FORMAT_DESCRIPTION_HEADER_LEN = (START_V3_HEADER_LEN + 1 + LOG_EVENT_TYPES),
+ XID_HEADER_LEN = 0,
+ BEGIN_LOAD_QUERY_HEADER_LEN = APPEND_BLOCK_HEADER_LEN,
+ ROWS_HEADER_LEN_V1 = 8,
+ TABLE_MAP_HEADER_LEN = 8,
+ EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN = (4 + 4 + 4 + 1),
+ EXECUTE_LOAD_QUERY_HEADER_LEN =
+ (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN),
+ INCIDENT_HEADER_LEN = 2,
+ HEARTBEAT_HEADER_LEN = 0,
+ IGNORABLE_HEADER_LEN = 0,
+ ROWS_HEADER_LEN_V2 = 10,
+ TRANSACTION_CONTEXT_HEADER_LEN = 18,
+ VIEW_CHANGE_HEADER_LEN = 52,
+ XA_PREPARE_HEADER_LEN = 0
+ }; // end enum_post_header_length
+ protected:
+ /**
+ This constructor is used to initialize the type_code of header object
+ m_header.
+ We set the type code to ENUM_END_EVENT so that the decoder
+ asserts if event type has not been modified by the sub classes
+ */
+ explicit Binary_log_event(Log_event_type type_code)
+ : m_reader(nullptr, 0), m_header(type_code) {}
+
+ /**
+ This constructor will create a new object of Log_event_header and initialize
+ the variable m_header, which in turn will be used to initialize Log_event's
+ member common_header.
+ It will also advance the Event_reader cursor after decoding the header (it
+ is done through the constructor of Log_event_header) and will be pointing to
+ the start of event data.
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event used to get checksum information of non FDE events.
+ */
+ Binary_log_event(const char **buf, const Format_description_event *fde);
+
+ public:
+#ifndef HAVE_MYSYS
+ /*
+ The print_event_info functions are used in the free standing version of
+ the library only. Since MySQL server does not use them, and it does not
+ link to standard input/output library on Windows 32 bit system ,these
+ methods are commented out when the library(libbinlogevents) is built
+ with the server.
+ */
+ /**
+ Returns short information about the event
+ */
+ virtual void print_event_info(std::ostream &info) = 0;
+ /**
+ Returns detailed information about the event
+ */
+ virtual void print_long_info(std::ostream &info) = 0;
+#endif
+ virtual ~Binary_log_event() = 0;
+
+ Binary_log_event(const Binary_log_event &) = default;
+ Binary_log_event(Binary_log_event &&) = default;
+ Binary_log_event &operator=(const Binary_log_event &) = default;
+ Binary_log_event &operator=(Binary_log_event &&) = default;
+
+ /**
+ * Helper method
+ */
+ enum Log_event_type get_event_type() const { return m_header.type_code; }
+
+ /**
+ Return a const pointer to the header of the log event
+ */
+ const Log_event_header *header() const { return &m_header; }
+ /**
+ Return a non-const pointer to the header of the log event
+ */
+ Log_event_header *header() { return &m_header; }
+ /**
+ Return a const pointer to the footer of the log event
+ */
+ const Log_event_footer *footer() const { return &m_footer; }
+ /**
+ Return a non-const pointer to the footer of the log event
+ */
+ Log_event_footer *footer() { return &m_footer; }
+ /**
+ Returns a reference to the event Event_reader object.
+ */
+ Event_reader &reader() { return m_reader; }
+
+ private:
+ /*
+ All the accesses to the event buffer shall be performed by using m_reader
+ methods.
+ */
+ Event_reader m_reader;
+ Log_event_header m_header;
+ Log_event_footer m_footer;
+};
+
+/**
+ @class Unknown_event
+
+ An unknown event should never occur. It is never written to a binary log.
+ If an event is read from a binary log that cannot be recognized as
+ something else, it is treated as UNKNOWN_EVENT.
+
+ The Post-Header and Body for this event type are empty; it only has
+ the Common-Header.
+*/
+class Unknown_event : public Binary_log_event {
+ public:
+ /**
+ This is the minimal constructor, and set the type_code as
+ UNKNOWN_EVENT in the header object in Binary_log_event
+ */
+ Unknown_event() : Binary_log_event(UNKNOWN_EVENT) {}
+
+ Unknown_event(const char *buf, const Format_description_event *fde);
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+} // end namespace binary_log
+/**
+ @} (end of group Replication)
+*/
+#endif /* BINLOG_EVENT_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/byteorder.h b/contrib/libs/libmysql_r/libbinlogevents/include/byteorder.h
new file mode 100644
index 0000000000..d0223899c8
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/byteorder.h
@@ -0,0 +1,121 @@
+/* Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @file libbinlogevents/include/byteorder.h
+
+ @brief The file contains functions to convert the byte encoding of integer
+ values to and from little-endian and big-endian byte order.
+*/
+
+#ifndef BYTEORDER_INCLUDED
+#define BYTEORDER_INCLUDED
+
+#include <stdint.h>
+#include "binlog_config.h"
+#include "my_compiler.h"
+#ifndef STANDALONE_BINLOG
+#define HAVE_MYSYS 1
+#endif
+
+/*
+ Methods for reading and storing in machine independent
+ format (low byte first).
+*/
+
+/*
+ Checking le16toh is required because the machine may have the header
+ but the functions might not be defined if the version of glibc < 2.9
+*/
+#ifdef HAVE_ENDIAN_CONVERSION_MACROS
+#include <endian.h>
+#endif
+
+#if !defined(le16toh)
+/**
+ Converting a 16 bit integer from little-endian byte order to host byteorder
+
+ @param x 16-bit integer in little endian byte order
+ @return 16-bit integer in host byte order
+*/
+uint16_t inline le16toh(uint16_t x) {
+#ifndef IS_BIG_ENDIAN
+ return x;
+#else
+ return ((x >> 8) | (x << 8));
+#endif
+}
+#endif
+
+#if !defined(le32toh)
+/**
+ Converting a 32 bit integer from little-endian byte order to host byteorder
+
+ @param x 32-bit integer in little endian byte order
+ @return 32-bit integer in host byte order
+*/
+uint32_t inline le32toh(uint32_t x) {
+#ifndef IS_BIG_ENDIAN
+ return x;
+#else
+ return (((x >> 24) & 0xff) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+ ((x << 24) & 0xff000000));
+#endif
+}
+#endif
+
+#if !defined(be32toh)
+/**
+ Converting a 32 bit integer from big-endian byte order to host byteorder
+
+ @param x 32-bit integer in big endian byte order
+ @return 32-bit integer in host byte order
+*/
+uint32_t inline be32toh(uint32_t x) {
+#ifndef IS_BIG_ENDIAN
+ return (((x >> 24) & 0xff) | ((x << 8) & 0xff0000) | ((x >> 8) & 0xff00) |
+ ((x << 24) & 0xff000000));
+#else
+ return x;
+#endif
+}
+#endif
+
+#if !defined(le64toh)
+/**
+ Converting a 64 bit integer from little-endian byte order to host byteorder
+
+ @param x 64-bit integer in little endian byte order
+ @return 64-bit integer in host byte order
+*/
+uint64_t inline le64toh(uint64_t x) {
+#ifndef IS_BIG_ENDIAN
+ return x;
+#else
+ x = ((x << 8) & 0xff00ff00ff00ff00ULL) | ((x >> 8) & 0x00ff00ff00ff00ffULL);
+ x = ((x << 16) & 0xffff0000ffff0000ULL) | ((x >> 16) & 0x0000ffff0000ffffULL);
+ return (x << 32) | (x >> 32);
+#endif
+}
+#endif
+
+#endif // BYTEORDER_INCLUDED
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/control_events.h b/contrib/libs/libmysql_r/libbinlogevents/include/control_events.h
new file mode 100644
index 0000000000..88de3b2848
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/control_events.h
@@ -0,0 +1,1292 @@
+/* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file control_events.h
+
+ @brief Contains the classes representing events operating in the replication
+ stream properties. Each event is represented as a byte sequence with logical
+ divisions as event header, event specific data and event footer. The header
+ and footer are common to all the events and are represented as two different
+ subclasses.
+*/
+
+#ifndef CONTROL_EVENT_INCLUDED
+#define CONTROL_EVENT_INCLUDED
+
+#include <sys/types.h>
+#include <time.h>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "binlog_event.h"
+#include "template_utils.h"
+#include "uuid.h"
+
+namespace binary_log {
+/**
+ @class Rotate_event
+
+ When a binary log file exceeds a size limit, a ROTATE_EVENT is written
+ at the end of the file that points to the next file in the squence.
+ This event is information for the slave to know the name of the next
+ binary log it is going to receive.
+
+ ROTATE_EVENT is generated locally and written to the binary log
+ on the master. It is written to the relay log on the slave when FLUSH LOGS
+ occurs, and when receiving a ROTATE_EVENT from the master.
+ In the latter case, there will be two rotate events in total originating
+ on different servers.
+
+ @section Rotate_event_binary_format Binary Format
+
+ <table>
+ <caption>Post-Header for Rotate_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>position</td>
+ <td>8 byte integer</td>
+ <td>The position within the binary log to rotate to.</td>
+ </tr>
+
+ </table>
+
+ The Body has one component:
+
+ <table>
+ <caption>Body for Rotate_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>new_log_ident</td>
+ <td>variable length string without trailing zero, extending to the
+ end of the event (determined by the length field of the
+ Common-Header)
+ </td>
+ <td>Name of the binlog to rotate to.</td>
+ </tr>
+
+ </table>
+*/
+class Rotate_event : public Binary_log_event {
+ public:
+ const char *new_log_ident;
+ size_t ident_len;
+ unsigned int flags;
+ uint64_t pos;
+
+ enum {
+ /* Values taken by the flag member variable */
+ DUP_NAME = 2, // if constructor should dup the string argument
+ RELAY_LOG = 4 // rotate event for the relay log
+ };
+
+ enum {
+ /* Rotate event post_header */
+ R_POS_OFFSET = 0,
+ R_IDENT_OFFSET = 8
+ };
+
+ /**
+ This is the minimal constructor, it will set the type code as ROTATE_EVENT.
+ */
+ Rotate_event(const char *new_log_ident_arg, size_t ident_len_arg,
+ unsigned int flags_arg, uint64_t pos_arg)
+ : Binary_log_event(ROTATE_EVENT),
+ new_log_ident(new_log_ident_arg),
+ ident_len(ident_len_arg ? ident_len_arg : strlen(new_log_ident_arg)),
+ flags(flags_arg),
+ pos(pos_arg) {}
+
+ /**
+ The layout of Rotate_event data part is as follows:
+
+ <pre>
+ +-----------------------------------------------------------------------+
+ | common_header | post_header | position of the first event | file name |
+ +-----------------------------------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event, used to get the following information:
+ -binlog_version
+ -server_version
+ -post_header_len
+ -common_header_len
+ The content of this object depends on the binlog-version
+ currently in use.
+ */
+ Rotate_event(const char *buf, const Format_description_event *fde);
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &);
+ void print_long_info(std::ostream &);
+#endif
+
+ ~Rotate_event() {
+ if (flags & DUP_NAME) bapi_free(const_cast<char *>(new_log_ident));
+ }
+};
+
+/**
+ @class Format_description_event
+ For binlog version 4.
+ This event is saved by threads which read it, as they need it for future
+ use (to decode the ordinary events).
+
+ @section Format_description_event_binary_format Binary Format
+
+ The Post-Header has six components:
+
+ <table>
+ <caption>Post-Header for Format_description_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>created</td>
+ <td>4 byte unsigned integer</td>
+ <td>The creation timestamp, if non-zero,
+ is the time in seconds when this event was created</td>
+ </tr>
+ <tr>
+ <td>binlog_version</td>
+ <td>2 byte unsigned integer</td>
+ <td>This is 1 in MySQL 3.23 and 3 in MySQL 4.0 and 4.1
+ (In MySQL 5.0 and up, FORMAT_DESCRIPTION_EVENT is
+ used instead of START_EVENT_V3 and for them its 4).</td>
+ </tr>
+ <tr>
+ <td>server_version</td>
+ <td>char array of 50 bytes</td>
+ <td>The MySQL server's version (example: 4.0.14-debug-log),
+ padded with 0x00 bytes on the right</td>
+ </tr>
+ <tr>
+ <td>common_header_len</td>
+ <td>1 byte unsigned integer</td>
+ <td>The length of the event header. This value includes the extra_headers
+ field, so this header length - 19 yields the size
+ of the extra_headers field.</td>
+ </tr>
+ <tr>
+ <td>post_header_len</td>
+ <td>array of type 1 byte unsigned integer</td>
+ <td>The lengths for the fixed data part of each event</td>
+ </tr>
+ <tr>
+ <td>server_version_split</td>
+ <td>unsigned char array</td>
+ <td>Stores the server version of the server
+ and splits them in three parts</td>
+ </tr>
+ <tr>
+ <td>number_of_event_types</td>
+ <td>1 byte unsigned integer</td>
+ <td>number of event types present in the server</td>
+ </tr>
+ </table>
+*/
+class Format_description_event : public Binary_log_event {
+ public:
+ /**
+ If this event is at the start of the first binary log since server
+ startup 'created' should be the timestamp when the event (and the
+ binary log) was created. In the other case (i.e. this event is at
+ the start of a binary log created by FLUSH LOGS or automatic
+ rotation), 'created' should be 0. This "trick" is used by MySQL
+ >=4.0.14 slaves to know whether they must drop stale temporary
+ tables and whether they should abort unfinished transaction.
+
+ Note that when 'created'!=0, it is always equal to the event's
+ timestamp; indeed Format_description_event is written only in binlog.cc
+ where the first constructor below is called, in which 'created' is set to
+ 'when'. So in fact 'created' is a useless variable. When it is 0 we can
+ read the actual value from timestamp ('when') and when it is non-zero we
+ can read the same value from timestamp
+ ('when'). Conclusion:
+ - we use timestamp to print when the binlog was created.
+ - we use 'created' only to know if this is a first binlog or not.
+ */
+ time_t created;
+ uint16_t binlog_version;
+ char server_version[ST_SERVER_VER_LEN];
+ /*
+ We set this to 1 if we don't want to have the created time in the log,
+ which is the case when we rollover to a new log.
+ */
+ bool dont_set_created;
+
+ /**
+ The size of the fixed header which _all_ events have
+ (for binlogs written by this version, this is equal to
+ LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT
+ (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN).
+ */
+ uint8_t common_header_len;
+ /*
+ The list of post-headers' lengths followed
+ by the checksum alg decription byte
+ */
+ std::vector<uint8_t> post_header_len;
+ unsigned char server_version_split[ST_SERVER_VER_SPLIT_LEN];
+
+ /**
+ Format_description_event 1st constructor.
+
+ This constructor can be used to create the event to write to the binary log
+ (when the server starts or when FLUSH LOGS)
+
+ @param binlog_ver the binlog version for which we want to build
+ an event. It should only be 4, old versions are not compatible anymore
+ since 8.0.2.
+ @param server_ver The MySQL server's version.
+ */
+ Format_description_event(uint8_t binlog_ver, const char *server_ver);
+ /**
+ The layout of Format_description_event data part is as follows:
+
+ <pre>
+ +=====================================+
+ | event | binlog_version 19 : 2 | = 4
+ | data +----------------------------+
+ | | server_version 21 : 50 |
+ | +----------------------------+
+ | | create_timestamp 71 : 4 |
+ | +----------------------------+
+ | | header_length 75 : 1 |
+ | +----------------------------+
+ | | post-header 76 : n | = array of n bytes, one byte
+ | | lengths for all | per event type that the
+ | | event types | server knows about
+ +=====================================+
+ </pre>
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+
+ @note The fde passed to this constructor was created through another
+ constructor of FDE class.
+ */
+ Format_description_event(const char *buf,
+ const Format_description_event *fde);
+
+ Format_description_event(const Format_description_event &) = default;
+ Format_description_event &operator=(const Format_description_event &) =
+ default;
+ uint8_t number_of_event_types;
+ /**
+ This method is used to find out the version of server that originated
+ the current FD instance.
+
+ @return the version of server.
+ */
+ unsigned long get_product_version() const;
+ /**
+ This method checks the MySQL version to determine whether checksums may be
+ present in the events contained in the binary log.
+
+ @retval true if the event's version is earlier than one that introduced
+ the replication event checksum.
+ @retval false otherwise.
+ */
+ bool is_version_before_checksum() const;
+ /**
+ This method populates the array server_version_split which is then used for
+ lookups to find if the server which created this event has some known bug.
+ */
+ void calc_server_version_split();
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+ ~Format_description_event();
+
+ bool header_is_valid() const {
+ return ((common_header_len >= LOG_EVENT_MINIMAL_HEADER_LEN) &&
+ (!post_header_len.empty()));
+ }
+
+ bool version_is_valid() const {
+ /* It is invalid only when all version numbers are 0 */
+ return server_version_split[0] != 0 || server_version_split[1] != 0 ||
+ server_version_split[2] != 0;
+ }
+};
+
+/**
+ @class Stop_event
+
+ A stop event is written to the log files under these circumstances:
+ - A master writes the event to the binary log when it shuts down.
+ - A slave writes the event to the relay log when it shuts down or
+ when a RESET SLAVE statement is executed.
+
+ @section Stop_event_binary_format Binary Format
+
+ The Post-Header and Body for this event type are empty; it only has
+ the Common-Header.
+*/
+
+class Stop_event : public Binary_log_event {
+ public:
+ /**
+ It is the minimal constructor, and all it will do is set the type_code as
+ STOP_EVENT in the header object in Binary_log_event.
+ */
+ Stop_event() : Binary_log_event(STOP_EVENT) {}
+
+ /**
+ A Stop_event is occurs under these circumstances:
+ - A master writes the event to the binary log when it shuts down
+ - A slave writes the event to the relay log when it shuts down or when a
+ RESET SLAVE statement is executed
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Stop_event(const char *buf, const Format_description_event *fde);
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &info);
+#endif
+};
+
+/**
+ @class Incident_event
+
+ Class representing an incident, an occurance out of the ordinary,
+ that happened on the master.
+
+ The event is used to inform the slave that something out of the
+ ordinary happened on the master that might cause the database to be
+ in an inconsistent state.
+
+ @section Incident_event_binary_format Binary Format
+
+ <table id="IncidentFormat">
+ <caption>Incident event format</caption>
+ <tr>
+ <th>Symbol</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>INCIDENT</td>
+ <td align="right">2</td>
+ <td>Incident number as an unsigned integer</td>
+ </tr>
+ <tr>
+ <td>MSGLEN</td>
+ <td align="right">1</td>
+ <td>Message length as an unsigned integer</td>
+ </tr>
+ <tr>
+ <td>MESSAGE</td>
+ <td align="right">MSGLEN</td>
+ <td>The message, if present. Not null terminated.</td>
+ </tr>
+ </table>
+
+*/
+class Incident_event : public Binary_log_event {
+ public:
+ /**
+ Enumeration of the incidents that can occur for the server.
+ */
+ enum enum_incident {
+ /** No incident */
+ INCIDENT_NONE = 0,
+ /** There are possibly lost events in the replication stream */
+ INCIDENT_LOST_EVENTS = 1,
+ /** Shall be last event of the enumeration */
+ INCIDENT_COUNT
+ };
+
+ enum_incident get_incident_type() { return incident; }
+ char *get_message() { return message; }
+
+ /**
+ This will create an Incident_event with an empty message and set the
+ type_code as INCIDENT_EVENT in the header object in Binary_log_event.
+ */
+ explicit Incident_event(enum_incident incident_arg)
+ : Binary_log_event(INCIDENT_EVENT),
+ incident(incident_arg),
+ message(nullptr),
+ message_length(0) {}
+
+ /**
+ Constructor of Incident_event
+ The buffer layout is as follows:
+ <pre>
+ +-----------------------------------------------------+
+ | Incident_number | message_length | Incident_message |
+ +-----------------------------------------------------+
+ </pre>
+
+ Incident number codes are listed in binlog_evnet.h.
+ The only code currently used is INCIDENT_LOST_EVENTS, which indicates that
+ there may be lost events (a "gap") in the replication stream that requires
+ databases to be resynchronized.
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Incident_event(const char *buf, const Format_description_event *fde);
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+ protected:
+ enum_incident incident;
+ char *message;
+ size_t message_length;
+};
+
+/**
+ @class Xid_event
+
+ An XID event is generated for a commit of a transaction that modifies one or
+ more tables of an XA-capable storage engine.
+
+ @section Xid_event_binary_format Binary Format
+
+The Body has the following component:
+
+ <table>
+ <caption>Body for Xid_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>xid</td>
+ <td>8 byte unsigned integer</td>
+ <td>The XID transaction number.</td>
+ </tr>
+ </table>
+ The Post-Header and Body for this event type are empty; it only has
+ the common header.
+*/
+class Xid_event : public Binary_log_event {
+ public:
+ /**
+ The minimal constructor of Xid_event, it initializes the instance variable
+ xid and set the type_code as XID_EVENT in the header object in
+ Binary_log_event
+ */
+ explicit Xid_event(uint64_t xid_arg)
+ : Binary_log_event(XID_EVENT), xid(xid_arg) {}
+
+ /**
+ An XID event is generated for a commit of a transaction that modifies one or
+ more tables of an XA-capable storage engine
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Xid_event(const char *buf, const Format_description_event *fde);
+ uint64_t xid;
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+
+/**
+ @class XA_prepare_event
+
+ An XA_prepare event is generated for a XA prepared transaction.
+ Like Xid_event it contans XID of the *prepared* transaction.
+
+ @section XA_prepare_event_binary_format Binary Format
+
+The Body has the following component:
+
+ <table>
+ <caption>Body for XA_prepare_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>my_xid</td>
+ <td>a struct similar to mysql/plugin.h containing three members.</td>
+ <td>serialized XID representation of XA transaction.</td>
+ </tr>
+
+ <tr>
+ <td>xid</td>
+ <td>a pointer to XID object.</td>
+ <td>a reference to an object for mysql logger.</td>
+ </tr>
+
+ <tr>
+ <td>one_phase</td>
+ <td>a bool</td>
+ <td>the value specifies the current XA transaction commit method.</td>
+ </tr>
+ </table>
+ The Post-Header and Body for this event type are empty; it only has
+ the common header.
+*/
+
+class XA_prepare_event : public Binary_log_event {
+ /*
+ Struct def is copied from $MYSQL/include/mysql/plugin.h,
+ consult there about fine details.
+ */
+ static const int MY_XIDDATASIZE = 128;
+
+ struct MY_XID {
+ long formatID;
+ long gtrid_length;
+ long bqual_length;
+ char data[MY_XIDDATASIZE]; /* Not \0-terminated */
+ };
+
+ protected:
+ /* size of serialization buffer is explained in $MYSQL/sql/xa.h. */
+ static const uint16_t ser_buf_size =
+ 8 + 2 * MY_XIDDATASIZE + 4 * sizeof(long) + 1;
+ MY_XID my_xid;
+ void *xid; /* Master side only */
+ bool one_phase;
+
+ public:
+ /**
+ The minimal constructor of XA_prepare_event, it initializes the
+ instance variable xid and set the type_code as XID_EVENT in the
+ header object in Binary_log_event
+ */
+ XA_prepare_event(void *xid_arg, bool oph_arg)
+ : Binary_log_event(XA_PREPARE_LOG_EVENT),
+ xid(xid_arg),
+ one_phase(oph_arg) {}
+
+ /**
+ An XID event is generated for a commit of a transaction that modifies one or
+ more tables of an XA-capable storage engine
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ XA_prepare_event(const char *buf, const Format_description_event *fde);
+#ifndef HAVE_MYSYS
+ /*
+ todo: we need to find way how to exploit server's code of
+ serialize_xid()
+ */
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+};
+
+/**
+ @class Ignorable_event
+
+ Base class for ignorable log events. Events deriving from
+ this class can be safely ignored by slaves that cannot
+ recognize them. Newer slaves, will be able to read and
+ handle them. This has been designed to be an open-ended
+ architecture, so adding new derived events shall not harm
+ the old slaves that support ignorable log event mechanism
+ (they will just ignore unrecognized ignorable events).
+
+ @note The only thing that makes an event ignorable is that it has
+ the LOG_EVENT_IGNORABLE_F flag set. It is not strictly necessary
+ that ignorable event types derive from Ignorable_event; they may
+ just as well derive from Binary_log_event and Log_event and pass
+ LOG_EVENT_IGNORABLE_F as argument to the Log_event constructor.
+
+ @section Ignoarble_event_binary_format Binary format
+
+ The Post-Header and Body for this event type are empty; it only has
+ the Common-Header.
+*/
+class Ignorable_event : public Binary_log_event {
+ public:
+ // buf is advanced in Binary_log_event constructor to point to beginning of
+ // post-header
+
+ /**
+ The minimal constructor and all it will do is set the type_code as
+ IGNORABLE_LOG_EVENT in the header object in Binary_log_event.
+ */
+ explicit Ignorable_event(Log_event_type type_arg = IGNORABLE_LOG_EVENT)
+ : Binary_log_event(type_arg) {}
+ /**
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Ignorable_event(const char *buf, const Format_description_event *fde);
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+};
+
+/**
+ @struct gtid_info
+ Structure to hold the members declared in the class Gtid_log_event those
+ member are objects of classes defined in server(rpl_gtid.h). As we can not
+ move all the classes defined there(in rpl_gtid.h) in libbinlogevents so this
+ structure was created, to provide a way to map the decoded value in Gtid_event
+ ctor and the class members defined in rpl_gtid.h, these classes are also the
+ members of Gtid_log_event(subclass of this in server code)
+
+ The structure contains the following components.
+ <table>
+ <caption>Structure gtid_info</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>rpl_gtid_sidno</td>
+ <td>4 bytes integer</td>
+ <td>SIDNO (source ID number, first component of GTID)</td>
+ </tr>
+ <tr>
+ <td>rpl_gtid_gno</td>
+ <td>8 bytes integer</td>
+ <td>GNO (group number, second component of GTID)</td>
+ </tr>
+ </table>
+*/
+struct gtid_info {
+ int32_t rpl_gtid_sidno;
+ int64_t rpl_gtid_gno;
+};
+
+/**
+ @class Gtid_event
+ GTID stands for Global Transaction IDentifier
+ It is composed of two parts:
+ - SID for Source Identifier, and
+ - GNO for Group Number.
+ The basic idea is to
+ - Associate an identifier, the Global Transaction IDentifier or GTID,
+ to every transaction.
+ - When a transaction is copied to a slave, re-executed on the slave,
+ and written to the slave's binary log, the GTID is preserved.
+ - When a slave connects to a master, the slave uses GTIDs instead of
+ (file, offset)
+
+ @section Gtid_event_binary_format Binary Format
+
+ The Body can have up to nine components:
+
+ <table>
+ <caption>Body for Gtid_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>GTID_FLAGS</td>
+ <td>1 byte</td>
+ <td>00000001 = Transaction may have changes logged with SBR.
+ In 5.6, 5.7.0-5.7.18, and 8.0.0-8.0.1, this flag is always set.
+ Starting in 5.7.19 and 8.0.2, this flag is cleared if the transaction
+ only contains row events. It is set if any part of the transaction is
+ written in statement format.</td>
+ </tr>
+ <tr>
+ <td>SID</td>
+ <td>16 byte sequence</td>
+ <td>UUID representing the SID</td>
+ </tr>
+ <tr>
+ <td>GNO</td>
+ <td>8 byte integer</td>
+ <td>Group number, second component of GTID.</td>
+ </tr>
+ <tr>
+ <td>logical clock timestamp typecode</td>
+ <td>1 byte integer</td>
+ <td>The type of logical timestamp used in the logical clock fields.</td>
+ </tr>
+ <tr>
+ <td>last_committed</td>
+ <td>8 byte integer</td>
+ <td>Store the transaction's commit parent sequence_number</td>
+ </tr>
+ <tr>
+ <td>sequence_number</td>
+ <td>8 byte integer</td>
+ <td>The transaction's logical timestamp assigned at prepare phase</td>
+ </tr>
+ <tr>
+ <td>immediate_commit_timestamp</td>
+ <td>7 byte integer</td>
+ <td>Timestamp of commit on the immediate master</td>
+ </tr>
+ <tr>
+ <td>original_commit_timestamp</td>
+ <td>7 byte integer</td>
+ <td>Timestamp of commit on the originating master</td>
+ </tr>
+ <tr>
+ <td>transaction_length</td>
+ <td>1 to 9 byte integer // See net_length_size(ulonglong num)</td>
+ <td>The packed transaction's length in bytes, including the Gtid</td>
+ </tr>
+ <tr>
+ <td>immediate_server_version</td>
+ <td>4 byte integer</td>
+ <td>Server version of the immediate server</td>
+ </tr>
+ <tr>
+ <td>original_server_version</td>
+ <td>4 byte integer</td>
+ <td>Version of the server where the transaction was originally executed</td>
+ </tr>
+ </table>
+
+*/
+class Gtid_event : public Binary_log_event {
+ public:
+ /*
+ The transaction's logical timestamps used for MTS: see
+ Transaction_ctx::last_committed and
+ Transaction_ctx::sequence_number for details.
+ Note: Transaction_ctx is in the MySQL server code.
+ */
+ long long int last_committed;
+ long long int sequence_number;
+ /** GTID flags constants */
+ unsigned const char FLAG_MAY_HAVE_SBR = 1;
+ /** Transaction might have changes logged with SBR */
+ bool may_have_sbr_stmts;
+ /** Timestamp when the transaction was committed on the originating master. */
+ unsigned long long int original_commit_timestamp;
+ /** Timestamp when the transaction was committed on the nearest master. */
+ unsigned long long int immediate_commit_timestamp;
+ bool has_commit_timestamps;
+ /** The length of the transaction in bytes. */
+ unsigned long long int transaction_length;
+
+ public:
+ /**
+ Ctor of Gtid_event
+
+ The layout of the buffer is as follows
+ <pre>
+ +----------+---+---+-------+--------------+---------+----------+
+ |gtid flags|SID|GNO|TS_TYPE|logical ts(:s)|commit ts|trx length|
+ +----------+---+---+-------+------------------------+----------+
+ </pre>
+ TS_TYPE is from {G_COMMIT_TS2} singleton set of values
+ Details on commit timestamps in Gtid_event(const char*...)
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+
+ Gtid_event(const char *buf, const Format_description_event *fde);
+ /**
+ Constructor.
+ */
+ explicit Gtid_event(long long int last_committed_arg,
+ long long int sequence_number_arg,
+ bool may_have_sbr_stmts_arg,
+ unsigned long long int original_commit_timestamp_arg,
+ unsigned long long int immediate_commit_timestamp_arg,
+ uint32_t original_server_version_arg,
+ uint32_t immediate_server_version_arg)
+ : Binary_log_event(GTID_LOG_EVENT),
+ last_committed(last_committed_arg),
+ sequence_number(sequence_number_arg),
+ may_have_sbr_stmts(may_have_sbr_stmts_arg),
+ original_commit_timestamp(original_commit_timestamp_arg),
+ immediate_commit_timestamp(immediate_commit_timestamp_arg),
+ transaction_length(0),
+ original_server_version(original_server_version_arg),
+ immediate_server_version(immediate_server_version_arg) {}
+#ifndef HAVE_MYSYS
+ // TODO(WL#7684): Implement the method print_event_info and print_long_info
+ // for all the events supported in MySQL Binlog
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+ protected:
+ static const int ENCODED_FLAG_LENGTH = 1;
+ static const int ENCODED_SID_LENGTH = 16; // Uuid::BYTE_LENGTH;
+ static const int ENCODED_GNO_LENGTH = 8;
+ /// Length of typecode for logical timestamps.
+ static const int LOGICAL_TIMESTAMP_TYPECODE_LENGTH = 1;
+ /// Length of two logical timestamps.
+ static const int LOGICAL_TIMESTAMP_LENGTH = 16;
+ // Type code used before the logical timestamps.
+ static const int LOGICAL_TIMESTAMP_TYPECODE = 2;
+
+ static const int IMMEDIATE_COMMIT_TIMESTAMP_LENGTH = 7;
+ static const int ORIGINAL_COMMIT_TIMESTAMP_LENGTH = 7;
+ // Length of two timestamps (from original/immediate masters)
+ static const int FULL_COMMIT_TIMESTAMP_LENGTH =
+ IMMEDIATE_COMMIT_TIMESTAMP_LENGTH + ORIGINAL_COMMIT_TIMESTAMP_LENGTH;
+ // We use 7 bytes out of which 1 bit is used as a flag.
+ static const int ENCODED_COMMIT_TIMESTAMP_LENGTH = 55;
+ // Minimum and maximum lengths of transaction length field.
+ static const int TRANSACTION_LENGTH_MIN_LENGTH = 1;
+ static const int TRANSACTION_LENGTH_MAX_LENGTH = 9;
+ /// Length of original_server_version
+ static const int ORIGINAL_SERVER_VERSION_LENGTH = 4;
+ /// Length of immediate_server_version
+ static const int IMMEDIATE_SERVER_VERSION_LENGTH = 4;
+ /// Length of original and immediate server version
+ static const int FULL_SERVER_VERSION_LENGTH =
+ ORIGINAL_SERVER_VERSION_LENGTH + IMMEDIATE_SERVER_VERSION_LENGTH;
+ // We use 4 bytes out of which 1 bit is used as a flag.
+ static const int ENCODED_SERVER_VERSION_LENGTH = 31;
+
+ /* We have only original commit timestamp if both timestamps are equal. */
+ int get_commit_timestamp_length() const {
+ if (original_commit_timestamp != immediate_commit_timestamp)
+ return FULL_COMMIT_TIMESTAMP_LENGTH;
+ return ORIGINAL_COMMIT_TIMESTAMP_LENGTH;
+ }
+
+ /**
+ We only store the immediate_server_version if both server versions are the
+ same.
+ */
+ int get_server_version_length() const {
+ if (original_server_version != immediate_server_version)
+ return FULL_SERVER_VERSION_LENGTH;
+ return IMMEDIATE_SERVER_VERSION_LENGTH;
+ }
+
+ gtid_info gtid_info_struct;
+ Uuid Uuid_parent_struct;
+
+ /* Minimum GNO expected in a serialized GTID event */
+ static const int64_t MIN_GNO = 1;
+ /* Maximum GNO expected in a serialized GTID event */
+ static const int64_t MAX_GNO = LLONG_MAX;
+
+ public:
+ /// Total length of post header
+ static const int POST_HEADER_LENGTH =
+ ENCODED_FLAG_LENGTH + /* flags */
+ ENCODED_SID_LENGTH + /* SID length */
+ ENCODED_GNO_LENGTH + /* GNO length */
+ LOGICAL_TIMESTAMP_TYPECODE_LENGTH + /* length of typecode */
+ LOGICAL_TIMESTAMP_LENGTH; /* length of two logical timestamps */
+
+ /*
+ We keep the commit timestamps in the body section because they can be of
+ variable length.
+ On the originating master, the event has only one timestamp as the two
+ timestamps are equal. On every other server we have two timestamps.
+ */
+ static const int MAX_DATA_LENGTH = FULL_COMMIT_TIMESTAMP_LENGTH +
+ TRANSACTION_LENGTH_MAX_LENGTH +
+ FULL_SERVER_VERSION_LENGTH;
+ static const int MAX_EVENT_LENGTH =
+ LOG_EVENT_HEADER_LEN + POST_HEADER_LENGTH + MAX_DATA_LENGTH;
+ /**
+ Set the transaction length information.
+
+ This function should be used when the full transaction length (including
+ the Gtid event length) is known.
+
+ @param transaction_length_arg The transaction length.
+ */
+ void set_trx_length(unsigned long long int transaction_length_arg) {
+ transaction_length = transaction_length_arg;
+ }
+
+ /** The version of the server where the transaction was originally executed */
+ uint32_t original_server_version;
+ /** The version of the immediate server */
+ uint32_t immediate_server_version;
+};
+
+/**
+ @class Previous_gtids_event
+
+ @section Previous_gtids_event_binary_format Binary Format
+
+ The Post-Header for this event type is empty. The Body has two
+ components:
+
+ <table>
+ <caption>Body for Previous_gtids_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>buf</td>
+ <td>unsigned char array</td>
+ <td>It contains the Gtids executed in the
+ last binary log file.</td>
+ </tr>
+
+ <tr>
+ <td>buf_size</td>
+ <td>4 byte integer</td>
+ <td>Size of the above buffer</td>
+ </tr>
+ </table>
+*/
+class Previous_gtids_event : public Binary_log_event {
+ public:
+ /**
+ Decodes the gtid_executed in the last binlog file
+
+ <pre>
+ The buffer layout is as follows
+ +--------------------------------------------+
+ | Gtids executed in the last binary log file |
+ +--------------------------------------------+
+ </pre>
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Previous_gtids_event(const char *buf, const Format_description_event *fde);
+ /**
+ This is the minimal constructor, and set the
+ type_code as PREVIOUS_GTIDS_LOG_EVENT in the header object in
+ Binary_log_event
+ */
+ Previous_gtids_event() : Binary_log_event(PREVIOUS_GTIDS_LOG_EVENT) {}
+#ifndef HAVE_MYSYS
+ // TODO(WL#7684): Implement the method print_event_info and print_long_info
+ // for all the events supported in MySQL Binlog
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+ protected:
+ size_t buf_size;
+ const unsigned char *buf;
+};
+
+/**
+ @class Transaction_context_event
+
+ This class is used to combine the information of the ongoing transaction
+ including the write set and other information of the thread executing the
+ transaction.
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>thread_id</td>
+ <td>4 byte integer</td>
+ <td>The identifier for the thread executing the transaction.</td>
+ </tr>
+
+ <tr>
+ <td>gtid_specified</td>
+ <td>bool type variable</td>
+ <td>Variable to identify whether the Gtid have been specified for the
+ ongoing transaction or not.
+ </td>
+ </tr>
+
+ <tr>
+ <td>encoded_snapshot_version</td>
+ <td>unsigned char array</td>
+ <td>A gtid_set which is used to store the transaction set used for
+ conflict detection.</td>
+ </tr>
+
+ <tr>
+ <td>encoded_snapshot_version_length</td>
+ <td>4 byte integer</td>
+ <td>Length of the above char array.</td>
+ </tr>
+
+ <tr>
+ <td>write_set</td>
+ <td>variable length list to store the hash values. </td>
+ <td>Used to store the hash values of the rows identifier for the rows
+ which have changed in the ongoing transaction.
+ </td>
+ </tr>
+
+ <tr>
+ <td>read_set</td>
+ <td>variable length list to store the read set values. Currently empty.
+ </td> <td>Will be used to store the read set values of the current
+ transaction.</td>
+ </tr>
+
+*/
+class Transaction_context_event : public Binary_log_event {
+ public:
+ /**
+ Decodes the transaction_context_log_event of the ongoing transaction.
+
+ <pre>
+ The buffer layout is as follows
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Transaction_context_event(const char *buf,
+ const Format_description_event *fde);
+
+ Transaction_context_event(unsigned int thread_id_arg,
+ bool is_gtid_specified_arg)
+ : Binary_log_event(TRANSACTION_CONTEXT_EVENT),
+ thread_id(thread_id_arg),
+ gtid_specified(is_gtid_specified_arg) {}
+
+ virtual ~Transaction_context_event();
+
+ static const char *read_data_set(const char *pos, uint32_t set_len,
+ std::list<const char *> *set,
+ uint32_t remaining_buffer);
+
+ static void clear_set(std::list<const char *> *set);
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+
+ protected:
+ const char *server_uuid;
+ uint32_t thread_id;
+ bool gtid_specified;
+ const unsigned char *encoded_snapshot_version;
+ uint32_t encoded_snapshot_version_length;
+ std::list<const char *> write_set;
+ std::list<const char *> read_set;
+
+ // The values mentioned on the next class constants is the offset where the
+ // data that will be copied in the buffer.
+
+ // 1 byte length.
+ static const int ENCODED_SERVER_UUID_LEN_OFFSET = 0;
+ // 4 bytes length.
+ static const int ENCODED_THREAD_ID_OFFSET = 1;
+ // 1 byte length.
+ static const int ENCODED_GTID_SPECIFIED_OFFSET = 5;
+ // 4 bytes length
+ static const int ENCODED_SNAPSHOT_VERSION_LEN_OFFSET = 6;
+ // 4 bytes length.
+ static const int ENCODED_WRITE_SET_ITEMS_OFFSET = 10;
+ // 4 bytes length.
+ static const int ENCODED_READ_SET_ITEMS_OFFSET = 14;
+
+ // The values mentioned on the next class's constants is the length of the
+ // data that will be copied in the buffer.
+ static const int ENCODED_READ_WRITE_SET_ITEM_LEN = 2;
+ static const int ENCODED_SNAPSHOT_VERSION_LEN = 2;
+};
+
+/**
+ @class View_change_event
+
+ This class is used to add view change markers in the binary log when a
+ member of the group enters or leaves the group.
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>view_id</td>
+ <td>40 length character array</td>
+ <td>This is used to store the view id value of the new view change when a
+ node add or leaves the group.
+ </td>
+ </tr>
+
+ <tr>
+ <td>seq_number</td>
+ <td>8 bytes integer</td>
+ <td>Variable to identify the next sequence number to be alloted to the
+ certified transaction.</td>
+ </tr>
+
+ <tr>
+ <td>certification_info</td>
+ <td>variable length map to store the certification data.</td>
+ <td>Map to store the certification info ie. the hash of write_set and the
+ snapshot sequence value.
+ </td>
+ </tr>
+
+*/
+class View_change_event : public Binary_log_event {
+ public:
+ /**
+ Decodes the view_change_log_event generated incase a server enters or
+ leaves the group.
+
+ <pre>
+ The buffer layout is as follows
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ View_change_event(const char *buf, const Format_description_event *fde);
+
+ explicit View_change_event(const char *raw_view_id);
+
+ virtual ~View_change_event();
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+
+ protected:
+ // The values mentioned on the next class constants is the offset where the
+ // data that will be copied in the buffer.
+
+ // 40 bytes length.
+ static const int ENCODED_VIEW_ID_OFFSET = 0;
+ // 8 bytes length.
+ static const int ENCODED_SEQ_NUMBER_OFFSET = 40;
+ // 4 bytes length.
+ static const int ENCODED_CERT_INFO_SIZE_OFFSET = 48;
+
+ /*
+ The layout of the buffer is as follows
+ +--------------------- -+-------------+----------+
+ | View Id | seq number | map size |
+ +-----------------------+-------------+----------+
+ view id (40 bytes) + seq number (8 bytes) + map size (4 bytes)
+ Sum of the length of the values at the above OFFSETS.
+ */
+
+ // The values mentioned on the next class constants is the length of the data
+ // that will be copied in the buffer.
+
+ // Field sizes on serialization
+ static const int ENCODED_VIEW_ID_MAX_LEN = 40;
+ static const int ENCODED_CERT_INFO_KEY_SIZE_LEN = 2;
+ static const int ENCODED_CERT_INFO_VALUE_LEN = 4;
+
+ char view_id[ENCODED_VIEW_ID_MAX_LEN];
+
+ long long int seq_number;
+
+ std::map<std::string, std::string> certification_info;
+};
+
+/**
+ @class Heartbeat_event
+
+ Replication event to ensure to slave that master is alive.
+ The event is originated by master's dump thread and sent straight to
+ slave without being logged. Slave itself does not store it in relay log
+ but rather uses a data for immediate checks and throws away the event.
+
+ Two members of the class log_ident and Binary_log_event::log_pos comprise
+ @see the rpl_event_coordinates instance. The coordinates that a heartbeat
+ instance carries correspond to the last event master has sent from
+ its binlog.
+
+ @section Heartbeat_event_binary_format Binary Format
+
+ The Body has one component:
+
+ <table>
+ <caption>Body for Heartbeat_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>log_ident</td>
+ <td>variable length string without trailing zero, extending to the
+ end of the event</td>
+ <td>Name of the current binlog being written to.</td>
+ </tr>
+ </table>
+*/
+class Heartbeat_event : public Binary_log_event {
+ public:
+ /**
+ Sent by a master to a slave to let the slave know that the master is
+ still alive. Events of this type do not appear in the binary or relay logs.
+ They are generated on a master server by the thread that dumps events and
+ sent straight to the slave without ever being written to the binary log.
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Heartbeat_event(const char *buf, const Format_description_event *fde);
+
+ const char *get_log_ident() { return log_ident; }
+ unsigned int get_ident_len() { return ident_len; }
+
+ protected:
+ const char *log_ident;
+ unsigned int ident_len; /** filename length */
+};
+
+} // end namespace binary_log
+/**
+ @} (end of group Replication)
+*/
+#endif /* CONTROL_EVENTS_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/debug_vars.h b/contrib/libs/libmysql_r/libbinlogevents/include/debug_vars.h
new file mode 100644
index 0000000000..fe2877ab42
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/debug_vars.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @file debug_vars.h
+
+ @brief This header file contains the status of variables used by MySQL tests
+ for debug operations. The variables are set to true by the MySQL server if
+ the test pertaining to the variable is active. The variables are initialized
+ with false (in binlog_event.cpp).
+*/
+#ifndef DEBUG_VARS_INCLUDED
+#define DEBUG_VARS_INCLUDED
+
+namespace binary_log_debug {
+extern bool debug_checksum_test;
+extern bool debug_query_mts_corrupt_db_names;
+extern bool debug_simulate_invalid_address;
+extern bool debug_pretend_version_50034_in_binlog;
+// TODO(WL#7546):Add variables here as we move methods into libbinlogevent
+// from the server while implementing the WL#7546(Moving binlog event
+// encoding into a separate package)
+} // namespace binary_log_debug
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/event_reader.h b/contrib/libs/libmysql_r/libbinlogevents/include/event_reader.h
new file mode 100644
index 0000000000..fa7373cd99
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/event_reader.h
@@ -0,0 +1,535 @@
+/* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file event_reader.h
+
+ @brief Contains the class responsible for deserializing fields of an event
+ previously stored in a buffer.
+*/
+
+#ifndef EVENT_READER_INCLUDED
+#define EVENT_READER_INCLUDED
+
+#include <list>
+#include <map>
+#include <vector>
+#include "byteorder.h"
+#include "wrapper_functions.h"
+
+namespace binary_log {
+
+#define PRINT_READER_STATUS(message) \
+ BAPI_PRINT("debug", (message ": m_buffer= %p, " \
+ "m_limit= %llu, " \
+ "m_length= %llu, " \
+ "position()= %llu", \
+ m_buffer, m_limit, m_length, Event_reader::position()))
+
+/**
+ Event_reader class purpose is to avoid out-of-buffer reads when deserializing
+ binary log events and increase robustness when dealing with corrupted event
+ buffers.
+
+ The Event_reader is composed by a pointer to the beginning of the serialized
+ event buffer (m_buffer), a variable containing the buffer length (m_length), a
+ cursor pointer that tells the current position to be read from the buffer
+ (m_ptr) and the buffer limit the reader shall respect (m_limit <= m_length).
+
+ All buffer reading functions shall move the cursor forward.
+
+ Before reading from the buffer, the Event_reader will check if the amount of
+ bytes expected to be read are less or equal to the remaining bytes to read:
+
+ remaining = m_limit - (m_ptr - m_buffer)
+
+ When there are no enough bytes to read from the buffer, Event_reader enters
+ in error state, so its owner can take an action.
+*/
+
+class Event_reader {
+ public:
+ /**
+ Event_reader constructor.
+
+ It sets the cursor to the first position of the buffer.
+
+ @param[in] buffer buffer holding a serialized event
+ @param[in] length known buffer length.
+ */
+ Event_reader(const char *buffer, unsigned long long length)
+ : m_buffer(buffer),
+ m_ptr(buffer),
+ m_length(length),
+ m_limit(length),
+ m_error(nullptr) {}
+
+ /**
+ Returns if the Event_reader is in an error state or not.
+
+ @retval true if the Event_reader is in error state.
+ @retval false if the Event_reader is not in error state.
+ */
+ bool has_error() {
+ BAPI_PRINT("debug", ("m_error= %s", m_error ? m_error : "nullptr"));
+ return m_error != nullptr;
+ }
+
+ /**
+ Returns the pointer to the error message.
+
+ @return the pointer to the error message when Event_reader is in error
+ state, or a nullptr otherwise.
+ */
+ const char *get_error() { return m_error; }
+
+ /**
+ Sets Event_reader error state by setting the error message.
+
+ @param[in] error pointer to the error message.
+ */
+ void set_error(const char *error);
+
+ /**
+ Returns the Event_reader buffer length.
+
+ Note: the buffer length might be larger than reader allowed buffer limit,
+ but the Event_reader will enter error state when trying to read above the
+ limit.
+
+ Example: an event buffer may contain the serialized event + checksum. The
+ event reader object will be configured with a buffer length that contains
+ both the serialized event and the checksum information, but once
+ Log_event_footer is instantiated, it shall adjust the event reader buffer
+ limit to the buffer position right before the checksum. This will avoid some
+ event deserialization relying on event buffer size to assume the checksum as
+ serialized event content.
+
+ @return the Event_reader buffer length.
+ */
+ unsigned long long length() { return (m_length); }
+
+ /**
+ Sets Event_reader buffer length and limit.
+
+ The length of the buffer should only be set to values greater or equal to
+ the current buffer length. Trying to set the length to less than current
+ buffer length will make the Event_buffer to enter error state.
+
+ The length is initially set in Event_reader constructor to
+ LOG_EVENT_MINIMAL_HEADER_LEN by the Log_event_header when instantiating it.
+ This should be enough to read the event header and determine the correct
+ buffer length. The Log_event_header will adjust the Event_reader length by
+ calling this function based on the value of event data_written header field.
+
+ @param[in] length the new Event_reader buffer length.
+ */
+ void set_length(unsigned long long length);
+
+ /**
+ Shrinks the Event_reader buffer limit.
+
+ This function is used by Log_event_footer to remove the checksum payload (if
+ necessary) from the serialized event size, as many event types rely on the
+ serialized event size to determine the size of some fields.
+
+ @param[in] bytes the amount of bytes to shrink the Event_reader buffer
+ length.
+ */
+ void shrink_limit(unsigned long long bytes);
+
+ /**
+ Returns the Event_reader buffer pointer.
+
+ @return the Event_reader buffer pointer.
+ */
+ const char *buffer() { return m_buffer; }
+
+ /**
+ Returns a pointer to the Event_reader cursor (next position to be read by
+ the Event_reader functions).
+
+ @return the pointer to the Event_reader cursor.
+ */
+ const char *ptr() { return m_ptr; }
+
+ /**
+ Returns a pointer to the Event_reader cursor (next position to be read) and
+ moves the cursor forward.
+
+ This function is used when the buffer contains a field of a known size and
+ the deserialization procedure must keep the pointer to the field but moving
+ the cursor to after it.
+
+ @param[in] length the amount of bytes to move the cursor forward.
+
+ @return the pointer to the Event_reader cursor before forwarding it.
+ */
+ const char *ptr(unsigned long long length);
+
+ /**
+ Returns the current Event_reader cursor position in bytes.
+
+ @retval m_limit if cursor position is invalid.
+ @retval position current Event_reader cursor position (if valid).
+ */
+ unsigned long long position() {
+ return m_ptr >= m_buffer ? m_ptr - m_buffer : m_limit;
+ }
+
+ /**
+ Returns the amount of bytes still available to read from cursor position.
+
+ @return the amount of bytes still available to read.
+ */
+ unsigned long long available_to_read() {
+ BAPI_ASSERT(position() <= m_limit);
+ return m_limit - position();
+ }
+
+ /**
+ Returns if the Event_reader can read a given amount of bytes from cursor
+ position.
+
+ @param bytes the amount of bytes expected to be read.
+
+ @retval true if the Event_reader can read the specified amount of bytes.
+ @retval false if the Event_reader cannot read the specified amount of bytes.
+ */
+ bool can_read(unsigned long long bytes) {
+ return (available_to_read() >= bytes);
+ }
+
+ /**
+ Moves cursor to a given absolute buffer position and returns the pointer to
+ the cursor.
+
+ @param position the position to jump to.
+
+ @retval pointer a pointer to the new cursor position.
+ @retval nullptr if the position is out of buffer boundaries.
+ */
+ const char *go_to(unsigned long long position);
+
+ /**
+ Moves the buffer position forward to a given relative position and returns
+ the pointer to the buffer on the specified position.
+
+ @param bytes the amount of bytes to move forward.
+
+ @retval pointer a pointer to the new buffer position.
+ @retval nullptr if the cursor is out of buffer boundaries.
+ */
+ const char *forward(unsigned long long bytes) {
+ BAPI_PRINT("debug", ("Event_reader::forward(%llu)", bytes));
+ return go_to((m_ptr - m_buffer) + bytes);
+ }
+
+ /**
+ Reads a basic type - bool, char, int, long, double, etc - from the buffer,
+ moves the cursor forward the number of bytes returned by sizeof(T)) and
+ returns the read value.
+
+ @retval value the T read from the cursor position.
+ @retval 0 if the cursor was out of buffer boundaries.
+ */
+ template <class T>
+ T read() {
+ PRINT_READER_STATUS("Event_reader::read");
+ if (!can_read(sizeof(T))) {
+ set_error("Cannot read from out of buffer bounds");
+ BAPI_PRINT("debug", ("Event_reader::tread(): "
+ "sizeof()= %zu",
+ sizeof(T)));
+ return 0;
+ }
+ T value = 0;
+ value = (T) * (m_ptr);
+ m_ptr = m_ptr + sizeof(T);
+ return value;
+ }
+
+ /**
+ Copies a basic type - bool, char, int, long, double, etc - from the buffer,
+ moves the cursor forward the number of bytes returned by sizeof(T)) and
+ returns the copied value.
+
+ @retval value the T copied from the cursor position.
+ @retval 0 if the cursor was out of buffer boundaries.
+ */
+ template <class T>
+ T memcpy() {
+ PRINT_READER_STATUS("Event_reader::memcpy");
+ if (!can_read(sizeof(T))) {
+ set_error("Cannot read from out of buffer bounds");
+ BAPI_PRINT("debug", ("Event_reader::memcpy(): "
+ "sizeof()= %zu",
+ sizeof(T)));
+ return 0;
+ }
+ T value = 0;
+ ::memcpy((char *)&value, m_ptr, sizeof(T));
+ m_ptr = m_ptr + sizeof(T);
+ return value;
+ }
+
+ /**
+ Copies a basic arithmetic type - uint8_t, [u]int16_t, [u]int32_t,
+ [u]int64_t - from the buffer, moves the cursor forward using specified bytes
+ parameter (or the number of bytes returned by sizeof(T) when not specified)
+ and returns the copied value transformed from little endian if necessary).
+
+ @param[in] bytes the amount of bytes to read from the buffer (and to move
+ forward). When not specified, will use sizeof(T).
+
+ @retval value the T copied from the cursor position.
+ @retval 0 if the cursor was out of buffer boundaries or there was no memory
+ to allocate to the new string..
+ */
+ template <typename T>
+ T read_and_letoh(unsigned char bytes = sizeof(T)) {
+ PRINT_READER_STATUS("Event_reader::read_and_letoh");
+ if (!can_read(bytes)) {
+ set_error("Cannot read from out of buffer bounds");
+ BAPI_PRINT("debug", ("Event_reader::read_and_letoh(): "
+ "sizeof()= %zu, bytes= %u",
+ sizeof(T), bytes));
+ return 0;
+ }
+ T value = 0;
+ ::memcpy((char *)&value, m_ptr, bytes);
+ m_ptr = m_ptr + bytes;
+ return letoh(value);
+ }
+
+ /**
+ Returns a pointer to a new string which is a duplicate of the input string.
+ The terminating null character is added. See: bapi_strndup().
+
+ @param[in] length the amount of bytes to read from the buffer (and to move
+ forward).
+
+ @retval pointer the T pointer from the cursor position.
+ @retval nullptr if the cursor was out of buffer boundaries.
+ */
+ template <typename T>
+ T strndup(size_t length) {
+ PRINT_READER_STATUS("Event_reader::strndup");
+ if (!can_read(length)) {
+ BAPI_PRINT("debug", ("Event_reader::strndup(%zu)", length));
+ set_error("Cannot read from out of buffer bounds");
+ return nullptr;
+ }
+ T str;
+ str = reinterpret_cast<T>(bapi_strndup(m_ptr, length));
+ m_ptr = m_ptr + length;
+ return str;
+ }
+
+ /**
+ Copies from the cursor to an already existent (and allocated) buffer and
+ moves forward the cursor.
+
+ @param[out] destination a pointer to the destination buffer.
+ @param[in] length the amount of bytes to read from the buffer (and to move
+ forward).
+ */
+ template <typename T>
+ void memcpy(T destination, size_t length) {
+ PRINT_READER_STATUS("Event_reader::memcpy");
+ if (!can_read(length)) {
+ BAPI_PRINT("debug", ("Event_reader::memcpy(%zu)", length));
+ set_error("Cannot read from out of buffer bounds");
+ return;
+ }
+ ::memcpy(destination, m_ptr, length);
+ m_ptr = m_ptr + length;
+ }
+
+ /**
+ Allocates memory to a destination buffer, copies from the cursor to the
+ destination buffer using memcpy() and moves forward the cursor.
+
+ This function is useful for pairs of fields when a first field describes the
+ second field size and the deserialization procedure must allocate a buffer
+ for the second field and then copy the event buffer content to the new
+ allocated buffer.
+
+ Before implementing this function and the Event_reader, the deserialization
+ process did like:
+
+ memcpy(length, ptr, sizeof(length);
+ ptr+=sizeof(length);
+ field = malloc(length);
+ memcpy(field, ptr, length);
+
+ Allocating the memory for the field before knowing if the content can be
+ read from the event buffer is a mistake, as it might allocate a very large
+ amount of memory that will not be used.
+
+ So, alloc_and_memcpy ensures that it will only allocate memory for the field
+ if it can be read from the event buffer, avoiding allocating a memory that
+ will not be used.
+
+ @param[out] destination the destination buffer.
+ @param[in] length the amount of bytes to allocate and read from the buffer
+ (and to move forward).
+ @param[in] flags flags to pass to MySQL server my_malloc() function.
+ */
+ void alloc_and_memcpy(unsigned char **destination, size_t length, int flags);
+
+ /**
+ Allocates memory to a destination buffer, copies from the cursor to the
+ destination buffer using strncpy() and moves forward the cursor.
+
+ See comments on alloc_and_memcpy() for more details.
+
+ @param[out] destination the destination buffer.
+ @param[in] length the amount of bytes to allocate and read from the buffer
+ (and to forward).
+ @param[in] flags flags to pass to MySQL server my_malloc() function.
+ */
+ void alloc_and_strncpy(char **destination, size_t length, int flags);
+
+ /**
+ Reads string from cursor.
+
+ Reads in the following format:
+ 1) Reads length stored on cursor first index. Moves cursor forward 1 byte.
+ 2) Set destination pointer to the cursor. Moves cursor forward length bytes.
+
+ @param[out] destination the destination pointer.
+ @param[out] length the amount of bytes to allocate and read from the buffer
+ (and to move forward).
+ */
+ void read_str_at_most_255_bytes(const char **destination, uint8_t *length);
+
+ /**
+ Reads a packed value.
+
+ This function can move the cursor forward by 1, 3, 4 or 9 bytes depending on
+ the value to be returned.
+
+ @return the packed value.
+ */
+ uint64_t net_field_length_ll();
+
+ /**
+ Reads a transaction context data set.
+
+ @param[in] set_len length of the set object (and to move forward).
+ @param[out] set pointer to the set object to be filled.
+ */
+ void read_data_set(uint32_t set_len, std::list<const char *> *set);
+
+ /**
+ Reads a view change certification map.
+
+ @param[in] map_len the length of the certification info map (and to move
+ forward).
+ @param[out] map the certification info map to be filled.
+ */
+ void read_data_map(uint32_t map_len, std::map<std::string, std::string> *map);
+
+ /**
+ Copy a string into the destination buffer up to a max length.
+
+ @param[out] destination the destination buffer.
+ @param[in] max_length the max length to copy from the cursor.
+ @param[in] dest_length the max length supported by the destination buffer.
+ */
+ void strncpyz(char *destination, size_t max_length, size_t dest_length);
+
+ /**
+ Fills a vector with a sequence of bytes from the cursor.
+
+ @param[out] destination the vector be filled.
+ @param[in] length the amount of bytes to read from the cursor (and to move
+ forward).
+ */
+ void assign(std::vector<uint8_t> *destination, size_t length);
+
+ private:
+ /* The buffer with the serialized binary log event */
+ const char *m_buffer;
+ /* The cursor: a pointer to the current read position in the buffer */
+ const char *m_ptr;
+ /* The length of the buffer */
+ unsigned long long m_length;
+ /* The limit the reader shall respect when reading from the buffer */
+ unsigned long long m_limit;
+ /* The pointer to the current error message, or nullptr */
+ const char *m_error;
+
+ /**
+ Wrapper to le16toh to be used by read_and_letoh function.
+
+ @param[in] value the value to be converted.
+
+ @return the converted value.
+ */
+ uint16_t letoh(uint16_t value) { return le16toh(value); }
+
+ /**
+ Wrapper to le32toh to be used by read_and_letoh function.
+
+ @param[in] value the value to be converted.
+
+ @return the converted value.
+ */
+ int32_t letoh(int32_t value) { return le32toh(value); }
+
+ /**
+ Wrapper to le32toh to be used by read_and_letoh function.
+
+ @param[in] value the value to be converted.
+
+ @return the converted value.
+ */
+ uint32_t letoh(uint32_t value) { return le32toh(value); }
+
+ /**
+ Wrapper to le64toh to be used by read_and_letoh function.
+
+ @param[in] value the value to be converted.
+
+ @return the converted value.
+ */
+ int64_t letoh(int64_t value) { return le64toh(value); }
+
+ /**
+ Wrapper to le64toh to be used by read_and_letoh function.
+
+ @param[in] value the value to be converted.
+
+ @return the converted value.
+ */
+ uint64_t letoh(uint64_t value) { return le64toh(value); }
+};
+} // end namespace binary_log
+/**
+ @} (end of group Replication)
+*/
+#endif /* EVENT_READER_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/load_data_events.h b/contrib/libs/libmysql_r/libbinlogevents/include/load_data_events.h
new file mode 100644
index 0000000000..4c8533bae3
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/load_data_events.h
@@ -0,0 +1,396 @@
+/* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file load_data_events.h
+
+ @brief LOAD DATA INFILE is not written to the binary log like other
+ statements. It is written as one or more events in a packed format,
+ not as a cleartext statement in the binary log. The events indicate
+ what options are present in the statement and how to process the data file.
+*/
+
+#ifndef LOAD_DATA_EVENTS_INCLUDED
+#define LOAD_DATA_EVENTS_INCLUDED
+
+#include <sys/types.h>
+#include "statement_events.h"
+#include "table_id.h"
+
+/*
+ These are flags and structs to handle all the LOAD DATA INFILE options (LINES
+ TERMINATED etc).
+ DUMPFILE_FLAG is probably not used (DUMPFILE is a clause of SELECT,
+ not of LOAD DATA).
+*/
+#define DUMPFILE_FLAG 0x1
+#define OPT_ENCLOSED_FLAG 0x2
+#define REPLACE_FLAG 0x4
+#define IGNORE_FLAG 0x8
+
+#define FIELD_TERM_EMPTY 0x1
+#define ENCLOSED_EMPTY 0x2
+#define LINE_TERM_EMPTY 0x4
+#define LINE_START_EMPTY 0x8
+#define ESCAPED_EMPTY 0x10
+
+namespace binary_log {
+/**
+ Elements of this enum describe how LOAD DATA handles duplicates.
+*/
+enum enum_load_dup_handling {
+ LOAD_DUP_ERROR = 0,
+ LOAD_DUP_IGNORE,
+ LOAD_DUP_REPLACE
+};
+
+/**
+ @class Execute_load_query_event
+
+ Event responsible for LOAD DATA execution, it similar to Query_event
+ but before executing the query it substitutes original filename in LOAD DATA
+ query with name of temporary file.
+
+ The first 13 bytes of the Post-Header for this event are the same as for
+ Query_event, as is the initial status variable block in the Body.
+
+ @section Execute_load_query_event_binary_format Binary Format
+
+ The additional members of the events are the following:
+
+ <table>
+ <caption>Body for Execute_load_query_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>file_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>ID of the temporary file to load</td>
+ </tr>
+
+ <tr>
+ <td>fn_pos_start</td>
+ <td>4 byte unsigned integer</td>
+ <td>The start position within the statement for filename substitution</td>
+ </tr>
+ <tr>
+
+ <td>fn_pos_end</td>
+ <td>4 byte unsigned integer</td>
+ <td>The end position within the statement for filename substitution</td>
+ </tr>
+
+ <tr>
+ <td>dup_handling</td>
+ <td>enum_load_dup_handling</td>
+ <td>Represents information on how to handle duplicates:
+ LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE= 1, LOAD_DUP_REPLACE= 2</td>
+ </tr>
+ </table>
+*/
+class Execute_load_query_event : public virtual Query_event {
+ public:
+ enum Execute_load_query_event_offset {
+ /** ELQ = "Execute Load Query" */
+ ELQ_FILE_ID_OFFSET = QUERY_HEADER_LEN,
+ ELQ_FN_POS_START_OFFSET = ELQ_FILE_ID_OFFSET + 4,
+ ELQ_FN_POS_END_OFFSET = ELQ_FILE_ID_OFFSET + 8,
+ ELQ_DUP_HANDLING_OFFSET = ELQ_FILE_ID_OFFSET + 12
+ };
+
+ int32_t file_id; /** file_id of temporary file */
+ uint32_t fn_pos_start; /** pointer to the part of the query that should
+ be substituted */
+ uint32_t fn_pos_end; /** pointer to the end of this part of query */
+
+ /**
+ We have to store type of duplicate handling explicitly, because
+ for LOAD DATA it also depends on LOCAL option. And this part
+ of query will be rewritten during replication so this information
+ may be lost...
+ */
+ enum_load_dup_handling dup_handling;
+
+ Execute_load_query_event(uint32_t file_id_arg, uint32_t fn_pos_start,
+ uint32_t fn_pos_end, enum_load_dup_handling dup);
+
+ /**
+ The constructor receives a buffer and instantiates a
+ Execute_load_query_event filled in with the data from the buffer.
+
+ <pre>
+ The fixed event data part buffer layout is as follows:
+ +---------------------------------------------------------------------+
+ | thread_id | query_exec_time | db_len | error_code | status_vars_len |
+ +---------------------------------------------------------------------+
+ +----------------------------------------------------+
+ | file_id | fn_pos_start | fn_pos_end | dup_handling |
+ +----------------------------------------------------+
+ </pre>
+
+ <pre>
+ The fixed event data part buffer layout is as follows:
+ +------------------------------------------------------------------+
+ | Zero or more status variables | db | LOAD DATA INFILE statement |
+ +------------------------------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Execute_load_query_event(const char *buf,
+ const Format_description_event *fde);
+
+ ~Execute_load_query_event() {}
+};
+
+/**
+ @class Delete_file_event
+
+ DELETE_FILE_EVENT occurs when the LOAD DATA failed on the master.
+ This event notifies the slave not to do the load and to delete
+ the temporary file.
+
+ @section Delete_file_event_binary_format Binary Format
+
+ The variable data part is empty. The post header contains the following:
+
+ <table>
+ <caption>Post header for Delete_file_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>file_id</td>
+ <td>32 bit integer</td>
+ <td>The ID of the file to be deleted</td>
+ </tr>
+ </table>
+*/
+class Delete_file_event : public Binary_log_event {
+ protected:
+ // Required by Delete_file_log_event(THD* ..)
+ Delete_file_event(uint32_t file_id_arg, const char *db_arg)
+ : Binary_log_event(DELETE_FILE_EVENT), file_id(file_id_arg), db(db_arg) {}
+
+ public:
+ enum Delete_file_offset {
+ /** DF = "Delete File" */
+ DF_FILE_ID_OFFSET = 0
+ };
+
+ uint32_t file_id;
+ const char *db; /** see comment in Append_block_event */
+
+ /**
+ The buffer layout for fixed data part is as follows:
+ <pre>
+ +---------+
+ | file_id |
+ +---------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Delete_file_event(const char *buf, const Format_description_event *fde);
+
+ ~Delete_file_event() {}
+
+#ifndef HAVE_MYSYS
+ // TODO(WL#7684): Implement the method print_event_info and print_long_info
+ // for
+ // all the events supported in MySQL Binlog
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+};
+
+/**
+ @class Append_block_event
+
+ This event is created to contain the file data. One LOAD_DATA_INFILE
+ can have 0 or more instances of this event written to the binary log
+ depending on the size of the file. If the file to be loaded is greater
+ than the threshold value, which is roughly 2^17 bytes, the file is
+ divided into blocks of size equal to the threshold, and each block
+ is sent across as a separate event.
+
+ @section Append_block_event_binary_format Binary Format
+
+ The post header contains the following:
+
+ <table>
+ <caption>Post header for Append_block_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>file_id</td>
+ <td>32 bit integer</td>
+ <td>The ID of the file to append the block to</td>
+ </tr>
+ </table>
+
+ The body of the event contains the raw data to load. The raw data
+ size is the event size minus the size of all the fixed event parts.
+*/
+class Append_block_event : public Binary_log_event {
+ protected:
+ /**
+ This constructor is used by the MySQL server.
+ */
+ Append_block_event(const char *db_arg, unsigned char *block_arg,
+ unsigned int block_len_arg, uint32_t file_id_arg)
+ : Binary_log_event(APPEND_BLOCK_EVENT),
+ block(block_arg),
+ block_len(block_len_arg),
+ file_id(file_id_arg),
+ db(db_arg) {}
+
+ Append_block_event(Log_event_type type_arg = APPEND_BLOCK_EVENT)
+ : Binary_log_event(type_arg) {}
+
+ public:
+ enum Append_block_offset {
+ /** AB = "Append Block" */
+ AB_FILE_ID_OFFSET = 0,
+ AB_DATA_OFFSET = APPEND_BLOCK_HEADER_LEN
+ };
+
+ unsigned char *block;
+ unsigned int block_len;
+ uint32_t file_id;
+ /**
+ 'db' is filled when the event is created in mysql_load() (the
+ event needs to have a 'db' member to be well filtered by
+ binlog-*-db rules). 'db' is not written to the binlog (it's not
+ used by Append_block_log_event::write()), so it can't be read in
+ the Append_block_event(const char* buf, int event_len)
+ constructor. In other words, 'db' is used only for filtering by
+ binlog-*-db rules. Create_file_event is different: it's 'db'
+ (which is inherited from Load_event) is written to the binlog
+ and can be re-read.
+ */
+ const char *db;
+
+ /**
+ Appends the buffered data, received as a parameter, to the file being loaded
+ via LOAD_DATA_FILE.
+
+ The buffer layout for fixed data part is as follows:
+ <pre>
+ +---------+
+ | file_id |
+ +---------+
+ </pre>
+
+ The buffer layout for variable data part is as follows:
+ <pre>
+ +-------------------+
+ | block | block_len |
+ +-------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Append_block_event(const char *buf, const Format_description_event *fde);
+ ~Append_block_event() {}
+
+#ifndef HAVE_MYSYS
+ // TODO(WL#7684): Implement the method print_event_info and print_long_info
+ // for
+ // all the events supported in MySQL Binlog
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+};
+
+/**
+ @class Begin_load_query_event
+
+ Event for the first block of file to be loaded, its only difference from
+ Append_block event is that this event creates or truncates existing file
+ before writing data.
+
+ @section Begin_load_query_event_binary_format Binary Format
+
+ The Post-Header and Body for this event type are empty; it only has
+ the Common-Header.
+*/
+class Begin_load_query_event : public virtual Append_block_event {
+ protected:
+ Begin_load_query_event() : Append_block_event(BEGIN_LOAD_QUERY_EVENT) {}
+
+ public:
+ /**
+ The buffer layout for fixed data part is as follows:
+ <pre>
+ +---------+
+ | file_id |
+ +---------+
+ </pre>
+
+ The buffer layout for variable data part is as follows:
+ <pre>
+ +-------------------+
+ | block | block_len |
+ +-------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Begin_load_query_event(const char *buf, const Format_description_event *fde);
+
+ ~Begin_load_query_event() {}
+
+#ifndef HAVE_MYSYS
+ // TODO(WL#7684): Implement the method print_event_info and print_long_info
+ // for
+ // all the events supported in MySQL Binlog
+ void print_event_info(std::ostream &) {}
+ void print_long_info(std::ostream &) {}
+#endif
+};
+} // end namespace binary_log
+/**
+ @} (end of group Replication)
+*/
+#endif /* LOAD_DATA_EVENTS_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/rows_event.h b/contrib/libs/libmysql_r/libbinlogevents/include/rows_event.h
new file mode 100644
index 0000000000..f3593b2c95
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/rows_event.h
@@ -0,0 +1,1165 @@
+/* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file rows_event.h
+
+ @brief Contains the classes representing events which are used for row based
+ replication. In row-based replication, the master writes events to the binary
+ log that indicate how individual table rows are changed.
+*/
+
+#ifndef ROWS_EVENT_INCLUDED
+#define ROWS_EVENT_INCLUDED
+
+#include <vector>
+#include "control_events.h"
+#include "table_id.h"
+
+// Undefine conflicting wingdi.h macro
+#undef DEFAULT_CHARSET
+
+/**
+ 1 byte length, 1 byte format
+ Length is total length in bytes, including 2 byte header
+ Length values 0 and 1 are currently invalid and reserved.
+*/
+#define EXTRA_ROW_INFO_LEN_OFFSET 0
+#define EXTRA_ROW_INFO_FORMAT_OFFSET 1
+#define EXTRA_ROW_INFO_HEADER_LENGTH 2
+#define EXTRA_ROW_INFO_MAX_PAYLOAD (255 - EXTRA_ROW_INFO_HEADER_LENGTH)
+
+#define ROWS_MAPID_OFFSET 0
+#define ROWS_FLAGS_OFFSET 6
+#define ROWS_VHLEN_OFFSET 8
+#define EXTRA_ROW_INFO_TYPECODE_LENGTH 1
+#define EXTRA_ROW_PART_INFO_VALUE_LENGTH 2
+
+/**
+ This is the typecode defined for the different elements present in
+ the container Extra_row_info, this is different from the format information
+ stored inside extra_row_ndb_info at EXTRA_ROW_INFO_FORMAT_OFFSET.
+*/
+enum class enum_extra_row_info_typecode { NDB = 0, PART = 1 };
+
+namespace binary_log {
+/**
+ @class Table_map_event
+
+ In row-based mode, every row operation event is preceded by a
+ Table_map_event which maps a table definition to a number. The
+ table definition consists of database name, table name, and column
+ definitions.
+
+ @section Table_map_event_binary_format Binary Format
+
+ The Post-Header has the following components:
+
+ <table>
+ <caption>Post-Header for Table_map_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>table_id</td>
+ <td>6 bytes unsigned integer</td>
+ <td>The number that identifies the table.</td>
+ </tr>
+
+ <tr>
+ <td>flags</td>
+ <td>2 byte bitfield</td>
+ <td>Reserved for future use; currently always 0.</td>
+ </tr>
+
+ </table>
+
+ The Body has the following components:
+
+ <table>
+ <caption>Body for Table_map_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>database_name</td>
+ <td>one byte string length, followed by null-terminated string</td>
+ <td>The name of the database in which the table resides. The name
+ is represented as a one byte unsigned integer representing the
+ number of bytes in the name, followed by length bytes containing
+ the database name, followed by a terminating 0 byte. (Note the
+ redundancy in the representation of the length.) </td>
+ </tr>
+
+ <tr>
+ <td>table_name</td>
+ <td>one byte string length, followed by null-terminated string</td>
+ <td>The name of the table, encoded the same way as the database
+ name above.</td>
+ </tr>
+
+ <tr>
+ <td>column_count</td>
+ <td>@ref packed_integer "Packed Integer"</td>
+ <td>The number of columns in the table, represented as a packed
+ variable-length integer.</td>
+ </tr>
+
+ <tr>
+ <td>column_type</td>
+ <td>List of column_count 1 byte enumeration values</td>
+ <td>The type of each column in the table, listed from left to
+ right. Each byte is mapped to a column type according to the
+ enumeration type enum_field_types defined in mysql_com.h. The
+ mapping of types to numbers is listed in the table @ref
+ Table_table_map_event_column_types "below" (along with
+ description of the associated metadata field). </td>
+ </tr>
+
+ <tr>
+ <td>metadata_length</td>
+ <td>@ref packed_integer "Packed Integer"</td>
+ <td>The length of the following metadata block</td>
+ </tr>
+
+ <tr>
+ <td>metadata</td>
+ <td>list of metadata for each column</td>
+ <td>For each column from left to right, a chunk of data who's
+ length and semantics depends on the type of the column. The
+ length and semantics for the metadata for each column are listed
+ in the table @ref Table_table_map_event_column_types
+ "below".</td>
+ </tr>
+
+ <tr>
+ <td>null_bits</td>
+ <td>column_count bits, rounded up to nearest byte</td>
+ <td>For each column, a bit indicating whether data in the column
+ can be NULL or not. The number of bytes needed for this is
+ int((column_count + 7) / 8). The flag for the first column from the
+ left is in the least-significant bit of the first byte, the second
+ is in the second least significant bit of the first byte, the
+ ninth is in the least significant bit of the second byte, and so
+ on. </td>
+ </tr>
+
+ <tr>
+ <td>optional metadata fields</td>
+ <td>optional metadata fields are stored in Type, Length, Value(TLV) format.
+ Type takes 1 byte. Length is a packed integer value. Values takes
+ Length bytes.
+ </td>
+ <td>There are some optional metadata defined. They are listed in the table
+ @ref Table_table_map_event_optional_metadata. Optional metadata fields
+ follow null_bits. Whether binlogging an optional metadata is decided by the
+ server. The order is not defined, so they can be binlogged in any order.
+ </td>
+ </tr>
+ </table>
+
+ The table below lists all column types, along with the numerical
+ identifier for it and the size and interpretation of meta-data used
+ to describe the type.
+
+ @anchor Table_table_map_event_column_types
+ <table>
+ <caption>Table_map_event column types: numerical identifier and
+ metadata</caption>
+ <tr>
+ <th>Name</th>
+ <th>Identifier</th>
+ <th>Size of metadata in bytes</th>
+ <th>Description of metadata</th>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_DECIMAL</td><td>0</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_TINY</td><td>1</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_SHORT</td><td>2</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_LONG</td><td>3</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_FLOAT</td><td>4</td>
+ <td>1 byte</td>
+ <td>1 byte unsigned integer, representing the "pack_length", which
+ is equal to sizeof(float) on the server from which the event
+ originates.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_DOUBLE</td><td>5</td>
+ <td>1 byte</td>
+ <td>1 byte unsigned integer, representing the "pack_length", which
+ is equal to sizeof(double) on the server from which the event
+ originates.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_NULL</td><td>6</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_TIMESTAMP</td><td>7</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_LONGLONG</td><td>8</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_INT24</td><td>9</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_DATE</td><td>10</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_TIME</td><td>11</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_DATETIME</td><td>12</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_YEAR</td><td>13</td>
+ <td>0</td>
+ <td>No column metadata.</td>
+ </tr>
+
+ <tr>
+ <td><i>MYSQL_TYPE_NEWDATE</i></td><td><i>14</i></td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_VARCHAR</td><td>15</td>
+ <td>2 bytes</td>
+ <td>2 byte unsigned integer representing the maximum length of
+ the string.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_BIT</td><td>16</td>
+ <td>2 bytes</td>
+ <td>A 1 byte unsigned int representing the length in bits of the
+ bitfield (0 to 64), followed by a 1 byte unsigned int
+ representing the number of bytes occupied by the bitfield. The
+ number of bytes is either int((length + 7) / 8) or int(length / 8).
+ </td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_NEWDECIMAL</td><td>246</td>
+ <td>2 bytes</td>
+ <td>A 1 byte unsigned int representing the precision, followed
+ by a 1 byte unsigned int representing the number of decimals.</td>
+ </tr>
+
+ <tr>
+ <td><i>MYSQL_TYPE_ENUM</i></td><td><i>247</i></td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td><i>MYSQL_TYPE_SET</i></td><td><i>248</i></td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_TINY_BLOB</td><td>249</td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td><i>MYSQL_TYPE_MEDIUM_BLOB</i></td><td><i>250</i></td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td><i>MYSQL_TYPE_LONG_BLOB</i></td><td><i>251</i></td>
+ <td>&ndash;</td>
+ <td><i>This enumeration value is only used internally and cannot
+ exist in a binlog.</i></td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_BLOB</td><td>252</td>
+ <td>1 byte</td>
+ <td>The pack length, i.e., the number of bytes needed to represent
+ the length of the blob: 1, 2, 3, or 4.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_VAR_STRING</td><td>253</td>
+ <td>2 bytes</td>
+ <td>This is used to store both strings and enumeration values.
+ The first byte is a enumeration value storing the <i>real
+ type</i>, which may be either MYSQL_TYPE_VAR_STRING or
+ MYSQL_TYPE_ENUM. The second byte is a 1 byte unsigned integer
+ representing the field size, i.e., the number of bytes needed to
+ store the length of the string.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_STRING</td><td>254</td>
+ <td>2 bytes</td>
+ <td>The first byte is always MYSQL_TYPE_VAR_STRING (i.e., 253).
+ The second byte is the field size, i.e., the number of bytes in
+ the representation of size of the string: 3 or 4.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_GEOMETRY</td><td>255</td>
+ <td>1 byte</td>
+ <td>The pack length, i.e., the number of bytes needed to represent
+ the length of the geometry: 1, 2, 3, or 4.</td>
+ </tr>
+
+ <tr>
+ <td>MYSQL_TYPE_TYPED_ARRAY</td><td>15</td>
+ <td>up to 4 bytes</td>
+ <td>
+ - The first byte holds the MySQL type for the elements.
+ - The following 0, 1, 2, or 3 bytes holds the metadata for the MySQL
+ type for the elements. The contents of these bytes depends on the
+ element type, as described in the other rows of this table.
+ </td>
+ </tr>
+
+ </table>
+
+ The table below lists all optional metadata types, along with the numerical
+ identifier for it and the size and interpretation of meta-data used
+ to describe the type.
+
+ @anchor Table_table_map_event_optional_metadata
+ <table>
+ <caption>Table_map_event optional metadata types: numerical identifier and
+ metadata. Optional metadata fields are stored in TLV fields.
+ Format of values are described in this table. </caption>
+ <tr>
+ <th>Type</th>
+ <th>Description</th>
+ <th>Format</th>
+ </tr>
+ <tr>
+ <td>SIGNEDNESS</td>
+ <td>signedness of numeric colums. This is included for all values of
+ binlog_row_metadata.</td>
+ <td>For each numeric column, a bit indicates whether the numeric
+ colunm has unsigned flag. 1 means it is unsigned. The number of
+ bytes needed for this is int((column_count + 7) / 8). The order is
+ the same as the order of column_type field.</td>
+ </tr>
+ <tr>
+ <td>DEFAULT_CHARSET</td>
+ <td>Charsets of character columns. It has a default charset for
+ the case that most of character columns have same charset and the
+ most used charset is binlogged as default charset.Collation
+ numbers are binlogged for identifying charsets. They are stored in
+ packed length format. Either DEFAULT_CHARSET or COLUMN_CHARSET is
+ included for all values of binlog_row_metadata.</td>
+ <td>Default charset's collation is logged first. The charsets which are not
+ same to default charset are logged following default charset. They are
+ logged as column index and charset collation number pair sequence. The
+ column index is counted only in all character columns. The order is same to
+ the order of column_type
+ field. </td>
+ </tr>
+ <tr>
+ <td>COLUMN_CHARSET</td>
+ <td>Charsets of character columns. For the case that most of columns have
+ different charsets, this field is logged. It is never logged with
+ DEFAULT_CHARSET together. Either DEFAULT_CHARSET or COLUMN_CHARSET is
+ included for all values of binlog_row_metadata.</td>
+ <td>It is a collation number sequence for all character columns.</td>
+ </tr>
+ <tr>
+ <td>COLUMN_NAME</td>
+ <td>Names of columns. This is only included if
+ binlog_row_metadata=FULL.</td>
+ <td>A sequence of column names. For each column name, 1 byte for
+ the string length in bytes is followed by a string without null
+ terminator.</td>
+ </tr>
+ <tr>
+ <td>SET_STR_VALUE</td>
+ <td>The string values of SET columns. This is only included if
+ binlog_row_metadata=FULL.</td>
+ <td>For each SET column, a pack_length representing the value
+ count is followed by a sequence of length and string pairs. length
+ is the byte count in pack_length format. The string has no null
+ terminator.</td>
+ </tr>
+ <tr>
+ <td>ENUM_STR_VALUE</td>
+ <td>The string values is ENUM columns. This is only included
+ if binlog_row_metadata=FULL.</td>
+ <td>The format is the same as SET_STR_VALUE.</td>
+ </tr>
+ <tr>
+ <td>GEOMETRY_TYPE</td>
+ <td>The real type of geometry columns. This is only included
+ if binlog_row_metadata=FULL.</td>
+ <td>A sequence of real type of geometry columns are stored in pack_length
+ format. </td>
+ </tr>
+ <tr>
+ <td>SIMPLE_PRIMARY_KEY</td>
+ <td>The primary key without any prefix. This is only included
+ if binlog_row_metadata=FULL and there is a primary key where every
+ key part covers an entire column.</td>
+ <td>A sequence of column indexes. The indexes are stored in pack_length
+ format.</td>
+ </tr>
+ <tr>
+ <td>PRIMARY_KEY_WITH_PREFIX</td>
+ <td>The primary key with some prefix. It doesn't appear together with
+ SIMPLE_PRIMARY_KEY. This is only included if
+ binlog_row_metadata=FULL and there is a primary key where some key
+ part covers a prefix of the column.</td>
+ <td>A sequence of column index and prefix length pairs. Both
+ column index and prefix length are in pack_length format. Prefix length
+ 0 means that the whole column value is used.</td>
+ </tr>
+ <tr>
+ <td>ENUM_AND_SET_DEFAULT_CHARSET</td>
+ <td>Charsets of ENUM and SET columns. It has the same layout as
+ DEFAULT_CHARSET. If there are SET or ENUM columns and
+ binlog_row_metadata=FULL, exactly one of
+ ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET
+ appears (the encoder chooses the representation that uses the
+ least amount of space). Otherwise, none of them appears.</td>
+ <td>The same format as for DEFAULT_CHARSET, except it counts ENUM
+ and SET columns rather than character columns.</td>
+ </tr>
+ <tr>
+ <td>ENUM_AND_SET_COLUMN_CHARSET</td>
+ <td>Charsets of ENUM and SET columns. It has the same layout as
+ COLUMN_CHARSET. If there are SET or ENUM columns and
+ binlog_row_metadata=FULL, exactly one of
+ ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET
+ appears (the encoder chooses the representation that uses the
+ least amount of space). Otherwise, none of them appears.</td>
+ <td>The same format as for COLUMN_CHARSET, except it counts ENUM
+ and SET columns rather than character columns.</td>
+ </tr>
+ </table>
+*/
+class Table_map_event : public Binary_log_event {
+ public:
+ /** Constants representing offsets */
+ enum Table_map_event_offset {
+ /** TM = "Table Map" */
+ TM_MAPID_OFFSET = 0,
+ TM_FLAGS_OFFSET = 6
+ };
+
+ typedef uint16_t flag_set;
+
+ /**
+ DEFAULT_CHARSET and COLUMN_CHARSET don't appear together, and
+ ENUM_AND_SET_DEFAULT_CHARSET and ENUM_AND_SET_COLUMN_CHARSET don't
+ appear together. They are just alternative ways to pack character
+ set information. When binlogging, it logs character sets in the
+ way that occupies least storage.
+
+ SIMPLE_PRIMARY_KEY and PRIMARY_KEY_WITH_PREFIX don't appear together.
+ SIMPLE_PRIMARY_KEY is for the primary keys which only use whole values of
+ pk columns. PRIMARY_KEY_WITH_PREFIX is
+ for the primary keys which just use part value of pk columns.
+ */
+ enum Optional_metadata_field_type {
+ SIGNEDNESS = 1, // UNSIGNED flag of numeric columns
+ DEFAULT_CHARSET, /* Character set of string columns, optimized to
+ minimize space when many columns have the
+ same charset. */
+ COLUMN_CHARSET, /* Character set of string columns, optimized to
+ minimize space when columns have many
+ different charsets. */
+ COLUMN_NAME,
+ SET_STR_VALUE, // String value of SET columns
+ ENUM_STR_VALUE, // String value of ENUM columns
+ GEOMETRY_TYPE, // Real type of geometry columns
+ SIMPLE_PRIMARY_KEY, // Primary key without prefix
+ PRIMARY_KEY_WITH_PREFIX, // Primary key with prefix
+ ENUM_AND_SET_DEFAULT_CHARSET, /* Character set of enum and set
+ columns, optimized to minimize
+ space when many columns have the
+ same charset. */
+ ENUM_AND_SET_COLUMN_CHARSET, /* Character set of enum and set
+ columns, optimized to minimize
+ space when many columns have the
+ same charset. */
+ };
+
+ /**
+ Metadata_fields organizes m_optional_metadata into a structured format which
+ is easy to access.
+ */
+ struct Optional_metadata_fields {
+ typedef std::pair<unsigned int, unsigned int> uint_pair;
+ typedef std::vector<std::string> str_vector;
+
+ struct Default_charset {
+ Default_charset() : default_charset(0) {}
+ bool empty() const { return default_charset == 0; }
+
+ // Default charset for the columns which are not in charset_pairs.
+ unsigned int default_charset;
+
+ /* The uint_pair means <column index, column charset number>. */
+ std::vector<uint_pair> charset_pairs;
+ };
+
+ // Contents of DEFAULT_CHARSET field are converted into Default_charset.
+ Default_charset m_default_charset;
+ // Contents of ENUM_AND_SET_DEFAULT_CHARSET are converted into
+ // Default_charset.
+ Default_charset m_enum_and_set_default_charset;
+ std::vector<bool> m_signedness;
+ // Character set number of every string column
+ std::vector<unsigned int> m_column_charset;
+ // Character set number of every ENUM or SET column.
+ std::vector<unsigned int> m_enum_and_set_column_charset;
+ std::vector<std::string> m_column_name;
+ // each str_vector stores values of one enum/set column
+ std::vector<str_vector> m_enum_str_value;
+ std::vector<str_vector> m_set_str_value;
+ std::vector<unsigned int> m_geometry_type;
+ /*
+ The uint_pair means <column index, prefix length>. Prefix length is 0 if
+ whole column value is used.
+ */
+ std::vector<uint_pair> m_primary_key;
+
+ /*
+ It parses m_optional_metadata and populates into above variables.
+
+ @param[in] optional_metadata points to the begin of optional metadata
+ fields in table_map_event.
+ @param[in] optional_metadata_len length of optional_metadata field.
+ */
+ Optional_metadata_fields(unsigned char *optional_metadata,
+ unsigned int optional_metadata_len);
+ // It is used to specify the validity of the deserialized structure
+ bool is_valid;
+ };
+
+ /**
+ <pre>
+ The buffer layout for fixed data part is as follows:
+ +-----------------------------------+
+ | table_id | Reserved for future use|
+ +-----------------------------------+
+ </pre>
+
+ <pre>
+ The buffer layout for variable data part is as follows:
+ +--------------------------------------------------------------------------+
+ | db len| db name | table len| table name | no of cols | array of col types|
+ +--------------------------------------------------------------------------+
+ +---------------------------------------------+
+ | metadata len | metadata block | m_null_bits |
+ +---------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Table_map_event(const char *buf, const Format_description_event *fde);
+
+ Table_map_event(const Table_id &tid, unsigned long colcnt, const char *dbnam,
+ size_t dblen, const char *tblnam, size_t tbllen)
+ : Binary_log_event(TABLE_MAP_EVENT),
+ m_table_id(tid),
+ m_data_size(0),
+ m_dbnam(""),
+ m_dblen(dblen),
+ m_tblnam(""),
+ m_tbllen(tbllen),
+ m_colcnt(colcnt),
+ m_field_metadata_size(0),
+ m_field_metadata(0),
+ m_null_bits(0),
+ m_optional_metadata_len(0),
+ m_optional_metadata(nullptr) {
+ if (dbnam) m_dbnam = std::string(dbnam, m_dblen);
+ if (tblnam) m_tblnam = std::string(tblnam, m_tbllen);
+ }
+
+ virtual ~Table_map_event();
+
+ /** Event post header contents */
+ Table_id m_table_id;
+ flag_set m_flags;
+
+ size_t m_data_size; /** event data size */
+
+ /** Event body contents */
+ std::string m_dbnam;
+ size_t m_dblen;
+ std::string m_tblnam;
+ size_t m_tbllen;
+ unsigned long m_colcnt;
+ unsigned char *m_coltype;
+
+ /**
+ The size of field metadata buffer set by calling save_field_metadata()
+ */
+ unsigned long m_field_metadata_size;
+ unsigned char *m_field_metadata; /** field metadata */
+ unsigned char *m_null_bits;
+ unsigned int m_optional_metadata_len;
+ unsigned char *m_optional_metadata;
+
+ Table_map_event()
+ : Binary_log_event(TABLE_MAP_EVENT),
+ m_coltype(0),
+ m_field_metadata_size(0),
+ m_field_metadata(0),
+ m_null_bits(0),
+ m_optional_metadata_len(0),
+ m_optional_metadata(nullptr) {}
+
+ unsigned long long get_table_id() { return m_table_id.id(); }
+ std::string get_table_name() { return m_tblnam; }
+ std::string get_db_name() { return m_dbnam; }
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+
+/**
+ @class Rows_event
+
+ Common base class for all row-containing binary log events.
+
+ RESPONSIBILITIES
+
+ - Provide an interface for adding an individual row to the event.
+
+ @section Rows_event_binary_format Binary Format
+
+ The Post-Header has the following components:
+
+ <table>
+ <caption>Post-Header for Rows_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>table_id</td>
+ <td>6 bytes unsigned integer</td>
+ <td>The number that identifies the table</td>
+ </tr>
+
+ <tr>
+ <td>flags</td>
+ <td>2 byte bitfield</td>
+ <td>Reserved for future use; currently always 0.</td>
+ </tr>
+
+ </table>
+
+ The Body has the following components:
+
+ <table>
+ <caption>Body for Rows_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+
+ <tr>
+ <td>width</td>
+ <td>packed integer</td>
+ <td>Represents the number of columns in the table</td>
+ </tr>
+
+ <tr>
+ <td>cols</td>
+ <td>Bitfield, variable sized</td>
+ <td>Indicates whether each column is used, one bit per column.
+ For this field, the amount of storage required is
+ INT((width + 7) / 8) bytes. </td>
+ </tr>
+
+ <tr>
+ <td>extra_row_info</td>
+ <td>An object of class Extra_row_info</td>
+ <td>The class Extra_row_info will be storing the information related
+ to m_extra_row_ndb_info and partition info (partition_id and
+ source_partition_id). At any given time a Rows_event can have both, one
+ or none of ndb_info and partition_info present as part of Rows_event.
+ In case both ndb_info and partition_info are present then below will
+ be the order in which they will be stored.
+
+ @verbatim
+ +----------+--------------------------------------+
+ |type_code | extra_row_ndb_info |
+ +--- ------+--------------------------------------+
+ | NDB |Len of ndb_info |Format |ndb_data |
+ | 1 byte |1 byte |1 byte |len - 2 byte |
+ +----------+----------------+-------+-------------+
+
+ In case of INSERT/DELETE
+ +-----------+----------------+
+ | type_code | partition_info |
+ +-----------+----------------+
+ | PART | partition_id |
+ | (1 byte) | 2 byte |
+ +-----------+----------------+
+
+ In case of UPDATE
+ +-----------+------------------------------------+
+ | type_code | partition_info |
+ +-----------+--------------+---------------------+
+ | PART | partition_id | source_partition_id |
+ | (1 byte) | 2 byte | 2 byte |
+ +-----------+--------------+---------------------+
+
+ source_partition_id is used only in the case of Update_event
+ to log the partition_id of the source partition.
+
+ @endverbatim
+ This is the format for any information stored as extra_row_info.
+ type_code is not a part of the class Extra_row_info as it is a constant
+ values used at the time of serializing and decoding the event.
+ </td>
+ </tr>
+
+ <tr>
+ <td>columns_before_image</td>
+ <td>vector of elements of type uint8_t</td>
+ <td>For DELETE and UPDATE only.
+ Bit-field indicating whether each column is used
+ one bit per column. For this field, the amount of storage
+ required for N columns is INT((N + 7) / 8) bytes.</td>
+ </tr>
+
+ <tr>
+ <td>columns_after_image</td>
+ <td>vector of elements of type uint8_t</td>
+ <td>For WRITE and UPDATE only.
+ Bit-field indicating whether each column is used in the
+ UPDATE_ROWS_EVENT and WRITE_ROWS_EVENT after-image; one bit per column.
+ For this field, the amount of storage required for N columns
+ is INT((N + 7) / 8) bytes.
+
+ @verbatim
+ +-------------------------------------------------------+
+ | Event Type | Cols_before_image | Cols_after_image |
+ +-------------------------------------------------------+
+ | DELETE | Deleted row | NULL |
+ | INSERT | NULL | Inserted row |
+ | UPDATE | Old row | Updated row |
+ +-------------------------------------------------------+
+ @endverbatim
+ </td>
+ </tr>
+
+ <tr>
+ <td>row</td>
+ <td>vector of elements of type uint8_t</td>
+ <td> A sequence of zero or more rows. The end is determined by the size
+ of the event. Each row has the following format:
+ - A Bit-field indicating whether each field in the row is NULL.
+ Only columns that are "used" according to the second field in
+ the variable data part are listed here. If the second field in
+ the variable data part has N one-bits, the amount of storage
+ required for this field is INT((N + 7) / 8) bytes.
+ - The row-image, containing values of all table fields. This only
+ lists table fields that are used (according to the second field
+ of the variable data part) and non-NULL (according to the
+ previous field). In other words, the number of values listed here
+ is equal to the number of zero bits in the previous field.
+ (not counting padding bits in the last byte).
+ @verbatim
+ For example, if a INSERT statement inserts into 4 columns of a
+ table, N= 4 (in the formula above).
+ length of bitmask= (4 + 7) / 8 = 1
+ Number of fields in the row= 4.
+
+ +------------------------------------------------+
+ |Null_bit_mask(4)|field-1|field-2|field-3|field 4|
+ +------------------------------------------------+
+ @endverbatim
+ </td>
+ </tr>
+ </table>
+*/
+class Rows_event : public Binary_log_event {
+ public:
+ /**
+ These definitions allow to combine the flags into an
+ appropriate flag set using the normal bitwise operators. The
+ implicit conversion from an enum-constant to an integer is
+ accepted by the compiler, which is then used to set the real set
+ of flags.
+ */
+ enum enum_flag {
+ /** Last event of a statement */
+ STMT_END_F = (1U << 0),
+ /** Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
+ NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
+ /** Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
+ RELAXED_UNIQUE_CHECKS_F = (1U << 2),
+ /**
+ Indicates that rows in this event are complete, that is contain
+ values for all columns of the table.
+ */
+ COMPLETE_ROWS_F = (1U << 3)
+ };
+
+ /**
+ Constructs an event directly. The members are assigned default values.
+
+ @param type_arg Type of ROW_EVENT. Expected types are:
+ - WRITE_ROWS_EVENT, WRITE_ROWS_EVENT_V1
+ - UPDATE_ROWS_EVENT, UPDATE_ROWS_EVENT_V1,
+ PARTIAL_UPDATE_ROWS_EVENT
+ - DELETE_ROWS_EVENT, DELETE_ROWS_EVENT_V1
+ */
+ explicit Rows_event(Log_event_type type_arg)
+ : Binary_log_event(type_arg),
+ m_table_id(0),
+ m_width(0),
+ columns_before_image(0),
+ columns_after_image(0),
+ row(0) {}
+ /**
+ The constructor is responsible for decoding the event contained in
+ the buffer.
+
+ <pre>
+ The buffer layout for fixed data part is as follows
+ +------------------------------------+
+ | table_id | reserved for future use |
+ +------------------------------------+
+ </pre>
+
+ <pre>
+ The buffer layout for variable data part is as follows
+ +------------------------------------------------------------------+
+ | var_header_len | column_before_image | columns_after_image | row |
+ +------------------------------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Rows_event(const char *buf, const Format_description_event *fde);
+
+ virtual ~Rows_event();
+
+ protected:
+ Log_event_type m_type; /** Actual event type */
+
+ /** Post header content */
+ Table_id m_table_id;
+ uint16_t m_flags; /** Flags for row-level events */
+
+ /* Body of the event */
+ unsigned long m_width; /** The width of the columns bitmap */
+ uint32_t n_bits_len; /** value determined by (m_width + 7) / 8 */
+ uint16_t var_header_len;
+
+ std::vector<uint8_t> columns_before_image;
+ std::vector<uint8_t> columns_after_image;
+ std::vector<uint8_t> row;
+
+ public:
+ class Extra_row_info {
+ private:
+ /** partition_id for a row in a partitioned table */
+ int m_partition_id;
+ /**
+ It is the partition_id of the source partition in case
+ of Update_event, the target's partition_id is m_partition_id.
+ This variable is used only in case of Update_event.
+ */
+ int m_source_partition_id;
+ /** The extra row info provided by NDB */
+ unsigned char *m_extra_row_ndb_info;
+
+ public:
+ Extra_row_info()
+ : m_partition_id(UNDEFINED),
+ m_source_partition_id(UNDEFINED),
+ m_extra_row_ndb_info(nullptr) {}
+
+ Extra_row_info(const Extra_row_info &) = delete;
+
+ int get_partition_id() const { return m_partition_id; }
+ void set_partition_id(int partition_id) {
+ BAPI_ASSERT(partition_id <= 65535);
+ m_partition_id = partition_id;
+ }
+
+ int get_source_partition_id() const { return m_source_partition_id; }
+ void set_source_partition_id(int source_partition_id) {
+ BAPI_ASSERT(source_partition_id <= 65535);
+ m_source_partition_id = source_partition_id;
+ }
+
+ unsigned char *get_ndb_info() const { return m_extra_row_ndb_info; }
+ void set_ndb_info(const unsigned char *ndb_info, size_t len) {
+ BAPI_ASSERT(!have_ndb_info());
+ m_extra_row_ndb_info =
+ static_cast<unsigned char *>(bapi_malloc(len, 16 /* flags */));
+ std::copy(ndb_info, ndb_info + len, m_extra_row_ndb_info);
+ }
+ /**
+ Compares the extra_row_info in a Row event, it checks three things
+ 1. The m_extra_row_ndb_info pointers. It compares their significant bytes.
+ 2. Partition_id
+ 3. source_partition_id
+
+ @return
+ true all the above variables are same in the event and the one passed
+ in parameter.
+ false Any of the above variable has a different value.
+ */
+ bool compare_extra_row_info(const unsigned char *ndb_info_arg,
+ int part_id_arg, int source_part_id);
+
+ bool have_part() const { return m_partition_id != UNDEFINED; }
+
+ bool have_ndb_info() const { return m_extra_row_ndb_info != nullptr; }
+ size_t get_ndb_length();
+ size_t get_part_length();
+ ~Extra_row_info();
+
+ static const int UNDEFINED{INT_MAX};
+ };
+ Extra_row_info m_extra_row_info;
+
+ unsigned long long get_table_id() const { return m_table_id.id(); }
+
+ enum_flag get_flags() const { return static_cast<enum_flag>(m_flags); }
+
+ uint32_t get_null_bits_len() const { return n_bits_len; }
+
+ unsigned long get_width() const { return m_width; }
+
+ static std::string get_flag_string(enum_flag flag) {
+ std::string str = "";
+ if (flag & STMT_END_F) str.append(" Last event of the statement");
+ if (flag & NO_FOREIGN_KEY_CHECKS_F) str.append(" No foreign Key checks");
+ if (flag & RELAXED_UNIQUE_CHECKS_F) str.append(" No unique key checks");
+ if (flag & COMPLETE_ROWS_F) str.append(" Complete Rows");
+ if (flag & ~(STMT_END_F | NO_FOREIGN_KEY_CHECKS_F |
+ RELAXED_UNIQUE_CHECKS_F | COMPLETE_ROWS_F))
+ str.append("Unknown Flag");
+ return str;
+ }
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+
+ template <class Iterator_value_type>
+ friend class Row_event_iterator;
+};
+
+/**
+ @class Write_rows_event
+
+ Log row insertions. The event contain several insert/update rows
+ for a table. Note that each event contains only rows for one table.
+
+ @section Write_rows_event_binary_format Binary Format
+*/
+class Write_rows_event : public virtual Rows_event {
+ public:
+ Write_rows_event(const char *buf, const Format_description_event *fde);
+ Write_rows_event() : Rows_event(WRITE_ROWS_EVENT) {}
+};
+
+/**
+ @class Update_rows_event
+
+ Log row updates with a before image. The event contain several
+ update rows for a table. Note that each event contains only rows for
+ one table.
+
+ Also note that the row data consists of pairs of row data: one row
+ for the old data and one row for the new data.
+
+ @section Update_rows_event_binary_format Binary Format
+*/
+class Update_rows_event : public virtual Rows_event {
+ public:
+ Update_rows_event(const char *buf, const Format_description_event *fde);
+ Update_rows_event(Log_event_type event_type) : Rows_event(event_type) {}
+};
+
+/**
+ @class Delete_rows_event
+
+ Log row deletions. The event contain several delete rows for a
+ table. Note that each event contains only rows for one table.
+
+ RESPONSIBILITIES
+
+ - Act as a container for rows that has been deleted on the master
+ and should be deleted on the slave.
+
+ @section Delete_rows_event_binary_format Binary Format
+*/
+class Delete_rows_event : public virtual Rows_event {
+ public:
+ Delete_rows_event(const char *buf, const Format_description_event *fde);
+ Delete_rows_event() : Rows_event(DELETE_ROWS_EVENT) {}
+};
+
+/**
+ @class Rows_query_event
+
+ Rows query event type, which is a subclass
+ of the Ignorable_event, to record the original query for the rows
+ events in RBR. This event can be used to display the original query as
+ comments by SHOW BINLOG EVENTS query, or mysqlbinlog client when the
+ --verbose option is given twice
+
+ @section Rows_query_var_event_binary_format Binary Format
+
+ The Post-Header for this event type is empty. The Body has one
+ component:
+
+ <table>
+ <caption>Body for Rows_query_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>m_rows_query</td>
+ <td>char array</td>
+ <td>Records the original query executed in RBR </td>
+ </tr>
+ </table>
+*/
+class Rows_query_event : public virtual Ignorable_event {
+ public:
+ /**
+ It is used to write the original query in the binlog file in case of RBR
+ when the session flag binlog_rows_query_log_events is set.
+
+ <pre>
+ The buffer layout is as follows:
+ +------------------------------------+
+ | The original query executed in RBR |
+ +------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+
+ Rows_query_event(const char *buf, const Format_description_event *fde);
+ /**
+ It is the minimal constructor, and all it will do is set the type_code as
+ ROWS_QUERY_LOG_EVENT in the header object in Binary_log_event.
+ */
+ Rows_query_event() : Ignorable_event(ROWS_QUERY_LOG_EVENT), m_rows_query(0) {}
+
+ virtual ~Rows_query_event();
+
+ protected:
+ char *m_rows_query;
+};
+} // namespace binary_log
+
+/**
+ @} (end of group Replication)
+*/
+#endif /* ROWS_EVENT_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/statement_events.h b/contrib/libs/libmysql_r/libbinlogevents/include/statement_events.h
new file mode 100644
index 0000000000..cb8ba51220
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/statement_events.h
@@ -0,0 +1,1074 @@
+/* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @addtogroup Replication
+ @{
+
+ @file statement_events.h
+
+ @brief Contains the classes representing statement events occurring in the
+ replication stream. Each event is represented as a byte sequence with logical
+ divisions as event header, event specific data and event footer. The header
+ and footer are common to all the events and are represented as two different
+ subclasses.
+*/
+
+#ifndef STATEMENT_EVENT_INCLUDED
+#define STATEMENT_EVENT_INCLUDED
+
+#include "control_events.h"
+#include "mysql/udf_registration_types.h"
+
+namespace binary_log {
+/**
+ The following constant represents the maximum of MYSQL_XID domain.
+ The maximum XID value practically is never supposed to grow beyond UINT64
+ range.
+*/
+const uint64_t INVALID_XID = 0xffffffffffffffffULL;
+
+/**
+ @class Query_event
+
+ A @c Query_event is created for each query that modifies the
+ database, unless the query is logged row-based.
+
+ @section Query_event_binary_format Binary format
+
+ See @ref Binary_log_event_binary_format "Binary format for log events" for
+ a general discussion and introduction to the binary format of binlog
+ events.
+
+ The Post-Header has five components:
+
+ <table>
+ <caption>Post-Header for Query_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>thread_id</td>
+ <td>4 byte unsigned integer</td>
+ <td>The ID of the thread that issued this statement. It is needed for
+ temporary tables.</td>
+ </tr>
+
+ <tr>
+ <td>query_exec_time</td>
+ <td>4 byte unsigned integer</td>
+ <td>The time from when the query started to when it was logged in
+ the binlog, in seconds.</td>
+ </tr>
+
+ <tr>
+ <td>db_len</td>
+ <td>1 byte integer</td>
+ <td>The length of the name of the currently selected database.</td>
+ </tr>
+
+ <tr>
+ <td>error_code</td>
+ <td>2 byte unsigned integer</td>
+ <td>Error code generated by the master. If the master fails, the
+ slave will fail with the same error code.
+ </td>
+ </tr>
+
+ <tr>
+ <td>status_vars_len</td>
+ <td>2 byte unsigned integer</td>
+ <td>The length of the status_vars block of the Body, in bytes. This is not
+ present for binlog version 1 and 3. See
+ @ref Query_event_status_vars "below".
+ </td>
+ </tr>
+ </table>
+
+ The Body has the following components:
+
+ <table>
+ <caption>Body for Query_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>@anchor Query_event_status_vars status_vars</td>
+ <td>status_vars_len bytes</td>
+ <td>Zero or more status variables. Each status variable consists
+ of one byte identifying the variable stored, followed by the value
+ of the variable. The possible variables are listed separately in
+ the table @ref Table_query_event_status_vars "below". MySQL
+ always writes events in the order defined below; however, it is
+ capable of reading them in any order. </td>
+ </tr>
+
+ <tr>
+ <td>m_db</td>
+ <td>db_len + 1</td>
+ <td>The currently selected database, as a null-terminated string.
+
+ (The trailing zero is redundant since the length is already known;
+ it is db_len from Post-Header.)
+ </td>
+ </tr>
+
+ <tr>
+ <td>m_query</td>
+ <td>variable length string without trailing zero, extending to the
+ end of the event (determined by the length field of the
+ Common-Header)
+ </td>
+ <td>The SQL query.</td>
+ </tr>
+ </table>
+
+ The following table lists the status variables that may appear in
+ the status_vars field.
+
+ @anchor Table_query_event_status_vars
+ <table>
+ <caption>Status variables for Query_event</caption>
+
+ <tr>
+ <th>Status variable</th>
+ <th>1 byte identifier</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>flags2</td>
+ <td>Q_FLAGS2_CODE == 0</td>
+ <td>4 byte bitfield</td>
+ <td>The flags in @c thd->options, binary AND-ed with @c
+ OPTIONS_WRITTEN_TO_BIN_LOG. The @c thd->options bitfield contains
+ options for "SELECT". @c OPTIONS_WRITTEN identifies those options
+ that need to be written to the binlog (not all do). Specifically,
+ @c OPTIONS_WRITTEN_TO_BIN_LOG equals (@c OPTION_AUTO_IS_NULL | @c
+ OPTION_NO_FOREIGN_KEY_CHECKS | @c OPTION_RELAXED_UNIQUE_CHECKS |
+ @c OPTION_NOT_AUTOCOMMIT), or 0x0c084000 in hex.
+
+ These flags correspond to the SQL variables SQL_AUTO_IS_NULL,
+ FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, and AUTOCOMMIT, documented in
+ the "SET Syntax" section of the MySQL Manual.
+
+ This field is always written to the binlog in version >= 5.0, and
+ never written in version < 5.0.
+ </td>
+ </tr>
+
+ <tr>
+ <td>sql_mode</td>
+ <td>Q_SQL_MODE_CODE == 1</td>
+ <td>8 byte bitfield</td>
+ <td>The @c sql_mode variable. See the section "SQL Modes" in the
+ MySQL manual, and see sql_class.h for a list of the possible
+ flags. Currently (2007-10-04), the following flags are available:
+ <pre>
+ MODE_REAL_AS_FLOAT==0x1
+ MODE_PIPES_AS_CONCAT==0x2
+ MODE_ANSI_QUOTES==0x4
+ MODE_IGNORE_SPACE==0x8
+ MODE_NOT_USED==0x10
+ MODE_ONLY_FULL_GROUP_BY==0x20
+ MODE_NO_UNSIGNED_SUBTRACTION==0x40
+ MODE_NO_DIR_IN_CREATE==0x80
+ MODE_ANSI==0x80000
+ MODE_NO_AUTO_VALUE_ON_ZERO==0x100000
+ MODE_NO_BACKSLASH_ESCAPES==0x200000
+ MODE_STRICT_TRANS_TABLES==0x400000
+ MODE_STRICT_ALL_TABLES==0x800000
+ MODE_NO_ZERO_IN_DATE==0x1000000
+ MODE_NO_ZERO_DATE==0x2000000
+ MODE_INVALID_DATES==0x4000000
+ MODE_ERROR_FOR_DIVISION_BY_ZERO==0x8000000
+ MODE_TRADITIONAL==0x10000000
+ MODE_HIGH_NOT_PRECEDENCE==0x40000000
+ MODE_PAD_CHAR_TO_FULL_LENGTH==0x80000000
+ MODE_TIME_TRUNCATE_FRACTIONAL==0x100000000
+ </pre>
+ All these flags are replicated from the server. However, all
+ flags except @c MODE_NO_DIR_IN_CREATE are honored by the slave;
+ the slave always preserves its old value of @c
+ MODE_NO_DIR_IN_CREATE.
+
+ This field is always written to the binlog.
+ </td>
+ </tr>
+
+ <tr>
+ <td>catalog</td>
+ <td>Q_CATALOG_NZ_CODE == 6</td>
+ <td>Variable-length string: the length in bytes (1 byte) followed
+ by the characters (at most 255 bytes)
+ </td>
+ <td>Stores the client's current catalog. Every database belongs
+ to a catalog, the same way that every table belongs to a
+ database. Currently, there is only one catalog, "std".
+
+ This field is written if the length of the catalog is > 0;
+ otherwise it is not written.
+ </td>
+ </tr>
+
+ <tr>
+ <td>auto_increment</td>
+ <td>Q_AUTO_INCREMENT == 3</td>
+ <td>two 2 byte unsigned integers, totally 2+2=4 bytes</td>
+
+ <td>The two variables auto_increment_increment and
+ auto_increment_offset, in that order. For more information, see
+ "System variables" in the MySQL manual.
+
+ This field is written if auto_increment > 1. Otherwise, it is not
+ written.
+ </td>
+ </tr>
+
+ <tr>
+ <td>charset</td>
+ <td>Q_CHARSET_CODE == 4</td>
+ <td>three 2 byte unsigned integers, totally 2+2+2=6 bytes</td>
+ <td>The three variables character_set_client,
+ collation_connection, and collation_server, in that order.
+ character_set_client is a code identifying the character set and
+ collation used by the client to encode the query.
+ collation_connection identifies the character set and collation
+ that the master converts the query to when it receives it; this is
+ useful when comparing literal strings. collation_server is the
+ default character set and collation used when a new database is
+ created.
+
+ See also "Connection Character Sets and Collations" in the MySQL
+ 5.1 manual.
+
+ All three variables are codes identifying a (character set,
+ collation) pair. To see which codes map to which pairs, run the
+ query "SELECT id, character_set_name, collation_name FROM
+ COLLATIONS".
+
+ Cf. Q_CHARSET_DATABASE_CODE below.
+
+ This field is always written.
+ </td>
+ </tr>
+
+ <tr>
+ <td>time_zone</td>
+ <td>Q_TIME_ZONE_CODE == 5</td>
+ <td>Variable-length string: the length in bytes (1 byte) followed
+ by the characters (at most 255 bytes).
+ <td>The time_zone of the master.
+
+ See also "System Variables" and "MySQL Server Time Zone Support"
+ in the MySQL manual.
+
+ This field is written if the length of the time zone string is >
+ 0; otherwise, it is not written.
+ </td>
+ </tr>
+
+ <tr>
+ <td>lc_time_names_number</td>
+ <td>Q_LC_TIME_NAMES_CODE == 7</td>
+ <td>2 byte integer</td>
+ <td>A code identifying a table of month and day names. The
+ mapping from codes to languages is defined in @c sql_locale.cc.
+
+ This field is written if it is not 0, i.e., if the locale is not
+ en_US.
+ </td>
+ </tr>
+
+ <tr>
+ <td>charset_database_number</td>
+ <td>Q_CHARSET_DATABASE_CODE == 8</td>
+ <td>2 byte integer</td>
+
+ <td>The value of the collation_database system variable (in the
+ source code stored in @c thd->variables.collation_database), which
+ holds the code for a (character set, collation) pair as described
+ above (see Q_CHARSET_CODE).
+
+ collation_database was used in old versions (???WHEN). Its value
+ was loaded when issuing a "use db" query and could be changed by
+ issuing a "SET collation_database=xxx" query. It used to affect
+ the "LOAD DATA INFILE" and "CREATE TABLE" commands.
+
+ In newer versions, "CREATE TABLE" has been changed to take the
+ character set from the database of the created table, rather than
+ the character set of the current database. This makes a
+ difference when creating a table in another database than the
+ current one. "LOAD DATA INFILE" has not yet changed to do this,
+ but there are plans to eventually do it, and to make
+ collation_database read-only.
+
+ This field is written if it is not 0.
+ </td>
+ </tr>
+ <tr>
+ <td>table_map_for_update</td>
+ <td>Q_TABLE_MAP_FOR_UPDATE_CODE == 9</td>
+ <td>8 byte integer</td>
+
+ <td>The value of the table map that is to be updated by the
+ multi-table update query statement. Every bit of this variable
+ represents a table, and is set to 1 if the corresponding table is
+ to be updated by this statement.
+
+ The value of this variable is set when executing a multi-table update
+ statement and used by slave to apply filter rules without opening
+ all the tables on slave. This is required because some tables may
+ not exist on slave because of the filter rules.
+ </td>
+ </tr>
+ <tr>
+ <td>master_data_written</td>
+ <td>Q_MASTER_DATA_WRITTEN_CODE == 10</td>
+ <td>4 byte bitfield</td>
+
+ <td>The value of the original length of a Query_event that comes from a
+ master. Master's event is relay-logged with storing the original size of
+ event in this field by the IO thread. The size is to be restored by reading
+ Q_MASTER_DATA_WRITTEN_CODE-marked event from the relay log.
+
+ This field is not written to slave's server binlog by the SQL thread.
+ This field only exists in relay logs where master has binlog_version<4 i.e.
+ server_version < 5.0 and the slave has binlog_version=4.
+ </td>
+ </tr>
+ <tr>
+ <td>binlog_invoker</td>
+ <td>Q_INVOKER == 11</td>
+ <td>2 Variable-length strings: the length in bytes (1 byte) followed
+ by characters (user), again followed by length in bytes (1 byte) followed
+ by characters(host)</td>
+
+ <td>The value of boolean variable m_binlog_invoker is set TRUE if
+ CURRENT_USER() is called in account management statements. SQL thread
+ uses it as a default definer in CREATE/ALTER SP, SF, Event, TRIGGER or
+ VIEW statements.
+
+ The field Q_INVOKER has length of user stored in 1 byte followed by the
+ user string which is assigned to 'user' and the length of host stored in
+ 1 byte followed by host string which is assigned to 'host'.
+ </td>
+ </tr>
+ <tr>
+ <td>mts_accessed_dbs</td>
+ <td>Q_UPDATED_DB_NAMES == 12</td>
+ <td>1 byte character, and a 2-D array</td>
+ <td>The total number and the names to of the databases accessed is stored,
+ to be propagated to the slave in order to facilitate the parallel
+ applying of the Query events.
+ </td>
+ </tr>
+ <tr>
+ <td>explicit_defaults_ts</td>
+ <td>Q_EXPLICIT_DEFAULTS_FOR_TIMESTAMP</td>
+ <td>1 byte boolean</td>
+ <td>Stores master connection @@session.explicit_defaults_for_timestamp when
+ CREATE and ALTER operate on a table with a TIMESTAMP column. </td>
+ </tr>
+ <tr>
+ <td>ddl_xid</td>
+ <td>Q_DDL_LOGGED_WITH_XID</td>
+ <td>8 byte integer</td>
+ <td>Stores variable carrying xid info of 2pc-aware (recoverable) DDL
+ queries. </td>
+ </tr>
+ <tr>
+ <td>default_collation_for_utf8mb4_number</td>
+ <td>Q_DEFAULT_COLLATION_FOR_UTF8MB4</td>
+ <td>2 byte integer</td>
+ <td>Stores variable carrying the the default collation for the utf8mb4
+ character set. Mainly used to support replication 5.7- master to a 8.0+
+ slave.
+ </td>
+ </tr>
+ <tr>
+ <td>sql_require_primary_key</td>
+ <td>Q_SQL_REQUIRE_PRIMARY_KEY</td>
+ <td>2 byte integer</td>
+ <td>Value of the config variable sql_require_primary_key</td>
+ </tr>
+ <tr>
+ <td>default_table_encryption</td>
+ <td>Q_DEFAULT_TABLE_ENCRYPTION</td>
+ <td>2 byte integer</td>
+ <td>Value of the config variable default_table_encryption</td>
+ </tr>
+ </table>
+
+ @subsection Query_event_notes_on_previous_versions Notes on Previous Versions
+
+ * Status vars were introduced in version 5.0. To read earlier
+ versions correctly, check the length of the Post-Header.
+
+ * The status variable Q_CATALOG_CODE == 2 existed in MySQL 5.0.x,
+ where 0<=x<=3. It was identical to Q_CATALOG_CODE, except that the
+ string had a trailing '\0'. The '\0' was removed in 5.0.4 since it
+ was redundant (the string length is stored before the string). The
+ Q_CATALOG_CODE will never be written by a new master, but can still
+ be understood by a new slave.
+
+ * See Q_CHARSET_DATABASE_CODE in the table above.
+
+ * When adding new status vars, please don't forget to update the
+ MAX_SIZE_LOG_EVENT_STATUS.
+
+*/
+
+class Query_event : public Binary_log_event {
+ public:
+ /** query event post-header */
+ enum Query_event_post_header_offset {
+ Q_THREAD_ID_OFFSET = 0,
+ Q_EXEC_TIME_OFFSET = 4,
+ Q_DB_LEN_OFFSET = 8,
+ Q_ERR_CODE_OFFSET = 9,
+ Q_STATUS_VARS_LEN_OFFSET = 11,
+ Q_DATA_OFFSET = QUERY_HEADER_LEN
+ };
+
+ /* these are codes, not offsets; not more than 256 values (1 byte). */
+ enum Query_event_status_vars {
+ Q_FLAGS2_CODE = 0,
+ Q_SQL_MODE_CODE,
+ /*
+ Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL
+ 5.0.x where 0<=x<=3. We have to keep it to be able to replicate these
+ old masters.
+ */
+ Q_CATALOG_CODE,
+ Q_AUTO_INCREMENT,
+ Q_CHARSET_CODE,
+ Q_TIME_ZONE_CODE,
+ /*
+ Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL
+ 5.0.x where x>=4. Saves one byte in every Query_event in binlog,
+ compared to Q_CATALOG_CODE. The reason we didn't simply re-use
+ Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4)
+ master would crash (segfault etc) because it would expect a 0 when there
+ is none.
+ */
+ Q_CATALOG_NZ_CODE,
+ Q_LC_TIME_NAMES_CODE,
+ Q_CHARSET_DATABASE_CODE,
+ Q_TABLE_MAP_FOR_UPDATE_CODE,
+ /* It is just a placeholder after 8.0.2*/
+ Q_MASTER_DATA_WRITTEN_CODE,
+ Q_INVOKER,
+ /*
+ Q_UPDATED_DB_NAMES status variable collects information of accessed
+ databases i.e. the total number and the names to be propagated to the
+ slave in order to facilitate the parallel applying of the Query events.
+ */
+ Q_UPDATED_DB_NAMES,
+ Q_MICROSECONDS,
+ /*
+ A old (unused now) code for Query_log_event status similar to G_COMMIT_TS.
+ */
+ Q_COMMIT_TS,
+ /*
+ An old (unused after migration to Gtid_event) code for
+ Query_log_event status, similar to G_COMMIT_TS2.
+ */
+ Q_COMMIT_TS2,
+ /*
+ The master connection @@session.explicit_defaults_for_timestamp which
+ is recorded for queries, CREATE and ALTER table that is defined with
+ a TIMESTAMP column, that are dependent on that feature.
+ For pre-WL6292 master's the associated with this code value is zero.
+ */
+ Q_EXPLICIT_DEFAULTS_FOR_TIMESTAMP,
+ /*
+ The variable carries xid info of 2pc-aware (recoverable) DDL queries.
+ */
+ Q_DDL_LOGGED_WITH_XID,
+ /*
+ This variable stores the default collation for the utf8mb4 character set.
+ Used to support cross-version replication.
+ */
+ Q_DEFAULT_COLLATION_FOR_UTF8MB4,
+
+ /*
+ Replicate sql_require_primary_key.
+ */
+ Q_SQL_REQUIRE_PRIMARY_KEY,
+
+ /*
+ Replicate default_table_encryption.
+ */
+ Q_DEFAULT_TABLE_ENCRYPTION
+ };
+ const char *query;
+ const char *db;
+ const char *catalog;
+ const char *time_zone_str;
+
+ protected:
+ const char *user;
+ size_t user_len;
+ const char *host;
+ size_t host_len;
+
+ /* Required by the MySQL server class Log_event::Query_event */
+ unsigned long data_len;
+ /*
+ Copies data into the buffer in the following fashion
+ +--------+-----------+------+------+---------+----+-------+----+
+ | catlog | time_zone | user | host | db name | \0 | Query | \0 |
+ +--------+-----------+------+------+---------+----+-------+----+
+ */
+ int fill_data_buf(unsigned char *dest, unsigned long len);
+
+ public:
+ /* data members defined in order they are packed and written into the log */
+ uint32_t thread_id;
+ uint32_t query_exec_time;
+ size_t db_len;
+ uint16_t error_code;
+ /*
+ We want to be able to store a variable number of N-bit status vars:
+ (generally N=32; but N=64 for SQL_MODE) a user may want to log the number
+ of affected rows (for debugging) while another does not want to lose 4
+ bytes in this.
+ The storage on disk is the following:
+ status_vars_len is part of the post-header,
+ status_vars are in the variable-length part, after the post-header, before
+ the db & query.
+ status_vars on disk is a sequence of pairs (code, value) where 'code' means
+ 'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so
+ its first byte is its length. For now the order of status vars is:
+ flags2 - sql_mode - catalog - autoinc - charset
+ We should add the same thing to Load_event, but in fact
+ LOAD DATA INFILE is going to be logged with a new type of event (logging of
+ the plain text query), so Load_event would be frozen, so no need. The
+ new way of logging LOAD DATA INFILE would use a derived class of
+ Query_event, so automatically benefit from the work already done for
+ status variables in Query_event.
+ */
+ uint16_t status_vars_len;
+ /*
+ If we already know the length of the query string
+ we pass it with q_len, so we would not have to call strlen()
+ otherwise, set it to 0, in which case, we compute it with strlen()
+ */
+ size_t q_len;
+
+ /* The members below represent the status variable block */
+
+ /*
+ 'flags2' is a second set of flags (on top of those in Log_event), for
+ session variables. These are thd->options which is & against a mask
+ (OPTIONS_WRITTEN_TO_BIN_LOG).
+ flags2_inited helps make a difference between flags2==0 (3.23 or 4.x
+ master, we don't know flags2, so use the slave server's global options) and
+ flags2==0 (5.0 master, we know this has a meaning of flags all down which
+ must influence the query).
+ */
+ bool flags2_inited;
+ bool sql_mode_inited;
+ bool charset_inited;
+
+ uint32_t flags2;
+ /* In connections sql_mode is 32 bits now but will be 64 bits soon */
+ uint64_t sql_mode;
+ uint16_t auto_increment_increment, auto_increment_offset;
+ char charset[6];
+ size_t time_zone_len; /* 0 means uninited */
+ /*
+ Binlog format 3 and 4 start to differ (as far as class members are
+ concerned) from here.
+ */
+ size_t catalog_len; // <= 255 char; 0 means uninited
+ uint16_t lc_time_names_number; /* 0 means en_US */
+ uint16_t charset_database_number;
+ /*
+ map for tables that will be updated for a multi-table update query
+ statement, for other query statements, this will be zero.
+ */
+ uint64_t table_map_for_update;
+ /*
+ The following member gets set to OFF or ON value when the
+ Query-log-event is marked as dependent on
+ @@explicit_defaults_for_timestamp. That is the member is relevant
+ to queries that declare TIMESTAMP column attribute, like CREATE
+ and ALTER.
+ The value is set to @c TERNARY_OFF when @@explicit_defaults_for_timestamp
+ encoded value is zero, otherwise TERNARY_ON.
+ */
+ enum enum_ternary {
+ TERNARY_UNSET,
+ TERNARY_OFF,
+ TERNARY_ON
+ } explicit_defaults_ts;
+ /*
+ number of updated databases by the query and their names. This info
+ is requested by both Coordinator and Worker.
+ */
+ unsigned char mts_accessed_dbs;
+ char mts_accessed_db_names[MAX_DBS_IN_EVENT_MTS][NAME_LEN];
+ /* XID value when the event is a 2pc-capable DDL */
+ uint64_t ddl_xid;
+ /* Default collation for the utf8mb4 set. Used in cross-version replication */
+ uint16_t default_collation_for_utf8mb4_number;
+ uint8_t sql_require_primary_key;
+
+ uint8_t default_table_encryption;
+
+ /**
+ The constructor will be used while creating a Query_event, to be
+ written to the binary log.
+ */
+ Query_event(const char *query_arg, const char *catalog_arg,
+ const char *db_arg, uint32_t query_length,
+ unsigned long thread_id_arg, unsigned long long sql_mode_arg,
+ unsigned long auto_increment_increment_arg,
+ unsigned long auto_increment_offset_arg, unsigned int number,
+ unsigned long long table_map_for_update_arg, int errcode);
+
+ /**
+ The constructor receives a buffer and instantiates a Query_event filled in
+ with the data from the buffer
+
+ <pre>
+ The fixed event data part buffer layout is as follows:
+ +---------------------------------------------------------------------+
+ | thread_id | query_exec_time | db_len | error_code | status_vars_len |
+ +---------------------------------------------------------------------+
+ </pre>
+
+ <pre>
+ The fixed event data part buffer layout is as follows:
+ +--------------------------------------------+
+ | Zero or more status variables | db | query |
+ +--------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ @param event_type Required to determine whether the event type is
+ QUERY_EVENT or EXECUTE_LOAD_QUERY_EVENT
+ */
+ Query_event(const char *buf, const Format_description_event *fde,
+ Log_event_type event_type);
+ /**
+ The simplest constructor that could possibly work. This is used for
+ creating static objects that have a special meaning and are invisible
+ to the log.
+ */
+ Query_event(Log_event_type type_arg = QUERY_EVENT);
+ virtual ~Query_event() {}
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+
+/*
+ Check how many bytes are available on buffer.
+
+ @param buf_start Pointer to buffer start.
+ @param buf_current Pointer to the current position on buffer.
+ @param buf_len Buffer length.
+
+ @return Number of bytes available on event buffer.
+*/
+template <class T>
+T available_buffer(const char *buf_start, const char *buf_current, T buf_len) {
+ /* Sanity check */
+ if (buf_current < buf_start ||
+ buf_len < static_cast<T>(buf_current - buf_start))
+ return static_cast<T>(0);
+
+ return static_cast<T>(buf_len - (buf_current - buf_start));
+}
+
+/**
+ Check if jump value is within buffer limits.
+
+ @param jump Number of positions we want to advance.
+ @param buf_start Pointer to buffer start
+ @param buf_current Pointer to the current position on buffer.
+ @param buf_len Buffer length.
+
+ @retval True If jump value is within buffer limits.
+ @retval False Otherwise.
+*/
+template <class T>
+bool valid_buffer_range(T jump, const char *buf_start, const char *buf_current,
+ T buf_len) {
+ return (jump <= available_buffer(buf_start, buf_current, buf_len));
+}
+
+/**
+ @class User_var_event
+
+ Written every time a statement uses a user variable; precedes other
+ events for the statement. Indicates the value to use for the user
+ variable in the next statement. This is written only before a QUERY_EVENT
+ and is not used with row-based logging
+
+ The Post-Header has following components:
+
+ <table>
+ <caption>Post-Header for Format_description_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>Value_type</td>
+ <td>enum</td>
+ <td>The user variable type.</td>
+ </tr>
+ <tr>
+ <td>User_var_event_data</td>
+ <td>enum</td>
+ <td>User_var event data</td>
+ </tr>
+ <tr>
+ <td>name</td>
+ <td>const char pointer</td>
+ <td>User variable name.</td>
+ </tr>
+ <tr>
+ <td>name_len</td>
+ <td>unsigned int</td>
+ <td>Length of the user variable name</td>
+ </tr>
+ <tr>
+ <td>val</td>
+ <td>char pointer</td>
+ <td>value of the user variable.</td>
+ </tr>
+ <tr>
+ <td>val_len</td>
+ <td>unsigned long</td>
+ <td>Length of the value of the user variable</td>
+ </tr>
+ <tr>
+ <td>type</td>
+ <td>enum Value_type</td>
+ <td>Type of the user variable</td>
+ </tr>
+ <tr>
+ <td>charset_number</td>
+ <td>unsigned int</td>
+ <td>The number of the character set for the user variable (needed for a
+ string variable). The character set number is really a collation
+ number that indicates a character set/collation pair.</td>
+ </tr>
+ <tr>
+ <td>is_null</td>
+ <td>bool</td>
+ <td>Non-zero if the variable value is the SQL NULL value, 0 otherwise.</td>
+ </tr>
+ </table>
+*/
+class User_var_event : public Binary_log_event {
+ public:
+ using Value_type = Item_result;
+ enum { UNDEF_F, UNSIGNED_F };
+ enum User_var_event_data {
+ UV_VAL_LEN_SIZE = 4,
+ UV_VAL_IS_NULL = 1,
+ UV_VAL_TYPE_SIZE = 1,
+ UV_NAME_LEN_SIZE = 4,
+ UV_CHARSET_NUMBER_SIZE = 4
+ };
+
+ /**
+ This constructor will initialize the instance variables and the type_code,
+ it will be used only by the server code.
+ */
+ User_var_event(const char *name_arg, unsigned int name_len_arg, char *val_arg,
+ unsigned long val_len_arg, Value_type type_arg,
+ unsigned int charset_number_arg, unsigned char flags_arg)
+ : Binary_log_event(USER_VAR_EVENT),
+ name(bapi_strndup(name_arg, name_len_arg)),
+ name_len(name_len_arg),
+ val(val_arg),
+ val_len(val_len_arg),
+ type(type_arg),
+ charset_number(charset_number_arg),
+ is_null(!val),
+ flags(flags_arg) {}
+
+ /**
+ The constructor receives a buffer and instantiates a User_var_event filled
+ in with the data from the buffer
+ Written every time a statement uses a user variable, precedes other
+ events for the statement. Indicates the value to use for the
+ user variable in the next statement. This is written only before a
+ QUERY_EVENT and is not used with row-based logging.
+
+ The buffer layout for variable data part is as follows:
+ <pre>
+ +-------------------------------------------------------------------+
+ | name_len | name | is_null | type | charset_number | val_len | val |
+ +-------------------------------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ User_var_event(const char *buf, const Format_description_event *fde);
+ virtual ~User_var_event();
+ const char *name;
+ unsigned int name_len;
+ char *val;
+ uint32_t val_len;
+ Value_type type;
+ unsigned int charset_number;
+ bool is_null;
+ unsigned char flags;
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+ const char *get_value_type_string(Value_type type_arg) const {
+ switch (type_arg) {
+ case STRING_RESULT:
+ return "String";
+ case REAL_RESULT:
+ return "Real";
+ case INT_RESULT:
+ return "Integer";
+ case ROW_RESULT:
+ return "Row";
+ case DECIMAL_RESULT:
+ return "Decimal";
+ default:
+ return "Unknown";
+ }
+ }
+#endif
+};
+
+/**
+ @class Intvar_event
+
+ An Intvar_event will be created just before a Query_event,
+ if the query uses one of the variables LAST_INSERT_ID or INSERT_ID.
+ Each Intvar_event holds the value of one of these variables.
+
+ @section Intvar_event_binary_format Binary Format
+
+ The Post-Header for this event type is empty. The Body has two
+ components:
+
+ <table>
+ <caption>Body for Intvar_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>type</td>
+ <td>1 byte enumeration</td>
+ <td>One byte identifying the type of variable stored. Currently,
+ two identifiers are supported: LAST_INSERT_ID_EVENT == 1 and
+ INSERT_ID_EVENT == 2.
+ </td>
+ </tr>
+
+ <tr>
+ <td>val</td>
+ <td>8 byte unsigned integer</td>
+ <td>The value of the variable.</td>
+ </tr>
+
+ </table>
+*/
+class Intvar_event : public Binary_log_event {
+ public:
+ uint8_t type;
+ uint64_t val;
+
+ /*
+ The enum recognizes the type of variables that can occur in an
+ INTVAR_EVENT. The two types supported are LAST_INSERT_ID and
+ INSERT_ID, in accordance to the SQL query using LAST_INSERT_ID
+ or INSERT_ID.
+ */
+ enum Int_event_type {
+ INVALID_INT_EVENT,
+ LAST_INSERT_ID_EVENT,
+ INSERT_ID_EVENT
+ };
+
+ /**
+ moving from pre processor symbols from global scope in log_event.h
+ to an enum inside the class, since these are used only by
+ members of this class itself.
+ */
+ enum Intvar_event_offset { I_TYPE_OFFSET = 0, I_VAL_OFFSET = 1 };
+
+ /**
+ This method returns the string representing the type of the variable
+ used in the event. Changed the definition to be similar to that
+ previously defined in log_event.cc.
+ */
+ std::string get_var_type_string() const {
+ switch (type) {
+ case INVALID_INT_EVENT:
+ return "INVALID_INT";
+ case LAST_INSERT_ID_EVENT:
+ return "LAST_INSERT_ID";
+ case INSERT_ID_EVENT:
+ return "INSERT_ID";
+ default: /* impossible */
+ return "UNKNOWN";
+ }
+ }
+
+ /**
+ Constructor receives a packet from the MySQL master or the binary
+ log and decodes it to create an Intvar_event.
+
+ The post header for the event is empty. Buffer layout for the variable
+ data part is as follows:
+ <pre>
+ +--------------------------------+
+ | type (4 bytes) | val (8 bytes) |
+ +--------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Intvar_event(const char *buf, const Format_description_event *fde);
+ /**
+ The minimal constructor for Intvar_event it initializes the instance
+ variables type & val and set the type_code as INTVAR_EVENT in the header
+ object in Binary_log_event
+ */
+ Intvar_event(uint8_t type_arg, uint64_t val_arg)
+ : Binary_log_event(INTVAR_EVENT), type(type_arg), val(val_arg) {}
+
+ ~Intvar_event() {}
+
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+
+/**
+ @class Rand_event
+
+ Logs random seed used by the next RAND(), and by PASSWORD() in 4.1.0.
+ 4.1.1 does not need it (it's repeatable again) so this event needn't be
+ written in 4.1.1 for PASSWORD() (but the fact that it is written is just a
+ waste, it does not cause bugs).
+
+ The state of the random number generation consists of 128 bits,
+ which are stored internally as two 64-bit numbers.
+
+ @section Rand_event_binary_format Binary Format
+
+ The Post-Header for this event type is empty. The Body has two
+ components:
+
+ <table>
+ <caption>Body for Rand_event</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+
+ <tr>
+ <td>seed1</td>
+ <td>8 byte unsigned integer</td>
+ <td>64 bit random seed1.</td>
+ </tr>
+
+ <tr>
+ <td>seed2</td>
+ <td>8 byte unsigned integer</td>
+ <td>64 bit random seed2.</td>
+ </tr>
+ </table>
+*/
+class Rand_event : public Binary_log_event {
+ public:
+ unsigned long long seed1;
+ unsigned long long seed2;
+ enum Rand_event_data { RAND_SEED1_OFFSET = 0, RAND_SEED2_OFFSET = 8 };
+
+ /**
+ This will initialize the instance variables seed1 & seed2, and set the
+type_code as RAND_EVENT in the header object in Binary_log_event
+ */
+ Rand_event(unsigned long long seed1_arg, unsigned long long seed2_arg)
+ : Binary_log_event(RAND_EVENT) {
+ seed1 = seed1_arg;
+ seed2 = seed2_arg;
+ }
+
+ /**
+ Written every time a statement uses the RAND() function; precedes other
+ events for the statement. Indicates the seed values to use for generating a
+ random number with RAND() in the next statement. This is written only before
+ a QUERY_EVENT and is not used with row-based logging
+
+ <pre>
+ The buffer layout for variable part is as follows:
+ +----------------------------------------------+
+ | value for first seed | value for second seed |
+ +----------------------------------------------+
+ </pre>
+
+ @param buf Contains the serialized event.
+ @param fde An FDE event (see Rotate_event constructor for more info).
+ */
+ Rand_event(const char *buf, const Format_description_event *fde);
+#ifndef HAVE_MYSYS
+ void print_event_info(std::ostream &info);
+ void print_long_info(std::ostream &info);
+#endif
+};
+} // end namespace binary_log
+/**
+ @} (end of group Replication)
+*/
+#endif /* STATEMENT_EVENTS_INCLUDED */
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/table_id.h b/contrib/libs/libmysql_r/libbinlogevents/include/table_id.h
new file mode 100644
index 0000000000..db9876577a
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/table_id.h
@@ -0,0 +1,74 @@
+/* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+/**
+ @file table_id.h
+
+ @brief Contains the class Table_id, mainly used for row based replication.
+*/
+
+#ifndef TABLE_ID_INCLUDED
+#define TABLE_ID_INCLUDED
+#include <stdint.h>
+#include "wrapper_functions.h"
+
+/**
+ @class Table_id
+
+ @brief Each table share has a table id, it is mainly used for row based
+ replication. Meanwhile it is used as table's version too.
+*/
+class Table_id {
+ private:
+ /* In table map event and rows events, table id is 6 bytes.*/
+ static const unsigned long long TABLE_ID_MAX = (~0ULL >> 16);
+ uint64_t m_id;
+
+ public:
+ Table_id() : m_id(0) {}
+ explicit Table_id(unsigned long long id) : m_id(id) {}
+
+ unsigned long long id() const { return m_id; }
+ bool is_valid() const { return m_id <= TABLE_ID_MAX; }
+
+ Table_id &operator=(unsigned long long id) {
+ m_id = id;
+ return *this;
+ }
+
+ bool operator==(const Table_id &tid) const { return m_id == tid.m_id; }
+ bool operator!=(const Table_id &tid) const { return m_id != tid.m_id; }
+
+ /* Support implicit type converting from Table_id to unsigned long long */
+ operator unsigned long long() const { return m_id; }
+
+ Table_id operator++(int) {
+ Table_id id(m_id);
+
+ /* m_id is reset to 0, when it exceeds the max value. */
+ m_id = (m_id == TABLE_ID_MAX ? 0 : m_id + 1);
+
+ BAPI_ASSERT(m_id <= TABLE_ID_MAX);
+ return id;
+ }
+};
+
+#endif
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/uuid.h b/contrib/libs/libmysql_r/libbinlogevents/include/uuid.h
new file mode 100644
index 0000000000..a08061ebb3
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/uuid.h
@@ -0,0 +1,173 @@
+/* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef UUID_H_INCLUDED
+#define UUID_H_INCLUDED 1
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <string>
+#include <utility>
+
+#include "template_utils.h"
+
+namespace binary_log {
+
+/**
+ @struct Uuid
+
+ This is a POD. It has to be a POD because it is a member of
+ Sid_map::Node which is stored in HASH in mysql-server code.
+ The structure contains the following components.
+ <table>
+ <caption>Structure gtid_info</caption>
+
+ <tr>
+ <th>Name</th>
+ <th>Format</th>
+ <th>Description</th>
+ </tr>
+ <tr>
+ <td>byte</td>
+ <td>unsigned char array</td>
+ <td>This stores the Uuid of the server on which transaction
+ is originated</td>
+ </tr>
+ </table>
+*/
+
+struct Uuid {
+ /// Set to all zeros.
+ void clear() { memset(bytes, 0, BYTE_LENGTH); }
+ /// Copies the given 16-byte data to this UUID.
+ void copy_from(const unsigned char *data) {
+ memcpy(bytes, data, BYTE_LENGTH);
+ }
+ /// Copies the given UUID object to this UUID.
+ void copy_from(const Uuid &data) {
+ copy_from(pointer_cast<const unsigned char *>(data.bytes));
+ }
+ /// Copies the given UUID object to this UUID.
+ void copy_to(unsigned char *data) const { memcpy(data, bytes, BYTE_LENGTH); }
+ /// Returns true if this UUID is equal the given UUID.
+ bool equals(const Uuid &other) const {
+ return memcmp(bytes, other.bytes, BYTE_LENGTH) == 0;
+ }
+ /**
+ Returns true if parse() would succeed, but doesn't store the result.
+
+ @param string String that needs to be checked.
+ @param len Length of that string.
+
+ @retval true valid string.
+ @retval false invalid string.
+ */
+ static bool is_valid(const char *string, size_t len);
+
+ /**
+ Stores the UUID represented by a string of the form
+ XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX or
+ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX or
+ {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}
+ in this object.
+
+ @param string String to be parsed and stored.
+ @param len Length of that string.
+
+ @retval 0 success.
+ @retval >0 failure.
+ */
+ int parse(const char *string, size_t len);
+
+ /**
+ Parses the UUID passed as argument in in_string and functions and writes
+ the binary representation in out_binary_string.
+ Depends on UUID's read_section method and the constants for text length.
+
+ @param[in] in_string String to be parsed.
+ @param[in] len Length of that string.
+ @param[out] out_binary_string String where the binary UUID will be stored
+
+ @retval 0 success.
+ @retval >0 failure.
+ */
+ static int parse(const char *in_string, size_t len,
+ const unsigned char *out_binary_string);
+ /**
+ Helper method used to validate and parse one section of a uuid.
+ If the last parameter, out_binary_str, is NULL then the function will
+ just validate the section.
+
+ @param[in] section_len Length of the section to be parsed.
+ @param[in,out] section_str Pointer to a string containing the
+ section. It will be updated during the
+ execution as the string is parsed.
+ @param[out] out_binary_str String where the section will be stored
+ in binary format. If null, the function
+ will just validate the input string.
+
+ @retval false success.
+ @retval true failure.
+ */
+ static bool read_section(int section_len, const char **section_str,
+ const unsigned char **out_binary_str);
+ /** The number of bytes in the data of a Uuid. */
+ static const size_t BYTE_LENGTH = 16;
+ /** The data for this Uuid. */
+ unsigned char bytes[BYTE_LENGTH];
+ /**
+ Generates a 36+1 character long representation of this UUID object
+ in the given string buffer.
+
+ @retval 36 - the length of the resulting string.
+ */
+ size_t to_string(char *buf) const;
+ /// Convert the given binary buffer to a UUID
+ static size_t to_string(const unsigned char *bytes_arg, char *buf);
+ void print() const {
+ char buf[TEXT_LENGTH + 1];
+ to_string(buf);
+ printf("%s\n", buf);
+ }
+ /// The number of bytes in the textual representation of a Uuid.
+ static const size_t TEXT_LENGTH = 36;
+ /// The number of bits in the data of a Uuid.
+ static const size_t BIT_LENGTH = 128;
+ static const int NUMBER_OF_SECTIONS = 5;
+ static const int bytes_per_section[NUMBER_OF_SECTIONS];
+ static const int hex_to_byte[256];
+};
+
+struct Hash_Uuid {
+ size_t operator()(const Uuid &uuid) const {
+ return std::hash<std::string>()(
+ std::string(pointer_cast<const char *>(uuid.bytes), Uuid::BYTE_LENGTH));
+ }
+};
+
+inline bool operator==(const Uuid &a, const Uuid &b) { return a.equals(b); }
+
+} // namespace binary_log
+
+#endif // UUID_H_INCLUDED
diff --git a/contrib/libs/libmysql_r/libbinlogevents/include/wrapper_functions.h b/contrib/libs/libmysql_r/libbinlogevents/include/wrapper_functions.h
new file mode 100644
index 0000000000..0515046610
--- /dev/null
+++ b/contrib/libs/libmysql_r/libbinlogevents/include/wrapper_functions.h
@@ -0,0 +1,193 @@
+/* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License, version 2.0,
+ as published by the Free Software Foundation.
+
+ This program is also distributed with certain software (including
+ but not limited to OpenSSL) that is licensed under separate terms,
+ as designated in a particular file or component or in included license
+ documentation. The authors of MySQL hereby grant you an additional
+ permission to link the program and your derivative works with the
+ separately licensed software that they have included with MySQL.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License, version 2.0, for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+/**
+ @file
+
+ @brief Contains wrapper functions for memory allocation and deallocation.
+ This includes generic functions to be called from the binlogevent library,
+ which call the appropriate corresponding function, depending on whether
+ the library is compiled independently, or with the MySQL server.
+*/
+
+#ifndef WRAPPER_FUNCTIONS_INCLUDED
+#define WRAPPER_FUNCTIONS_INCLUDED
+
+#include "binlog_config.h"
+#ifndef STANDALONE_BINLOG
+#define HAVE_MYSYS 1
+#endif
+
+#ifdef HAVE_MYSYS
+#include "my_config.h"
+#include "my_sys.h"
+#include "mysql/service_mysql_alloc.h"
+
+extern PSI_memory_key key_memory_log_event;
+#else
+#include <cassert>
+#ifndef _GNU_SOURCE
+#define _GNU_SOURCE
+#endif
+#include <stdlib.h>
+#include <string.h>
+
+#endif
+
+#if !defined(DBUG_OFF)
+
+#include "my_dbug.h"
+
+#ifdef HAVE_MYSYS
+#define BAPI_ASSERT(x) DBUG_ASSERT(x)
+#define BAPI_PRINT(name, params) DBUG_PRINT(name, params)
+#define BAPI_ENTER(x) DBUG_ENTER(x)
+#define BAPI_RETURN(x) DBUG_RETURN(x)
+#define BAPI_VOID_RETURN DBUG_VOID_RETURN
+#else
+#define BAPI_ASSERT(x) assert(x)
+#define BAPI_PRINT(name, params)
+#define BAPI_ENTER(x)
+#define BAPI_RETURN(x) return (x)
+#define BAPI_VOID_RETURN return
+#endif
+#else
+#define BAPI_ASSERT(x) \
+ do { \
+ } while (0)
+#define BAPI_PRINT(name, params)
+#define BAPI_ENTER(x)
+#define BAPI_RETURN(x) return (x)
+#define BAPI_VOID_RETURN return
+#endif
+
+#ifndef HAVE_STRNDUP
+/**
+ The strndup() function returns a pointer to a new string which is a duplicate
+ of the string s, but it only copies at most n bytes. If s is longer than n,
+ only n bytes are copied, and a terminating null byte ('\0') is added.
+ Memory for the new string is obtained with malloc,
+ and can be freed with free.
+ @param s The string whose copy we want to create
+ @param n Number of bytes to be copied
+
+ @return The duplicated string, or NULL if insufficient memory was
+ available.
+*/
+inline char *strndup(const char *s, size_t n) {
+ char *result;
+ size_t len = strlen(s);
+
+ if (n < len) len = n;
+
+ result = (char *)malloc(len + 1);
+ if (!result) return 0;
+
+ result[len] = '\0';
+ return (char *)memcpy(result, s, len);
+}
+#endif
+
+/**
+ This is a wrapper function, and returns a pointer to a new string which is
+ a duplicate of the input string. The terminating Null character is added.
+
+ If compiled with MySQL server,the strndup function from the mysys library is
+ called, which allow instrumenting memory allocated. Else, the standard
+ string function is called.
+
+ @param destination The string to be duplicated
+ @param n The number of bytes to be copied
+
+ @return The duplicated string, or NULL if insufficient memory was available.
+*/
+inline const char *bapi_strndup(const char *destination, size_t n) {
+#ifdef HAVE_MYSYS
+ /* Call the function in mysys library, required for memory instrumentation */
+ return my_strndup(key_memory_log_event, destination, n, MYF(MY_WME));
+#else
+ return strndup(destination, n);
+#endif
+}
+
+/**
+ This is a wrapper function, and returns a pointer to a new memory with the
+ contents copied from the input memory pointer, upto a given length
+
+ @param source Pointer to the buffer from which data is to be copied
+ @param len Length upto which the source should be copied
+
+ @return dest pointer to a new memory if allocation was successful
+ NULL otherwise
+*/
+inline void *bapi_memdup(const void *source, size_t len) {
+ void *dest;
+#ifdef HAVE_MYSYS
+ /* Call the function in mysys library, required for memory instrumentation */
+ dest = my_memdup(key_memory_log_event, source, len, MYF(MY_WME));
+#else
+ dest = malloc(len);
+ if (dest) memcpy(dest, source, len);
+#endif
+ return dest;
+}
+
+/**
+ This is a wrapper function in order to allocate memory from the heap
+ in the binlogevent library.
+
+ If compiled with the MySQL server, and memory is allocated using memory
+ allocating methods from the mysys library, my_malloc is called. Otherwise,
+ the standard malloc() is called from the function.
+
+ @param size Size of the memory to be allocated.
+ @param flags flags to pass to MySQL server my_malloc functions
+ @return Void pointer to the allocated chunk of memory
+*/
+inline void *bapi_malloc(size_t size, int flags MY_ATTRIBUTE((unused))) {
+ void *dest = nullptr;
+#ifdef HAVE_MYSYS
+ dest = my_malloc(key_memory_log_event, size, MYF(flags));
+#else
+ dest = malloc(size);
+#endif
+ return dest;
+}
+
+/**
+ This is a wrapper function in order to free the memory allocated from the heap
+ in the binlogevent library.
+
+ If compiled with the MySQL server, and memory is allocated using memory
+ allocating methods from the mysys library, my_free is called. Otherwise,
+ the standard free() is called from the function.
+
+ @param ptr Pointer to the memory which is to be freed.
+*/
+inline void bapi_free(void *ptr) {
+#ifdef HAVE_MYSYS
+ return my_free(ptr);
+#else
+ return free(ptr);
+#endif
+}
+#endif