My Project
log_event.h
Go to the documentation of this file.
00001 /* Copyright (c) 2000, 2015, Oracle and/or its affiliates. All rights reserved.
00002 
00003    This program is free software; you can redistribute it and/or modify
00004    it under the terms of the GNU General Public License as published by
00005    the Free Software Foundation; version 2 of the License.
00006 
00007    This program is distributed in the hope that it will be useful,
00008    but WITHOUT ANY WARRANTY; without even the implied warranty of
00009    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00010    GNU General Public License for more details.
00011 
00012    You should have received a copy of the GNU General Public License
00013    along with this program; if not, write to the Free Software
00014    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
00015 
00028 #ifndef _log_event_h
00029 #define _log_event_h
00030 
00031 #include <my_bitmap.h>
00032 #include "rpl_constants.h"
00033 #include "table_id.h"
00034 #include <set>
00035 
00036 #ifdef MYSQL_CLIENT
00037 #include "sql_const.h"
00038 #include "rpl_utility.h"
00039 #include "hash.h"
00040 #include "rpl_tblmap.h"
00041 #endif
00042 
00043 #ifdef MYSQL_SERVER
00044 #include "rpl_record.h"
00045 #include "rpl_reporting.h"
00046 #include "sql_class.h"                          /* THD */
00047 #include "rpl_utility.h"                        /* Hash_slave_rows */
00048 #include "rpl_filter.h"
00049 #include "key.h"                                /* key_copy, compare_keys */
00050 #endif
00051 
00052 /* Forward declarations */
00053 class String;
00054 typedef ulonglong sql_mode_t;
00055 typedef struct st_db_worker_hash_entry db_worker_hash_entry;
00056 
00057 #define PREFIX_SQL_LOAD "SQL_LOAD-"
00058 
00069 #define TEMP_FILE_MAX_LEN UUID_LENGTH+38 
00070 
00080 #ifdef DBUG_OFF
00081 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
00082   do { if (!(COND)) return ERRNO; } while (0)
00083 #else
00084 #define ASSERT_OR_RETURN_ERROR(COND, ERRNO) \
00085   DBUG_ASSERT(COND)
00086 #endif
00087 
00088 #define LOG_READ_EOF    -1
00089 #define LOG_READ_BOGUS  -2
00090 #define LOG_READ_IO     -3
00091 #define LOG_READ_MEM    -5
00092 #define LOG_READ_TRUNC  -6
00093 #define LOG_READ_TOO_LARGE -7
00094 #define LOG_READ_CHECKSUM_FAILURE -8
00095 
00096 #define LOG_EVENT_OFFSET 4
00097 
00098 /*
00099    3 is MySQL 4.x; 4 is MySQL 5.0.0.
00100    Compared to version 3, version 4 has:
00101    - a different Start_log_event, which includes info about the binary log
00102    (sizes of headers); this info is included for better compatibility if the
00103    master's MySQL version is different from the slave's.
00104    - all events have a unique ID (the triplet (server_id, timestamp at server
00105    start, other) to be sure an event is not executed more than once in a
00106    multimaster setup, example:
00107                 M1
00108               /   \
00109              v     v
00110              M2    M3
00111              \     /
00112               v   v
00113                 S
00114    if a query is run on M1, it will arrive twice on S, so we need that S
00115    remembers the last unique ID it has processed, to compare and know if the
00116    event should be skipped or not. Example of ID: we already have the server id
00117    (4 bytes), plus:
00118    timestamp_when_the_master_started (4 bytes), a counter (a sequence number
00119    which increments every time we write an event to the binlog) (3 bytes).
00120    Q: how do we handle when the counter is overflowed and restarts from 0 ?
00121 
00122    - Query and Load (Create or Execute) events may have a more precise
00123      timestamp (with microseconds), number of matched/affected/warnings rows
00124    and fields of session variables: SQL_MODE,
00125    FOREIGN_KEY_CHECKS, UNIQUE_CHECKS, SQL_AUTO_IS_NULL, the collations and
00126    charsets, the PASSWORD() version (old/new/...).
00127 */
00128 #define BINLOG_VERSION    4
00129 
00130 /*
00131  We could have used SERVER_VERSION_LENGTH, but this introduces an
00132  obscure dependency - if somebody decided to change SERVER_VERSION_LENGTH
00133  this would break the replication protocol
00134 */
00135 #define ST_SERVER_VER_LEN 50
00136 
00137 /*
00138   These are flags and structs to handle all the LOAD DATA INFILE options (LINES
00139   TERMINATED etc).
00140 */
00141 
00142 /*
00143   These are flags and structs to handle all the LOAD DATA INFILE options (LINES
00144   TERMINATED etc).
00145   DUMPFILE_FLAG is probably useless (DUMPFILE is a clause of SELECT, not of LOAD
00146   DATA).
00147 */
00148 #define DUMPFILE_FLAG           0x1
00149 #define OPT_ENCLOSED_FLAG       0x2
00150 #define REPLACE_FLAG            0x4
00151 #define IGNORE_FLAG             0x8
00152 
00153 #define FIELD_TERM_EMPTY        0x1
00154 #define ENCLOSED_EMPTY          0x2
00155 #define LINE_TERM_EMPTY         0x4
00156 #define LINE_START_EMPTY        0x8
00157 #define ESCAPED_EMPTY           0x10
00158 
00159 /*****************************************************************************
00160 
00161   old_sql_ex struct
00162 
00163  ****************************************************************************/
00164 struct old_sql_ex
00165 {
00166   char field_term;
00167   char enclosed;
00168   char line_term;
00169   char line_start;
00170   char escaped;
00171   char opt_flags;
00172   char empty_flags;
00173 };
00174 
00175 #define NUM_LOAD_DELIM_STRS 5
00176 
00177 /*****************************************************************************
00178 
00179   sql_ex_info struct
00180 
00181  ****************************************************************************/
00182 struct sql_ex_info
00183 {
00184   sql_ex_info() {}                            /* Remove gcc warning */
00185   const char* field_term;
00186   const char* enclosed;
00187   const char* line_term;
00188   const char* line_start;
00189   const char* escaped;
00190   int cached_new_format;
00191   uint8 field_term_len,enclosed_len,line_term_len,line_start_len, escaped_len;
00192   char opt_flags;
00193   char empty_flags;
00194 
00195   // store in new format even if old is possible
00196   void force_new_format() { cached_new_format = 1;}
00197   int data_size()
00198   {
00199     return (new_format() ?
00200             field_term_len + enclosed_len + line_term_len +
00201             line_start_len + escaped_len + 6 : 7);
00202   }
00203   bool write_data(IO_CACHE* file);
00204   const char* init(const char* buf, const char* buf_end, bool use_new_format);
00205   bool new_format()
00206   {
00207     return ((cached_new_format != -1) ? cached_new_format :
00208             (cached_new_format=(field_term_len > 1 ||
00209                                 enclosed_len > 1 ||
00210                                 line_term_len > 1 || line_start_len > 1 ||
00211                                 escaped_len > 1)));
00212   }
00213 };
00214 
00215 /*****************************************************************************
00216 
00217   MySQL Binary Log
00218 
00219   This log consists of events.  Each event has a fixed-length header,
00220   possibly followed by a variable length data body.
00221 
00222   The data body consists of an optional fixed length segment (post-header)
00223   and  an optional variable length segment.
00224 
00225   See the #defines below for the format specifics.
00226 
00227   The events which really update data are Query_log_event,
00228   Execute_load_query_log_event and old Load_log_event and
00229   Execute_load_log_event events (Execute_load_query is used together with
00230   Begin_load_query and Append_block events to replicate LOAD DATA INFILE.
00231   Create_file/Append_block/Execute_load (which includes Load_log_event)
00232   were used to replicate LOAD DATA before the 5.0.3).
00233 
00234  ****************************************************************************/
00235 
00236 #define LOG_EVENT_HEADER_LEN 19U    /* the fixed header length */
00237 #define OLD_HEADER_LEN       13U    /* the fixed header length in 3.23 */
00238 /*
00239    Fixed header length, where 4.x and 5.0 agree. That is, 5.0 may have a longer
00240    header (it will for sure when we have the unique event's ID), but at least
00241    the first 19 bytes are the same in 4.x and 5.0. So when we have the unique
00242    event's ID, LOG_EVENT_HEADER_LEN will be something like 26, but
00243    LOG_EVENT_MINIMAL_HEADER_LEN will remain 19.
00244 */
00245 #define LOG_EVENT_MINIMAL_HEADER_LEN 19U
00246 
00247 /* event-specific post-header sizes */
00248 // where 3.23, 4.x and 5.0 agree
00249 #define QUERY_HEADER_MINIMAL_LEN     (4 + 4 + 1 + 2)
00250 // where 5.0 differs: 2 for len of N-bytes vars.
00251 #define QUERY_HEADER_LEN     (QUERY_HEADER_MINIMAL_LEN + 2)
00252 #define STOP_HEADER_LEN      0
00253 #define LOAD_HEADER_LEN      (4 + 4 + 4 + 1 +1 + 4)
00254 #define START_V3_HEADER_LEN     (2 + ST_SERVER_VER_LEN + 4)
00255 #define ROTATE_HEADER_LEN    8 // this is FROZEN (the Rotate post-header is frozen)
00256 #define INTVAR_HEADER_LEN      0
00257 #define CREATE_FILE_HEADER_LEN 4
00258 #define APPEND_BLOCK_HEADER_LEN 4
00259 #define EXEC_LOAD_HEADER_LEN   4
00260 #define DELETE_FILE_HEADER_LEN 4
00261 #define NEW_LOAD_HEADER_LEN    LOAD_HEADER_LEN
00262 #define RAND_HEADER_LEN        0
00263 #define USER_VAR_HEADER_LEN    0
00264 #define FORMAT_DESCRIPTION_HEADER_LEN (START_V3_HEADER_LEN+1+LOG_EVENT_TYPES)
00265 #define XID_HEADER_LEN         0
00266 #define BEGIN_LOAD_QUERY_HEADER_LEN APPEND_BLOCK_HEADER_LEN
00267 #define ROWS_HEADER_LEN_V1     8
00268 #define TABLE_MAP_HEADER_LEN   8
00269 #define EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN (4 + 4 + 4 + 1)
00270 #define EXECUTE_LOAD_QUERY_HEADER_LEN  (QUERY_HEADER_LEN + EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN)
00271 #define INCIDENT_HEADER_LEN    2
00272 #define HEARTBEAT_HEADER_LEN   0
00273 #define IGNORABLE_HEADER_LEN   0
00274 #define ROWS_HEADER_LEN_V2     10
00275 
00276 /*
00277    The maximum number of updated databases that a status of
00278    Query-log-event can carry.  It can redefined within a range
00279    [1.. OVER_MAX_DBS_IN_EVENT_MTS].
00280 */
00281 #define MAX_DBS_IN_EVENT_MTS 16
00282 
00283 /*
00284    When the actual number of databases exceeds MAX_DBS_IN_EVENT_MTS
00285    the value of OVER_MAX_DBS_IN_EVENT_MTS is is put into the
00286    mts_accessed_dbs status.
00287 */
00288 #define OVER_MAX_DBS_IN_EVENT_MTS 254
00289 
00290 /* 
00291   Max number of possible extra bytes in a replication event compared to a
00292   packet (i.e. a query) sent from client to master;
00293   First, an auxiliary log_event status vars estimation:
00294 */
00295 #define MAX_SIZE_LOG_EVENT_STATUS (1U + 4          /* type, flags2 */   + \
00296                                    1U + 8          /* type, sql_mode */ + \
00297                                    1U + 1 + 255    /* type, length, catalog */ + \
00298                                    1U + 4          /* type, auto_increment */ + \
00299                                    1U + 6          /* type, charset */ + \
00300                                    1U + 1 + 255    /* type, length, time_zone */ + \
00301                                    1U + 2          /* type, lc_time_names_number */ + \
00302                                    1U + 2          /* type, charset_database_number */ + \
00303                                    1U + 8          /* type, table_map_for_update */ + \
00304                                    1U + 4          /* type, master_data_written */ + \
00305                                                    /* type, db_1, db_2, ... */  \
00306                                    1U + (MAX_DBS_IN_EVENT_MTS * (1 + NAME_LEN)) + \
00307                                    3U +            /* type, microseconds */ + \
00308                                    1U + 16 + 1 + 60/* type, user_len, user, host_len, host */)
00309 #define MAX_LOG_EVENT_HEADER   ( /* in order of Query_log_event::write */ \
00310   LOG_EVENT_HEADER_LEN + /* write_header */ \
00311   QUERY_HEADER_LEN     + /* write_data */   \
00312   EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN + /*write_post_header_for_derived */ \
00313   MAX_SIZE_LOG_EVENT_STATUS + /* status */ \
00314   NAME_LEN + 1)
00315 
00316 /*
00317   The new option is added to handle large packets that are sent from the master 
00318   to the slave. It is used to increase the thd(max_allowed) for both the
00319   DUMP thread on the master and the SQL/IO thread on the slave. 
00320 */
00321 #define MAX_MAX_ALLOWED_PACKET 1024*1024*1024
00322 
00323 /* 
00324    Event header offsets; 
00325    these point to places inside the fixed header.
00326 */
00327 
00328 #define EVENT_TYPE_OFFSET    4
00329 #define SERVER_ID_OFFSET     5
00330 #define EVENT_LEN_OFFSET     9
00331 #define LOG_POS_OFFSET       13
00332 #define FLAGS_OFFSET         17
00333 
00334 /* start event post-header (for v3 and v4) */
00335 
00336 #define ST_BINLOG_VER_OFFSET  0
00337 #define ST_SERVER_VER_OFFSET  2
00338 #define ST_CREATED_OFFSET     (ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
00339 #define ST_COMMON_HEADER_LEN_OFFSET (ST_CREATED_OFFSET + 4)
00340 
00341 /* slave event post-header (this event is never written) */
00342 
00343 #define SL_MASTER_PORT_OFFSET   8
00344 #define SL_MASTER_POS_OFFSET    0
00345 #define SL_MASTER_HOST_OFFSET   10
00346 
00347 /* query event post-header */
00348 
00349 #define Q_THREAD_ID_OFFSET      0
00350 #define Q_EXEC_TIME_OFFSET      4
00351 #define Q_DB_LEN_OFFSET         8
00352 #define Q_ERR_CODE_OFFSET       9
00353 #define Q_STATUS_VARS_LEN_OFFSET 11
00354 #define Q_DATA_OFFSET           QUERY_HEADER_LEN
00355 /* these are codes, not offsets; not more than 256 values (1 byte). */
00356 #define Q_FLAGS2_CODE           0
00357 #define Q_SQL_MODE_CODE         1
00358 /*
00359   Q_CATALOG_CODE is catalog with end zero stored; it is used only by MySQL
00360   5.0.x where 0<=x<=3. We have to keep it to be able to replicate these
00361   old masters.
00362 */
00363 #define Q_CATALOG_CODE          2
00364 #define Q_AUTO_INCREMENT        3
00365 #define Q_CHARSET_CODE          4
00366 #define Q_TIME_ZONE_CODE        5
00367 /*
00368   Q_CATALOG_NZ_CODE is catalog withOUT end zero stored; it is used by MySQL
00369   5.0.x where x>=4. Saves one byte in every Query_log_event in binlog,
00370   compared to Q_CATALOG_CODE. The reason we didn't simply re-use
00371   Q_CATALOG_CODE is that then a 5.0.3 slave of this 5.0.x (x>=4) master would
00372   crash (segfault etc) because it would expect a 0 when there is none.
00373 */
00374 #define Q_CATALOG_NZ_CODE       6
00375 
00376 #define Q_LC_TIME_NAMES_CODE    7
00377 
00378 #define Q_CHARSET_DATABASE_CODE 8
00379 
00380 #define Q_TABLE_MAP_FOR_UPDATE_CODE 9
00381 
00382 #define Q_MASTER_DATA_WRITTEN_CODE 10
00383 
00384 #define Q_INVOKER 11
00385 
00386 /*
00387   Q_UPDATED_DB_NAMES status variable collects of the updated databases
00388   total number and their names to be propagated to the slave in order
00389   to facilitate the parallel applying of the Query events.
00390 */
00391 #define Q_UPDATED_DB_NAMES 12
00392 
00393 #define Q_MICROSECONDS 13
00394 
00395 /* Intvar event post-header */
00396 
00397 /* Intvar event data */
00398 #define I_TYPE_OFFSET        0
00399 #define I_VAL_OFFSET         1
00400 
00401 /* Rand event data */
00402 #define RAND_SEED1_OFFSET 0
00403 #define RAND_SEED2_OFFSET 8
00404 
00405 /* User_var event data */
00406 #define UV_VAL_LEN_SIZE        4
00407 #define UV_VAL_IS_NULL         1
00408 #define UV_VAL_TYPE_SIZE       1
00409 #define UV_NAME_LEN_SIZE       4
00410 #define UV_CHARSET_NUMBER_SIZE 4
00411 
00412 /* Load event post-header */
00413 #define L_THREAD_ID_OFFSET   0
00414 #define L_EXEC_TIME_OFFSET   4
00415 #define L_SKIP_LINES_OFFSET  8
00416 #define L_TBL_LEN_OFFSET     12
00417 #define L_DB_LEN_OFFSET      13
00418 #define L_NUM_FIELDS_OFFSET  14
00419 #define L_SQL_EX_OFFSET      18
00420 #define L_DATA_OFFSET        LOAD_HEADER_LEN
00421 
00422 /* Rotate event post-header */
00423 #define R_POS_OFFSET       0
00424 #define R_IDENT_OFFSET     8
00425 
00426 /* CF to DF handle LOAD DATA INFILE */
00427 
00428 /* CF = "Create File" */
00429 #define CF_FILE_ID_OFFSET  0
00430 #define CF_DATA_OFFSET     CREATE_FILE_HEADER_LEN
00431 
00432 /* AB = "Append Block" */
00433 #define AB_FILE_ID_OFFSET  0
00434 #define AB_DATA_OFFSET     APPEND_BLOCK_HEADER_LEN
00435 
00436 /* EL = "Execute Load" */
00437 #define EL_FILE_ID_OFFSET  0
00438 
00439 /* DF = "Delete File" */
00440 #define DF_FILE_ID_OFFSET  0
00441 
00442 /* TM = "Table Map" */
00443 #define TM_MAPID_OFFSET    0
00444 #define TM_FLAGS_OFFSET    6
00445 
00446 /* RW = "RoWs" */
00447 #define RW_MAPID_OFFSET    0
00448 #define RW_FLAGS_OFFSET    6
00449 #define RW_VHLEN_OFFSET    8
00450 #define RW_V_TAG_LEN       1
00451 #define RW_V_EXTRAINFO_TAG 0
00452 
00453 /* ELQ = "Execute Load Query" */
00454 #define ELQ_FILE_ID_OFFSET QUERY_HEADER_LEN
00455 #define ELQ_FN_POS_START_OFFSET ELQ_FILE_ID_OFFSET + 4
00456 #define ELQ_FN_POS_END_OFFSET ELQ_FILE_ID_OFFSET + 8
00457 #define ELQ_DUP_HANDLING_OFFSET ELQ_FILE_ID_OFFSET + 12
00458 
00459 /* 4 bytes which all binlogs should begin with */
00460 #define BINLOG_MAGIC        "\xfe\x62\x69\x6e"
00461 
00462 /*
00463   The 2 flags below were useless :
00464   - the first one was never set
00465   - the second one was set in all Rotate events on the master, but not used for
00466   anything useful.
00467   So they are now removed and their place may later be reused for other
00468   flags. Then one must remember that Rotate events in 4.x have
00469   LOG_EVENT_FORCED_ROTATE_F set, so one should not rely on the value of the
00470   replacing flag when reading a Rotate event.
00471   I keep the defines here just to remember what they were.
00472 */
00473 #ifdef TO_BE_REMOVED
00474 #define LOG_EVENT_TIME_F            0x1
00475 #define LOG_EVENT_FORCED_ROTATE_F   0x2
00476 #endif
00477 
00478 /*
00479    This flag only makes sense for Format_description_log_event. It is set
00480    when the event is written, and *reset* when a binlog file is
00481    closed (yes, it's the only case when MySQL modifies already written
00482    part of binlog).  Thus it is a reliable indicator that binlog was
00483    closed correctly.  (Stop_log_event is not enough, there's always a
00484    small chance that mysqld crashes in the middle of insert and end of
00485    the binlog would look like a Stop_log_event).
00486 
00487    This flag is used to detect a restart after a crash, and to provide
00488    "unbreakable" binlog. The problem is that on a crash storage engines
00489    rollback automatically, while binlog does not.  To solve this we use this
00490    flag and automatically append ROLLBACK to every non-closed binlog (append
00491    virtually, on reading, file itself is not changed). If this flag is found,
00492    mysqlbinlog simply prints "ROLLBACK" Replication master does not abort on
00493    binlog corruption, but takes it as EOF, and replication slave forces a
00494    rollback in this case.
00495 
00496    Note, that old binlogs does not have this flag set, so we get a
00497    a backward-compatible behaviour.
00498 */
00499 
00500 #define LOG_EVENT_BINLOG_IN_USE_F       0x1
00501 
00510 #define LOG_EVENT_THREAD_SPECIFIC_F 0x4
00511 
00525 #define LOG_EVENT_SUPPRESS_USE_F    0x8
00526 
00527 /*
00528   Note: this is a place holder for the flag
00529   LOG_EVENT_UPDATE_TABLE_MAP_VERSION_F (0x10), which is not used any
00530   more, please do not reused this value for other flags.
00531  */
00532 
00542 #define LOG_EVENT_ARTIFICIAL_F 0x20
00543 
00550 #define LOG_EVENT_RELAY_LOG_F 0x40
00551 
00561 #define LOG_EVENT_IGNORABLE_F 0x80
00562 
00570 #define LOG_EVENT_NO_FILTER_F 0x100
00571 
00581 #define LOG_EVENT_MTS_ISOLATE_F 0x200
00582 
00583 
00605 #define OPTIONS_WRITTEN_TO_BIN_LOG \
00606   (OPTION_AUTO_IS_NULL | OPTION_NO_FOREIGN_KEY_CHECKS |  \
00607    OPTION_RELAXED_UNIQUE_CHECKS | OPTION_NOT_AUTOCOMMIT)
00608 
00609 /* Shouldn't be defined before */
00610 #define EXPECTED_OPTIONS \
00611   ((ULL(1) << 14) | (ULL(1) << 26) | (ULL(1) << 27) | (ULL(1) << 19))
00612 
00613 #if OPTIONS_WRITTEN_TO_BIN_LOG != EXPECTED_OPTIONS
00614 #error OPTIONS_WRITTEN_TO_BIN_LOG must NOT change their values!
00615 #endif
00616 #undef EXPECTED_OPTIONS         /* You shouldn't use this one */
00617 
00618 enum enum_binlog_checksum_alg {
00619   BINLOG_CHECKSUM_ALG_OFF= 0,    // Events are without checksum though its generator
00620                                  // is checksum-capable New Master (NM).
00621   BINLOG_CHECKSUM_ALG_CRC32= 1,  // CRC32 of zlib algorithm.
00622   BINLOG_CHECKSUM_ALG_ENUM_END,  // the cut line: valid alg range is [1, 0x7f].
00623   BINLOG_CHECKSUM_ALG_UNDEF= 255 // special value to tag undetermined yet checksum
00624                                  // or events from checksum-unaware servers
00625 };
00626 
00627 #define CHECKSUM_CRC32_SIGNATURE_LEN 4
00628 
00631 #define BINLOG_CHECKSUM_LEN CHECKSUM_CRC32_SIGNATURE_LEN
00632 #define BINLOG_CHECKSUM_ALG_DESC_LEN 1  /* 1 byte checksum alg descriptor */
00633 
00639 enum Log_event_type
00640 {
00641   /*
00642     Every time you update this enum (when you add a type), you have to
00643     fix Format_description_log_event::Format_description_log_event().
00644   */
00645   UNKNOWN_EVENT= 0,
00646   START_EVENT_V3= 1,
00647   QUERY_EVENT= 2,
00648   STOP_EVENT= 3,
00649   ROTATE_EVENT= 4,
00650   INTVAR_EVENT= 5,
00651   LOAD_EVENT= 6,
00652   SLAVE_EVENT= 7,  /* Unused. Slave_log_event code has been removed. (15th Oct. 2010) */
00653   CREATE_FILE_EVENT= 8,
00654   APPEND_BLOCK_EVENT= 9,
00655   EXEC_LOAD_EVENT= 10,
00656   DELETE_FILE_EVENT= 11,
00657   /*
00658     NEW_LOAD_EVENT is like LOAD_EVENT except that it has a longer
00659     sql_ex, allowing multibyte TERMINATED BY etc; both types share the
00660     same class (Load_log_event)
00661   */
00662   NEW_LOAD_EVENT= 12,
00663   RAND_EVENT= 13,
00664   USER_VAR_EVENT= 14,
00665   FORMAT_DESCRIPTION_EVENT= 15,
00666   XID_EVENT= 16,
00667   BEGIN_LOAD_QUERY_EVENT= 17,
00668   EXECUTE_LOAD_QUERY_EVENT= 18,
00669 
00670   TABLE_MAP_EVENT = 19,
00671 
00672   /*
00673     These event numbers were used for 5.1.0 to 5.1.15 and are
00674     therefore obsolete.
00675    */
00676   PRE_GA_WRITE_ROWS_EVENT = 20,
00677   PRE_GA_UPDATE_ROWS_EVENT = 21,
00678   PRE_GA_DELETE_ROWS_EVENT = 22,
00679 
00680   /*
00681     These event numbers are used from 5.1.16 until mysql-trunk-xx
00682    */
00683   WRITE_ROWS_EVENT_V1 = 23,
00684   UPDATE_ROWS_EVENT_V1 = 24,
00685   DELETE_ROWS_EVENT_V1 = 25,
00686 
00687   /*
00688     Something out of the ordinary happened on the master
00689    */
00690   INCIDENT_EVENT= 26,
00691 
00692   /*
00693     Heartbeat event to be send by master at its idle time 
00694     to ensure master's online status to slave 
00695   */
00696   HEARTBEAT_LOG_EVENT= 27,
00697 
00698   /*
00699     In some situations, it is necessary to send over ignorable
00700     data to the slave: data that a slave can handle in case there
00701     is code for handling it, but which can be ignored if it is not
00702     recognized.
00703   */
00704   IGNORABLE_LOG_EVENT= 28,
00705   ROWS_QUERY_LOG_EVENT= 29,
00706 
00707   /* Version 2 of the Row events */
00708   WRITE_ROWS_EVENT = 30,
00709   UPDATE_ROWS_EVENT = 31,
00710   DELETE_ROWS_EVENT = 32,
00711 
00712   GTID_LOG_EVENT= 33,
00713   ANONYMOUS_GTID_LOG_EVENT= 34,
00714 
00715   PREVIOUS_GTIDS_LOG_EVENT= 35,
00716   /*
00717     Add new events here - right above this comment!
00718     Existing events (except ENUM_END_EVENT) should never change their numbers
00719   */
00720 
00721   ENUM_END_EVENT /* end marker */
00722 };
00723 
00724 /*
00725    The number of types we handle in Format_description_log_event (UNKNOWN_EVENT
00726    is not to be handled, it does not exist in binlogs, it does not have a
00727    format).
00728 */
00729 #define LOG_EVENT_TYPES (ENUM_END_EVENT-1)
00730 
00731 enum Int_event_type
00732 {
00733   INVALID_INT_EVENT = 0, LAST_INSERT_ID_EVENT = 1, INSERT_ID_EVENT = 2
00734 };
00735 
00736 
00737 #ifdef MYSQL_SERVER
00738 class String;
00739 class MYSQL_BIN_LOG;
00740 class THD;
00741 #endif
00742 
00743 class Format_description_log_event;
00744 class Relay_log_info;
00745 class Slave_worker;
00746 class Slave_committed_queue;
00747 
00748 #ifdef MYSQL_CLIENT
00749 enum enum_base64_output_mode {
00750   BASE64_OUTPUT_NEVER= 0,
00751   BASE64_OUTPUT_AUTO= 1,
00752   BASE64_OUTPUT_UNSPEC= 2,
00753   BASE64_OUTPUT_DECODE_ROWS= 3,
00754   /* insert new output modes here */
00755   BASE64_OUTPUT_MODE_COUNT
00756 };
00757 
00758 /*
00759   A structure for mysqlbinlog to know how to print events
00760 
00761   This structure is passed to the event's print() methods,
00762 
00763   There are two types of settings stored here:
00764   1. Last db, flags2, sql_mode etc comes from the last printed event.
00765      They are stored so that only the necessary USE and SET commands
00766      are printed.
00767   2. Other information on how to print the events, e.g. short_form,
00768      hexdump_from.  These are not dependent on the last event.
00769 */
00770 typedef struct st_print_event_info
00771 {
00772   /*
00773     Settings for database, sql_mode etc that comes from the last event
00774     that was printed.  We cache these so that we don't have to print
00775     them if they are unchanged.
00776   */
00777   // TODO: have the last catalog here ??
00778   char db[FN_REFLEN+1]; // TODO: make this a LEX_STRING when thd->db is
00779   bool flags2_inited;
00780   uint32 flags2;
00781   bool sql_mode_inited;
00782   sql_mode_t sql_mode;          /* must be same as THD.variables.sql_mode */
00783   ulong auto_increment_increment, auto_increment_offset;
00784   bool charset_inited;
00785   char charset[6]; // 3 variables, each of them storable in 2 bytes
00786   char time_zone_str[MAX_TIME_ZONE_NAME_LENGTH];
00787   uint lc_time_names_number;
00788   uint charset_database_number;
00789   uint thread_id;
00790   bool thread_id_printed;
00791   uint32 server_id_from_fd_event;
00792 
00793   st_print_event_info();
00794 
00795   ~st_print_event_info() {
00796     close_cached_file(&head_cache);
00797     close_cached_file(&body_cache);
00798   }
00799   bool init_ok() /* tells if construction was successful */
00800     { return my_b_inited(&head_cache) && my_b_inited(&body_cache); }
00801 
00802 
00803   /* Settings on how to print the events */
00804   bool short_form;
00805   enum_base64_output_mode base64_output_mode;
00806   /*
00807     This is set whenever a Format_description_event is printed.
00808     Later, when an event is printed in base64, this flag is tested: if
00809     no Format_description_event has been seen, it is unsafe to print
00810     the base64 event, so an error message is generated.
00811   */
00812   bool printed_fd_event;
00813   my_off_t hexdump_from;
00814   uint8 common_header_len;
00815   char delimiter[16];
00816 
00817   uint verbose;
00818   table_mapping m_table_map;
00819   table_mapping m_table_map_ignored;
00820 
00821   /*
00822      These two caches are used by the row-based replication events to
00823      collect the header information and the main body of the events
00824      making up a statement.
00825    */
00826   IO_CACHE head_cache;
00827   IO_CACHE body_cache;
00828   /* Indicate if the body cache has unflushed events */
00829   bool have_unflushed_events;
00830 
00831   /*
00832      True if an event was skipped while printing the events of
00833      a transaction and no COMMIT statement or XID event was ever
00834      output (ie, was filtered out as well). This can be triggered
00835      by the --database option of mysqlbinlog.
00836 
00837      False, otherwise.
00838    */
00839   bool skipped_event_in_transaction;
00840 
00841   /* true if gtid_next is set with a value */
00842   bool is_gtid_next_set;
00843 
00844   /*
00845     Determines if the current value of gtid_next needs to be restored
00846     to AUTOMATIC if the binary log would end after the current event.
00847 
00848     If the log ends after a transaction, then this should be false.
00849     If the log ends in the middle of a transaction, then this should
00850     be true; this can happen for relay logs where transactions are
00851     split over multiple logs.
00852 
00853     Set to true initially, and after a Gtid_log_event is processed.
00854     Set to false if is_gtid_next_set is true.
00855    */
00856   bool is_gtid_next_valid;
00857 } PRINT_EVENT_INFO;
00858 #endif
00859 
00860 /*
00861   A specific to the database-scheduled MTS type.
00862 */
00863 typedef struct st_mts_db_names
00864 {
00865   const char *name[MAX_DBS_IN_EVENT_MTS];
00866   int  num;
00867 } Mts_db_names;
00868 
00869 
01000 class Log_event
01001 {
01002 public:
01010   enum enum_skip_reason {
01014     EVENT_SKIP_NOT,
01015 
01021     EVENT_SKIP_IGNORE,
01022 
01026     EVENT_SKIP_COUNT
01027   };
01028 
01029 protected:
01030   enum enum_event_cache_type 
01031   {
01032     EVENT_INVALID_CACHE= 0,
01033     /* 
01034       If possible the event should use a non-transactional cache before
01035       being flushed to the binary log. This means that it must be flushed
01036       right after its correspondent statement is completed.
01037     */
01038     EVENT_STMT_CACHE,
01039     /* 
01040       The event should use a transactional cache before being flushed to
01041       the binary log. This means that it must be flushed upon commit or 
01042       rollback. 
01043     */
01044     EVENT_TRANSACTIONAL_CACHE,
01045     /* 
01046       The event must be written directly to the binary log without going
01047       through any cache.
01048     */
01049     EVENT_NO_CACHE,
01050     /*
01051        If there is a need for different types, introduce them before this.
01052     */
01053     EVENT_CACHE_COUNT
01054   };
01055 
01056   enum enum_event_logging_type
01057   {
01058     EVENT_INVALID_LOGGING= 0,
01059     /*
01060       The event must be written to a cache and upon commit or rollback
01061       written to the binary log.
01062     */
01063     EVENT_NORMAL_LOGGING,
01064     /*
01065       The event must be written to an empty cache and immediatly written
01066       to the binary log without waiting for any other event.
01067     */
01068     EVENT_IMMEDIATE_LOGGING,
01069     /*
01070        If there is a need for different types, introduce them before this.
01071     */
01072     EVENT_CACHE_LOGGING_COUNT
01073   };
01074 
01075 public:
01076   /*
01077     The following type definition is to be used whenever data is placed 
01078     and manipulated in a common buffer. Use this typedef for buffers
01079     that contain data containing binary and character data.
01080   */
01081   typedef unsigned char Byte;
01082 
01083   /*
01084     The offset in the log where this event originally appeared (it is
01085     preserved in relay logs, making SHOW SLAVE STATUS able to print
01086     coordinates of the event in the master's binlog). Note: when a
01087     transaction is written by the master to its binlog (wrapped in
01088     BEGIN/COMMIT) the log_pos of all the queries it contains is the
01089     one of the BEGIN (this way, when one does SHOW SLAVE STATUS it
01090     sees the offset of the BEGIN, which is logical as rollback may
01091     occur), except the COMMIT query which has its real offset.
01092   */
01093   my_off_t log_pos;
01094   /*
01095      A temp buffer for read_log_event; it is later analysed according to the
01096      event's type, and its content is distributed in the event-specific fields.
01097   */
01098   char *temp_buf;
01099   /*
01100     Timestamp on the master(for debugging and replication of
01101     NOW()/TIMESTAMP).  It is important for queries and LOAD DATA
01102     INFILE. This is set at the event's creation time, except for Query
01103     and Load (et al.) events where this is set at the query's
01104     execution time, which guarantees good replication (otherwise, we
01105     could have a query and its event with different timestamps).
01106   */
01107   struct timeval when;
01108   /* The number of seconds the query took to run on the master. */
01109   ulong exec_time;
01110   /* Number of bytes written by write() function */
01111   ulong data_written;
01112 
01113   /*
01114     The master's server id (is preserved in the relay log; used to
01115     prevent from infinite loops in circular replication).
01116   */
01117   uint32 server_id;
01118 
01119   /*
01120     The server id read from the Binlog.  server_id above has
01121     lowest bits of this only according to the value of
01122     opt_server_id_bits
01123   */
01124   uint32 unmasked_server_id;
01125 
01131   uint16 flags;
01132   
01137   ulong slave_exec_mode;
01138 
01143   enum_event_cache_type event_cache_type;
01144 
01149   enum_event_logging_type event_logging_type;
01150 
01154   ha_checksum crc;
01155 
01162   ulong mts_group_idx;
01163 
01169   Relay_log_info *worker;
01170 
01174   ulonglong future_event_relay_log_pos;
01175 
01176 #ifdef MYSQL_SERVER
01177   THD* thd;
01181   db_worker_hash_entry *mts_assigned_partitions[MAX_DBS_IN_EVENT_MTS];
01182 
01183   Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE,
01184             enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING);
01185   Log_event(THD* thd_arg, uint16 flags_arg,
01186             enum_event_cache_type cache_type_arg,
01187             enum_event_logging_type logging_type_arg);
01188   /*
01189     read_log_event() functions read an event from a binlog or relay
01190     log; used by SHOW BINLOG EVENTS, the binlog_dump thread on the
01191     master (reads master's binlog), the slave IO thread (reads the
01192     event sent by binlog_dump), the slave SQL thread (reads the event
01193     from the relay log).  If mutex is 0, the read will proceed without
01194     mutex.  We need the description_event to be able to parse the
01195     event (to know the post-header's size); in fact in read_log_event
01196     we detect the event's type, then call the specific event's
01197     constructor and pass description_event as an argument.
01198   */
01199   static Log_event* read_log_event(IO_CACHE* file,
01200                                    mysql_mutex_t* log_lock,
01201                                    const Format_description_log_event
01202                                    *description_event,
01203                                    my_bool crc_check);
01204 
01229   static int read_log_event(IO_CACHE* file, String* packet,
01230                             mysql_mutex_t* log_lock,
01231                             uint8 checksum_alg_arg,
01232                             const char *log_file_name_arg= NULL,
01233                             bool* is_binlog_active= NULL);
01234   /*
01235     init_show_field_list() prepares the column names and types for the
01236     output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
01237     EVENTS.
01238   */
01239   static void init_show_field_list(List<Item>* field_list);
01240 #ifdef HAVE_REPLICATION
01241   int net_send(Protocol *protocol, const char* log_name, my_off_t pos);
01242 
01250   virtual int pack_info(Protocol *protocol);
01251 
01252 #endif /* HAVE_REPLICATION */
01253   virtual const char* get_db()
01254   {
01255     return thd ? thd->db : 0;
01256   }
01257 #else // ifdef MYSQL_SERVER
01258   Log_event(enum_event_cache_type cache_type_arg= EVENT_INVALID_CACHE,
01259             enum_event_logging_type logging_type_arg= EVENT_INVALID_LOGGING)
01260   : temp_buf(0), flags(0), event_cache_type(cache_type_arg),
01261     event_logging_type(logging_type_arg)
01262   { }
01263     /* avoid having to link mysqlbinlog against libpthread */
01264   static Log_event* read_log_event(IO_CACHE* file,
01265                                    const Format_description_log_event
01266                                    *description_event, my_bool crc_check);
01267   /* print*() functions are used by mysqlbinlog */
01268   virtual void print(FILE* file, PRINT_EVENT_INFO* print_event_info) = 0;
01269   void print_timestamp(IO_CACHE* file, time_t* ts);
01270   void print_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
01271                     bool is_more);
01272   void print_base64(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info,
01273                     bool is_more);
01274 #endif // ifdef MYSQL_SERVER ... else
01275   /* 
01276      The value is set by caller of FD constructor and
01277      Log_event::write_header() for the rest.
01278      In the FD case it's propagated into the last byte 
01279      of post_header_len[] at FD::write().
01280      On the slave side the value is assigned from post_header_len[last] 
01281      of the last seen FD event.
01282   */
01283   uint8 checksum_alg;
01284 
01285   static void *operator new(size_t size)
01286   {
01287     return (void*) my_malloc((uint)size, MYF(MY_WME|MY_FAE));
01288   }
01289 
01290   static void operator delete(void *ptr, size_t)
01291   {
01292     my_free(ptr);
01293   }
01294 
01295   /* Placement version of the above operators */
01296   static void *operator new(size_t, void* ptr) { return ptr; }
01297   static void operator delete(void*, void*) { }
01298   bool wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong data_length);
01299 
01300 #ifdef MYSQL_SERVER
01301   bool write_header(IO_CACHE* file, ulong data_length);
01302   bool write_footer(IO_CACHE* file);
01303   my_bool need_checksum();
01304 
01305   virtual bool write(IO_CACHE* file)
01306   {
01307     return(write_header(file, get_data_size()) ||
01308            write_data_header(file) ||
01309            write_data_body(file) ||
01310            write_footer(file));
01311   }
01312   virtual bool write_data_header(IO_CACHE* file)
01313   { return 0; }
01314   virtual bool write_data_body(IO_CACHE* file __attribute__((unused)))
01315   { return 0; }
01316   inline time_t get_time()
01317   {
01318     if (!when.tv_sec && !when.tv_usec) /* Not previously initialized */
01319     {
01320       THD *tmp_thd= thd ? thd : current_thd;
01321       if (tmp_thd)
01322         when= tmp_thd->start_time;
01323       else
01324         my_micro_time_to_timeval(my_micro_time(), &when);
01325     }
01326     return (time_t) when.tv_sec;
01327   }
01328 #endif
01329   virtual Log_event_type get_type_code() = 0;
01330   virtual bool is_valid() const = 0;
01331   void set_artificial_event() { flags |= LOG_EVENT_ARTIFICIAL_F; }
01332   void set_relay_log_event() { flags |= LOG_EVENT_RELAY_LOG_F; }
01333   bool is_artificial_event() const { return flags & LOG_EVENT_ARTIFICIAL_F; }
01334   bool is_relay_log_event() const { return flags & LOG_EVENT_RELAY_LOG_F; }
01335   bool is_ignorable_event() const { return flags & LOG_EVENT_IGNORABLE_F; }
01336   bool is_no_filter_event() const { return flags & LOG_EVENT_NO_FILTER_F; }
01337   inline bool is_using_trans_cache() const
01338   {
01339     return (event_cache_type == EVENT_TRANSACTIONAL_CACHE);
01340   }
01341   inline bool is_using_stmt_cache() const
01342   {
01343     return(event_cache_type == EVENT_STMT_CACHE);
01344   }
01345   inline bool is_using_immediate_logging() const
01346   {
01347     return(event_logging_type == EVENT_IMMEDIATE_LOGGING);
01348   }
01349   Log_event(const char* buf, const Format_description_log_event
01350             *description_event);
01351   virtual ~Log_event() { free_temp_buf();}
01352   void register_temp_buf(char* buf) { temp_buf = buf; }
01353   void free_temp_buf()
01354   {
01355     if (temp_buf)
01356     {
01357       my_free(temp_buf);
01358       temp_buf = 0;
01359     }
01360   }
01361   /*
01362     Get event length for simple events. For complicated events the length
01363     is calculated during write()
01364   */
01365   virtual int get_data_size() { return 0;}
01366   static Log_event* read_log_event(const char* buf, uint event_len,
01367                                    const char **error,
01368                                    const Format_description_log_event
01369                                    *description_event, my_bool crc_check);
01373   static const char* get_type_str(Log_event_type type);
01377   const char* get_type_str();
01378 
01379   /* Return start of query time or current time */
01380 
01381 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
01382 
01383 private:
01384 
01385   /*
01386     possible decisions by get_mts_execution_mode().
01387     The execution mode can be PARALLEL or not (thereby sequential
01388     unless impossible at all). When it's sequential it further  breaks into
01389     ASYNChronous and SYNChronous.
01390   */
01391   enum enum_mts_event_exec_mode
01392   {
01393     /*
01394       Event is run by a Worker.
01395     */
01396     EVENT_EXEC_PARALLEL,
01397     /*
01398       Event is run by Coordinator.
01399     */
01400     EVENT_EXEC_ASYNC,
01401     /*
01402       Event is run by Coordinator and requires synchronization with Workers.
01403     */
01404     EVENT_EXEC_SYNC,
01405     /*
01406       Event can't be executed neither by Workers nor Coordinator.
01407     */
01408     EVENT_EXEC_CAN_NOT
01409   };
01410 
01424   bool is_mts_sequential_exec()
01425   {
01426     return
01427       get_type_code() == START_EVENT_V3          ||
01428       get_type_code() == STOP_EVENT              ||
01429       get_type_code() == ROTATE_EVENT            ||
01430       get_type_code() == LOAD_EVENT              ||
01431       get_type_code() == SLAVE_EVENT             ||
01432       get_type_code() == CREATE_FILE_EVENT       ||
01433       get_type_code() == DELETE_FILE_EVENT       ||
01434       get_type_code() == NEW_LOAD_EVENT          ||
01435       get_type_code() == EXEC_LOAD_EVENT         ||
01436       get_type_code() == FORMAT_DESCRIPTION_EVENT||
01437 
01438       get_type_code() == INCIDENT_EVENT;
01439   }
01440 
01453   enum enum_mts_event_exec_mode get_mts_execution_mode(ulong slave_server_id,
01454                                                    bool mts_in_group)
01455   {
01456     if ((get_type_code() == FORMAT_DESCRIPTION_EVENT &&
01457          ((server_id == (uint32) ::server_id) || (log_pos == 0))) ||
01458         (get_type_code() == ROTATE_EVENT &&
01459          ((server_id == (uint32) ::server_id) ||
01460           (log_pos == 0    /* very first fake Rotate (R_f) */
01461            && mts_in_group /* ignored event turned into R_f at slave stop */))))
01462       return EVENT_EXEC_ASYNC;
01463     else if (is_mts_sequential_exec())
01464       return EVENT_EXEC_SYNC;
01465     else
01466       return EVENT_EXEC_PARALLEL;
01467   }
01468 
01474   Slave_worker *get_slave_worker(Relay_log_info *rli);
01475 
01488   virtual uint8 get_mts_dbs(Mts_db_names *arg)
01489   {
01490     arg->name[0]= get_db();
01491 
01492     return arg->num= mts_number_dbs();
01493   }
01494 
01495   /*
01496     Group of events can be marked to force its execution
01497     in isolation from any other Workers.
01498     Typically that is done for a transaction that contains
01499     a query accessing more than OVER_MAX_DBS_IN_EVENT_MTS databases.
01500     Factually that's a sequential mode where a Worker remains to
01501     be the applier.
01502   */
01503   virtual void set_mts_isolate_group()
01504   {
01505     DBUG_ASSERT(ends_group() ||
01506                 get_type_code() == QUERY_EVENT ||
01507                 get_type_code() == EXEC_LOAD_EVENT ||
01508                 get_type_code() == EXECUTE_LOAD_QUERY_EVENT);
01509     flags |= LOG_EVENT_MTS_ISOLATE_F;
01510   }
01511 
01512 
01513 public:
01514 
01518   bool contains_partition_info(bool);
01519 
01520   /*
01521     @return  the number of updated by the event databases.
01522 
01523     @note In other than Query-log-event case that's one.
01524   */
01525   virtual uint8 mts_number_dbs() { return 1; }
01526 
01532   bool is_mts_group_isolated() { return flags & LOG_EVENT_MTS_ISOLATE_F; }
01533 
01543   virtual bool starts_group() { return FALSE; }
01544 
01549   virtual bool ends_group()   { return FALSE; }
01550 
01559   int apply_event(Relay_log_info *rli);
01560 
01569   int update_pos(Relay_log_info *rli)
01570   {
01571     return do_update_pos(rli);
01572   }
01573 
01580   enum_skip_reason shall_skip(Relay_log_info *rli)
01581   {
01582     return do_shall_skip(rli);
01583   }
01584 
01600   virtual int do_apply_event(Relay_log_info const *rli)
01601   {
01602     return 0;                /* Default implementation does nothing */
01603   }
01604 
01605   virtual int do_apply_event_worker(Slave_worker *w);
01606 
01607 protected:
01608 
01626   enum_skip_reason continue_group(Relay_log_info *rli);
01627 
01651   virtual int do_update_pos(Relay_log_info *rli);
01652 
01653 
01683   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
01684 #endif
01685 };
01686 
01687 
01688 /*
01689    One class for each type of event.
01690    Two constructors for each class:
01691    - one to create the event for logging (when the server acts as a master),
01692    called after an update to the database is done,
01693    which accepts parameters like the query, the database, the options for LOAD
01694    DATA INFILE...
01695    - one to create the event from a packet (when the server acts as a slave),
01696    called before reproducing the update, which accepts parameters (like a
01697    buffer). Used to read from the master, from the relay log, and in
01698    mysqlbinlog. This constructor must be format-tolerant.
01699 */
01700 
02041 class Query_log_event: public Log_event
02042 {
02043   LEX_STRING user;
02044   LEX_STRING host;
02045 protected:
02046   Log_event::Byte* data_buf;
02047 public:
02048   const char* query;
02049   const char* catalog;
02050   const char* db;
02051   /*
02052     If we already know the length of the query string
02053     we pass it with q_len, so we would not have to call strlen()
02054     otherwise, set it to 0, in which case, we compute it with strlen()
02055   */
02056   uint32 q_len;
02057   uint32 db_len;
02058   uint16 error_code;
02059   ulong thread_id;
02060   /*
02061     For events created by Query_log_event::do_apply_event (and
02062     Load_log_event::do_apply_event()) we need the *original* thread
02063     id, to be able to log the event with the original (=master's)
02064     thread id (fix for BUG#1686).
02065   */
02066   ulong slave_proxy_id;
02067 
02068   /*
02069     Binlog format 3 and 4 start to differ (as far as class members are
02070     concerned) from here.
02071   */
02072 
02073   uint catalog_len;                     // <= 255 char; 0 means uninited
02074 
02075   /*
02076     We want to be able to store a variable number of N-bit status vars:
02077     (generally N=32; but N=64 for SQL_MODE) a user may want to log the number
02078     of affected rows (for debugging) while another does not want to lose 4
02079     bytes in this.
02080     The storage on disk is the following:
02081     status_vars_len is part of the post-header,
02082     status_vars are in the variable-length part, after the post-header, before
02083     the db & query.
02084     status_vars on disk is a sequence of pairs (code, value) where 'code' means
02085     'sql_mode', 'affected' etc. Sometimes 'value' must be a short string, so
02086     its first byte is its length. For now the order of status vars is:
02087     flags2 - sql_mode - catalog - autoinc - charset
02088     We should add the same thing to Load_log_event, but in fact
02089     LOAD DATA INFILE is going to be logged with a new type of event (logging of
02090     the plain text query), so Load_log_event would be frozen, so no need. The
02091     new way of logging LOAD DATA INFILE would use a derived class of
02092     Query_log_event, so automatically benefit from the work already done for
02093     status variables in Query_log_event.
02094  */
02095   uint16 status_vars_len;
02096 
02097   /*
02098     'flags2' is a second set of flags (on top of those in Log_event), for
02099     session variables. These are thd->options which is & against a mask
02100     (OPTIONS_WRITTEN_TO_BIN_LOG).
02101     flags2_inited helps make a difference between flags2==0 (3.23 or 4.x
02102     master, we don't know flags2, so use the slave server's global options) and
02103     flags2==0 (5.0 master, we know this has a meaning of flags all down which
02104     must influence the query).
02105   */
02106   bool flags2_inited;
02107   bool sql_mode_inited;
02108   bool charset_inited;
02109 
02110   uint32 flags2;
02111   /* In connections sql_mode is 32 bits now but will be 64 bits soon */
02112   sql_mode_t sql_mode;
02113   ulong auto_increment_increment, auto_increment_offset;
02114   char charset[6];
02115   uint time_zone_len; /* 0 means uninited */
02116   const char *time_zone_str;
02117   uint lc_time_names_number; /* 0 means en_US */
02118   uint charset_database_number;
02119   /*
02120     map for tables that will be updated for a multi-table update query
02121     statement, for other query statements, this will be zero.
02122   */
02123   ulonglong table_map_for_update;
02124   /*
02125     Holds the original length of a Query_log_event that comes from a
02126     master of version < 5.0 (i.e., binlog_version < 4). When the IO
02127     thread writes the relay log, it augments the Query_log_event with a
02128     Q_MASTER_DATA_WRITTEN_CODE status_var that holds the original event
02129     length. This field is initialized to non-zero in the SQL thread when
02130     it reads this augmented event. SQL thread does not write 
02131     Q_MASTER_DATA_WRITTEN_CODE to the slave's server binlog.
02132   */
02133   uint32 master_data_written;
02134   /*
02135     number of updated databases by the query and their names. This info
02136     is requested by both Coordinator and Worker.
02137   */
02138   uchar mts_accessed_dbs;
02139   char mts_accessed_db_names[MAX_DBS_IN_EVENT_MTS][NAME_LEN];
02140 
02141 #ifdef MYSQL_SERVER
02142 
02143   Query_log_event(THD* thd_arg, const char* query_arg, ulong query_length,
02144                   bool using_trans, bool immediate, bool suppress_use,
02145                   int error, bool ignore_command= FALSE);
02146   const char* get_db() { return db; }
02147 
02158   virtual uint8 get_mts_dbs(Mts_db_names* arg)
02159   {
02160     if (mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS)
02161     {
02162       // the empty string db name is special to indicate sequential applying
02163       mts_accessed_db_names[0][0]= 0;
02164     }
02165     else
02166     {
02167       for (uchar i= 0; i < mts_accessed_dbs; i++)
02168       {
02169         char *db_name= mts_accessed_db_names[i];
02170 
02171         // Only default database is rewritten.
02172         if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
02173         {
02174           size_t dummy_len;
02175           const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
02176           // db_name != db_filtered means that db_name is rewritten.
02177           if (strcmp(db_name, db_filtered))
02178             db_name= (char*)db_filtered;
02179         }
02180         arg->name[i]= db_name;
02181       }
02182     }
02183     return arg->num= mts_accessed_dbs;
02184   }
02185 
02186   void attach_temp_tables_worker(THD*);
02187   void detach_temp_tables_worker(THD*);
02188 
02189   virtual uchar mts_number_dbs() { return mts_accessed_dbs; }
02190 
02191 #ifdef HAVE_REPLICATION
02192   int pack_info(Protocol* protocol);
02193 #endif /* HAVE_REPLICATION */
02194 #else
02195   void print_query_header(IO_CACHE* file, PRINT_EVENT_INFO* print_event_info);
02196   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02197 #endif
02198 
02199   Query_log_event();
02200   Query_log_event(const char* buf, uint event_len,
02201                   const Format_description_log_event *description_event,
02202                   Log_event_type event_type);
02203   ~Query_log_event()
02204   {
02205     if (data_buf)
02206       my_free(data_buf);
02207   }
02208   Log_event_type get_type_code() { return QUERY_EVENT; }
02209 #ifdef MYSQL_SERVER
02210   bool write(IO_CACHE* file);
02211   virtual bool write_post_header_for_derived(IO_CACHE* file) { return FALSE; }
02212 #endif
02213   bool is_valid() const { return query != 0; }
02214 
02215   /*
02216     Returns number of bytes additionaly written to post header by derived
02217     events (so far it is only Execute_load_query event).
02218   */
02219   virtual ulong get_post_header_size_for_derived() { return 0; }
02220   /* Writes derived event-specific part of post header. */
02221 
02222 public:        /* !!! Public in this patch to allow old usage */
02223 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02224   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
02225   virtual int do_apply_event(Relay_log_info const *rli);
02226   virtual int do_update_pos(Relay_log_info *rli);
02227 
02228   int do_apply_event(Relay_log_info const *rli,
02229                        const char *query_arg,
02230                        uint32 q_len_arg);
02231 #endif /* HAVE_REPLICATION */
02232   /*
02233     If true, the event always be applied by slave SQL thread or be printed by
02234     mysqlbinlog
02235    */
02236   bool is_trans_keyword()
02237   {
02238     /*
02239       Before the patch for bug#50407, The 'SAVEPOINT and ROLLBACK TO'
02240       queries input by user was written into log events directly.
02241       So the keywords can be written in both upper case and lower case
02242       together, strncasecmp is used to check both cases. they also could be
02243       binlogged with comments in the front of these keywords. for examples:
02244         / * bla bla * / SAVEPOINT a;
02245         / * bla bla * / ROLLBACK TO a;
02246       but we don't handle these cases and after the patch, both quiries are
02247       binlogged in upper case with no comments.
02248      */
02249     return !strncmp(query, "BEGIN", q_len) ||
02250       !strncmp(query, "COMMIT", q_len) ||
02251       !strncasecmp(query, "SAVEPOINT", 9) ||
02252       !strncasecmp(query, "ROLLBACK", 8);
02253   }
02259   bool starts_group() { return !strncmp(query, "BEGIN", q_len); }
02260   virtual bool ends_group()
02261   {  
02262     return
02263       !strncmp(query, "COMMIT", q_len) ||
02264       (!strncasecmp(query, STRING_WITH_LEN("ROLLBACK"))
02265        && strncasecmp(query, STRING_WITH_LEN("ROLLBACK TO ")));
02266   }
02267 };
02268 
02269 
02469 class Load_log_event: public Log_event
02470 {
02471 private:
02472 protected:
02473   int copy_log_event(const char *buf, ulong event_len,
02474                      int body_offset,
02475                      const Format_description_log_event* description_event);
02476 
02477 public:
02478   uint get_query_buffer_length();
02479   void print_query(bool need_db, const char *cs, char *buf, char **end,
02480                    char **fn_start, char **fn_end);
02481   ulong thread_id;
02482   ulong slave_proxy_id;
02483   uint32 table_name_len;
02484   /*
02485     No need to have a catalog, as these events can only come from 4.x.
02486     TODO: this may become false if Dmitri pushes his new LOAD DATA INFILE in
02487     5.0 only (not in 4.x).
02488   */
02489   uint32 db_len;
02490   uint32 fname_len;
02491   uint32 num_fields;
02492   const char* fields;
02493   const uchar* field_lens;
02494   uint32 field_block_len;
02495 
02496   const char* table_name;
02497   const char* db;
02498   const char* fname;
02499   uint32 skip_lines;
02500   sql_ex_info sql_ex;
02501   bool local_fname;
02512   bool is_concurrent;
02513 
02514   /* fname doesn't point to memory inside Log_event::temp_buf  */
02515   void set_fname_outside_temp_buf(const char *afname, uint alen)
02516   {
02517     fname= afname;
02518     fname_len= alen;
02519     local_fname= TRUE;
02520   }
02521   /* fname doesn't point to memory inside Log_event::temp_buf  */
02522   int  check_fname_outside_temp_buf()
02523   {
02524     return local_fname;
02525   }
02526 
02527 #ifdef MYSQL_SERVER
02528   String field_lens_buf;
02529   String fields_buf;
02530 
02531   Load_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
02532                  const char* table_name_arg,
02533                  List<Item>& fields_arg,
02534                  bool is_concurrent_arg,
02535                  enum enum_duplicates handle_dup, bool ignore,
02536                  bool using_trans);
02537   void set_fields(const char* db, List<Item> &fields_arg,
02538                   Name_resolution_context *context);
02539   const char* get_db() { return db; }
02540 #ifdef HAVE_REPLICATION
02541   int pack_info(Protocol* protocol);
02542 #endif /* HAVE_REPLICATION */
02543 #else
02544   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02545   void print(FILE* file, PRINT_EVENT_INFO* print_event_info, bool commented);
02546 #endif
02547 
02548   /*
02549     Note that for all the events related to LOAD DATA (Load_log_event,
02550     Create_file/Append/Exec/Delete, we pass description_event; however as
02551     logging of LOAD DATA is going to be changed in 4.1 or 5.0, this is only used
02552     for the common_header_len (post_header_len will not be changed).
02553   */
02554   Load_log_event(const char* buf, uint event_len,
02555                  const Format_description_log_event* description_event);
02556   ~Load_log_event()
02557   {}
02558   Log_event_type get_type_code()
02559   {
02560     return sql_ex.new_format() ? NEW_LOAD_EVENT: LOAD_EVENT;
02561   }
02562 #ifdef MYSQL_SERVER
02563   bool write_data_header(IO_CACHE* file);
02564   bool write_data_body(IO_CACHE* file);
02565 #endif
02566   bool is_valid() const { return table_name != 0; }
02567   int get_data_size()
02568   {
02569     return (table_name_len + db_len + 2 + fname_len
02570             + LOAD_HEADER_LEN
02571             + sql_ex.data_size() + field_block_len + num_fields);
02572   }
02573 
02574 public:        /* !!! Public in this patch to allow old usage */
02575 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02576   virtual int do_apply_event(Relay_log_info const* rli)
02577   {
02578     return do_apply_event(thd->slave_net,rli,0);
02579   }
02580 
02581   int do_apply_event(NET *net, Relay_log_info const *rli,
02582                      bool use_rli_only_for_errors);
02583 #endif
02584 };
02585 
02586 extern char server_version[SERVER_VERSION_LENGTH];
02587 
02603 class Start_log_event_v3: public Log_event
02604 {
02605 public:
02606   /*
02607     If this event is at the start of the first binary log since server
02608     startup 'created' should be the timestamp when the event (and the
02609     binary log) was created.  In the other case (i.e. this event is at
02610     the start of a binary log created by FLUSH LOGS or automatic
02611     rotation), 'created' should be 0.  This "trick" is used by MySQL
02612     >=4.0.14 slaves to know whether they must drop stale temporary
02613     tables and whether they should abort unfinished transaction.
02614 
02615     Note that when 'created'!=0, it is always equal to the event's
02616     timestamp; indeed Start_log_event is written only in log.cc where
02617     the first constructor below is called, in which 'created' is set
02618     to 'when'.  So in fact 'created' is a useless variable. When it is
02619     0 we can read the actual value from timestamp ('when') and when it
02620     is non-zero we can read the same value from timestamp
02621     ('when'). Conclusion:
02622      - we use timestamp to print when the binlog was created.
02623      - we use 'created' only to know if this is a first binlog or not.
02624      In 3.23.57 we did not pay attention to this identity, so mysqlbinlog in
02625      3.23.57 does not print 'created the_date' if created was zero. This is now
02626      fixed.
02627   */
02628   time_t created;
02629   uint16 binlog_version;
02630   char server_version[ST_SERVER_VER_LEN];
02631   /*
02632     We set this to 1 if we don't want to have the created time in the log,
02633     which is the case when we rollover to a new log.
02634   */
02635   bool dont_set_created;
02636 
02637 #ifdef MYSQL_SERVER
02638   Start_log_event_v3();
02639 #ifdef HAVE_REPLICATION
02640   int pack_info(Protocol* protocol);
02641 #endif /* HAVE_REPLICATION */
02642 #else
02643   Start_log_event_v3() {}
02644   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02645 #endif
02646 
02647   Start_log_event_v3(const char* buf, uint event_len,
02648                      const Format_description_log_event* description_event);
02649   ~Start_log_event_v3() {}
02650   Log_event_type get_type_code() { return START_EVENT_V3;}
02651 #ifdef MYSQL_SERVER
02652   bool write(IO_CACHE* file);
02653 #endif
02654   bool is_valid() const { return server_version[0] != 0; }
02655   int get_data_size()
02656   {
02657     return START_V3_HEADER_LEN; //no variable-sized part
02658   }
02659 
02660 protected:
02661 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02662   virtual int do_apply_event(Relay_log_info const *rli);
02663   virtual enum_skip_reason do_shall_skip(Relay_log_info*)
02664   {
02665     /*
02666       Events from ourself should be skipped, but they should not
02667       decrease the slave skip counter.
02668      */
02669     if (this->server_id == ::server_id)
02670       return Log_event::EVENT_SKIP_IGNORE;
02671     else
02672       return Log_event::EVENT_SKIP_NOT;
02673   }
02674 #endif
02675 };
02676 
02677 
02688 class Format_description_log_event: public Start_log_event_v3
02689 {
02690 public:
02691   /*
02692      The size of the fixed header which _all_ events have
02693      (for binlogs written by this version, this is equal to
02694      LOG_EVENT_HEADER_LEN), except FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT
02695      (those have a header of size LOG_EVENT_MINIMAL_HEADER_LEN).
02696   */
02697   uint8 common_header_len;
02698   uint8 number_of_event_types;
02699   /* 
02700      The list of post-headers' lengths followed 
02701      by the checksum alg decription byte
02702   */
02703   uint8 *post_header_len;
02704   uchar server_version_split[3];
02705   const uint8 *event_type_permutation;
02706 
02707   Format_description_log_event(uint8 binlog_ver, const char* server_ver=0);
02708   Format_description_log_event(const char* buf, uint event_len,
02709                                const Format_description_log_event
02710                                *description_event);
02711   ~Format_description_log_event()
02712   {
02713     my_free(post_header_len);
02714   }
02715   Log_event_type get_type_code() { return FORMAT_DESCRIPTION_EVENT;}
02716 #ifdef MYSQL_SERVER
02717   bool write(IO_CACHE* file);
02718 #endif
02719   bool header_is_valid() const
02720   {
02721     return ((common_header_len >= ((binlog_version==1) ? OLD_HEADER_LEN :
02722                                    LOG_EVENT_MINIMAL_HEADER_LEN)) &&
02723             (post_header_len != NULL));
02724   }
02725 
02726   bool version_is_valid() const
02727   {
02728     /* It is invalid only when all version numbers are 0 */
02729     return !(server_version_split[0] == 0 &&
02730              server_version_split[1] == 0 &&
02731              server_version_split[2] == 0);
02732   }
02733 
02734   bool is_valid() const
02735   {
02736     return header_is_valid() && version_is_valid();
02737   }
02738 
02739   int get_data_size()
02740   {
02741     /*
02742       The vector of post-header lengths is considered as part of the
02743       post-header, because in a given version it never changes (contrary to the
02744       query in a Query_log_event).
02745     */
02746     return FORMAT_DESCRIPTION_HEADER_LEN;
02747   }
02748 
02749   void calc_server_version_split();
02750   ulong get_version_product() const;
02751   bool is_version_before_checksum() const;
02752 protected:
02753 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02754   virtual int do_apply_event(Relay_log_info const *rli);
02755   virtual int do_update_pos(Relay_log_info *rli);
02756   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
02757 #endif
02758 };
02759 
02760 
02799 class Intvar_log_event: public Log_event
02800 {
02801 public:
02802   ulonglong val;
02803   uchar type;
02804 
02805 #ifdef MYSQL_SERVER
02806   Intvar_log_event(THD* thd_arg, uchar type_arg, ulonglong val_arg,
02807                    enum_event_cache_type cache_type_arg,
02808                    enum_event_logging_type logging_type_arg)
02809     :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg),
02810     val(val_arg), type(type_arg) { }
02811 #ifdef HAVE_REPLICATION
02812   int pack_info(Protocol* protocol);
02813 #endif /* HAVE_REPLICATION */
02814 #else
02815   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02816 #endif
02817 
02818   Intvar_log_event(const char* buf,
02819                    const Format_description_log_event *description_event);
02820   ~Intvar_log_event() {}
02821   Log_event_type get_type_code() { return INTVAR_EVENT;}
02822   const char* get_var_type_name();
02823   int get_data_size() { return  9; /* sizeof(type) + sizeof(val) */;}
02824 #ifdef MYSQL_SERVER
02825   bool write(IO_CACHE* file);
02826 #endif
02827   bool is_valid() const { return 1; }
02828 
02829 private:
02830 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02831   virtual int do_apply_event(Relay_log_info const *rli);
02832   virtual int do_update_pos(Relay_log_info *rli);
02833   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
02834 #endif
02835 };
02836 
02837 
02877 class Rand_log_event: public Log_event
02878 {
02879  public:
02880   ulonglong seed1;
02881   ulonglong seed2;
02882 
02883 #ifdef MYSQL_SERVER
02884   Rand_log_event(THD* thd_arg, ulonglong seed1_arg, ulonglong seed2_arg,
02885                  enum_event_cache_type cache_type_arg,
02886                  enum_event_logging_type logging_type_arg)
02887     :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg),
02888     seed1(seed1_arg), seed2(seed2_arg) { }
02889 #ifdef HAVE_REPLICATION
02890   int pack_info(Protocol* protocol);
02891 #endif /* HAVE_REPLICATION */
02892 #else
02893   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02894 #endif
02895 
02896   Rand_log_event(const char* buf,
02897                  const Format_description_log_event *description_event);
02898   ~Rand_log_event() {}
02899   Log_event_type get_type_code() { return RAND_EVENT;}
02900   int get_data_size() { return 16; /* sizeof(ulonglong) * 2*/ }
02901 #ifdef MYSQL_SERVER
02902   bool write(IO_CACHE* file);
02903 #endif
02904   bool is_valid() const { return 1; }
02905 
02906 private:
02907 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02908   virtual int do_apply_event(Relay_log_info const *rli);
02909   virtual int do_update_pos(Relay_log_info *rli);
02910   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
02911 #endif
02912 };
02913 
02922 #ifdef MYSQL_CLIENT
02923 typedef ulonglong my_xid; // this line is the same as in handler.h
02924 #endif
02925 
02926 class Xid_log_event: public Log_event
02927 {
02928  public:
02929    my_xid xid;
02930 
02931 #ifdef MYSQL_SERVER
02932   Xid_log_event(THD* thd_arg, my_xid x)
02933   : Log_event(thd_arg, 0, 
02934               Log_event::EVENT_TRANSACTIONAL_CACHE,
02935               Log_event::EVENT_NORMAL_LOGGING),
02936   xid(x)
02937   { }
02938 #ifdef HAVE_REPLICATION
02939   int pack_info(Protocol* protocol);
02940 #endif /* HAVE_REPLICATION */
02941 #else
02942   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
02943 #endif
02944 
02945   Xid_log_event(const char* buf,
02946                 const Format_description_log_event *description_event);
02947   ~Xid_log_event() {}
02948   Log_event_type get_type_code() { return XID_EVENT;}
02949   int get_data_size() { return sizeof(xid); }
02950 #ifdef MYSQL_SERVER
02951   bool write(IO_CACHE* file);
02952 #endif
02953   bool is_valid() const { return 1; }
02954   virtual bool ends_group() { return TRUE; }
02955 private:
02956 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
02957   virtual int do_apply_event(Relay_log_info const *rli);
02958   virtual int do_apply_event_worker(Slave_worker *rli);
02959   enum_skip_reason do_shall_skip(Relay_log_info *rli);
02960   bool do_commit(THD *thd);
02961 #endif
02962 };
02963 
02973 class User_var_log_event: public Log_event
02974 {
02975 public:
02976   enum {
02977     UNDEF_F= 0,
02978     UNSIGNED_F= 1
02979   };
02980   const char *name;
02981   uint name_len;
02982   char *val;
02983   ulong val_len;
02984   Item_result type;
02985   uint charset_number;
02986   bool is_null;
02987   uchar flags;
02988 #ifdef MYSQL_SERVER
02989   bool deferred;
02990   query_id_t query_id;
02991   User_var_log_event(THD* thd_arg, const char *name_arg, uint name_len_arg,
02992                      char *val_arg, ulong val_len_arg, Item_result type_arg,
02993                      uint charset_number_arg, uchar flags_arg,
02994                      enum_event_cache_type cache_type_arg,
02995                      enum_event_logging_type logging_type_arg)
02996     :Log_event(thd_arg, 0, cache_type_arg, logging_type_arg), name(name_arg),
02997      name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg),
02998      charset_number(charset_number_arg), flags(flags_arg), deferred(false)
02999     { 
03000       is_null= !val;
03001     }
03002   int pack_info(Protocol* protocol);
03003 #else
03004   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03005 #endif
03006 
03007   User_var_log_event(const char* buf, uint event_len,
03008                      const Format_description_log_event *description_event);
03009   ~User_var_log_event() {}
03010   Log_event_type get_type_code() { return USER_VAR_EVENT;}
03011 #ifdef MYSQL_SERVER
03012   bool write(IO_CACHE* file);
03013   /* 
03014      Getter and setter for deferred User-event. 
03015      Returns true if the event is not applied directly 
03016      and which case the applier adjusts execution path.
03017   */
03018   bool is_deferred() { return deferred; }
03019   /*
03020     In case of the deffered applying the variable instance is flagged
03021     and the parsing time query id is stored to be used at applying time.
03022   */
03023   void set_deferred(query_id_t qid) { deferred= true; query_id= qid; }
03024 #endif
03025   bool is_valid() const { return name != 0; }
03026 
03027 private:
03028 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03029   virtual int do_apply_event(Relay_log_info const *rli);
03030   virtual int do_update_pos(Relay_log_info *rli);
03031   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
03032 #endif
03033 };
03034 
03035 
03044 class Stop_log_event: public Log_event
03045 {
03046 public:
03047 #ifdef MYSQL_SERVER
03048   Stop_log_event() :Log_event()
03049   {}
03050 #else
03051   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03052 #endif
03053 
03054   Stop_log_event(const char* buf,
03055                  const Format_description_log_event *description_event):
03056     Log_event(buf, description_event)
03057   {}
03058   ~Stop_log_event() {}
03059   Log_event_type get_type_code() { return STOP_EVENT;}
03060   bool is_valid() const { return 1; }
03061 
03062 private:
03063 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03064   virtual int do_update_pos(Relay_log_info *rli);
03065   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli)
03066   {
03067     /*
03068       Events from ourself should be skipped, but they should not
03069       decrease the slave skip counter.
03070      */
03071     if (this->server_id == ::server_id)
03072       return Log_event::EVENT_SKIP_IGNORE;
03073     else
03074       return Log_event::EVENT_SKIP_NOT;
03075   }
03076 #endif
03077 };
03078 
03128 class Rotate_log_event: public Log_event
03129 {
03130 public:
03131   enum {
03132     DUP_NAME= 2, // if constructor should dup the string argument
03133     RELAY_LOG=4  // rotate event for relay log
03134   };
03135   const char* new_log_ident;
03136   ulonglong pos;
03137   uint ident_len;
03138   uint flags;
03139 #ifdef MYSQL_SERVER
03140   Rotate_log_event(const char* new_log_ident_arg,
03141                    uint ident_len_arg,
03142                    ulonglong pos_arg, uint flags);
03143 #ifdef HAVE_REPLICATION
03144   int pack_info(Protocol* protocol);
03145 #endif /* HAVE_REPLICATION */
03146 #else
03147   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03148 #endif
03149 
03150   Rotate_log_event(const char* buf, uint event_len,
03151                    const Format_description_log_event* description_event);
03152   ~Rotate_log_event()
03153   {
03154     if (flags & DUP_NAME)
03155       my_free((void*) new_log_ident);
03156   }
03157   Log_event_type get_type_code() { return ROTATE_EVENT;}
03158   int get_data_size() { return  ident_len + ROTATE_HEADER_LEN;}
03159   bool is_valid() const { return new_log_ident != 0; }
03160 #ifdef MYSQL_SERVER
03161   bool write(IO_CACHE* file);
03162 #endif
03163 
03164 private:
03165 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03166   virtual int do_update_pos(Relay_log_info *rli);
03167   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
03168 #endif
03169 };
03170 
03171 
03172 /* the classes below are for the new LOAD DATA INFILE logging */
03173 
03180 class Create_file_log_event: public Load_log_event
03181 {
03182 protected:
03183   /*
03184     Pretend we are Load event, so we can write out just
03185     our Load part - used on the slave when writing event out to
03186     SQL_LOAD-*.info file
03187   */
03188   bool fake_base;
03189 public:
03190   uchar* block;
03191   const char *event_buf;
03192   uint block_len;
03193   uint file_id;
03194   bool inited_from_old;
03195 
03196 #ifdef MYSQL_SERVER
03197   Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg,
03198                         const char* table_name_arg,
03199                         List<Item>& fields_arg,
03200                         bool is_concurrent_arg,
03201                         enum enum_duplicates handle_dup, bool ignore,
03202                         uchar* block_arg, uint block_len_arg,
03203                         bool using_trans);
03204 #ifdef HAVE_REPLICATION
03205   int pack_info(Protocol* protocol);
03206 #endif /* HAVE_REPLICATION */
03207 #else
03208   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03209   void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
03210              bool enable_local);
03211 #endif
03212 
03213   Create_file_log_event(const char* buf, uint event_len,
03214                         const Format_description_log_event* description_event);
03215   ~Create_file_log_event()
03216   {
03217     my_free((void*) event_buf);
03218   }
03219 
03220   Log_event_type get_type_code()
03221   {
03222     return fake_base ? Load_log_event::get_type_code() : CREATE_FILE_EVENT;
03223   }
03224   int get_data_size()
03225   {
03226     return (fake_base ? Load_log_event::get_data_size() :
03227             Load_log_event::get_data_size() +
03228             4 + 1 + block_len);
03229   }
03230   bool is_valid() const { return inited_from_old || block != 0; }
03231 #ifdef MYSQL_SERVER
03232   bool write_data_header(IO_CACHE* file);
03233   bool write_data_body(IO_CACHE* file);
03234   /*
03235     Cut out Create_file extentions and
03236     write it as Load event - used on the slave
03237   */
03238   bool write_base(IO_CACHE* file);
03239 #endif
03240 
03241 private:
03242 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03243   virtual int do_apply_event(Relay_log_info const *rli);
03244 #endif
03245 };
03246 
03247 
03254 class Append_block_log_event: public Log_event
03255 {
03256 public:
03257   uchar* block;
03258   uint block_len;
03259   uint file_id;
03260   /*
03261     'db' is filled when the event is created in mysql_load() (the
03262     event needs to have a 'db' member to be well filtered by
03263     binlog-*-db rules). 'db' is not written to the binlog (it's not
03264     used by Append_block_log_event::write()), so it can't be read in
03265     the Append_block_log_event(const char* buf, int event_len)
03266     constructor.  In other words, 'db' is used only for filtering by
03267     binlog-*-db rules.  Create_file_log_event is different: it's 'db'
03268     (which is inherited from Load_log_event) is written to the binlog
03269     and can be re-read.
03270   */
03271   const char* db;
03272 
03273 #ifdef MYSQL_SERVER
03274   Append_block_log_event(THD* thd, const char* db_arg, uchar* block_arg,
03275                          uint block_len_arg, bool using_trans);
03276 #ifdef HAVE_REPLICATION
03277   int pack_info(Protocol* protocol);
03278   virtual int get_create_or_append() const;
03279 #endif /* HAVE_REPLICATION */
03280 #else
03281   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03282 #endif
03283 
03284   Append_block_log_event(const char* buf, uint event_len,
03285                          const Format_description_log_event
03286                          *description_event);
03287   ~Append_block_log_event() {}
03288   Log_event_type get_type_code() { return APPEND_BLOCK_EVENT;}
03289   int get_data_size() { return  block_len + APPEND_BLOCK_HEADER_LEN ;}
03290   bool is_valid() const { return block != 0; }
03291 #ifdef MYSQL_SERVER
03292   bool write(IO_CACHE* file);
03293   const char* get_db() { return db; }
03294 #endif
03295 
03296 private:
03297 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03298   virtual int do_apply_event(Relay_log_info const *rli);
03299 #endif
03300 };
03301 
03302 
03309 class Delete_file_log_event: public Log_event
03310 {
03311 public:
03312   uint file_id;
03313   const char* db; /* see comment in Append_block_log_event */
03314 
03315 #ifdef MYSQL_SERVER
03316   Delete_file_log_event(THD* thd, const char* db_arg, bool using_trans);
03317 #ifdef HAVE_REPLICATION
03318   int pack_info(Protocol* protocol);
03319 #endif /* HAVE_REPLICATION */
03320 #else
03321   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03322   void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
03323              bool enable_local);
03324 #endif
03325 
03326   Delete_file_log_event(const char* buf, uint event_len,
03327                         const Format_description_log_event* description_event);
03328   ~Delete_file_log_event() {}
03329   Log_event_type get_type_code() { return DELETE_FILE_EVENT;}
03330   int get_data_size() { return DELETE_FILE_HEADER_LEN ;}
03331   bool is_valid() const { return file_id != 0; }
03332 #ifdef MYSQL_SERVER
03333   bool write(IO_CACHE* file);
03334   const char* get_db() { return db; }
03335 #endif
03336 
03337 private:
03338 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03339   virtual int do_apply_event(Relay_log_info const *rli);
03340 #endif
03341 };
03342 
03343 
03350 class Execute_load_log_event: public Log_event
03351 {
03352 public:
03353   uint file_id;
03354   const char* db; /* see comment in Append_block_log_event */
03355 
03356 #ifdef MYSQL_SERVER
03357   Execute_load_log_event(THD* thd, const char* db_arg, bool using_trans);
03358 #ifdef HAVE_REPLICATION
03359   int pack_info(Protocol* protocol);
03360 #endif /* HAVE_REPLICATION */
03361 #else
03362   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03363 #endif
03364 
03365   Execute_load_log_event(const char* buf, uint event_len,
03366                          const Format_description_log_event
03367                          *description_event);
03368   ~Execute_load_log_event() {}
03369   Log_event_type get_type_code() { return EXEC_LOAD_EVENT;}
03370   int get_data_size() { return  EXEC_LOAD_HEADER_LEN ;}
03371   bool is_valid() const { return file_id != 0; }
03372 #ifdef MYSQL_SERVER
03373   bool write(IO_CACHE* file);
03374   const char* get_db() { return db; }
03375 #endif
03376 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03377   virtual uint8 mts_number_dbs() { return OVER_MAX_DBS_IN_EVENT_MTS; }
03385   virtual uint8 get_mts_dbs(Mts_db_names *arg)
03386   {
03387     return arg->num= mts_number_dbs();
03388   }
03389 #endif
03390 
03391 private:
03392 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03393   virtual int do_apply_event(Relay_log_info const *rli);
03394 #endif
03395 };
03396 
03397 
03407 class Begin_load_query_log_event: public Append_block_log_event
03408 {
03409 public:
03410 #ifdef MYSQL_SERVER
03411   Begin_load_query_log_event(THD* thd_arg, const char *db_arg,
03412                              uchar* block_arg, uint block_len_arg,
03413                              bool using_trans);
03414 #ifdef HAVE_REPLICATION
03415   Begin_load_query_log_event(THD* thd);
03416   int get_create_or_append() const;
03417 #endif /* HAVE_REPLICATION */
03418 #endif
03419   Begin_load_query_log_event(const char* buf, uint event_len,
03420                              const Format_description_log_event
03421                              *description_event);
03422   ~Begin_load_query_log_event() {}
03423   Log_event_type get_type_code() { return BEGIN_LOAD_QUERY_EVENT; }
03424 private:
03425 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03426   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
03427 #endif
03428 };
03429 
03430 
03431 /*
03432   Elements of this enum describe how LOAD DATA handles duplicates.
03433 */
03434 enum enum_load_dup_handling { LOAD_DUP_ERROR= 0, LOAD_DUP_IGNORE,
03435                               LOAD_DUP_REPLACE };
03436 
03446 class Execute_load_query_log_event: public Query_log_event
03447 {
03448 public:
03449   uint file_id;       // file_id of temporary file
03450   uint fn_pos_start;  // pointer to the part of the query that should
03451                       // be substituted
03452   uint fn_pos_end;    // pointer to the end of this part of query
03453   /*
03454     We have to store type of duplicate handling explicitly, because
03455     for LOAD DATA it also depends on LOCAL option. And this part
03456     of query will be rewritten during replication so this information
03457     may be lost...
03458   */
03459   enum_load_dup_handling dup_handling;
03460 
03461 #ifdef MYSQL_SERVER
03462   Execute_load_query_log_event(THD* thd, const char* query_arg,
03463                                ulong query_length, uint fn_pos_start_arg,
03464                                uint fn_pos_end_arg,
03465                                enum_load_dup_handling dup_handling_arg,
03466                                bool using_trans, bool immediate,
03467                                bool suppress_use, int errcode);
03468 #ifdef HAVE_REPLICATION
03469   int pack_info(Protocol* protocol);
03470 #endif /* HAVE_REPLICATION */
03471 #else
03472   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03473   /* Prints the query as LOAD DATA LOCAL and with rewritten filename */
03474   void print(FILE* file, PRINT_EVENT_INFO* print_event_info,
03475              const char *local_fname);
03476 #endif
03477   Execute_load_query_log_event(const char* buf, uint event_len,
03478                                const Format_description_log_event
03479                                *description_event);
03480   ~Execute_load_query_log_event() {}
03481 
03482   Log_event_type get_type_code() { return EXECUTE_LOAD_QUERY_EVENT; }
03483   bool is_valid() const { return Query_log_event::is_valid() && file_id != 0; }
03484 
03485   ulong get_post_header_size_for_derived();
03486 #ifdef MYSQL_SERVER
03487   bool write_post_header_for_derived(IO_CACHE* file);
03488 #endif
03489 
03490 private:
03491 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03492   virtual int do_apply_event(Relay_log_info const *rli);
03493 #endif
03494 };
03495 
03496 
03497 #ifdef MYSQL_CLIENT
03498 
03503 class Unknown_log_event: public Log_event
03504 {
03505 public:
03506   /*
03507     Even if this is an unknown event, we still pass description_event to
03508     Log_event's ctor, this way we can extract maximum information from the
03509     event's header (the unique ID for example).
03510   */
03511   Unknown_log_event(const char* buf,
03512                     const Format_description_log_event *description_event):
03513     Log_event(buf, description_event)
03514   {}
03515   ~Unknown_log_event() {}
03516   void print(FILE* file, PRINT_EVENT_INFO* print_event_info);
03517   Log_event_type get_type_code() { return UNKNOWN_EVENT;}
03518   bool is_valid() const { return 1; }
03519 };
03520 #endif
03521 char *str_to_hex(char *to, const char *from, uint len);
03522 
03837 class Table_map_log_event : public Log_event
03838 {
03839 public:
03840   /* Constants */
03841   enum
03842   {
03843     TYPE_CODE = TABLE_MAP_EVENT
03844   };
03845 
03849   enum enum_error
03850   {
03851     ERR_OPEN_FAILURE = -1,               
03852     ERR_OK = 0,                                 
03853     ERR_TABLE_LIMIT_EXCEEDED = 1,      
03854     ERR_OUT_OF_MEM = 2,                         
03855     ERR_BAD_TABLE_DEF = 3,     
03856     ERR_RBR_TO_SBR = 4  
03857   };
03858 
03859   enum enum_flag
03860   {
03861     /* 
03862        Nothing here right now, but the flags support is there in
03863        preparation for changes that are coming.  Need to add a
03864        constant to make it compile under HP-UX: aCC does not like
03865        empty enumerations.
03866     */
03867     ENUM_FLAG_COUNT
03868   };
03869 
03870   typedef uint16 flag_set;
03871 
03872   /* Special constants representing sets of flags */
03873   enum 
03874   {
03875     TM_NO_FLAGS = 0U,
03876     TM_BIT_LEN_EXACT_F = (1U << 0),
03877     TM_REFERRED_FK_DB_F = (1U << 1)
03878   };
03879 
03880   flag_set get_flags(flag_set flag) const { return m_flags & flag; }
03881 
03882 #ifdef MYSQL_SERVER
03883   Table_map_log_event(THD *thd, TABLE *tbl, const Table_id& tid,
03884                       bool is_transactional);
03885 #endif
03886 #ifdef HAVE_REPLICATION
03887   Table_map_log_event(const char *buf, uint event_len, 
03888                       const Format_description_log_event *description_event);
03889 #endif
03890 
03891   ~Table_map_log_event();
03892 
03893 #ifdef MYSQL_CLIENT
03894   table_def *create_table_def()
03895   {
03896     return new table_def(m_coltype, m_colcnt, m_field_metadata,
03897                          m_field_metadata_size, m_null_bits, m_flags);
03898   }
03899 #endif
03900   const Table_id& get_table_id() const { return m_table_id; }
03901   const char *get_table_name() const { return m_tblnam; }
03902   const char *get_db_name() const    { return m_dbnam; }
03903 
03904   virtual Log_event_type get_type_code() { return TABLE_MAP_EVENT; }
03905   virtual bool is_valid() const { return m_memory != NULL; /* we check malloc */ }
03906 
03907   virtual int get_data_size() { return (uint) m_data_size; }
03908 #ifdef MYSQL_SERVER
03909   virtual int save_field_metadata();
03910   virtual bool write_data_header(IO_CACHE *file);
03911   virtual bool write_data_body(IO_CACHE *file);
03912   virtual const char *get_db() { return m_dbnam; }
03913   virtual uint8 mts_number_dbs()
03914   {
03915     return get_flags(TM_REFERRED_FK_DB_F) ? OVER_MAX_DBS_IN_EVENT_MTS : 1;
03916   }
03925   virtual uint8 get_mts_dbs(Mts_db_names *arg)
03926   {
03927     const char *db_name= get_db();
03928 
03929     if (!rpl_filter->is_rewrite_empty() && !get_flags(TM_REFERRED_FK_DB_F))
03930     {
03931       size_t dummy_len;
03932       const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
03933       // db_name != db_filtered means that db_name is rewritten.
03934       if (strcmp(db_name, db_filtered))
03935         db_name= db_filtered;
03936     }
03937 
03938     if (!get_flags(TM_REFERRED_FK_DB_F))
03939       arg->name[0]= db_name;
03940 
03941     return arg->num= mts_number_dbs();
03942   }
03943 
03944 #endif
03945 
03946 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03947   virtual int pack_info(Protocol *protocol);
03948 #endif
03949 
03950 #ifdef MYSQL_CLIENT
03951   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
03952 #endif
03953 
03954 
03955 private:
03956 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
03957   virtual int do_apply_event(Relay_log_info const *rli);
03958   virtual int do_update_pos(Relay_log_info *rli);
03959   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
03960 #endif
03961 
03962 #ifdef MYSQL_SERVER
03963   TABLE         *m_table;
03964 #endif
03965   char const    *m_dbnam;
03966   size_t         m_dblen;
03967   char const    *m_tblnam;
03968   size_t         m_tbllen;
03969   ulong          m_colcnt;
03970   uchar         *m_coltype;
03971 
03972   uchar         *m_memory;
03973   Table_id       m_table_id;
03974   flag_set       m_flags;
03975 
03976   size_t         m_data_size;
03977 
03978   uchar          *m_field_metadata;        // buffer for field metadata
03979   /*
03980     The size of field metadata buffer set by calling save_field_metadata()
03981   */
03982   ulong          m_field_metadata_size;   
03983   uchar         *m_null_bits;
03984   uchar         *m_meta_memory;
03985 };
03986 
03987 
04003 class Rows_log_event : public Log_event
04004 {
04005 public:
04006   enum row_lookup_mode {
04007        ROW_LOOKUP_UNDEFINED= 0,
04008        ROW_LOOKUP_NOT_NEEDED= 1,
04009        ROW_LOOKUP_INDEX_SCAN= 2,
04010        ROW_LOOKUP_TABLE_SCAN= 3,
04011        ROW_LOOKUP_HASH_SCAN= 4
04012   };
04013 
04017   enum enum_error
04018   {
04019     ERR_OPEN_FAILURE = -1,               
04020     ERR_OK = 0,                                 
04021     ERR_TABLE_LIMIT_EXCEEDED = 1,      
04022     ERR_OUT_OF_MEM = 2,                         
04023     ERR_BAD_TABLE_DEF = 3,     
04024     ERR_RBR_TO_SBR = 4  
04025   };
04026 
04027   /*
04028     These definitions allow you to combine the flags into an
04029     appropriate flag set using the normal bitwise operators.  The
04030     implicit conversion from an enum-constant to an integer is
04031     accepted by the compiler, which is then used to set the real set
04032     of flags.
04033   */
04034   enum enum_flag
04035   {
04036     /* Last event of a statement */
04037     STMT_END_F = (1U << 0),
04038 
04039     /* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
04040     NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
04041 
04042     /* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
04043     RELAXED_UNIQUE_CHECKS_F = (1U << 2),
04044 
04049     COMPLETE_ROWS_F = (1U << 3)
04050   };
04051 
04052   typedef uint16 flag_set;
04053 
04054   /* Special constants representing sets of flags */
04055   enum 
04056   {
04057       RLE_NO_FLAGS = 0U
04058   };
04059 
04060   virtual ~Rows_log_event();
04061 
04062   void set_flags(flag_set flags_arg) { m_flags |= flags_arg; }
04063   void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
04064   flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
04065 
04066   Log_event_type get_type_code() { return m_type; } /* Specific type (_V1 etc) */
04067   virtual Log_event_type get_general_type_code() = 0; /* General rows op type, no version */
04068 
04069 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04070   virtual int pack_info(Protocol *protocol);
04071 #endif
04072 
04073 #ifdef MYSQL_CLIENT
04074   /* not for direct call, each derived has its own ::print() */
04075   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
04076   void print_verbose(IO_CACHE *file,
04077                      PRINT_EVENT_INFO *print_event_info);
04078   size_t print_verbose_one_row(IO_CACHE *file, table_def *td,
04079                                PRINT_EVENT_INFO *print_event_info,
04080                                MY_BITMAP *cols_bitmap,
04081                                const uchar *ptr, const uchar *prefix);
04082 #endif
04083 
04084 #ifdef MYSQL_SERVER
04085   int add_row_data(uchar *data, size_t length)
04086   {
04087     return do_add_row_data(data,length); 
04088   }
04089 #endif
04090 
04091   /* Member functions to implement superclass interface */
04092   virtual int get_data_size();
04093 
04094   MY_BITMAP const *get_cols() const { return &m_cols; }
04095   MY_BITMAP const *get_cols_ai() const { return &m_cols_ai; }
04096   size_t get_width() const          { return m_width; }
04097   const Table_id& get_table_id() const        { return m_table_id; }
04098 
04099 #if defined(MYSQL_SERVER)
04100   /*
04101     This member function compares the table's read/write_set
04102     with this event's m_cols and m_cols_ai. Comparison takes 
04103     into account what type of rows event is this: Delete, Write or
04104     Update, therefore it uses the correct m_cols[_ai] according
04105     to the event type code.
04106 
04107     Note that this member function should only be called for the
04108     following events:
04109     - Delete_rows_log_event
04110     - Write_rows_log_event
04111     - Update_rows_log_event
04112 
04113     @param[IN] table The table to compare this events bitmaps 
04114                      against.
04115 
04116     @return TRUE if sets match, FALSE otherwise. (following 
04117                  bitmap_cmp return logic).
04118 
04119    */
04120   virtual bool read_write_bitmaps_cmp(TABLE *table)
04121   {
04122     bool res= FALSE;
04123 
04124     switch (get_general_type_code())
04125     {
04126       case DELETE_ROWS_EVENT:
04127         res= bitmap_cmp(get_cols(), table->read_set);
04128         break;
04129       case UPDATE_ROWS_EVENT:
04130         res= (bitmap_cmp(get_cols(), table->read_set) &&
04131               bitmap_cmp(get_cols_ai(), table->write_set));
04132         break;
04133       case WRITE_ROWS_EVENT:
04134         res= bitmap_cmp(get_cols(), table->write_set);
04135         break;
04136       default:
04137         /* 
04138           We should just compare bitmaps for Delete, Write
04139           or Update rows events.
04140         */
04141         DBUG_ASSERT(0);
04142     }
04143     return res;
04144   }
04145 #endif
04146 
04147 #ifdef MYSQL_SERVER
04148   virtual bool write_data_header(IO_CACHE *file);
04149   virtual bool write_data_body(IO_CACHE *file);
04150   virtual const char *get_db() { return m_table->s->db.str; }
04151 #endif
04152   /*
04153     Check that malloc() succeeded in allocating memory for the rows
04154     buffer and the COLS vector. Checking that an Update_rows_log_event
04155     is valid is done in the Update_rows_log_event::is_valid()
04156     function.
04157   */
04158   virtual bool is_valid() const
04159   {
04160     return m_rows_buf && m_cols.bitmap;
04161   }
04162 
04163   uint     m_row_count;         /* The number of rows added to the event */
04164 
04165   const uchar* get_extra_row_data() const   { return m_extra_row_data; }
04166 
04167 protected:
04168   /* 
04169      The constructors are protected since you're supposed to inherit
04170      this class, not create instances of this class.
04171   */
04172 #ifdef MYSQL_SERVER
04173   Rows_log_event(THD*, TABLE*, const Table_id& table_id,
04174                  MY_BITMAP const *cols, bool is_transactional,
04175                  Log_event_type event_type,
04176                  const uchar* extra_row_info);
04177 #endif
04178   Rows_log_event(const char *row_data, uint event_len, 
04179                  const Format_description_log_event *description_event);
04180 
04181 #ifdef MYSQL_CLIENT
04182   void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
04183 #endif
04184 
04185 #ifdef MYSQL_SERVER
04186   virtual int do_add_row_data(uchar *data, size_t length);
04187 #endif
04188 
04189 #ifdef MYSQL_SERVER
04190   TABLE *m_table;               /* The table the rows belong to */
04191 #endif
04192   Table_id    m_table_id;       /* Table ID */
04193   MY_BITMAP   m_cols;           /* Bitmap denoting columns available */
04194   ulong       m_width;          /* The width of the columns bitmap */
04195 #ifndef MYSQL_CLIENT
04196 
04200   Hash_slave_rows m_hash;
04201 
04206   uint            m_rows_lookup_algorithm;  
04207 #endif
04208   /*
04209     Bitmap for columns available in the after image, if present. These
04210     fields are only available for Update_rows events. Observe that the
04211     width of both the before image COLS vector and the after image
04212     COLS vector is the same: the number of columns of the table on the
04213     master.
04214   */
04215   MY_BITMAP   m_cols_ai;
04216 
04217   ulong       m_master_reclength; /* Length of record on master side */
04218 
04219   /* Bit buffers in the same memory as the class */
04220   uint32    m_bitbuf[128/(sizeof(uint32)*8)];
04221   uint32    m_bitbuf_ai[128/(sizeof(uint32)*8)];
04222 
04223   uchar    *m_rows_buf;         /* The rows in packed format */
04224   uchar    *m_rows_cur;         /* One-after the end of the data */
04225   uchar    *m_rows_end;         /* One-after the end of the allocated space */
04226 
04227   flag_set m_flags;             /* Flags for row-level events */
04228 
04229   Log_event_type m_type;        /* Actual event type */
04230 
04231   uchar    *m_extra_row_data;   /* Pointer to extra row data if any */
04232                                 /* If non null, first byte is length */
04233 
04234   /* helper functions */
04235 
04236 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04237   const uchar *m_curr_row;     /* Start of the row being processed */
04238   const uchar *m_curr_row_end; /* One-after the end of the current row */
04239   uchar    *m_key;      /* Buffer to keep key value during searches */
04240   uint     m_key_index;
04241   KEY      *m_key_info; /* Points to description of index #m_key_index */
04242   class Key_compare
04243   {
04244 public:
04256     Key_compare(KEY **ki= NULL) : m_key_info(ki) {}
04257     bool operator()(uchar *k1, uchar *k2) const
04258     {
04259       return key_cmp2((*m_key_info)->key_part,
04260                       k1, (*m_key_info)->key_length,
04261                       k2, (*m_key_info)->key_length) < 0 ;
04262     }
04263 private:
04264     KEY **m_key_info;
04265   };
04266   std::set<uchar *, Key_compare> m_distinct_keys;
04267   std::set<uchar *, Key_compare>::iterator m_itr;
04272   uchar *m_distinct_key_spare_buf;
04273 
04274   // Unpack the current row into m_table->record[0]
04275   int unpack_current_row(const Relay_log_info *const rli,
04276                          MY_BITMAP const *cols)
04277   { 
04278     DBUG_ASSERT(m_table);
04279 
04280     ASSERT_OR_RETURN_ERROR(m_curr_row <= m_rows_end, HA_ERR_CORRUPT_EVENT);
04281     return ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
04282                                    &m_curr_row_end, &m_master_reclength, m_rows_end);
04283   }
04284 
04285   /*
04286     This member function is called when deciding the algorithm to be used to
04287     find the rows to be updated on the slave during row based replication.
04288     This this functions sets the m_rows_lookup_algorithm and also the
04289     m_key_index with the key index to be used if the algorithm is dependent on
04290     an index.
04291    */
04292   void decide_row_lookup_algorithm_and_key();
04293 
04294   /*
04295     Encapsulates the  operations to be done before applying
04296     row event for update and delete.
04297    */
04298   int row_operations_scan_and_key_setup();
04299 
04300   /*
04301    Encapsulates the  operations to be done after applying
04302    row event for update and delete.
04303   */
04304   int row_operations_scan_and_key_teardown(int error);
04305 
04313   inline bool is_auto_inc_in_extra_columns()
04314   {
04315     DBUG_ASSERT(m_table);
04316     return (m_table->next_number_field &&
04317             m_table->next_number_field->field_index >= m_width);
04318   }
04319 #endif
04320 
04321 private:
04322 
04323 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04324   virtual int do_apply_event(Relay_log_info const *rli);
04325   virtual int do_update_pos(Relay_log_info *rli);
04326   virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
04327 
04328   /*
04329     Primitive to prepare for a sequence of row executions.
04330 
04331     DESCRIPTION
04332 
04333       Before doing a sequence of do_prepare_row() and do_exec_row()
04334       calls, this member function should be called to prepare for the
04335       entire sequence. Typically, this member function will allocate
04336       space for any buffers that are needed for the two member
04337       functions mentioned above.
04338 
04339     RETURN VALUE
04340 
04341       The member function will return 0 if all went OK, or a non-zero
04342       error code otherwise.
04343   */
04344   virtual 
04345   int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
04346 
04347   /*
04348     Primitive to clean up after a sequence of row executions.
04349 
04350     DESCRIPTION
04351     
04352       After doing a sequence of do_prepare_row() and do_exec_row(),
04353       this member function should be called to clean up and release
04354       any allocated buffers.
04355       
04356       The error argument, if non-zero, indicates an error which happened during
04357       row processing before this function was called. In this case, even if 
04358       function is successful, it should return the error code given in the argument.
04359   */
04360   virtual 
04361   int do_after_row_operations(const Slave_reporting_capability *const log,
04362                               int error) = 0;
04363 
04364   /*
04365     Primitive to do the actual execution necessary for a row.
04366 
04367     DESCRIPTION
04368       The member function will do the actual execution needed to handle a row.
04369       The row is located at m_curr_row. When the function returns, 
04370       m_curr_row_end should point at the next row (one byte after the end
04371       of the current row).    
04372 
04373     RETURN VALUE
04374       0 if execution succeeded, 1 if execution failed.
04375       
04376   */
04377   virtual int do_exec_row(const Relay_log_info *const rli) = 0;
04378 
04386   int handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err);
04387 
04396   void do_post_row_operations(Relay_log_info const *rli, int err);
04397 
04402   int do_apply_row(Relay_log_info const *rli);
04403 
04409   int do_index_scan_and_update(Relay_log_info const *rli);
04410   
04418   int do_hash_scan_and_update(Relay_log_info const *rli);
04419 
04426   int do_table_scan_and_update(Relay_log_info const *rli);
04427 
04433   int open_record_scan();
04434 
04440   int close_record_scan();
04441 
04454   int next_record_scan(bool first_read);
04455 
04462   int add_key_to_distinct_keyset();
04463 
04476   int do_hash_row(Relay_log_info const *rli);
04477 
04486   int do_scan_and_update(Relay_log_info const *rli);
04487 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
04488 
04489   friend class Old_rows_log_event;
04490 };
04491 
04501 class Write_rows_log_event : public Rows_log_event
04502 {
04503 public:
04504   enum 
04505   {
04506     /* Support interface to THD::binlog_prepare_pending_rows_event */
04507     TYPE_CODE = WRITE_ROWS_EVENT
04508   };
04509 
04510 #if defined(MYSQL_SERVER)
04511   Write_rows_log_event(THD*, TABLE*, const Table_id& table_id,
04512                        bool is_transactional,
04513                        const uchar* extra_row_info);
04514 #endif
04515 #ifdef HAVE_REPLICATION
04516   Write_rows_log_event(const char *buf, uint event_len, 
04517                        const Format_description_log_event *description_event);
04518 #endif
04519 #if defined(MYSQL_SERVER) 
04520   static bool binlog_row_logging_function(THD *thd, TABLE *table,
04521                                           bool is_transactional,
04522                                           const uchar *before_record
04523                                           __attribute__((unused)),
04524                                           const uchar *after_record)
04525   {
04526     return thd->binlog_write_row(table, is_transactional,
04527                                  after_record, NULL);
04528   }
04529 #endif
04530 
04531 protected:
04532   int write_row(const Relay_log_info *const, const bool);
04533 
04534 private:
04535   virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
04536 
04537 #ifdef MYSQL_CLIENT
04538   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04539 #endif
04540 
04541 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04542   virtual int do_before_row_operations(const Slave_reporting_capability *const);
04543   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
04544   virtual int do_exec_row(const Relay_log_info *const);
04545 #endif
04546 };
04547 
04548 
04561 class Update_rows_log_event : public Rows_log_event
04562 {
04563 public:
04564   enum 
04565   {
04566     /* Support interface to THD::binlog_prepare_pending_rows_event */
04567     TYPE_CODE = UPDATE_ROWS_EVENT
04568   };
04569 
04570 #ifdef MYSQL_SERVER
04571   Update_rows_log_event(THD*, TABLE*, const Table_id& table_id,
04572                         MY_BITMAP const *cols_bi,
04573                         MY_BITMAP const *cols_ai,
04574                         bool is_transactional,
04575                         const uchar* extra_row_info);
04576 
04577   Update_rows_log_event(THD*, TABLE*, const Table_id& table_id,
04578                         bool is_transactional,
04579                         const uchar* extra_row_info);
04580 
04581   void init(MY_BITMAP const *cols);
04582 #endif
04583 
04584   virtual ~Update_rows_log_event();
04585 
04586 #ifdef HAVE_REPLICATION
04587   Update_rows_log_event(const char *buf, uint event_len, 
04588                         const Format_description_log_event *description_event);
04589 #endif
04590 
04591 #ifdef MYSQL_SERVER
04592   static bool binlog_row_logging_function(THD *thd, TABLE *table,
04593                                           bool is_transactional,
04594                                           const uchar *before_record,
04595                                           const uchar *after_record)
04596   {
04597     return thd->binlog_update_row(table, is_transactional,
04598                                   before_record, after_record, NULL);
04599   }
04600 #endif
04601 
04602   virtual bool is_valid() const
04603   {
04604     return Rows_log_event::is_valid() && m_cols_ai.bitmap;
04605   }
04606 
04607 protected:
04608   virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
04609 
04610 #ifdef MYSQL_CLIENT
04611   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04612 #endif
04613 
04614 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04615   virtual int do_before_row_operations(const Slave_reporting_capability *const);
04616   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
04617   virtual int do_exec_row(const Relay_log_info *const);
04618 #endif /* defined(MYSQL_SERVER) && defined(HAVE_REPLICATION) */
04619 };
04620 
04641 class Delete_rows_log_event : public Rows_log_event
04642 {
04643 public:
04644   enum 
04645   {
04646     /* Support interface to THD::binlog_prepare_pending_rows_event */
04647     TYPE_CODE = DELETE_ROWS_EVENT
04648   };
04649 
04650 #ifdef MYSQL_SERVER
04651   Delete_rows_log_event(THD*, TABLE*, const Table_id&,
04652                         bool is_transactional, const uchar* extra_row_info);
04653 #endif
04654 #ifdef HAVE_REPLICATION
04655   Delete_rows_log_event(const char *buf, uint event_len, 
04656                         const Format_description_log_event *description_event);
04657 #endif
04658 #ifdef MYSQL_SERVER
04659   static bool binlog_row_logging_function(THD *thd, TABLE *table,
04660                                           bool is_transactional,
04661                                           const uchar *before_record,
04662                                           const uchar *after_record
04663                                           __attribute__((unused)))
04664   {
04665     return thd->binlog_delete_row(table, is_transactional,
04666                                   before_record, NULL);
04667   }
04668 #endif
04669   
04670 protected:
04671   virtual Log_event_type get_general_type_code() { return (Log_event_type)TYPE_CODE; }
04672 
04673 #ifdef MYSQL_CLIENT
04674   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04675 #endif
04676 
04677 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04678   virtual int do_before_row_operations(const Slave_reporting_capability *const);
04679   virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
04680   virtual int do_exec_row(const Relay_log_info *const);
04681 #endif
04682 };
04683 
04684 
04685 #include "log_event_old.h"
04686 
04723 class Incident_log_event : public Log_event {
04724 public:
04725 #ifdef MYSQL_SERVER
04726   Incident_log_event(THD *thd_arg, Incident incident)
04727     : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F, Log_event::EVENT_NO_CACHE,
04728                 Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident)
04729   {
04730     DBUG_ENTER("Incident_log_event::Incident_log_event");
04731     DBUG_PRINT("enter", ("m_incident: %d", m_incident));
04732     m_message.str= NULL;                    /* Just as a precaution */
04733     m_message.length= 0;
04734     DBUG_VOID_RETURN;
04735   }
04736 
04737   Incident_log_event(THD *thd_arg, Incident incident, LEX_STRING const msg)
04738     : Log_event(thd_arg, LOG_EVENT_NO_FILTER_F,
04739                 Log_event::EVENT_NO_CACHE,
04740                 Log_event::EVENT_IMMEDIATE_LOGGING), m_incident(incident)
04741   {
04742     DBUG_ENTER("Incident_log_event::Incident_log_event");
04743     DBUG_PRINT("enter", ("m_incident: %d", m_incident));
04744     m_message.str= NULL;
04745     m_message.length= 0;
04746     if (!(m_message.str= (char*) my_malloc(msg.length+1, MYF(MY_WME))))
04747     {
04748       /* Mark this event invalid */
04749       m_incident= INCIDENT_NONE;
04750       DBUG_VOID_RETURN;
04751     }
04752     strmake(m_message.str, msg.str, msg.length);
04753     m_message.length= msg.length;
04754     DBUG_VOID_RETURN;
04755   }
04756 #endif
04757 
04758 #ifdef MYSQL_SERVER
04759   int pack_info(Protocol*);
04760 #endif
04761 
04762   Incident_log_event(const char *buf, uint event_len,
04763                      const Format_description_log_event *descr_event);
04764 
04765   virtual ~Incident_log_event();
04766 
04767 #ifdef MYSQL_CLIENT
04768   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04769 #endif
04770 
04771 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04772   virtual int do_apply_event(Relay_log_info const *rli);
04773 #endif
04774 
04775   virtual bool write_data_header(IO_CACHE *file);
04776   virtual bool write_data_body(IO_CACHE *file);
04777 
04778   virtual Log_event_type get_type_code() { return INCIDENT_EVENT; }
04779 
04780   virtual bool is_valid() const
04781   {
04782     return m_incident > INCIDENT_NONE && m_incident < INCIDENT_COUNT;
04783   }
04784   virtual int get_data_size() {
04785     return INCIDENT_HEADER_LEN + 1 + (uint) m_message.length;
04786   }
04787 
04788 private:
04789   const char *description() const;
04790 
04791   Incident m_incident;
04792   LEX_STRING m_message;
04793 };
04794 
04795 
04813 class Ignorable_log_event : public Log_event {
04814 public:
04815 #ifndef MYSQL_CLIENT
04816   Ignorable_log_event(THD *thd_arg)
04817       : Log_event(thd_arg, LOG_EVENT_IGNORABLE_F, 
04818                   Log_event::EVENT_STMT_CACHE,
04819                   Log_event::EVENT_NORMAL_LOGGING)
04820   {
04821     DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
04822     DBUG_VOID_RETURN;
04823   }
04824 #endif
04825 
04826   Ignorable_log_event(const char *buf,
04827                       const Format_description_log_event *descr_event);
04828   virtual ~Ignorable_log_event();
04829 
04830 #ifndef MYSQL_CLIENT
04831   int pack_info(Protocol*);
04832 #endif
04833 
04834 #ifdef MYSQL_CLIENT
04835   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04836 #endif
04837 
04838   virtual Log_event_type get_type_code() { return IGNORABLE_LOG_EVENT; }
04839 
04840   virtual bool is_valid() const { return 1; }
04841 
04842   virtual int get_data_size() { return IGNORABLE_HEADER_LEN; }
04843 };
04844 
04845 
04846 class Rows_query_log_event : public Ignorable_log_event {
04847 public:
04848 #ifndef MYSQL_CLIENT
04849   Rows_query_log_event(THD *thd_arg, const char * query, ulong query_len)
04850     : Ignorable_log_event(thd_arg)
04851   {
04852     DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
04853     if (!(m_rows_query= (char*) my_malloc(query_len + 1, MYF(MY_WME))))
04854       return;
04855     my_snprintf(m_rows_query, query_len + 1, "%s", query);
04856     DBUG_PRINT("enter", ("%s", m_rows_query));
04857     DBUG_VOID_RETURN;
04858   }
04859 #endif
04860 
04861 #ifndef MYSQL_CLIENT
04862   int pack_info(Protocol*);
04863 #endif
04864 
04865   Rows_query_log_event(const char *buf, uint event_len,
04866                      const Format_description_log_event *descr_event);
04867 
04868   virtual ~Rows_query_log_event();
04869 
04870 #ifdef MYSQL_CLIENT
04871   virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04872 #endif
04873   virtual bool write_data_body(IO_CACHE *file);
04874 
04875   virtual Log_event_type get_type_code() { return ROWS_QUERY_LOG_EVENT; }
04876 
04877   virtual int get_data_size()
04878   {
04879     return IGNORABLE_HEADER_LEN + 1 + (uint) strlen(m_rows_query);
04880   }
04881 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04882   virtual int do_apply_event(Relay_log_info const *rli);
04883 #endif
04884 
04885 private:
04886 
04887   char * m_rows_query;
04888 };
04889 
04890 
04891 
04892 static inline bool copy_event_cache_to_file_and_reinit(IO_CACHE *cache,
04893                                                        FILE *file,
04894                                                        bool flush_stream)
04895 {
04896   return         
04897     my_b_copy_to_file(cache, file) ||
04898     (flush_stream ? (fflush(file) || ferror(file)) : 0) ||
04899     reinit_io_cache(cache, WRITE_CACHE, 0, FALSE, TRUE);
04900 }
04901 
04902 #ifdef MYSQL_SERVER
04903 /*****************************************************************************
04904 
04905   Heartbeat Log Event class
04906 
04907   Replication event to ensure to slave that master is alive.
04908   The event is originated by master's dump thread and sent straight to
04909   slave without being logged. Slave itself does not store it in relay log
04910   but rather uses a data for immediate checks and throws away the event.
04911 
04912   Two members of the class log_ident and Log_event::log_pos comprise 
04913   @see the event_coordinates instance. The coordinates that a heartbeat
04914   instance carries correspond to the last event master has sent from
04915   its binlog.
04916 
04917  ****************************************************************************/
04918 class Heartbeat_log_event: public Log_event
04919 {
04920 public:
04921   Heartbeat_log_event(const char* buf, uint event_len,
04922                       const Format_description_log_event* description_event);
04923   Log_event_type get_type_code() { return HEARTBEAT_LOG_EVENT; }
04924   bool is_valid() const
04925     {
04926       return (log_ident != NULL &&
04927               log_pos >= BIN_LOG_HEADER_SIZE);
04928     }
04929   const char * get_log_ident() { return log_ident; }
04930   uint get_ident_len() { return ident_len; }
04931   
04932 private:
04933   const char* log_ident;
04934   uint ident_len;
04935 };
04936 
04943 bool slave_execute_deferred_events(THD *thd);
04944 #endif
04945 
04946 int append_query_string(THD *thd, const CHARSET_INFO *csinfo,
04947                         String const *from, String *to);
04948 bool event_checksum_test(uchar *buf, ulong event_len, uint8 alg);
04949 uint8 get_checksum_alg(const char* buf, ulong len);
04950 extern TYPELIB binlog_checksum_typelib;
04951 
04952 class Gtid_log_event : public Log_event
04953 {
04954 public:
04955 #ifndef MYSQL_CLIENT
04956 
04960   Gtid_log_event(THD *thd_arg, bool using_trans,
04961                  const Gtid_specification *spec= NULL);
04962 #endif
04963 
04964 #ifndef MYSQL_CLIENT
04965   int pack_info(Protocol*);
04966 #endif
04967 
04968   Gtid_log_event(const char *buffer, uint event_len,
04969                  const Format_description_log_event *descr_event);
04970 
04971   virtual ~Gtid_log_event() {}
04972 
04973   Log_event_type get_type_code()
04974   {
04975     DBUG_ENTER("Gtid_log_event::get_type_code()");
04976     Log_event_type ret= (spec.type == ANONYMOUS_GROUP ?
04977                          ANONYMOUS_GTID_LOG_EVENT : GTID_LOG_EVENT);
04978     DBUG_PRINT("info", ("code=%d=%s", ret, get_type_str(ret)));
04979     DBUG_RETURN(ret);
04980   }
04981 
04982   int get_data_size() { return POST_HEADER_LENGTH; }
04983 
04984 private:
04986   size_t to_string(char *buf) const;
04987 
04988 public:
04989 #ifdef MYSQL_CLIENT
04990   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
04991 #endif
04992 #ifdef MYSQL_SERVER
04993   bool write_data_header(IO_CACHE *file);
04994 #endif
04995 
04996 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
04997   int do_apply_event(Relay_log_info const *rli);
04998   int do_update_pos(Relay_log_info *rli);
04999 #endif
05000 
05005   enum_group_type get_type() const { return spec.type; }
05006   bool is_valid() const { return true; }
05007 
05012   const rpl_sid* get_sid() const { return &sid; }
05028   rpl_sidno get_sidno(bool need_lock)
05029   {
05030     if (spec.gtid.sidno < 0)
05031     {
05032       if (need_lock)
05033         global_sid_lock->rdlock();
05034       else
05035         global_sid_lock->assert_some_lock();
05036       spec.gtid.sidno= global_sid_map->add_sid(sid);
05037       if (need_lock)
05038         global_sid_lock->unlock();
05039     }
05040     return spec.gtid.sidno;
05041   }
05052   rpl_sidno get_sidno(Sid_map *sid_map)
05053   {
05054     return sid_map->add_sid(sid);
05055   }
05057   rpl_gno get_gno() const { return spec.gtid.gno; }
05059   bool get_commit_flag() const { return commit_flag; }
05060 
05062   static const char *SET_STRING_PREFIX;
05063 private:
05065   static const size_t SET_STRING_PREFIX_LENGTH= 26;
05067   static const size_t MAX_SET_STRING_LENGTH= SET_STRING_PREFIX_LENGTH +
05068     rpl_sid::TEXT_LENGTH + 1 + MAX_GNO_TEXT_LENGTH + 1;
05069 
05071   static const int ENCODED_FLAG_LENGTH= 1;
05073   static const int ENCODED_SID_LENGTH= rpl_sid::BYTE_LENGTH;
05075   static const int ENCODED_GNO_LENGTH= 8;
05076 
05077 public:
05079   static const int POST_HEADER_LENGTH=
05080     ENCODED_FLAG_LENGTH + ENCODED_SID_LENGTH + ENCODED_GNO_LENGTH;
05081 
05082 private:
05087   Gtid_specification spec;
05089   rpl_sid sid;
05091   bool commit_flag;
05092 };
05093 
05094 
05095 class Previous_gtids_log_event : public Log_event
05096 {
05097 public:
05098 #ifndef MYSQL_CLIENT
05099   Previous_gtids_log_event(const Gtid_set *set);
05100 #endif
05101 
05102 #ifndef MYSQL_CLIENT
05103   int pack_info(Protocol*);
05104 #endif
05105 
05106   Previous_gtids_log_event(const char *buffer, uint event_len,
05107                            const Format_description_log_event *descr_event);
05108   virtual ~Previous_gtids_log_event() {}
05109 
05110   Log_event_type get_type_code() { return PREVIOUS_GTIDS_LOG_EVENT; }
05111 
05112   bool is_valid() const { return buf != NULL; }
05113   int get_data_size() { return buf_size; }
05114 
05115 #ifdef MYSQL_CLIENT
05116   void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
05117 #endif
05118 #ifdef MYSQL_SERVER
05119   bool write(IO_CACHE* file)
05120   {
05121     if (DBUG_EVALUATE_IF("skip_writing_previous_gtids_log_event", 1, 0))
05122     {
05123       DBUG_PRINT("info", ("skip writing Previous_gtids_log_event because of debug option 'skip_writing_previous_gtids_log_event'"));
05124       return false;
05125     }
05126 
05127     if (DBUG_EVALUATE_IF("write_partial_previous_gtids_log_event", 1, 0))
05128     {
05129       DBUG_PRINT("info", ("writing partial Previous_gtids_log_event because of debug option 'write_partial_previous_gtids_log_event'"));
05130       return (Log_event::write_header(file, get_data_size()) ||
05131               Log_event::write_data_header(file));
05132     }
05133   
05134     return (Log_event::write_header(file, get_data_size()) ||
05135             Log_event::write_data_header(file) ||
05136             write_data_body(file) ||
05137             Log_event::write_footer(file));
05138   }
05139   bool write_data_body(IO_CACHE *file);
05140 #endif
05141 
05143   const uchar *get_buf() { return buf; }
05150   char *get_str(size_t *length,
05151                 const Gtid_set::String_format *string_format) const;
05153   int add_to_set(Gtid_set *gtid_set) const;
05154   /*
05155     Previous Gtid Log events should always be skipped
05156     there is nothing to apply there, whether it is
05157     relay log's (generated on Slave) or it is binary log's
05158     (generated on Master, copied to slave as relay log).
05159     Also, we should not increment slave_skip_counter
05160     for this event, hence return EVENT_SKIP_IGNORE.
05161    */
05162   enum_skip_reason do_shall_skip(Relay_log_info *rli)
05163   {
05164     return EVENT_SKIP_IGNORE;
05165   }
05166 
05167 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
05168   int do_apply_event(Relay_log_info const *rli) { return 0; }
05169   int do_update_pos(Relay_log_info *rli);
05170 #endif
05171 
05172 private:
05173   int buf_size;
05174   const uchar *buf;
05175 };
05176 
05177 inline bool is_gtid_event(Log_event* evt)
05178 {
05179   return (evt->get_type_code() == GTID_LOG_EVENT ||
05180           evt->get_type_code() == ANONYMOUS_GTID_LOG_EVENT);
05181 }
05182 
05183 inline ulong version_product(const uchar* version_split)
05184 {
05185   return ((version_split[0] * 256 + version_split[1]) * 256
05186           + version_split[2]);
05187 }
05188 
05195 inline void do_server_version_split(char* version, uchar split_versions[3])
05196 {
05197   char *p= version, *r;
05198   ulong number;
05199   for (uint i= 0; i<=2; i++)
05200   {
05201     number= strtoul(p, &r, 10);
05202     /*
05203       It is an invalid version if any version number greater than 255 or
05204       first number is not followed by '.'.
05205     */
05206     if (number < 256 && (*r == '.' || i != 0))
05207       split_versions[i]= (uchar)number;
05208     else
05209     {
05210       split_versions[0]= 0;
05211       split_versions[1]= 0;
05212       split_versions[2]= 0;
05213       break;
05214     }
05215 
05216     p= r;
05217     if (*r == '.')
05218       p++; // skip the dot
05219   }
05220 }
05221 
05222 #ifdef MYSQL_SERVER
05223 /*
05224   This is an utility function that adds a quoted identifier into the a buffer.
05225   This also escapes any existance of the quote string inside the identifier.
05226  */
05227 size_t my_strmov_quoted_identifier(THD *thd, char *buffer,
05228                                    const char* identifier,
05229                                    uint length);
05230 #else
05231 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier);
05232 #endif
05233 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
05234                                           const char* identifier,
05235                                           uint length);
05236 
05241 #endif /* _log_event_h */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines