1 /*
2    Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
3 
4    This program is free software; you can redistribute it and/or modify
5    it under the terms of the GNU General Public License, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA */
23 
24 
25 #ifdef MYSQL_CLIENT
26 
27 #include "sql_priv.h"
28 #include "mysqld_error.h"
29 
30 #else
31 
32 #include "binlog.h"
33 #include "sql_priv.h"
34 #include "unireg.h"
35 #include "my_global.h" // REQUIRED by log_event.h > m_string.h > my_bitmap.h
36 #include "log_event.h"
37 #include "sql_base.h"                           // close_thread_tables
38 #include "sql_cache.h"                       // QUERY_CACHE_FLAGS_SIZE
39 #include "sql_locale.h" // MY_LOCALE, my_locale_by_number, my_locale_en_US
40 #include "lock.h"       // mysql_unlock_tables
41 #include "sql_parse.h"  // mysql_test_parse_for_slave
42 #include "tztime.h"     // struct Time_zone
43 #include "sql_load.h"   // mysql_load
44 #include "sql_db.h"     // load_db_opt_by_name
45 #include "rpl_slave.h"
46 #include "rpl_rli.h"
47 #include "rpl_mi.h"
48 #include "rpl_filter.h"
49 #include "rpl_record.h"
50 #include "transaction.h"
51 #include <my_dir.h>
52 #include "rpl_rli_pdb.h"
53 #include "sql_show.h"    // append_identifier
54 #include "debug_sync.h"  // debug_sync
55 #include <mysql/psi/mysql_statement.h>
56 #define window_size Log_throttle::LOG_THROTTLE_WINDOW_SIZE
57 Error_log_throttle
58 slave_ignored_err_throttle(window_size,
59                            sql_print_warning,
60                            "Error log throttle: %lu time(s) Error_code: 1237"
61                            " \"Slave SQL thread ignored the query because of"
62                            " replicate-*-table rules\" got suppressed.");
63 #endif /* MYSQL_CLIENT */
64 
65 #include <base64.h>
66 #include <my_bitmap.h>
67 #include "rpl_utility.h"
68 
69 #include "sql_digest.h"
70 #ifndef EMBEDDED_LIBRARY
71 #include "sql_connect.h" //update_global_user_stats
72 #endif
73 
74 using std::min;
75 using std::max;
76 
77 /* The number of event types need to be permuted. */
78 static const uint EVENT_TYPE_PERMUTATION_NUM= 23;
79 
80 /**
81   BINLOG_CHECKSUM variable.
82 */
83 const char *binlog_checksum_type_names[]= {
84   "NONE",
85   "CRC32",
86   NullS
87 };
88 
89 unsigned int binlog_checksum_type_length[]= {
90   sizeof("NONE") - 1,
91   sizeof("CRC32") - 1,
92   0
93 };
94 
95 TYPELIB binlog_checksum_typelib=
96 {
97   array_elements(binlog_checksum_type_names) - 1, "",
98   binlog_checksum_type_names,
99   binlog_checksum_type_length
100 };
101 
102 
103 #define log_cs	&my_charset_latin1
104 
105 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
106 
107 /*
108   Size of buffer for printing a double in format %.<PREC>g
109 
110   optional '-' + optional zero + '.'  + PREC digits + 'e' + sign +
111   exponent digits + '\0'
112 */
113 #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
114 
115 /*
116   Explicit instantiation to unsigned int of template available_buffer
117   function.
118 */
119 template unsigned int available_buffer<unsigned int>(const char*,
120                                                      const char*,
121                                                      unsigned int);
122 
123 /*
124   Explicit instantiation to unsigned int of template valid_buffer_range
125   function.
126 */
127 template bool valid_buffer_range<unsigned int>(unsigned int,
128                                                const char*,
129                                                const char*,
130                                                unsigned int);
131 
132 /*
133    replication event checksum is introduced in the following "checksum-home" version.
134    The checksum-aware servers extract FD's version to decide whether the FD event
135    carries checksum info.
136 */
137 const uchar checksum_version_split[3]= {5, 6, 1};
138 const ulong checksum_version_product=
139   (checksum_version_split[0] * 256 + checksum_version_split[1]) * 256 +
140   checksum_version_split[2];
141 
142 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
143 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
144 
HA_ERR(int i)145 static const char *HA_ERR(int i)
146 {
147   /*
148     This function should only be called in case of an error
149     was detected
150    */
151   DBUG_ASSERT(i != 0);
152   switch (i) {
153   case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
154   case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
155   case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
156   case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
157   case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
158   case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
159   case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
160   case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
161   case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
162   case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
163   case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
164   case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
165   case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
166   case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
167   case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
168   case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
169   case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
170   case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
171   case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
172   case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
173   case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
174   case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
175   case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
176   case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
177   case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
178   case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
179   case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
180   case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
181   case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
182   case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
183   case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
184   case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
185   case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
186   case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
187   case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
188   case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
189   case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
190   case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
191   case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
192   case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
193   case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
194   case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
195   case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
196   case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
197   case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
198   case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
199   case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
200   case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
201   case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
202   case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
203   case HA_ERR_INNODB_READ_ONLY: return "HA_ERR_INNODB_READ_ONLY";
204   case HA_ERR_FTS_TOO_MANY_NESTED_EXP: return "HA_ERR_FTS_TOO_MANY_NESTED_EXP";
205   }
206   return "No Error!";
207 }
208 
209 /**
210    Error reporting facility for Rows_log_event::do_apply_event
211 
212    @param level     error, warning or info
213    @param ha_error  HA_ERR_ code
214    @param rli       pointer to the active Relay_log_info instance
215    @param thd       pointer to the slave thread's thd
216    @param table     pointer to the event's table object
217    @param type      the type of the event
218    @param log_name  the master binlog file name
219    @param pos       the master binlog file pos (the next after the event)
220 
221 */
slave_rows_error_report(enum loglevel level,int ha_error,Relay_log_info const * rli,THD * thd,TABLE * table,const char * type,const char * log_name,ulong pos)222 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
223                                            Relay_log_info const *rli, THD *thd,
224                                            TABLE *table, const char * type,
225                                            const char *log_name, ulong pos)
226 {
227   const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
228   char buff[MAX_SLAVE_ERRMSG], *slider;
229   const char *buff_end= buff + sizeof(buff);
230   uint len;
231   Diagnostics_area::Sql_condition_iterator it=
232     thd->get_stmt_da()->sql_conditions();
233   const Sql_condition *err;
234   buff[0]= 0;
235 
236   for (err= it++, slider= buff; err && slider < buff_end - 1;
237        slider += len, err= it++)
238   {
239     len= my_snprintf(slider, buff_end - slider,
240                      " %s, Error_code: %d;", err->get_message_text(),
241                      err->get_sql_errno());
242   }
243 
244   if (ha_error != 0)
245     rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
246                 "Could not execute %s event on table %s.%s;"
247                 "%s handler error %s; "
248                 "the event's master log %s, end_log_pos %lu",
249                 type, table->s->db.str, table->s->table_name.str,
250                 buff, handler_error == NULL ? "<unknown>" : handler_error,
251                 log_name, pos);
252   else
253     rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
254                 "Could not execute %s event on table %s.%s;"
255                 "%s the event's master log %s, end_log_pos %lu",
256                 type, table->s->db.str, table->s->table_name.str,
257                 buff, log_name, pos);
258 }
259 
set_thd_db(THD * thd,const char * db,uint32 db_len)260 static void set_thd_db(THD *thd, const char *db, uint32 db_len)
261 {
262   char lcase_db_buf[NAME_LEN +1];
263   LEX_STRING new_db;
264   new_db.length= db_len;
265   if (lower_case_table_names == 1)
266   {
267     strmov(lcase_db_buf, db);
268     my_casedn_str(system_charset_info, lcase_db_buf);
269     new_db.str= lcase_db_buf;
270   }
271   else
272     new_db.str= (char*) db;
273 
274   new_db.str= (char*) rpl_filter->get_rewrite_db(new_db.str,
275                                                  &new_db.length);
276   thd->set_db(new_db.str, new_db.length);
277 }
278 
279 #endif
280 
281 
282 /*
283   pretty_print_str()
284 */
285 
286 #ifdef MYSQL_CLIENT
pretty_print_str(IO_CACHE * cache,const char * str,int len)287 static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
288 {
289   const char* end = str + len;
290   my_b_printf(cache, "\'");
291   while (str < end)
292   {
293     char c;
294     switch ((c=*str++)) {
295     case '\n': my_b_printf(cache, "\\n"); break;
296     case '\r': my_b_printf(cache, "\\r"); break;
297     case '\\': my_b_printf(cache, "\\\\"); break;
298     case '\b': my_b_printf(cache, "\\b"); break;
299     case '\t': my_b_printf(cache, "\\t"); break;
300     case '\'': my_b_printf(cache, "\\'"); break;
301     case 0   : my_b_printf(cache, "\\0"); break;
302     default:
303       my_b_printf(cache, "%c", c);
304       break;
305     }
306   }
307   my_b_printf(cache, "\'");
308 }
309 #endif /* MYSQL_CLIENT */
310 
311 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
312 
clear_all_errors(THD * thd,Relay_log_info * rli)313 static void clear_all_errors(THD *thd, Relay_log_info *rli)
314 {
315   thd->is_slave_error = 0;
316   thd->clear_error();
317   rli->clear_error();
318 }
319 
idempotent_error_code(int err_code)320 inline int idempotent_error_code(int err_code)
321 {
322   int ret= 0;
323 
324   switch (err_code)
325   {
326     case 0:
327       ret= 1;
328     break;
329     /*
330       The following list of "idempotent" errors
331       means that an error from the list might happen
332       because of idempotent (more than once)
333       applying of a binlog file.
334       Notice, that binlog has a  ddl operation its
335       second applying may cause
336 
337       case HA_ERR_TABLE_DEF_CHANGED:
338       case HA_ERR_CANNOT_ADD_FOREIGN:
339 
340       which are not included into to the list.
341 
342       Note that HA_ERR_RECORD_DELETED is not in the list since
343       do_exec_row() should not return that error code.
344     */
345     case HA_ERR_RECORD_CHANGED:
346     case HA_ERR_KEY_NOT_FOUND:
347     case HA_ERR_END_OF_FILE:
348     case HA_ERR_FOUND_DUPP_KEY:
349     case HA_ERR_FOUND_DUPP_UNIQUE:
350     case HA_ERR_FOREIGN_DUPLICATE_KEY:
351     case HA_ERR_NO_REFERENCED_ROW:
352     case HA_ERR_ROW_IS_REFERENCED:
353       ret= 1;
354     break;
355     default:
356       ret= 0;
357     break;
358   }
359   return (ret);
360 }
361 
362 /**
363   Ignore error code specified on command line.
364 */
365 
ignored_error_code(int err_code)366 int ignored_error_code(int err_code)
367 {
368 #ifdef HAVE_NDB_BINLOG
369   /*
370     The following error codes are hard-coded and will always be ignored.
371   */
372   switch (err_code)
373   {
374   case ER_DB_CREATE_EXISTS:
375   case ER_DB_DROP_EXISTS:
376     return 1;
377   default:
378     /* Nothing to do */
379     break;
380   }
381 #endif
382   return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
383           (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
384 }
385 
386 /*
387   This function converts an engine's error to a server error.
388 
389   If the thread does not have an error already reported, it tries to
390   define it by calling the engine's method print_error. However, if a
391   mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
392   warning message.
393 */
convert_handler_error(int error,THD * thd,TABLE * table)394 int convert_handler_error(int error, THD* thd, TABLE *table)
395 {
396   uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
397                            0);
398 
399   if (actual_error == 0)
400   {
401     table->file->print_error(error, MYF(0));
402     actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
403                         ER_UNKNOWN_ERROR);
404     if (actual_error == ER_UNKNOWN_ERROR)
405       if (log_warnings)
406         sql_print_warning("Unknown error detected %d in handler", error);
407   }
408 
409   return (actual_error);
410 }
411 
concurrency_error_code(int error)412 inline bool concurrency_error_code(int error)
413 {
414   switch (error)
415   {
416   case ER_LOCK_WAIT_TIMEOUT:
417   case ER_LOCK_DEADLOCK:
418   case ER_XA_RBDEADLOCK:
419     return TRUE;
420   default:
421     return (FALSE);
422   }
423 }
424 
unexpected_error_code(int unexpected_error)425 inline bool unexpected_error_code(int unexpected_error)
426 {
427   switch (unexpected_error)
428   {
429   case ER_NET_READ_ERROR:
430   case ER_NET_ERROR_ON_WRITE:
431   case ER_QUERY_INTERRUPTED:
432   case ER_SERVER_SHUTDOWN:
433   case ER_NEW_ABORTING_CONNECTION:
434     return(TRUE);
435   default:
436     return(FALSE);
437   }
438 }
439 
440 /*
441   pretty_print_str()
442 */
443 
pretty_print_str(char * packet,const char * str,int len)444 static char *pretty_print_str(char *packet, const char *str, int len)
445 {
446   const char *end= str + len;
447   char *pos= packet;
448   *pos++= '\'';
449   while (str < end)
450   {
451     char c;
452     switch ((c=*str++)) {
453     case '\n': *pos++= '\\'; *pos++= 'n'; break;
454     case '\r': *pos++= '\\'; *pos++= 'r'; break;
455     case '\\': *pos++= '\\'; *pos++= '\\'; break;
456     case '\b': *pos++= '\\'; *pos++= 'b'; break;
457     case '\t': *pos++= '\\'; *pos++= 't'; break;
458     case '\'': *pos++= '\\'; *pos++= '\''; break;
459     case 0   : *pos++= '\\'; *pos++= '0'; break;
460     default:
461       *pos++= c;
462       break;
463     }
464   }
465   *pos++= '\'';
466   return pos;
467 }
468 #endif /* !MYSQL_CLIENT */
469 
470 
471 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
472 
473 /**
474   Creates a temporary name for load data infile:.
475 
476   @param buf		      Store new filename here
477   @param file_id	      File_id (part of file name)
478   @param event_server_id     Event_id (part of file name)
479   @param ext		      Extension for file name
480 
481   @return
482     Pointer to start of extension
483 */
484 
slave_load_file_stem(char * buf,uint file_id,int event_server_id,const char * ext)485 static char *slave_load_file_stem(char *buf, uint file_id,
486                                   int event_server_id, const char *ext)
487 {
488   char *res;
489   fn_format(buf,PREFIX_SQL_LOAD,slave_load_tmpdir, "", MY_UNPACK_FILENAME);
490   to_unix_path(buf);
491 
492   buf= strend(buf);
493   int appended_length= sprintf(buf, "%s-%d-", server_uuid, event_server_id);
494   buf+= appended_length;
495   res= int10_to_str(file_id, buf, 10);
496   strmov(res, ext);                             // Add extension last
497   return res;                                   // Pointer to extension
498 }
499 #endif
500 
501 
502 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
503 
504 /**
505   Delete all temporary files used for SQL_LOAD.
506 */
507 
cleanup_load_tmpdir()508 static void cleanup_load_tmpdir()
509 {
510   MY_DIR *dirp;
511   FILEINFO *file;
512   uint i;
513   char fname[FN_REFLEN], prefbuf[TEMP_FILE_MAX_LEN], *p;
514 
515   if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
516     return;
517 
518   /*
519      When we are deleting temporary files, we should only remove
520      the files associated with the server id of our server.
521      We don't use event_server_id here because since we've disabled
522      direct binlogging of Create_file/Append_file/Exec_load events
523      we cannot meet Start_log event in the middle of events from one
524      LOAD DATA.
525   */
526   p= strmake(prefbuf, STRING_WITH_LEN(PREFIX_SQL_LOAD));
527   sprintf(p,"%s-",server_uuid);
528 
529   for (i=0 ; i < (uint)dirp->number_off_files; i++)
530   {
531     file=dirp->dir_entry+i;
532     if (is_prefix(file->name, prefbuf))
533     {
534       fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
535       mysql_file_delete(key_file_misc, fname, MYF(0));
536     }
537   }
538 
539   my_dirend(dirp);
540 }
541 #endif
542 
543 
544 /*
545   Stores string to IO_CACHE file.
546 
547   Writes str to file in the following format:
548    1. Stores length using only one byte (255 maximum value);
549    2. Stores complete str.
550 */
551 
write_str_at_most_255_bytes(IO_CACHE * file,const char * str,uint length)552 static bool write_str_at_most_255_bytes(IO_CACHE *file, const char *str,
553                                         uint length)
554 {
555   uchar tmp[1];
556   tmp[0]= (uchar) length;
557   return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
558 	  my_b_safe_write(file, (uchar*) str, length));
559 }
560 
561 
562 /*
563   Reads string from buf.
564 
565   Reads str from buf in the following format:
566    1. Read length stored on buf first index, as it only has 1 byte values
567       bigger than 255 where lost.
568    2. Set str pointer to buf second index.
569   Despite str contains the complete stored string, when it is read until
570   len its value will be truncated if original length was bigger than 255.
571 */
572 
read_str_at_most_255_bytes(const char ** buf,const char * buf_end,const char ** str,uint8 * len)573 static inline int read_str_at_most_255_bytes(const char **buf,
574                                              const char *buf_end,
575                                              const char **str,
576                                              uint8 *len)
577 {
578   if (*buf + ((uint) (uchar) **buf) >= buf_end)
579     return 1;
580   *len= (uint8) **buf;
581   *str= (*buf)+1;
582   (*buf)+= (uint) *len+1;
583   return 0;
584 }
585 
586 
587 /**
588   Transforms a string into "" or its expression in 0x... form.
589 */
590 
str_to_hex(char * to,const char * from,uint len)591 char *str_to_hex(char *to, const char *from, uint len)
592 {
593   if (len)
594   {
595     *to++= '0';
596     *to++= 'x';
597     to= octet2hex(to, from, len);
598   }
599   else
600     to= strmov(to, "\"\"");
601   return to;                               // pointer to end 0 of 'to'
602 }
603 
604 #ifndef MYSQL_CLIENT
605 
606 /**
607   Append a version of the 'from' string suitable for use in a query to
608   the 'to' string.  To generate a correct escaping, the character set
609   information in 'csinfo' is used.
610 */
611 
612 int
append_query_string(THD * thd,const CHARSET_INFO * csinfo,String const * from,String * to)613 append_query_string(THD *thd, const CHARSET_INFO *csinfo,
614                     String const *from, String *to)
615 {
616   char *beg, *ptr;
617   uint32 const orig_len= to->length();
618   if (to->reserve(orig_len + from->length()*2+3))
619     return 1;
620 
621   beg= to->c_ptr_quick() + to->length();
622   ptr= beg;
623   if (csinfo->escape_with_backslash_is_dangerous)
624     ptr= str_to_hex(ptr, from->ptr(), from->length());
625   else
626   {
627     *ptr++= '\'';
628     if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
629     {
630       ptr+= escape_string_for_mysql(csinfo, ptr, 0,
631                                     from->ptr(), from->length());
632     }
633     else
634     {
635       const char *frm_str= from->ptr();
636 
637       for (; frm_str < (from->ptr() + from->length()); frm_str++)
638       {
639         /* Using '' way to represent "'" */
640         if (*frm_str == '\'')
641           *ptr++= *frm_str;
642 
643         *ptr++= *frm_str;
644       }
645     }
646 
647     *ptr++= '\'';
648   }
649   to->length(orig_len + ptr - beg);
650   return 0;
651 }
652 #endif
653 
654 
655 /**
656   Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
657   commands just before it prints a query.
658 */
659 
660 #ifdef MYSQL_CLIENT
661 
print_set_option(IO_CACHE * file,uint32 bits_changed,uint32 option,uint32 flags,const char * name,bool * need_comma)662 static void print_set_option(IO_CACHE* file, uint32 bits_changed,
663                              uint32 option, uint32 flags, const char* name,
664                              bool* need_comma)
665 {
666   if (bits_changed & option)
667   {
668     if (*need_comma)
669       my_b_printf(file,", ");
670     my_b_printf(file,"%s=%d", name, MY_TEST(flags & option));
671     *need_comma= 1;
672   }
673 }
674 #endif
675 /**************************************************************************
676 	Log_event methods (= the parent class of all events)
677 **************************************************************************/
678 
679 /**
680   @return
681   returns the human readable name of the event's type
682 */
683 
get_type_str(Log_event_type type)684 const char* Log_event::get_type_str(Log_event_type type)
685 {
686   switch(type) {
687   case START_EVENT_V3:  return "Start_v3";
688   case STOP_EVENT:   return "Stop";
689   case QUERY_EVENT:  return "Query";
690   case ROTATE_EVENT: return "Rotate";
691   case INTVAR_EVENT: return "Intvar";
692   case LOAD_EVENT:   return "Load";
693   case NEW_LOAD_EVENT:   return "New_load";
694   case CREATE_FILE_EVENT: return "Create_file";
695   case APPEND_BLOCK_EVENT: return "Append_block";
696   case DELETE_FILE_EVENT: return "Delete_file";
697   case EXEC_LOAD_EVENT: return "Exec_load";
698   case RAND_EVENT: return "RAND";
699   case XID_EVENT: return "Xid";
700   case USER_VAR_EVENT: return "User var";
701   case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
702   case TABLE_MAP_EVENT: return "Table_map";
703   case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
704   case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
705   case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
706   case WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
707   case UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
708   case DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
709   case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
710   case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
711   case INCIDENT_EVENT: return "Incident";
712   case IGNORABLE_LOG_EVENT: return "Ignorable";
713   case ROWS_QUERY_LOG_EVENT: return "Rows_query";
714   case WRITE_ROWS_EVENT: return "Write_rows";
715   case UPDATE_ROWS_EVENT: return "Update_rows";
716   case DELETE_ROWS_EVENT: return "Delete_rows";
717   case GTID_LOG_EVENT: return "Gtid";
718   case ANONYMOUS_GTID_LOG_EVENT: return "Anonymous_Gtid";
719   case PREVIOUS_GTIDS_LOG_EVENT: return "Previous_gtids";
720   case HEARTBEAT_LOG_EVENT: return "Heartbeat";
721   default: return "Unknown";				/* impossible */
722   }
723 }
724 
get_type_str()725 const char* Log_event::get_type_str()
726 {
727   return get_type_str(get_type_code());
728 }
729 
730 
731 /*
732   Log_event::Log_event()
733 */
734 
735 #ifndef MYSQL_CLIENT
Log_event(THD * thd_arg,uint16 flags_arg,enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg)736 Log_event::Log_event(THD* thd_arg, uint16 flags_arg,
737                      enum_event_cache_type cache_type_arg,
738                      enum_event_logging_type logging_type_arg)
739   :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
740   event_cache_type(cache_type_arg),
741   event_logging_type(logging_type_arg),
742   crc(0), thd(thd_arg), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
743 {
744   server_id= thd->server_id;
745   unmasked_server_id= server_id;
746   when= thd->start_time;
747 }
748 
749 /**
750   This minimal constructor is for when you are not even sure that there
751   is a valid THD. For example in the server when we are shutting down or
752   flushing logs after receiving a SIGHUP (then we must write a Rotate to
753   the binlog but we have no THD, so we need this minimal constructor).
754 */
755 
Log_event(enum_event_cache_type cache_type_arg,enum_event_logging_type logging_type_arg)756 Log_event::Log_event(enum_event_cache_type cache_type_arg,
757                      enum_event_logging_type logging_type_arg)
758   :temp_buf(0), exec_time(0), flags(0), event_cache_type(cache_type_arg),
759   event_logging_type(logging_type_arg), crc(0), thd(0),
760   checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
761 {
762   server_id=	::server_id;
763   unmasked_server_id= server_id;
764   /*
765     We can't call my_time() here as this would cause a call before
766     my_init() is called
767   */
768   when.tv_sec=  0;
769   when.tv_usec= 0;
770   log_pos=	0;
771 }
772 #endif /* !MYSQL_CLIENT */
773 
774 
775 /*
776   Log_event::Log_event()
777 */
778 
Log_event(const char * buf,const Format_description_log_event * description_event)779 Log_event::Log_event(const char* buf,
780                      const Format_description_log_event* description_event)
781   :temp_buf(0), exec_time(0),
782   event_cache_type(EVENT_INVALID_CACHE),
783   event_logging_type(EVENT_INVALID_LOGGING),
784   crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
785 {
786 #ifndef MYSQL_CLIENT
787   thd = 0;
788 #endif
789   when.tv_sec= uint4korr(buf);
790   when.tv_usec= 0;
791   server_id = uint4korr(buf + SERVER_ID_OFFSET);
792   unmasked_server_id = server_id;
793   /*
794      Mask out any irrelevant parts of the server_id
795   */
796 #ifdef HAVE_REPLICATION
797   server_id = unmasked_server_id & opt_server_id_mask;
798 #else
799   server_id = unmasked_server_id;
800 #endif
801   data_written= uint4korr(buf + EVENT_LEN_OFFSET);
802   if (description_event->binlog_version==1)
803   {
804     log_pos= 0;
805     flags= 0;
806     return;
807   }
808   /* 4.0 or newer */
809   log_pos= uint4korr(buf + LOG_POS_OFFSET);
810   /*
811     If the log is 4.0 (so here it can only be a 4.0 relay log read by
812     the SQL thread or a 4.0 master binlog read by the I/O thread),
813     log_pos is the beginning of the event: we transform it into the end
814     of the event, which is more useful.
815     But how do you know that the log is 4.0: you know it if
816     description_event is version 3 *and* you are not reading a
817     Format_desc (remember that mysqlbinlog starts by assuming that 5.0
818     logs are in 4.0 format, until it finds a Format_desc).
819   */
820   if (description_event->binlog_version==3 &&
821       buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
822   {
823       /*
824         If log_pos=0, don't change it. log_pos==0 is a marker to mean
825         "don't change rli->group_master_log_pos" (see
826         inc_group_relay_log_pos()). As it is unreal log_pos, adding the
827         event len's is nonsense. For example, a fake Rotate event should
828         not have its log_pos (which is 0) changed or it will modify
829         Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
830         value of (a non-zero offset which does not exist in the master's
831         binlog, so which will cause problems if the user uses this value
832         in CHANGE MASTER).
833       */
834     log_pos+= data_written; /* purecov: inspected */
835   }
836   DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
837 
838   flags= uint2korr(buf + FLAGS_OFFSET);
839   if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
840       (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
841   {
842     /*
843       These events always have a header which stops here (i.e. their
844       header is FROZEN).
845     */
846     /*
847       Initialization to zero of all other Log_event members as they're
848       not specified. Currently there are no such members; in the future
849       there will be an event UID (but Format_description and Rotate
850       don't need this UID, as they are not propagated through
851       --log-slave-updates (remember the UID is used to not play a query
852       twice when you have two masters which are slaves of a 3rd master).
853       Then we are done.
854     */
855     return;
856   }
857   /* otherwise, go on with reading the header from buf (nothing now) */
858 }
859 
860 #ifndef MYSQL_CLIENT
861 #ifdef HAVE_REPLICATION
do_apply_event_worker(Slave_worker * w)862 inline int Log_event::do_apply_event_worker(Slave_worker *w)
863 {
864   return do_apply_event(w);
865 }
866 
do_update_pos(Relay_log_info * rli)867 int Log_event::do_update_pos(Relay_log_info *rli)
868 {
869   int error= 0;
870   DBUG_ASSERT(!rli->belongs_to_client());
871   /*
872     rli is null when (as far as I (Guilhem) know) the caller is
873     Load_log_event::do_apply_event *and* that one is called from
874     Execute_load_log_event::do_apply_event.  In this case, we don't
875     do anything here ; Execute_load_log_event::do_apply_event will
876     call Log_event::do_apply_event again later with the proper rli.
877     Strictly speaking, if we were sure that rli is null only in the
878     case discussed above, 'if (rli)' is useless here.  But as we are
879     not 100% sure, keep it for now.
880 
881     Matz: I don't think we will need this check with this refactoring.
882   */
883 
884   DBUG_ASSERT(!is_mts_worker(rli->info_thd));
885 
886   if (rli)
887     error= rli->stmt_done(log_pos);
888   return error;
889 }
890 
891 
892 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)893 Log_event::do_shall_skip(Relay_log_info *rli)
894 {
895   DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
896                       " rli->replicate_same_server_id=%d,"
897                       " rli->slave_skip_counter=%d",
898                       (ulong) server_id, (ulong) ::server_id,
899                       rli->replicate_same_server_id,
900                       rli->slave_skip_counter));
901   if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
902       (rli->slave_skip_counter == 1 && rli->is_in_group()))
903     return EVENT_SKIP_IGNORE;
904   else if (rli->slave_skip_counter > 0)
905     return EVENT_SKIP_COUNT;
906   else
907     return EVENT_SKIP_NOT;
908 }
909 
910 
911 /*
912   Log_event::pack_info()
913 */
914 
pack_info(Protocol * protocol)915 int Log_event::pack_info(Protocol *protocol)
916 {
917   protocol->store("", &my_charset_bin);
918   return 0;
919 }
920 
921 
922 /**
923   Only called by SHOW BINLOG EVENTS
924 */
net_send(Protocol * protocol,const char * log_name,my_off_t pos)925 int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
926 {
927   const char *p= strrchr(log_name, FN_LIBCHAR);
928   const char *event_type;
929   if (p)
930     log_name = p + 1;
931 
932   protocol->prepare_for_resend();
933   protocol->store(log_name, &my_charset_bin);
934   protocol->store((ulonglong) pos);
935   event_type = get_type_str();
936   protocol->store(event_type, strlen(event_type), &my_charset_bin);
937   protocol->store((uint32) server_id);
938   protocol->store((ulonglong) log_pos);
939   if (pack_info(protocol))
940     return 1;
941   return protocol->write();
942 }
943 #endif /* HAVE_REPLICATION */
944 
945 
946 /**
947   init_show_field_list() prepares the column names and types for the
948   output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
949   EVENTS.
950 */
951 
init_show_field_list(List<Item> * field_list)952 void Log_event::init_show_field_list(List<Item>* field_list)
953 {
954   field_list->push_back(new Item_empty_string("Log_name", 20));
955   field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
956 					    MYSQL_TYPE_LONGLONG));
957   field_list->push_back(new Item_empty_string("Event_type", 20));
958   field_list->push_back(new Item_return_int("Server_id", 10,
959 					    MYSQL_TYPE_LONG));
960   field_list->push_back(new Item_return_int("End_log_pos",
961                                             MY_INT32_NUM_DECIMAL_DIGITS,
962 					    MYSQL_TYPE_LONGLONG));
963   field_list->push_back(new Item_empty_string("Info", 20));
964 }
965 
966 /**
967    A decider of whether to trigger checksum computation or not.
968    To be invoked in Log_event::write() stack.
969    The decision is positive
970 
971     S,M) if it's been marked for checksumming with @c checksum_alg
972 
973     M) otherwise, if @@global.binlog_checksum is not NONE and the event is
974        directly written to the binlog file.
975        The to-be-cached event decides at @c write_cache() time.
976 
977    Otherwise the decision is negative.
978 
979    @note   A side effect of the method is altering Log_event::checksum_alg
980            it the latter was undefined at calling.
981 
982    @return true (positive) or false (negative)
983 */
need_checksum()984 my_bool Log_event::need_checksum()
985 {
986   DBUG_ENTER("Log_event::need_checksum");
987   my_bool ret= FALSE;
988   /*
989      few callers of Log_event::write
990      (incl FD::write, FD constructing code on the slave side, Rotate relay log
991      and Stop event)
992      provides their checksum alg preference through Log_event::checksum_alg.
993   */
994   if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
995     ret= (checksum_alg != BINLOG_CHECKSUM_ALG_OFF);
996   else if (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF &&
997            event_cache_type == Log_event::EVENT_NO_CACHE)
998     ret= binlog_checksum_options;
999   else
1000     ret= FALSE;
1001 
1002   /*
1003     FD calls the methods before data_written has been calculated.
1004     The following invariant claims if the current is not the first
1005     call (and therefore data_written is not zero) then `ret' must be
1006     TRUE. It may not be null because FD is always checksummed.
1007   */
1008 
1009   DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
1010               data_written == 0);
1011 
1012   if (checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
1013     checksum_alg= ret ? // calculated value stored
1014       binlog_checksum_options : (uint8) BINLOG_CHECKSUM_ALG_OFF;
1015 
1016   DBUG_ASSERT(!ret ||
1017               ((checksum_alg == binlog_checksum_options ||
1018                /*
1019                   Stop event closes the relay-log and its checksum alg
1020                   preference is set by the caller can be different
1021                   from the server's binlog_checksum_options.
1022                */
1023                get_type_code() == STOP_EVENT ||
1024                /*
1025                   Rotate:s can be checksummed regardless of the server's
1026                   binlog_checksum_options. That applies to both
1027                   the local RL's Rotate and the master's Rotate
1028                   which IO thread instantiates via queue_binlog_ver_3_event.
1029                */
1030                get_type_code() == ROTATE_EVENT ||
1031                /*
1032                   The previous event has its checksum option defined
1033                   according to the format description event.
1034                */
1035                get_type_code() == PREVIOUS_GTIDS_LOG_EVENT ||
1036                /* FD is always checksummed */
1037                get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
1038                checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
1039 
1040   DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
1041   DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
1042                 get_type_code() != STOP_EVENT) ||
1043                 get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
1044               event_cache_type == Log_event::EVENT_NO_CACHE);
1045 
1046   DBUG_RETURN(ret);
1047 }
1048 
wrapper_my_b_safe_write(IO_CACHE * file,const uchar * buf,ulong size)1049 bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong size)
1050 {
1051   DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1052                   {
1053                     file->write_pos = file->write_end;
1054                     DBUG_SET("+d,simulate_file_write_error");
1055                   });
1056   if (need_checksum() && size != 0)
1057     crc= my_checksum(crc, buf, size);
1058   bool ret = my_b_safe_write(file, buf, size);
1059   DBUG_EXECUTE_IF("simulate_temp_file_write_error",
1060                   {
1061                     DBUG_SET("-d,simulate_file_write_error");
1062                   });
1063   return ret;
1064 }
1065 
write_footer(IO_CACHE * file)1066 bool Log_event::write_footer(IO_CACHE* file)
1067 {
1068   /*
1069      footer contains the checksum-algorithm descriptor
1070      followed by the checksum value
1071   */
1072   if (need_checksum())
1073   {
1074     uchar buf[BINLOG_CHECKSUM_LEN];
1075     int4store(buf, crc);
1076     return (my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
1077   }
1078   return 0;
1079 }
1080 
1081 /*
1082   Log_event::write()
1083 */
1084 
write_header(IO_CACHE * file,ulong event_data_length)1085 bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
1086 {
1087   uchar header[LOG_EVENT_HEADER_LEN];
1088   ulong now;
1089   bool ret;
1090   DBUG_ENTER("Log_event::write_header");
1091 
1092   /* Store number of bytes that will be written by this event */
1093   data_written= event_data_length + sizeof(header);
1094 
1095   if (need_checksum())
1096   {
1097     crc= my_checksum(0L, NULL, 0);
1098     data_written += BINLOG_CHECKSUM_LEN;
1099   }
1100 
1101   /*
1102     log_pos != 0 if this is relay-log event. In this case we should not
1103     change the position
1104   */
1105 
1106   if (is_artificial_event())
1107   {
1108     /*
1109       Artificial events are automatically generated and do not exist
1110       in master's binary log, so log_pos should be set to 0.
1111     */
1112     log_pos= 0;
1113   }
1114   else  if (!log_pos)
1115   {
1116     /*
1117       Calculate position of end of event
1118 
1119       Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
1120       work well.  So this will give slightly wrong positions for the
1121       Format_desc/Rotate/Stop events which the slave writes to its
1122       relay log. For example, the initial Format_desc will have
1123       end_log_pos=91 instead of 95. Because after writing the first 4
1124       bytes of the relay log, my_b_tell() still reports 0. Because
1125       my_b_append() does not update the counter which my_b_tell()
1126       later uses (one should probably use my_b_append_tell() to work
1127       around this).  To get right positions even when writing to the
1128       relay log, we use the (new) my_b_safe_tell().
1129 
1130       Note that this raises a question on the correctness of all these
1131       DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
1132 
1133       If in a transaction, the log_pos which we calculate below is not
1134       very good (because then my_b_safe_tell() returns start position
1135       of the BEGIN, so it's like the statement was at the BEGIN's
1136       place), but it's not a very serious problem (as the slave, when
1137       it is in a transaction, does not take those end_log_pos into
1138       account (as it calls inc_event_relay_log_pos()). To be fixed
1139       later, so that it looks less strange. But not bug.
1140     */
1141 
1142     log_pos= my_b_safe_tell(file)+data_written;
1143   }
1144 
1145   now= (ulong) get_time();                              // Query start time
1146   if (DBUG_EVALUATE_IF("inc_event_time_by_1_hour",1,0)  &&
1147       DBUG_EVALUATE_IF("dec_event_time_by_1_hour",1,0))
1148   {
1149     /**
1150        This assertion guarantees that these debug flags are not
1151        used at the same time (they would cancel each other).
1152     */
1153     DBUG_ASSERT(0);
1154   }
1155   else
1156   {
1157     DBUG_EXECUTE_IF("inc_event_time_by_1_hour", now= now + 3600;);
1158     DBUG_EXECUTE_IF("dec_event_time_by_1_hour", now= now - 3600;);
1159   }
1160 
1161   /*
1162     Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1163     FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1164     LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1165     because we read them before knowing the format).
1166   */
1167 
1168   int4store(header, now);              // timestamp
1169   header[EVENT_TYPE_OFFSET]= get_type_code();
1170   int4store(header+ SERVER_ID_OFFSET, server_id);
1171   int4store(header+ EVENT_LEN_OFFSET, data_written);
1172   int4store(header+ LOG_POS_OFFSET, log_pos);
1173   /*
1174     recording checksum of FD event computed with dropped
1175     possibly active LOG_EVENT_BINLOG_IN_USE_F flag.
1176     Similar step at verication: the active flag is dropped before
1177     checksum computing.
1178   */
1179   if (header[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT ||
1180       !need_checksum() || !(flags & LOG_EVENT_BINLOG_IN_USE_F))
1181   {
1182     int2store(header+ FLAGS_OFFSET, flags);
1183     ret= wrapper_my_b_safe_write(file, header, sizeof(header)) != 0;
1184   }
1185   else
1186   {
1187     ret= (wrapper_my_b_safe_write(file, header, FLAGS_OFFSET) != 0);
1188     if (!ret)
1189     {
1190       flags &= ~LOG_EVENT_BINLOG_IN_USE_F;
1191       int2store(header + FLAGS_OFFSET, flags);
1192       crc= my_checksum(crc, header + FLAGS_OFFSET, sizeof(flags));
1193       flags |= LOG_EVENT_BINLOG_IN_USE_F;
1194       int2store(header + FLAGS_OFFSET, flags);
1195       ret= (my_b_safe_write(file, header + FLAGS_OFFSET, sizeof(flags)) != 0);
1196     }
1197     if (!ret)
1198       ret= (wrapper_my_b_safe_write(file, header + FLAGS_OFFSET + sizeof(flags),
1199                                     sizeof(header)
1200                                     - (FLAGS_OFFSET + sizeof(flags))) != 0);
1201   }
1202   DBUG_RETURN( ret);
1203 }
1204 
1205 
1206 /**
1207   This needn't be format-tolerant, because we only read
1208   LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
1209 */
1210 
read_log_event(IO_CACHE * file,String * packet,mysql_mutex_t * log_lock,uint8 checksum_alg_arg,const char * log_file_name_arg,bool * is_binlog_active)1211 int Log_event::read_log_event(IO_CACHE* file, String* packet,
1212                               mysql_mutex_t* log_lock,
1213                               uint8 checksum_alg_arg,
1214                               const char *log_file_name_arg,
1215                               bool* is_binlog_active)
1216 {
1217   ulong data_len;
1218   int result=0;
1219   char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1220   uchar ev_offset= packet->length();
1221   DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, String *, mysql_mutex_t, uint8)");
1222 
1223   if (log_lock)
1224     mysql_mutex_lock(log_lock);
1225 
1226   if (log_file_name_arg)
1227     *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
1228 
1229   if (my_b_read(file, (uchar*) buf, sizeof(buf)))
1230   {
1231     /*
1232       If the read hits eof, we must report it as eof so the caller
1233       will know it can go into cond_wait to be woken up on the next
1234       update to the log.
1235     */
1236     DBUG_PRINT("error",("my_b_read failed. file->error: %d", file->error));
1237     if (!file->error)
1238       result= LOG_READ_EOF;
1239     else
1240       result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1241     goto end;
1242   }
1243   data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1244   if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
1245       data_len > max(current_thd->variables.max_allowed_packet,
1246                      opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
1247   {
1248     DBUG_PRINT("error",("data_len is out of bounds. data_len: %lu", data_len));
1249     result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
1250 	     LOG_READ_TOO_LARGE);
1251     goto end;
1252   }
1253 
1254   /* Append the log event header to packet */
1255   if (packet->append(buf, sizeof(buf)))
1256   {
1257     DBUG_PRINT("info", ("first packet->append failed (out of memory)"));
1258     /* Failed to allocate packet */
1259     result= LOG_READ_MEM;
1260     goto end;
1261   }
1262   data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
1263   if (data_len)
1264   {
1265     /* Append rest of event, read directly from file into packet */
1266     if (packet->append(file, data_len))
1267     {
1268       /*
1269         Fatal error occured when appending rest of the event
1270         to packet, possible failures:
1271 	1. EOF occured when reading from file, it's really an error
1272            as data_len is >=0 there's supposed to be more bytes available.
1273            file->error will have been set to number of bytes left to read
1274         2. Read was interrupted, file->error would normally be set to -1
1275         3. Failed to allocate memory for packet, my_errno
1276            will be ENOMEM(file->error shuold be 0, but since the
1277            memory allocation occurs before the call to read it might
1278            be uninitialized)
1279       */
1280       DBUG_PRINT("info", ("second packet->append failed (out of memory)"));
1281       result= (my_errno == ENOMEM ? LOG_READ_MEM :
1282                (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1283       goto end;
1284     }
1285     else
1286     {
1287       /*
1288         Corrupt the event for Dump thread.
1289         We also need to exclude Previous_gtids_log_event and Gtid_log_event
1290         events from injected corruption to allow dump thread to move forward
1291         on binary log until the missing transactions from slave when
1292         MASTER_AUTO_POSITION= 1.
1293       */
1294       DBUG_EXECUTE_IF("corrupt_read_log_event",
1295 	uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
1296         if (debug_event_buf_c[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT &&
1297             debug_event_buf_c[EVENT_TYPE_OFFSET] != PREVIOUS_GTIDS_LOG_EVENT &&
1298             debug_event_buf_c[EVENT_TYPE_OFFSET] != GTID_LOG_EVENT)
1299         {
1300           int debug_cor_pos = rand() % (data_len + sizeof(buf) - BINLOG_CHECKSUM_LEN);
1301           debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1302           DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
1303 	}
1304       );
1305       /*
1306         CRC verification of the Dump thread
1307       */
1308       if (opt_master_verify_checksum &&
1309           event_checksum_test((uchar*) packet->ptr() + ev_offset,
1310                               data_len + sizeof(buf),
1311                               checksum_alg_arg))
1312       {
1313         DBUG_PRINT("info", ("checksum test failed"));
1314         result= LOG_READ_CHECKSUM_FAILURE;
1315         goto end;
1316       }
1317     }
1318   }
1319 
1320 end:
1321   if (log_lock)
1322     mysql_mutex_unlock(log_lock);
1323   DBUG_PRINT("info", ("read_log_event returns %d", result));
1324   DBUG_RETURN(result);
1325 }
1326 #endif /* !MYSQL_CLIENT */
1327 
1328 #ifndef MYSQL_CLIENT
1329 #define UNLOCK_MUTEX if (log_lock) mysql_mutex_unlock(log_lock);
1330 #define LOCK_MUTEX if (log_lock) mysql_mutex_lock(log_lock);
1331 #else
1332 #define UNLOCK_MUTEX
1333 #define LOCK_MUTEX
1334 #endif
1335 
1336 #ifndef MYSQL_CLIENT
1337 /**
1338   @note
1339     Allocates memory;  The caller is responsible for clean-up.
1340 */
read_log_event(IO_CACHE * file,mysql_mutex_t * log_lock,const Format_description_log_event * description_event,my_bool crc_check)1341 Log_event* Log_event::read_log_event(IO_CACHE* file,
1342                                      mysql_mutex_t* log_lock,
1343                                      const Format_description_log_event
1344                                      *description_event,
1345                                      my_bool crc_check)
1346 #else
1347 Log_event* Log_event::read_log_event(IO_CACHE* file,
1348                                      const Format_description_log_event
1349                                      *description_event,
1350                                      my_bool crc_check)
1351 #endif
1352 {
1353   DBUG_ENTER("Log_event::read_log_event(IO_CACHE *[, mysql_mutex_t *], Format_description_log_event *, my_bool)");
1354   DBUG_ASSERT(description_event != 0);
1355   char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1356   /*
1357     First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1358     check the event for sanity and to know its length; no need to really parse
1359     it. We say "at most" because this could be a 3.23 master, which has header
1360     of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
1361     "minimal" over the set {MySQL >=4.0}).
1362   */
1363   uint header_size= min<uint>(description_event->common_header_len,
1364                               LOG_EVENT_MINIMAL_HEADER_LEN);
1365 
1366   LOCK_MUTEX;
1367   DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
1368   if (my_b_read(file, (uchar *) head, header_size))
1369   {
1370     DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) "
1371                         "failed in my_b_read((IO_CACHE*)%p, (uchar*)%p, %u)",
1372                         file, head, header_size));
1373     UNLOCK_MUTEX;
1374     /*
1375       No error here; it could be that we are at the file's end. However
1376       if the next my_b_read() fails (below), it will be an error as we
1377       were able to read the first bytes.
1378     */
1379     DBUG_RETURN(0);
1380   }
1381   ulong data_len = uint4korr(head + EVENT_LEN_OFFSET);
1382   char *buf= 0;
1383   const char *error= 0;
1384   Log_event *res=  0;
1385 #ifndef max_allowed_packet
1386   THD *thd=current_thd;
1387   ulong max_allowed_packet= thd ? slave_max_allowed_packet : ~(ulong)0;
1388 #endif
1389 
1390   ulong const max_size=
1391     max<ulong>(max_allowed_packet,
1392                opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER);
1393   if (data_len > max_size)
1394   {
1395     error = "Event too big";
1396     goto err;
1397   }
1398 
1399   if (data_len < header_size)
1400   {
1401     error = "Event too small";
1402     goto err;
1403   }
1404 
1405   // some events use the extra byte to null-terminate strings
1406   if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
1407   {
1408     error = "Out of memory";
1409     goto err;
1410   }
1411   buf[data_len] = 0;
1412   memcpy(buf, head, header_size);
1413   if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1414   {
1415     error = "read error";
1416     goto err;
1417   }
1418   if ((res= read_log_event(buf, data_len, &error, description_event, crc_check)))
1419     res->register_temp_buf(buf);
1420 
1421 err:
1422   UNLOCK_MUTEX;
1423   if (!res)
1424   {
1425     DBUG_ASSERT(error != 0);
1426     /* Don't log error if read_log_event invoked from SHOW BINLOG EVENTS */
1427 #ifdef MYSQL_SERVER
1428     THD *thd= current_thd;
1429     if (!(thd && thd->lex &&
1430           thd->lex->sql_command == SQLCOM_SHOW_BINLOG_EVENTS)) {
1431 #endif
1432       sql_print_error("Error in Log_event::read_log_event(): "
1433                       "'%s', data_len: %lu, event_type: %d",
1434 		      error,data_len,head[EVENT_TYPE_OFFSET]);
1435 #ifdef MYSQL_SERVER
1436     }
1437 #endif
1438     my_free(buf);
1439     /*
1440       The SQL slave thread will check if file->error<0 to know
1441       if there was an I/O error. Even if there is no "low-level" I/O errors
1442       with 'file', any of the high-level above errors is worrying
1443       enough to stop the SQL thread now ; as we are skipping the current event,
1444       going on with reading and successfully executing other events can
1445       only corrupt the slave's databases. So stop.
1446       The file->error is also checked to record the position of
1447       the last valid event when master server recovers.
1448     */
1449     file->error= -1;
1450   }
1451   DBUG_RETURN(res);
1452 }
1453 
1454 
1455 /**
1456   Binlog format tolerance is in (buf, event_len, description_event)
1457   constructors.
1458 */
1459 
read_log_event(const char * buf,uint event_len,const char ** error,const Format_description_log_event * description_event,my_bool crc_check)1460 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1461 				     const char **error,
1462                                      const Format_description_log_event *description_event,
1463                                      my_bool crc_check)
1464 {
1465   Log_event* ev;
1466   uint8 alg;
1467   DBUG_ENTER("Log_event::read_log_event(char *, uint, char **, Format_description_log_event *, my_bool)");
1468   DBUG_ASSERT(description_event != 0);
1469   DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1470   DBUG_DUMP("data", (unsigned char*) buf, event_len);
1471 
1472   /* Check the integrity */
1473   if (event_len < EVENT_LEN_OFFSET ||
1474       (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1475   {
1476     DBUG_PRINT("error", ("event_len=%u EVENT_LEN_OFFSET=%d "
1477                          "buf[EVENT_TYPE_OFFSET]=%d ENUM_END_EVENT=%d "
1478                          "uint4korr(buf+EVENT_LEN_OFFSET)=%d",
1479                          event_len, EVENT_LEN_OFFSET,
1480                          buf[EVENT_TYPE_OFFSET], ENUM_END_EVENT,
1481                          uint4korr(buf+EVENT_LEN_OFFSET)));
1482     *error="Sanity check failed";		// Needed to free buffer
1483     DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1484   }
1485 
1486   uint event_type= buf[EVENT_TYPE_OFFSET];
1487   // all following START events in the current file are without checksum
1488   if (event_type == START_EVENT_V3)
1489     (const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
1490   // Sanity check for Format description event
1491   if (event_type == FORMAT_DESCRIPTION_EVENT)
1492   {
1493     if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN +
1494         ST_COMMON_HEADER_LEN_OFFSET)
1495     {
1496       *error= "Found invalid Format description event in binary log";
1497       DBUG_RETURN(0);
1498     }
1499     uint tmp_header_len= buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET];
1500     if (event_len < tmp_header_len + ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
1501     {
1502       *error= "Found invalid Format description event in binary log";
1503       DBUG_RETURN(0);
1504     }
1505   }
1506   /*
1507     CRC verification by SQL and Show-Binlog-Events master side.
1508     The caller has to provide @description_event->checksum_alg to
1509     be the last seen FD's (A) descriptor.
1510     If event is FD the descriptor is in it.
1511     Notice, FD of the binlog can be only in one instance and therefore
1512     Show-Binlog-Events executing master side thread needs just to know
1513     the only FD's (A) value -  whereas RL can contain more.
1514     In the RL case, the alg is kept in FD_e (@description_event) which is reset
1515     to the newer read-out event after its execution with possibly new alg descriptor.
1516     Therefore in a typical sequence of RL:
1517     {FD_s^0, FD_m, E_m^1} E_m^1
1518     will be verified with (A) of FD_m.
1519 
1520     See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
1521     lines (log.h).
1522 
1523     Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
1524   */
1525   alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
1526     description_event->checksum_alg : get_checksum_alg(buf, event_len);
1527   // Emulate the corruption during reading an event
1528   DBUG_EXECUTE_IF("corrupt_read_log_event_char",
1529     if (event_type != FORMAT_DESCRIPTION_EVENT)
1530     {
1531       char *debug_event_buf_c = (char *)buf;
1532       int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
1533       debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1534       DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
1535       DBUG_SET("");
1536     }
1537   );
1538   if (crc_check &&
1539       event_checksum_test((uchar *) buf, event_len, alg) &&
1540       /* Skip the crc check when simulating an unknown ignorable log event. */
1541       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1542   {
1543     *error= "Event crc check failed! Most likely there is event corruption.";
1544 #ifdef MYSQL_CLIENT
1545     if (force_opt)
1546     {
1547       ev= new Unknown_log_event(buf, description_event);
1548       DBUG_RETURN(ev);
1549     }
1550 #endif
1551     DBUG_RETURN(NULL);
1552   }
1553 
1554   if (event_type > description_event->number_of_event_types &&
1555       event_type != FORMAT_DESCRIPTION_EVENT &&
1556       /*
1557         Skip the event type check when simulating an
1558         unknown ignorable log event.
1559       */
1560       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1561   {
1562     /*
1563       It is unsafe to use the description_event if its post_header_len
1564       array does not include the event type.
1565     */
1566     DBUG_PRINT("error", ("event type %d found, but the current "
1567                          "Format_description_log_event supports only %d event "
1568                          "types", event_type,
1569                          description_event->number_of_event_types));
1570     ev= NULL;
1571   }
1572   else
1573   {
1574     /*
1575       In some previuos versions (see comment in
1576       Format_description_log_event::Format_description_log_event(char*,...)),
1577       event types were assigned different id numbers than in the
1578       present version. In order to replicate from such versions to the
1579       present version, we must map those event type id's to our event
1580       type id's.  The mapping is done with the event_type_permutation
1581       array, which was set up when the Format_description_log_event
1582       was read.
1583     */
1584     if (description_event->event_type_permutation)
1585     {
1586       uint new_event_type;
1587       if (event_type >= EVENT_TYPE_PERMUTATION_NUM)
1588         /* Safe guard for read out of bounds of event_type_permutation. */
1589         new_event_type= UNKNOWN_EVENT;
1590       else
1591         new_event_type= description_event->event_type_permutation[event_type];
1592 
1593       DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1594                  event_type, new_event_type,
1595                  get_type_str((Log_event_type)new_event_type)));
1596       event_type= new_event_type;
1597     }
1598 
1599     if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
1600         (event_type == FORMAT_DESCRIPTION_EVENT ||
1601          alg != BINLOG_CHECKSUM_ALG_OFF))
1602       event_len= event_len - BINLOG_CHECKSUM_LEN;
1603 
1604     switch(event_type) {
1605     case QUERY_EVENT:
1606       ev  = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1607       break;
1608     case LOAD_EVENT:
1609       ev = new Load_log_event(buf, event_len, description_event);
1610       break;
1611     case NEW_LOAD_EVENT:
1612       ev = new Load_log_event(buf, event_len, description_event);
1613       break;
1614     case ROTATE_EVENT:
1615       ev = new Rotate_log_event(buf, event_len, description_event);
1616       break;
1617     case CREATE_FILE_EVENT:
1618       ev = new Create_file_log_event(buf, event_len, description_event);
1619       break;
1620     case APPEND_BLOCK_EVENT:
1621       ev = new Append_block_log_event(buf, event_len, description_event);
1622       break;
1623     case DELETE_FILE_EVENT:
1624       ev = new Delete_file_log_event(buf, event_len, description_event);
1625       break;
1626     case EXEC_LOAD_EVENT:
1627       ev = new Execute_load_log_event(buf, event_len, description_event);
1628       break;
1629     case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1630       ev = new Start_log_event_v3(buf, event_len, description_event);
1631       break;
1632     case STOP_EVENT:
1633       ev = new Stop_log_event(buf, description_event);
1634       break;
1635     case INTVAR_EVENT:
1636       ev = new Intvar_log_event(buf, description_event);
1637       break;
1638     case XID_EVENT:
1639       ev = new Xid_log_event(buf, description_event);
1640       break;
1641     case RAND_EVENT:
1642       ev = new Rand_log_event(buf, description_event);
1643       break;
1644     case USER_VAR_EVENT:
1645       ev = new User_var_log_event(buf, event_len, description_event);
1646       break;
1647     case FORMAT_DESCRIPTION_EVENT:
1648       ev = new Format_description_log_event(buf, event_len, description_event);
1649       break;
1650 #if defined(HAVE_REPLICATION)
1651     case PRE_GA_WRITE_ROWS_EVENT:
1652       ev = new Write_rows_log_event_old(buf, event_len, description_event);
1653       break;
1654     case PRE_GA_UPDATE_ROWS_EVENT:
1655       ev = new Update_rows_log_event_old(buf, event_len, description_event);
1656       break;
1657     case PRE_GA_DELETE_ROWS_EVENT:
1658       ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1659       break;
1660     case WRITE_ROWS_EVENT_V1:
1661       ev = new Write_rows_log_event(buf, event_len, description_event);
1662       break;
1663     case UPDATE_ROWS_EVENT_V1:
1664       ev = new Update_rows_log_event(buf, event_len, description_event);
1665       break;
1666     case DELETE_ROWS_EVENT_V1:
1667       ev = new Delete_rows_log_event(buf, event_len, description_event);
1668       break;
1669     case TABLE_MAP_EVENT:
1670       ev = new Table_map_log_event(buf, event_len, description_event);
1671       break;
1672 #endif
1673     case BEGIN_LOAD_QUERY_EVENT:
1674       ev = new Begin_load_query_log_event(buf, event_len, description_event);
1675       break;
1676     case EXECUTE_LOAD_QUERY_EVENT:
1677       ev= new Execute_load_query_log_event(buf, event_len, description_event);
1678       break;
1679     case INCIDENT_EVENT:
1680       ev = new Incident_log_event(buf, event_len, description_event);
1681       break;
1682     case ROWS_QUERY_LOG_EVENT:
1683       ev= new Rows_query_log_event(buf, event_len, description_event);
1684       break;
1685     case GTID_LOG_EVENT:
1686     case ANONYMOUS_GTID_LOG_EVENT:
1687       ev= new Gtid_log_event(buf, event_len, description_event);
1688       break;
1689     case PREVIOUS_GTIDS_LOG_EVENT:
1690       ev= new Previous_gtids_log_event(buf, event_len, description_event);
1691       break;
1692 #if defined(HAVE_REPLICATION)
1693     case WRITE_ROWS_EVENT:
1694       ev = new Write_rows_log_event(buf, event_len, description_event);
1695       break;
1696     case UPDATE_ROWS_EVENT:
1697       ev = new Update_rows_log_event(buf, event_len, description_event);
1698       break;
1699     case DELETE_ROWS_EVENT:
1700       ev = new Delete_rows_log_event(buf, event_len, description_event);
1701       break;
1702 #endif
1703     default:
1704       /*
1705         Create an object of Ignorable_log_event for unrecognized sub-class.
1706         So that SLAVE SQL THREAD will only update the position and continue.
1707       */
1708       if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1709       {
1710         ev= new Ignorable_log_event(buf, description_event);
1711       }
1712       else
1713       {
1714         DBUG_PRINT("error",("Unknown event code: %d",
1715                             (int) buf[EVENT_TYPE_OFFSET]));
1716         ev= NULL;
1717       }
1718       break;
1719     }
1720   }
1721 
1722   if (ev)
1723   {
1724     ev->checksum_alg= alg;
1725     if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1726         ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1727       ev->crc= uint4korr(buf + (event_len));
1728   }
1729 
1730   DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1731                             ev ? ev->get_type_str() : "<unknown>",
1732                             buf[EVENT_TYPE_OFFSET],
1733                             event_len));
1734   /*
1735     is_valid() are small event-specific sanity tests which are
1736     important; for example there are some my_malloc() in constructors
1737     (e.g. Query_log_event::Query_log_event(char*...)); when these
1738     my_malloc() fail we can't return an error out of the constructor
1739     (because constructor is "void") ; so instead we leave the pointer we
1740     wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1741     Same for Format_description_log_event, member 'post_header_len'.
1742 
1743     SLAVE_EVENT is never used, so it should not be read ever.
1744   */
1745   if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
1746   {
1747     DBUG_PRINT("error",("Found invalid event in binary log"));
1748 
1749     delete ev;
1750 #ifdef MYSQL_CLIENT
1751     if (!force_opt) /* then mysqlbinlog dies */
1752     {
1753       *error= "Found invalid event in binary log";
1754       DBUG_RETURN(0);
1755     }
1756     ev= new Unknown_log_event(buf, description_event);
1757 #else
1758     *error= "Found invalid event in binary log";
1759     DBUG_RETURN(0);
1760 #endif
1761   }
1762   DBUG_RETURN(ev);
1763 }
1764 
1765 #ifdef MYSQL_CLIENT
1766 
1767 /*
1768   Log_event::print_header()
1769 */
1770 
print_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool is_more MY_ATTRIBUTE ((unused)))1771 void Log_event::print_header(IO_CACHE* file,
1772                              PRINT_EVENT_INFO* print_event_info,
1773                              bool is_more MY_ATTRIBUTE((unused)))
1774 {
1775   char llbuff[22];
1776   my_off_t hexdump_from= print_event_info->hexdump_from;
1777   DBUG_ENTER("Log_event::print_header");
1778 
1779   my_b_printf(file, "#");
1780   print_timestamp(file, NULL);
1781   my_b_printf(file, " server id %lu  end_log_pos %s ", (ulong) server_id,
1782               llstr(log_pos,llbuff));
1783 
1784   /* print the checksum */
1785 
1786   if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1787       checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1788   {
1789     char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
1790     size_t const bytes_written=
1791       my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
1792     my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
1793     my_b_printf(file, checksum_buf, bytes_written);
1794   }
1795 
1796   /* mysqlbinlog --hexdump */
1797   if (print_event_info->hexdump_from)
1798   {
1799     my_b_printf(file, "\n");
1800     uchar *ptr= (uchar*)temp_buf;
1801     my_off_t size=
1802       uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1803     my_off_t i;
1804 
1805     /* Header len * 4 >= header len * (2 chars + space + extra space) */
1806     char *h, hex_string[49]= {0};
1807     char *c, char_string[16+1]= {0};
1808 
1809     /* Pretty-print event common header if header is exactly 19 bytes */
1810     if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1811     {
1812       char emit_buf[256];               // Enough for storing one line
1813       my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
1814                   "Size      Master Pos    Flags \n");
1815       size_t const bytes_written=
1816         my_snprintf(emit_buf, sizeof(emit_buf),
1817                     "# %8.8lx %02x %02x %02x %02x   %02x   "
1818                     "%02x %02x %02x %02x   %02x %02x %02x %02x   "
1819                     "%02x %02x %02x %02x   %02x %02x\n",
1820                     (unsigned long) hexdump_from,
1821                     ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1822                     ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1823                     ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1824       DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1825       my_b_write(file, (uchar*) emit_buf, bytes_written);
1826       ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1827       hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1828     }
1829 
1830     /* Rest of event (without common header) */
1831     for (i= 0, c= char_string, h=hex_string;
1832 	 i < size;
1833 	 i++, ptr++)
1834     {
1835       my_snprintf(h, 4, (i % 16 <= 7) ? "%02x " : " %02x", *ptr);
1836       h += 3;
1837 
1838       *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1839 
1840       if (i % 16 == 15)
1841       {
1842         /*
1843           my_b_printf() does not support full printf() formats, so we
1844           have to do it this way.
1845 
1846           TODO: Rewrite my_b_printf() to support full printf() syntax.
1847          */
1848         char emit_buf[256];
1849         size_t const bytes_written=
1850           my_snprintf(emit_buf, sizeof(emit_buf),
1851                       "# %8.8lx %-48.48s |%16s|\n",
1852                       (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1853                       hex_string, char_string);
1854         DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1855 	my_b_write(file, (uchar*) emit_buf, bytes_written);
1856 	hex_string[0]= 0;
1857 	char_string[0]= 0;
1858 	c= char_string;
1859 	h= hex_string;
1860       }
1861     }
1862     *c= '\0';
1863     DBUG_ASSERT(hex_string[48] == 0);
1864 
1865     if (hex_string[0])
1866     {
1867       char emit_buf[256];
1868       // Right-pad hex_string with spaces, up to 48 characters.
1869       memset(h, ' ', (sizeof(hex_string) -1) - (h - hex_string));
1870       size_t const bytes_written=
1871         my_snprintf(emit_buf, sizeof(emit_buf),
1872                     "# %8.8lx %-48.48s |%s|\n",
1873                     (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1874                     hex_string, char_string);
1875       DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1876       my_b_write(file, (uchar*) emit_buf, bytes_written);
1877     }
1878     /*
1879       need a # to prefix the rest of printouts for example those of
1880       Rows_log_event::print_helper().
1881     */
1882     my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1883   }
1884   DBUG_VOID_RETURN;
1885 }
1886 
1887 
1888 /**
1889   Prints a quoted string to io cache.
1890   Control characters are displayed as hex sequence, e.g. \x00
1891 
1892   @param[in] file              IO cache
1893   @param[in] prt               Pointer to string
1894   @param[in] length            String length
1895 */
1896 
1897 static void
my_b_write_quoted(IO_CACHE * file,const uchar * ptr,uint length)1898 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
1899 {
1900   const uchar *s;
1901   my_b_printf(file, "'");
1902   for (s= ptr; length > 0 ; s++, length--)
1903   {
1904     if (*s > 0x1F && *s != '\'' && *s != '\\')
1905       my_b_write(file, s, 1);
1906     else
1907     {
1908       uchar hex[10];
1909       size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
1910       my_b_write(file, hex, len);
1911     }
1912   }
1913   my_b_printf(file, "'");
1914 }
1915 
1916 /**
1917   Prints a bit string to io cache in format  b'1010'.
1918 
1919   @param[in] file              IO cache
1920   @param[in] ptr               Pointer to string
1921   @param[in] nbits             Number of bits
1922 */
1923 static void
my_b_write_bit(IO_CACHE * file,const uchar * ptr,uint nbits)1924 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
1925 {
1926   uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
1927   my_b_printf(file, "b'");
1928   for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
1929   {
1930     int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8))  & 0x01;
1931     my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
1932   }
1933   my_b_printf(file, "'");
1934 }
1935 
1936 
1937 /**
1938   Prints a packed string to io cache.
1939   The string consists of length packed to 1 or 2 bytes,
1940   followed by string data itself.
1941 
1942   @param[in] file              IO cache
1943   @param[in] ptr               Pointer to string
1944   @param[in] length            String size
1945 
1946   @retval   - number of bytes scanned.
1947 */
1948 static size_t
my_b_write_quoted_with_length(IO_CACHE * file,const uchar * ptr,uint length)1949 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
1950 {
1951   if (length < 256)
1952   {
1953     length= *ptr;
1954     my_b_write_quoted(file, ptr + 1, length);
1955     return length + 1;
1956   }
1957   else
1958   {
1959     length= uint2korr(ptr);
1960     my_b_write_quoted(file, ptr + 2, length);
1961     return length + 2;
1962   }
1963 }
1964 
1965 
1966 /**
1967   Prints a 32-bit number in both signed and unsigned representation
1968 
1969   @param[in] file              IO cache
1970   @param[in] sl                Signed number
1971   @param[in] ul                Unsigned number
1972 */
1973 static void
my_b_write_sint32_and_uint32(IO_CACHE * file,int32 si,uint32 ui)1974 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
1975 {
1976   my_b_printf(file, "%d", si);
1977   if (si < 0)
1978     my_b_printf(file, " (%u)", ui);
1979 }
1980 
1981 
1982 /**
1983   Print a packed value of the given SQL type into IO cache
1984 
1985   @param[in] file              IO cache
1986   @param[in] ptr               Pointer to string
1987   @param[in] type              Column type
1988   @param[in] meta              Column meta information
1989   @param[out] typestr          SQL type string buffer (for verbose output)
1990   @param[out] typestr_length   Size of typestr
1991 
1992   @retval   - number of bytes scanned from ptr.
1993 */
1994 static size_t
log_event_print_value(IO_CACHE * file,const uchar * ptr,uint type,uint meta,char * typestr,size_t typestr_length)1995 log_event_print_value(IO_CACHE *file, const uchar *ptr,
1996                       uint type, uint meta,
1997                       char *typestr, size_t typestr_length)
1998 {
1999   uint32 length= 0;
2000 
2001   if (type == MYSQL_TYPE_STRING)
2002   {
2003     if (meta >= 256)
2004     {
2005       uint byte0= meta >> 8;
2006       uint byte1= meta & 0xFF;
2007 
2008       if ((byte0 & 0x30) != 0x30)
2009       {
2010         /* a long CHAR() field: see #37426 */
2011         length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
2012         type= byte0 | 0x30;
2013       }
2014       else
2015         length = meta & 0xFF;
2016     }
2017     else
2018       length= meta;
2019   }
2020 
2021   switch (type) {
2022   case MYSQL_TYPE_LONG:
2023     {
2024       int32 si= sint4korr(ptr);
2025       uint32 ui= uint4korr(ptr);
2026       my_b_write_sint32_and_uint32(file, si, ui);
2027       my_snprintf(typestr, typestr_length, "INT");
2028       return 4;
2029     }
2030 
2031   case MYSQL_TYPE_TINY:
2032     {
2033       my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
2034                                   (uint) (unsigned char) *ptr);
2035       my_snprintf(typestr, typestr_length, "TINYINT");
2036       return 1;
2037     }
2038 
2039   case MYSQL_TYPE_SHORT:
2040     {
2041       int32 si= (int32) sint2korr(ptr);
2042       uint32 ui= (uint32) uint2korr(ptr);
2043       my_b_write_sint32_and_uint32(file, si, ui);
2044       my_snprintf(typestr, typestr_length, "SHORTINT");
2045       return 2;
2046     }
2047 
2048   case MYSQL_TYPE_INT24:
2049     {
2050       int32 si= sint3korr(ptr);
2051       uint32 ui= uint3korr(ptr);
2052       my_b_write_sint32_and_uint32(file, si, ui);
2053       my_snprintf(typestr, typestr_length, "MEDIUMINT");
2054       return 3;
2055     }
2056 
2057   case MYSQL_TYPE_LONGLONG:
2058     {
2059       char tmp[64];
2060       longlong si= sint8korr(ptr);
2061       longlong10_to_str(si, tmp, -10);
2062       my_b_printf(file, "%s", tmp);
2063       if (si < 0)
2064       {
2065         ulonglong ui= uint8korr(ptr);
2066         longlong10_to_str((longlong) ui, tmp, 10);
2067         my_b_printf(file, " (%s)", tmp);
2068       }
2069       my_snprintf(typestr, typestr_length, "LONGINT");
2070       return 8;
2071     }
2072 
2073   case MYSQL_TYPE_NEWDECIMAL:
2074     {
2075       uint precision= meta >> 8;
2076       uint decimals= meta & 0xFF;
2077       uint bin_size= my_decimal_get_binary_size(precision, decimals);
2078       my_decimal dec;
2079       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2080                         precision, decimals);
2081       int len= DECIMAL_MAX_STR_LENGTH;
2082       char buff[DECIMAL_MAX_STR_LENGTH + 1];
2083       decimal2string(&dec,buff,&len, 0, 0, 0);
2084       my_b_printf(file, "%s", buff);
2085       my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2086                   precision, decimals);
2087       return bin_size;
2088     }
2089 
2090   case MYSQL_TYPE_FLOAT:
2091     {
2092       float fl;
2093       float4get(fl, ptr);
2094       char tmp[320];
2095       sprintf(tmp, "%-20g", (double) fl);
2096       my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2097       my_snprintf(typestr, typestr_length, "FLOAT");
2098       return 4;
2099     }
2100 
2101   case MYSQL_TYPE_DOUBLE:
2102     {
2103       double dbl;
2104       float8get(dbl, ptr);
2105       char tmp[320];
2106       sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
2107       my_b_printf(file, "%s", tmp);
2108       strcpy(typestr, "DOUBLE");
2109       return 8;
2110     }
2111 
2112   case MYSQL_TYPE_BIT:
2113     {
2114       /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2115       uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2116       length= (nbits + 7) / 8;
2117       my_b_write_bit(file, ptr, nbits);
2118       my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2119       return length;
2120     }
2121 
2122   case MYSQL_TYPE_TIMESTAMP:
2123     {
2124       uint32 i32= uint4korr(ptr);
2125       my_b_printf(file, "%d", i32);
2126       my_snprintf(typestr, typestr_length, "TIMESTAMP");
2127       return 4;
2128     }
2129 
2130   case MYSQL_TYPE_TIMESTAMP2:
2131     {
2132       char buf[MAX_DATE_STRING_REP_LENGTH];
2133       struct timeval tm;
2134       my_timestamp_from_binary(&tm, ptr, meta);
2135       int buflen= my_timeval_to_str(&tm, buf, meta);
2136       my_b_write(file, buf, buflen);
2137       my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2138       return my_timestamp_binary_length(meta);
2139     }
2140 
2141   case MYSQL_TYPE_DATETIME:
2142     {
2143       size_t d, t;
2144       uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2145       d= i64 / 1000000;
2146       t= i64 % 1000000;
2147       my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
2148                   static_cast<int>(d / 10000),
2149                   static_cast<int>(d % 10000) / 100,
2150                   static_cast<int>(d % 100),
2151                   static_cast<int>(t / 10000),
2152                   static_cast<int>(t % 10000) / 100,
2153                   static_cast<int>(t % 100));
2154       my_snprintf(typestr, typestr_length, "DATETIME");
2155       return 8;
2156     }
2157 
2158   case MYSQL_TYPE_DATETIME2:
2159     {
2160       char buf[MAX_DATE_STRING_REP_LENGTH];
2161       MYSQL_TIME ltime;
2162       longlong packed= my_datetime_packed_from_binary(ptr, meta);
2163       TIME_from_longlong_datetime_packed(&ltime, packed);
2164       int buflen= my_datetime_to_str(&ltime, buf, meta);
2165       my_b_write_quoted(file, (uchar *) buf, buflen);
2166       my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2167       return my_datetime_binary_length(meta);
2168     }
2169 
2170   case MYSQL_TYPE_TIME:
2171     {
2172       uint32 i32= uint3korr(ptr);
2173       my_b_printf(file, "'%02d:%02d:%02d'",
2174                   i32 / 10000, (i32 % 10000) / 100, i32 % 100);
2175       my_snprintf(typestr, typestr_length, "TIME");
2176       return 3;
2177     }
2178 
2179   case MYSQL_TYPE_TIME2:
2180     {
2181       char buf[MAX_DATE_STRING_REP_LENGTH];
2182       MYSQL_TIME ltime;
2183       longlong packed= my_time_packed_from_binary(ptr, meta);
2184       TIME_from_longlong_time_packed(&ltime, packed);
2185       int buflen= my_time_to_str(&ltime, buf, meta);
2186       my_b_write_quoted(file, (uchar *) buf, buflen);
2187       my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2188       return my_time_binary_length(meta);
2189     }
2190 
2191   case MYSQL_TYPE_NEWDATE:
2192     {
2193       uint32 tmp= uint3korr(ptr);
2194       int part;
2195       char buf[11];
2196       char *pos= &buf[10];  // start from '\0' to the beginning
2197 
2198       /* Copied from field.cc */
2199       *pos--=0;					// End NULL
2200       part=(int) (tmp & 31);
2201       *pos--= (char) ('0'+part%10);
2202       *pos--= (char) ('0'+part/10);
2203       *pos--= ':';
2204       part=(int) (tmp >> 5 & 15);
2205       *pos--= (char) ('0'+part%10);
2206       *pos--= (char) ('0'+part/10);
2207       *pos--= ':';
2208       part=(int) (tmp >> 9);
2209       *pos--= (char) ('0'+part%10); part/=10;
2210       *pos--= (char) ('0'+part%10); part/=10;
2211       *pos--= (char) ('0'+part%10); part/=10;
2212       *pos=   (char) ('0'+part);
2213       my_b_printf(file , "'%s'", buf);
2214       my_snprintf(typestr, typestr_length, "DATE");
2215       return 3;
2216     }
2217 
2218   case MYSQL_TYPE_YEAR:
2219     {
2220       uint32 i32= *ptr;
2221       my_b_printf(file, "%04d", i32+ 1900);
2222       my_snprintf(typestr, typestr_length, "YEAR");
2223       return 1;
2224     }
2225 
2226   case MYSQL_TYPE_ENUM:
2227     switch (meta & 0xFF) {
2228     case 1:
2229       my_b_printf(file, "%d", (int) *ptr);
2230       my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
2231       return 1;
2232     case 2:
2233       {
2234         int32 i32= uint2korr(ptr);
2235         my_b_printf(file, "%d", i32);
2236         my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
2237         return 2;
2238       }
2239     default:
2240       my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2241       return 0;
2242     }
2243     break;
2244 
2245   case MYSQL_TYPE_SET:
2246     my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2247     my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2248     return meta & 0xFF;
2249 
2250   case MYSQL_TYPE_BLOB:
2251     switch (meta) {
2252     case 1:
2253       length= *ptr;
2254       my_b_write_quoted(file, ptr + 1, length);
2255       my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
2256       return length + 1;
2257     case 2:
2258       length= uint2korr(ptr);
2259       my_b_write_quoted(file, ptr + 2, length);
2260       my_snprintf(typestr, typestr_length, "BLOB/TEXT");
2261       return length + 2;
2262     case 3:
2263       length= uint3korr(ptr);
2264       my_b_write_quoted(file, ptr + 3, length);
2265       my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
2266       return length + 3;
2267     case 4:
2268       length= uint4korr(ptr);
2269       my_b_write_quoted(file, ptr + 4, length);
2270       my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
2271       return length + 4;
2272     default:
2273       my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2274       return 0;
2275     }
2276 
2277   case MYSQL_TYPE_VARCHAR:
2278   case MYSQL_TYPE_VAR_STRING:
2279     length= meta;
2280     my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
2281     return my_b_write_quoted_with_length(file, ptr, length);
2282 
2283   case MYSQL_TYPE_STRING:
2284     my_snprintf(typestr, typestr_length, "STRING(%d)", length);
2285     return my_b_write_quoted_with_length(file, ptr, length);
2286 
2287   default:
2288     {
2289       char tmp[5];
2290       my_snprintf(tmp, sizeof(tmp), "%04x", meta);
2291       my_b_printf(file,
2292                   "!! Don't know how to handle column type=%d meta=%d (%s)",
2293                   type, meta, tmp);
2294     }
2295     break;
2296   }
2297   *typestr= 0;
2298   return 0;
2299 }
2300 
2301 
2302 /**
2303   Print a packed row into IO cache
2304 
2305   @param[in] file              IO cache
2306   @param[in] td                Table definition
2307   @param[in] print_event_into  Print parameters
2308   @param[in] cols_bitmap       Column bitmaps.
2309   @param[in] value             Pointer to packed row
2310   @param[in] prefix            Row's SQL clause ("SET", "WHERE", etc)
2311 
2312   @retval   - number of bytes scanned.
2313 */
2314 
2315 
2316 size_t
print_verbose_one_row(IO_CACHE * file,table_def * td,PRINT_EVENT_INFO * print_event_info,MY_BITMAP * cols_bitmap,const uchar * value,const uchar * prefix)2317 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
2318                                       PRINT_EVENT_INFO *print_event_info,
2319                                       MY_BITMAP *cols_bitmap,
2320                                       const uchar *value, const uchar *prefix)
2321 {
2322   const uchar *value0= value;
2323   const uchar *null_bits= value;
2324   uint null_bit_index= 0;
2325   char typestr[64]= "";
2326 
2327   /*
2328     Skip metadata bytes which gives the information about nullabity of master
2329     columns. Master writes one bit for each affected column.
2330    */
2331   value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
2332 
2333   my_b_printf(file, "%s", prefix);
2334 
2335   for (size_t i= 0; i < td->size(); i ++)
2336   {
2337     int is_null= (null_bits[null_bit_index / 8]
2338                   >> (null_bit_index % 8))  & 0x01;
2339 
2340     if (bitmap_is_set(cols_bitmap, i) == 0)
2341       continue;
2342 
2343     if (is_null)
2344     {
2345       my_b_printf(file, "###   @%d=NULL", static_cast<int>(i + 1));
2346     }
2347     else
2348     {
2349       my_b_printf(file, "###   @%d=", static_cast<int>(i + 1));
2350       size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
2351       if (value + fsize > m_rows_end)
2352       {
2353         my_b_printf(file, "***Corrupted replication event was detected."
2354                     " Not printing the value***\n");
2355         value+= fsize;
2356         return 0;
2357       }
2358       size_t size= log_event_print_value(file, value,
2359                                          td->type(i), td->field_metadata(i),
2360                                          typestr, sizeof(typestr));
2361       if (!size)
2362         return 0;
2363 
2364       value+= size;
2365     }
2366 
2367     if (print_event_info->verbose > 1)
2368     {
2369       my_b_printf(file, " /* ");
2370 
2371       if (typestr[0])
2372         my_b_printf(file, "%s ", typestr);
2373       else
2374         my_b_printf(file, "type=%d ", td->type(i));
2375 
2376       my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
2377                   td->field_metadata(i),
2378                   td->maybe_null(i), is_null);
2379       my_b_printf(file, "*/");
2380     }
2381 
2382     my_b_printf(file, "\n");
2383 
2384     null_bit_index++;
2385   }
2386   return value - value0;
2387 }
2388 
2389 
2390 /**
2391   Print a row event into IO cache in human readable form (in SQL format)
2392 
2393   @param[in] file              IO cache
2394   @param[in] print_event_into  Print parameters
2395 */
print_verbose(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)2396 void Rows_log_event::print_verbose(IO_CACHE *file,
2397                                    PRINT_EVENT_INFO *print_event_info)
2398 {
2399   // Quoted length of the identifier can be twice the original length
2400   char quoted_db[1 + NAME_LEN * 2 + 2];
2401   char quoted_table[1 + NAME_LEN * 2 + 2];
2402   int quoted_db_len, quoted_table_len;
2403   Table_map_log_event *map;
2404   table_def *td;
2405   const char *sql_command, *sql_clause1, *sql_clause2;
2406   Log_event_type general_type_code= get_general_type_code();
2407 
2408   if (m_extra_row_data)
2409   {
2410     uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
2411     uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
2412     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
2413 
2414     my_b_printf(file, "### Extra row data format: %u, len: %u :",
2415                 m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
2416                 extra_payload_len);
2417     if (extra_payload_len)
2418     {
2419       /*
2420          Buffer for hex view of string, including '0x' prefix,
2421          2 hex chars / byte and trailing 0
2422       */
2423       const int buff_len= 2 + (256 * 2) + 1;
2424       char buff[buff_len];
2425       str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
2426                  extra_payload_len);
2427       my_b_printf(file, "%s", buff);
2428     }
2429     my_b_printf(file, "\n");
2430   }
2431 
2432   switch (general_type_code) {
2433   case WRITE_ROWS_EVENT:
2434     sql_command= "INSERT INTO";
2435     sql_clause1= "### SET\n";
2436     sql_clause2= NULL;
2437     break;
2438   case DELETE_ROWS_EVENT:
2439     sql_command= "DELETE FROM";
2440     sql_clause1= "### WHERE\n";
2441     sql_clause2= NULL;
2442     break;
2443   case UPDATE_ROWS_EVENT:
2444     sql_command= "UPDATE";
2445     sql_clause1= "### WHERE\n";
2446     sql_clause2= "### SET\n";
2447     break;
2448   default:
2449     sql_command= sql_clause1= sql_clause2= NULL;
2450     DBUG_ASSERT(0); /* Not possible */
2451   }
2452 
2453   if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2454       !(td= map->create_table_def()))
2455   {
2456     char llbuff[22];
2457     my_b_printf(file, "### Row event for unknown table #%s",
2458                 llstr(m_table_id, llbuff));
2459     return;
2460   }
2461 
2462   /* If the write rows event contained no values for the AI */
2463   if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
2464   {
2465     my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
2466                       map->get_db_name(), map->get_table_name());
2467     goto end;
2468   }
2469 
2470   for (const uchar *value= m_rows_buf; value < m_rows_end; )
2471   {
2472     size_t length;
2473 #ifdef MYSQL_SERVER
2474     quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2475                                         map->get_db_name(), 0);
2476     quoted_table_len= my_strmov_quoted_identifier(this->thd,
2477                                                   (char *) quoted_table,
2478                                                   map->get_table_name(), 0);
2479 #else
2480     quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2481                                                map->get_db_name());
2482     quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2483                                           map->get_table_name());
2484 #endif
2485     quoted_db[quoted_db_len]= '\0';
2486     quoted_table[quoted_table_len]= '\0';
2487     my_b_printf(file, "### %s %s.%s\n",
2488                       sql_command,
2489                       quoted_db, quoted_table);
2490     /* Print the first image */
2491     if (!(length= print_verbose_one_row(file, td, print_event_info,
2492                                   &m_cols, value,
2493                                   (const uchar*) sql_clause1)))
2494       goto end;
2495     value+= length;
2496 
2497     /* Print the second image (for UPDATE only) */
2498     if (sql_clause2)
2499     {
2500       if (!(length= print_verbose_one_row(file, td, print_event_info,
2501                                       &m_cols_ai, value,
2502                                       (const uchar*) sql_clause2)))
2503         goto end;
2504       value+= length;
2505     }
2506   }
2507 
2508 end:
2509   delete td;
2510 }
2511 
2512 #ifdef MYSQL_CLIENT
free_table_map_log_event(Table_map_log_event * event)2513 void free_table_map_log_event(Table_map_log_event *event)
2514 {
2515   delete event;
2516 }
2517 #endif
2518 
print_base64(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool more)2519 void Log_event::print_base64(IO_CACHE* file,
2520                              PRINT_EVENT_INFO* print_event_info,
2521                              bool more)
2522 {
2523   const uchar *ptr= (const uchar *)temp_buf;
2524   uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2525   DBUG_ENTER("Log_event::print_base64");
2526 
2527   uint64 const tmp_str_sz= base64_needed_encoded_length((uint64) size);
2528   char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
2529   if (!tmp_str) {
2530     fprintf(stderr, "\nError: Out of memory. "
2531             "Could not print correct binlog event.\n");
2532     DBUG_VOID_RETURN;
2533   }
2534 
2535   if (base64_encode(ptr, (size_t) size, tmp_str))
2536   {
2537     DBUG_ASSERT(0);
2538   }
2539 
2540   if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2541   {
2542     if (my_b_tell(file) == 0)
2543       my_b_printf(file, "\nBINLOG '\n");
2544 
2545     my_b_printf(file, "%s\n", tmp_str);
2546 
2547     if (!more)
2548       my_b_printf(file, "'%s\n", print_event_info->delimiter);
2549   }
2550 
2551   if (print_event_info->verbose)
2552   {
2553     Rows_log_event *ev= NULL;
2554     Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
2555 
2556     if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
2557         checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
2558       size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
2559 
2560     switch(et)
2561     {
2562     case TABLE_MAP_EVENT:
2563     {
2564       Table_map_log_event *map;
2565       map= new Table_map_log_event((const char*) ptr, size,
2566                                    glob_description_event);
2567       print_event_info->m_table_map.set_table(map->get_table_id(), map);
2568       break;
2569     }
2570     case WRITE_ROWS_EVENT:
2571     case WRITE_ROWS_EVENT_V1:
2572     {
2573       ev= new Write_rows_log_event((const char*) ptr, size,
2574                                    glob_description_event);
2575       break;
2576     }
2577     case DELETE_ROWS_EVENT:
2578     case DELETE_ROWS_EVENT_V1:
2579     {
2580       ev= new Delete_rows_log_event((const char*) ptr, size,
2581                                     glob_description_event);
2582       break;
2583     }
2584     case UPDATE_ROWS_EVENT:
2585     case UPDATE_ROWS_EVENT_V1:
2586     {
2587       ev= new Update_rows_log_event((const char*) ptr, size,
2588                                     glob_description_event);
2589       break;
2590     }
2591     default:
2592       break;
2593     }
2594 
2595     if (ev)
2596     {
2597       ev->print_verbose(file, print_event_info);
2598       delete ev;
2599     }
2600   }
2601 
2602   my_free(tmp_str);
2603   DBUG_VOID_RETURN;
2604 }
2605 
2606 
2607 /*
2608   Log_event::print_timestamp()
2609 */
2610 
print_timestamp(IO_CACHE * file,time_t * ts)2611 void Log_event::print_timestamp(IO_CACHE* file, time_t *ts)
2612 {
2613   struct tm *res;
2614   /*
2615     In some Windows versions timeval.tv_sec is defined as "long",
2616     not as "time_t" and can be of a different size.
2617     Let's use a temporary time_t variable to execute localtime()
2618     with a correct argument type.
2619   */
2620   time_t ts_tmp= ts ? *ts : (ulong)when.tv_sec;
2621   DBUG_ENTER("Log_event::print_timestamp");
2622   struct tm tm_tmp;
2623   localtime_r(&ts_tmp, (res= &tm_tmp));
2624   my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2625               res->tm_year % 100,
2626               res->tm_mon+1,
2627               res->tm_mday,
2628               res->tm_hour,
2629               res->tm_min,
2630               res->tm_sec);
2631   DBUG_VOID_RETURN;
2632 }
2633 
2634 #endif /* MYSQL_CLIENT */
2635 
2636 
2637 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2638 inline Log_event::enum_skip_reason
continue_group(Relay_log_info * rli)2639 Log_event::continue_group(Relay_log_info *rli)
2640 {
2641   if (rli->slave_skip_counter == 1)
2642     return Log_event::EVENT_SKIP_IGNORE;
2643   return Log_event::do_shall_skip(rli);
2644 }
2645 
2646 /**
2647    @param end_group_sets_max_dbs  when true the group terminal event
2648                           can carry partition info, see a note below.
2649    @return true  in cases the current event
2650                  carries partition data,
2651            false otherwise
2652 
2653    @note Some events combination may force to adjust partition info.
2654          In particular BEGIN, BEGIN_LOAD_QUERY_EVENT, COMMIT
2655          where none of the events holds partitioning data
2656          causes the sequential applying of the group through
2657          assigning OVER_MAX_DBS_IN_EVENT_MTS to mts_accessed_dbs
2658          of COMMIT query event.
2659 */
contains_partition_info(bool end_group_sets_max_dbs)2660 bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2661 {
2662   bool res;
2663 
2664   switch (get_type_code()) {
2665   case TABLE_MAP_EVENT:
2666   case EXECUTE_LOAD_QUERY_EVENT:
2667     res= true;
2668 
2669     break;
2670 
2671   case QUERY_EVENT:
2672     if (ends_group() && end_group_sets_max_dbs)
2673     {
2674       res= true;
2675       static_cast<Query_log_event*>(this)->mts_accessed_dbs=
2676         OVER_MAX_DBS_IN_EVENT_MTS;
2677     }
2678     else
2679       res= (!ends_group() && !starts_group()) ? true : false;
2680 
2681     break;
2682 
2683   default:
2684     res= false;
2685   }
2686 
2687   return res;
2688 }
2689 
2690 /**
2691    The method maps the event to a Worker and return a pointer to it.
2692    As a part of the group, an event belongs to one of the following types:
2693 
2694    B - beginning of a group of events (BEGIN query_log_event)
2695    g - mini-group representative event containing the partition info
2696       (any Table_map, a Query_log_event)
2697    p - a mini-group internal event that *p*receeding its g-parent
2698       (int_, rand_, user_ var:s)
2699    r - a mini-group internal "regular" event that follows its g-parent
2700       (Delete, Update, Write -rows)
2701    T - terminator of the group (XID, COMMIT, ROLLBACK, auto-commit query)
2702 
2703    Only the first g-event computes the assigned Worker which once
2704    is determined remains to be for the rest of the group.
2705    That is the g-event solely carries partitioning info.
2706    For B-event the assigned Worker is NULL to indicate Coordinator
2707    has not yet decided. The same applies to p-event.
2708 
2709    Notice, these is a special group consisting of optionally multiple p-events
2710    terminating with a g-event.
2711    Such case is caused by old master binlog and a few corner-cases of
2712    the current master version (todo: to fix).
2713 
2714    In case of the event accesses more than OVER_MAX_DBS the method
2715    has to ensure sure previously assigned groups to all other workers are
2716    done.
2717 
2718 
2719    @note The function updates GAQ queue directly, updates APH hash
2720          plus relocates some temporary tables from Coordinator's list into
2721          involved entries of APH through @c map_db_to_worker.
2722          There's few memory allocations commented where to be freed.
2723 
2724    @return a pointer to the Worker struct or NULL.
2725 */
2726 
get_slave_worker(Relay_log_info * rli)2727 Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
2728 {
2729   Slave_job_group group, *ptr_group= NULL;
2730   bool is_s_event;
2731   Slave_worker *ret_worker= NULL;
2732   char llbuff[22];
2733 #ifndef DBUG_OFF
2734   THD *thd= rli->info_thd;
2735 #endif
2736   Slave_committed_queue *gaq= rli->gaq;
2737 
2738   /* checking partioning properties and perform corresponding actions */
2739 
2740   // Beginning of a group designated explicitly with BEGIN or GTID
2741   if ((is_s_event= starts_group()) || is_gtid_event(this) ||
2742       // or DDL:s or autocommit queries possibly associated with own p-events
2743       (!rli->curr_group_seen_begin && !rli->curr_group_seen_gtid &&
2744        /*
2745          the following is a special case of B-free still multi-event group like
2746          { p_1,p_2,...,p_k, g }.
2747          In that case either GAQ is empty (the very first group is being
2748          assigned) or the last assigned group index points at one of
2749          mapped-to-a-worker.
2750        */
2751        (gaq->empty() ||
2752         gaq->get_job_group(rli->gaq->assigned_group_index)->
2753         worker_id != MTS_WORKER_UNDEF)))
2754   {
2755     if (!rli->curr_group_seen_gtid && !rli->curr_group_seen_begin)
2756     {
2757       ulong gaq_idx MY_ATTRIBUTE((unused));
2758       rli->mts_groups_assigned++;
2759 
2760       rli->curr_group_isolated= FALSE;
2761       group.reset(log_pos, rli->mts_groups_assigned);
2762       // the last occupied GAQ's array index
2763       gaq_idx= gaq->assigned_group_index= gaq->en_queue((void *) &group);
2764 
2765       DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF && gaq_idx < gaq->size);
2766       DBUG_ASSERT(gaq->get_job_group(rli->gaq->assigned_group_index)->
2767                   group_relay_log_name == NULL);
2768       DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF);  // gaq must have room
2769       DBUG_ASSERT(rli->last_assigned_worker == NULL);
2770 
2771       if (is_s_event || is_gtid_event(this))
2772       {
2773         Log_event *ptr_curr_ev= this;
2774         // B-event is appended to the Deferred Array associated with GCAP
2775         insert_dynamic(&rli->curr_group_da,
2776                        (uchar*) &ptr_curr_ev);
2777 
2778         DBUG_ASSERT(rli->curr_group_da.elements == 1);
2779 
2780         if (starts_group())
2781         {
2782           // mark the current group as started with explicit B-event
2783           rli->mts_end_group_sets_max_dbs= true;
2784           rli->curr_group_seen_begin= true;
2785         }
2786 
2787         if (is_gtid_event(this))
2788           // mark the current group as started with explicit Gtid-event
2789           rli->curr_group_seen_gtid= true;
2790 
2791         return ret_worker;
2792       }
2793     }
2794     else
2795     {
2796       Log_event *ptr_curr_ev= this;
2797       // B-event is appended to the Deferred Array associated with GCAP
2798       insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2799       rli->curr_group_seen_begin= true;
2800       rli->mts_end_group_sets_max_dbs= true;
2801       DBUG_ASSERT(rli->curr_group_da.elements == 2);
2802       DBUG_ASSERT(starts_group());
2803       return ret_worker;
2804     }
2805   }
2806 
2807   // mini-group representative
2808 
2809   if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
2810   {
2811     int i= 0;
2812     Mts_db_names mts_dbs;
2813 
2814     get_mts_dbs(&mts_dbs);
2815     /*
2816       Bug 12982188 - MTS: SBR ABORTS WITH ERROR 1742 ON LOAD DATA
2817       Logging on master can create a group with no events holding
2818       the partition info.
2819       The following assert proves there's the only reason
2820       for such group.
2821     */
2822     DBUG_ASSERT(!ends_group() ||
2823                 /*
2824                   This is an empty group being processed due to gtids.
2825                 */
2826                 (rli->curr_group_seen_begin && rli->curr_group_seen_gtid &&
2827                  ends_group()) ||
2828                 (rli->mts_end_group_sets_max_dbs &&
2829                  ((rli->curr_group_da.elements == 3 && rli->curr_group_seen_gtid) ||
2830                  (rli->curr_group_da.elements == 2 && !rli->curr_group_seen_gtid)) &&
2831                  ((*(Log_event **)
2832                    dynamic_array_ptr(&rli->curr_group_da,
2833                                      rli->curr_group_da.elements - 1))->
2834                   get_type_code() == BEGIN_LOAD_QUERY_EVENT)));
2835 
2836     // partioning info is found which drops the flag
2837     rli->mts_end_group_sets_max_dbs= false;
2838     ret_worker= rli->last_assigned_worker;
2839     if (mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS)
2840     {
2841       // Worker with id 0 to handle serial execution
2842       if (!ret_worker)
2843         ret_worker= *(Slave_worker**) dynamic_array_ptr(&rli->workers, 0);
2844       // No need to know a possible error out of synchronization call.
2845       (void) wait_for_workers_to_finish(rli, ret_worker);
2846       /*
2847         this marking is transferred further into T-event of the current group.
2848       */
2849       rli->curr_group_isolated= TRUE;
2850     }
2851 
2852     /* One run of the loop in the case of over-max-db:s */
2853     for (i= 0; i < ((mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS) ? mts_dbs.num : 1);
2854          i++)
2855     {
2856       /*
2857         The over max db:s case handled through passing to map_db_to_worker
2858         such "all" db as encoded as  the "" empty string.
2859         Note, the empty string is allocated in a large buffer
2860         to satisfy hashcmp() implementation.
2861       */
2862       const char all_db[NAME_LEN]= {0};
2863       if (!(ret_worker=
2864             map_db_to_worker(mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS ?
2865                              all_db : mts_dbs.name[i], rli,
2866                              &mts_assigned_partitions[i],
2867                              /*
2868                                todo: optimize it. Although pure
2869                                rows- event load in insensetive to the flag value
2870                              */
2871                              TRUE,
2872                              ret_worker)))
2873       {
2874         llstr(rli->get_event_relay_log_pos(), llbuff);
2875         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2876                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2877                  "could not distribute the event to a Worker");
2878         return ret_worker;
2879       }
2880       // all temporary tables are transferred from Coordinator in over-max case
2881       DBUG_ASSERT(mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
2882       DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db,
2883                           mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS ?
2884                           mts_dbs.name[i] : all_db));
2885       DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
2886       DBUG_ASSERT(mts_assigned_partitions[i]->usage >= 0);
2887     }
2888 
2889     if ((ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index))->
2890         worker_id == MTS_WORKER_UNDEF)
2891     {
2892       ptr_group->worker_id= ret_worker->id;
2893 
2894       DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2895     }
2896 
2897     DBUG_ASSERT(i == mts_dbs.num || mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS);
2898   }
2899   else
2900   {
2901     // a mini-group internal "regular" event
2902     if (rli->last_assigned_worker)
2903     {
2904       ret_worker= rli->last_assigned_worker;
2905 
2906       DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0 ||
2907                   ret_worker->id == 0);
2908     }
2909     else // int_, rand_, user_ var:s, load-data events
2910     {
2911       Log_event *ptr_curr_ev= this;
2912 
2913       if (!(get_type_code() == INTVAR_EVENT ||
2914             get_type_code() == RAND_EVENT ||
2915             get_type_code() == USER_VAR_EVENT ||
2916             get_type_code() == BEGIN_LOAD_QUERY_EVENT ||
2917             get_type_code() == APPEND_BLOCK_EVENT ||
2918             is_ignorable_event()))
2919       {
2920         DBUG_ASSERT(!ret_worker);
2921 
2922         llstr(rli->get_event_relay_log_pos(), llbuff);
2923         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2924                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2925                  "the event is a part of a group that is unsupported in "
2926                  "the parallel execution mode");
2927 
2928         return ret_worker;
2929       }
2930 
2931       insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2932 
2933       DBUG_ASSERT(!ret_worker);
2934       return ret_worker;
2935     }
2936   }
2937 
2938   DBUG_ASSERT(ret_worker);
2939 
2940   /*
2941     Preparing event physical coordinates info for Worker before any
2942     event got scheduled so when Worker error-stopped at the first
2943     event it would be aware of where exactly in the event stream.
2944   */
2945   if (!ret_worker->master_log_change_notified)
2946   {
2947     if (!ptr_group)
2948       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2949     ptr_group->group_master_log_name=
2950       my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2951     ret_worker->master_log_change_notified= true;
2952 
2953     DBUG_ASSERT(!ptr_group->notified);
2954 #ifndef DBUG_OFF
2955     ptr_group->notified= true;
2956 #endif
2957   }
2958 
2959   // T-event: Commit, Xid, a DDL query or dml query of B-less group.
2960   if (ends_group() || !rli->curr_group_seen_begin)
2961   {
2962     rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
2963     if (rli->curr_group_isolated)
2964       set_mts_isolate_group();
2965     if (!ptr_group)
2966       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2967 
2968     DBUG_ASSERT(ret_worker != NULL);
2969 
2970     /*
2971       The following two blocks are executed if the worker has not been
2972       notified about new relay-log or a new checkpoints.
2973       Relay-log string is freed by Coordinator, Worker deallocates
2974       strings in the checkpoint block.
2975       However if the worker exits earlier reclaiming for both happens anyway at
2976       GAQ delete.
2977     */
2978     if (!ret_worker->relay_log_change_notified)
2979     {
2980       /*
2981         Prior this event, C rotated the relay log to drop each
2982         Worker's notified flag. Now group terminating event initiates
2983         the new relay-log (where the current event is from) name
2984         delivery to Worker that will receive it in commit_positions().
2985       */
2986       DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2987 
2988       ptr_group->group_relay_log_name= (char *)
2989         my_malloc(strlen(rli->
2990                          get_group_relay_log_name()) + 1, MYF(MY_WME));
2991       strcpy(ptr_group->group_relay_log_name,
2992              rli->get_event_relay_log_name());
2993 
2994       DBUG_ASSERT(ptr_group->group_relay_log_name != NULL);
2995 
2996       ret_worker->relay_log_change_notified= TRUE;
2997     }
2998 
2999     if (!ret_worker->checkpoint_notified)
3000     {
3001       if (!ptr_group)
3002         ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
3003       ptr_group->checkpoint_log_name=
3004         my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
3005       ptr_group->checkpoint_log_pos= rli->get_group_master_log_pos();
3006       ptr_group->checkpoint_relay_log_name=
3007         my_strdup(rli->get_group_relay_log_name(), MYF(MY_WME));
3008       ptr_group->checkpoint_relay_log_pos= rli->get_group_relay_log_pos();
3009       ptr_group->shifted= ret_worker->bitmap_shifted;
3010       ret_worker->bitmap_shifted= 0;
3011       ret_worker->checkpoint_notified= TRUE;
3012     }
3013     ptr_group->checkpoint_seqno= rli->checkpoint_seqno;
3014     ptr_group->ts= when.tv_sec + (time_t) exec_time; // Seconds_behind_master related
3015     rli->checkpoint_seqno++;
3016     /*
3017       Coordinator should not use the main memroot however its not
3018       reset elsewhere either, so let's do it safe way.
3019       The main mem root is also reset by the SQL thread in at the end
3020       of applying which Coordinator does not do in this case.
3021       That concludes the memroot reset can't harm anything in SQL thread roles
3022       after Coordinator has finished its current scheduling.
3023     */
3024     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3025 
3026 #ifndef DBUG_OFF
3027     w_rr++;
3028 #endif
3029 
3030   }
3031 
3032   return ret_worker;
3033 }
3034 
3035 /**
3036    Scheduling event to execute in parallel or execute it directly.
3037    In MTS case the event gets associated with either Coordinator or a
3038    Worker.  A special case of the association is NULL when the Worker
3039    can't be decided yet.  In the single threaded sequential mode the
3040    event maps to SQL thread rli.
3041 
3042    @note in case of MTS failure Coordinator destroys all gathered
3043          deferred events.
3044 
3045    @return 0 as success, otherwise a failure.
3046 */
apply_event(Relay_log_info * rli)3047 int Log_event::apply_event(Relay_log_info *rli)
3048 {
3049   DBUG_ENTER("LOG_EVENT:apply_event");
3050   bool parallel= FALSE;
3051   enum enum_mts_event_exec_mode actual_exec_mode= EVENT_EXEC_PARALLEL;
3052   THD *thd= rli->info_thd;
3053 
3054   worker= rli;
3055 
3056   if (rli->is_mts_recovery())
3057   {
3058     bool skip=
3059       bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index) &&
3060       (get_mts_execution_mode(::server_id,
3061        rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
3062        == EVENT_EXEC_PARALLEL);
3063     if (skip)
3064     {
3065       DBUG_RETURN(0);
3066     }
3067     else
3068     {
3069       DBUG_RETURN(do_apply_event(rli));
3070     }
3071   }
3072 
3073   if (!(parallel= rli->is_parallel_exec()) ||
3074       ((actual_exec_mode=
3075         get_mts_execution_mode(::server_id,
3076                            rli->mts_group_status == Relay_log_info::MTS_IN_GROUP))
3077        != EVENT_EXEC_PARALLEL))
3078   {
3079     if (parallel)
3080     {
3081       /*
3082          There are two classes of events that Coordinator executes
3083          itself. One e.g the master Rotate requires all Workers to finish up
3084          their assignments. The other async class, e.g the slave Rotate,
3085          can't have this such synchronization because Worker might be waiting
3086          for terminal events to finish.
3087       */
3088 
3089       if (actual_exec_mode != EVENT_EXEC_ASYNC)
3090       {
3091         /*
3092           this  event does not split the current group but is indeed
3093           a separator beetwen two master's binlog therefore requiring
3094           Workers to sync.
3095         */
3096         if (rli->curr_group_da.elements > 0)
3097         {
3098           char llbuff[22];
3099           /*
3100              Possible reason is a old version binlog sequential event
3101              wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var.
3102              MTS has to stop to suggest restart in the permanent sequential mode.
3103           */
3104           llstr(rli->get_event_relay_log_pos(), llbuff);
3105           my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3106                    get_type_str(), rli->get_event_relay_log_name(), llbuff,
3107                    "possible malformed group of events from an old master");
3108 
3109           /* Coordinator cant continue, it marks MTS group status accordingly */
3110           rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
3111 
3112           goto err;
3113         }
3114         /*
3115           Marking sure the event will be executed in sequential mode.
3116         */
3117         if (wait_for_workers_to_finish(rli) == -1)
3118         {
3119           // handle synchronization error
3120           rli->report(WARNING_LEVEL, 0,
3121                       "Slave worker thread has failed to apply an event. As a "
3122                       "consequence, the coordinator thread is stopping "
3123                       "execution.");
3124           DBUG_RETURN(-1);
3125         }
3126         /*
3127           Given not in-group mark the event handler can invoke checkpoint
3128           update routine in the following course.
3129         */
3130         DBUG_ASSERT(rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP);
3131 
3132 #ifndef DBUG_OFF
3133         /* all Workers are idle as done through wait_for_workers_to_finish */
3134         for (uint k= 0; k < rli->curr_group_da.elements; k++)
3135         {
3136           DBUG_ASSERT(!(*(Slave_worker **)
3137                         dynamic_array_ptr(&rli->workers, k))->usage_partition);
3138           DBUG_ASSERT(!(*(Slave_worker **)
3139                         dynamic_array_ptr(&rli->workers, k))->jobs.len);
3140         }
3141 #endif
3142       }
3143       else
3144       {
3145         DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_ASYNC);
3146       }
3147     }
3148     DBUG_RETURN(do_apply_event(rli));
3149   }
3150 
3151   DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_PARALLEL);
3152   DBUG_ASSERT(!(rli->curr_group_seen_begin && ends_group()) ||
3153               /*
3154                 This is an empty group being processed due to gtids.
3155               */
3156               (rli->curr_group_seen_begin && rli->curr_group_seen_gtid
3157                && ends_group()) ||
3158               rli->last_assigned_worker ||
3159               /*
3160                 Begin_load_query can be logged w/o db info and within
3161                 Begin/Commit. That's a pattern forcing sequential
3162                 applying of LOAD-DATA.
3163               */
3164               (*(Log_event **)
3165                dynamic_array_ptr(&rli->curr_group_da,
3166                                  rli->curr_group_da.elements - 1))->
3167               get_type_code() == BEGIN_LOAD_QUERY_EVENT);
3168 
3169   worker= NULL;
3170   rli->mts_group_status= Relay_log_info::MTS_IN_GROUP;
3171 
3172   worker= (Relay_log_info*)
3173     (rli->last_assigned_worker= get_slave_worker(rli));
3174 
3175 #ifndef DBUG_OFF
3176   if (rli->last_assigned_worker)
3177     DBUG_PRINT("mts", ("Assigning job to worker %lu",
3178                rli->last_assigned_worker->id));
3179 #endif
3180 
3181 err:
3182   if (thd->is_error())
3183   {
3184     DBUG_ASSERT(!worker);
3185 
3186     /*
3187       Destroy all deferred buffered events but the current prior to exit.
3188       The current one will be deleted as an event never destined/assigned
3189       to any Worker in Coordinator's regular execution path.
3190     */
3191     for (uint k= 0; k < rli->curr_group_da.elements; k++)
3192     {
3193       Log_event *ev_buf=
3194         *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k);
3195       if (this != ev_buf)
3196         delete ev_buf;
3197     }
3198     rli->curr_group_da.elements= 0;
3199   }
3200   else
3201   {
3202     DBUG_ASSERT(worker || rli->curr_group_assigned_parts.elements == 0);
3203   }
3204 
3205   DBUG_RETURN((!thd->is_error() ||
3206                DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ?
3207               0 : -1);
3208 }
3209 
3210 #endif
3211 
3212 /**************************************************************************
3213 	Query_log_event methods
3214 **************************************************************************/
3215 
3216 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3217 
3218 /**
3219   This (which is used only for SHOW BINLOG EVENTS) could be updated to
3220   print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
3221   only an information, it does not produce suitable queries to replay (for
3222   example it does not print LOAD DATA INFILE).
3223   @todo
3224     show the catalog ??
3225 */
3226 
pack_info(Protocol * protocol)3227 int Query_log_event::pack_info(Protocol *protocol)
3228 {
3229   // TODO: show the catalog ??
3230   String temp_buf;
3231   // Add use `DB` to the string if required
3232   if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
3233       && db && db_len)
3234   {
3235     temp_buf.append("use ");
3236     append_identifier(this->thd, &temp_buf, db, db_len);
3237     temp_buf.append("; ");
3238   }
3239   // Add the query to the string
3240   if (query && q_len)
3241     temp_buf.append(query);
3242  // persist the buffer in protocol
3243   protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
3244   return 0;
3245 }
3246 #endif
3247 
3248 #ifndef MYSQL_CLIENT
3249 
3250 /**
3251   Utility function for the next method (Query_log_event::write()) .
3252 */
write_str_with_code_and_len(uchar ** dst,const char * src,uint len,uint code)3253 static void write_str_with_code_and_len(uchar **dst, const char *src,
3254                                         uint len, uint code)
3255 {
3256   /*
3257     only 1 byte to store the length of catalog, so it should not
3258     surpass 255
3259   */
3260   DBUG_ASSERT(len <= 255);
3261   DBUG_ASSERT(src);
3262   *((*dst)++)= code;
3263   *((*dst)++)= (uchar) len;
3264   bmove(*dst, src, len);
3265   (*dst)+= len;
3266 }
3267 
3268 
3269 /**
3270   Query_log_event::write().
3271 
3272   @note
3273     In this event we have to modify the header to have the correct
3274     EVENT_LEN_OFFSET as we don't yet know how many status variables we
3275     will print!
3276 */
3277 
write(IO_CACHE * file)3278 bool Query_log_event::write(IO_CACHE* file)
3279 {
3280   uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3281   uchar *start, *start_of_status;
3282   ulong event_length;
3283 
3284   if (!query)
3285     return 1;                                   // Something wrong with event
3286 
3287   /*
3288     We want to store the thread id:
3289     (- as an information for the user when he reads the binlog)
3290     - if the query uses temporary table: for the slave SQL thread to know to
3291     which master connection the temp table belongs.
3292     Now imagine we (write()) are called by the slave SQL thread (we are
3293     logging a query executed by this thread; the slave runs with
3294     --log-slave-updates). Then this query will be logged with
3295     thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
3296     the same name were created simultaneously on the master (in the master
3297     binlog you have
3298     CREATE TEMPORARY TABLE t; (thread 1)
3299     CREATE TEMPORARY TABLE t; (thread 2)
3300     ...)
3301     then in the slave's binlog there will be
3302     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3303     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3304     which is bad (same thread id!).
3305 
3306     To avoid this, we log the thread's thread id EXCEPT for the SQL
3307     slave thread for which we log the original (master's) thread id.
3308     Now this moves the bug: what happens if the thread id on the
3309     master was 10 and when the slave replicates the query, a
3310     connection number 10 is opened by a normal client on the slave,
3311     and updates a temp table of the same name? We get a problem
3312     again. To avoid this, in the handling of temp tables (sql_base.cc)
3313     we use thread_id AND server_id.  TODO when this is merged into
3314     4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
3315     and is a session variable: that's to make mysqlbinlog work with
3316     temp tables. We probably need to introduce
3317 
3318     SET PSEUDO_SERVER_ID
3319     for mysqlbinlog in 4.1. mysqlbinlog would print:
3320     SET PSEUDO_SERVER_ID=
3321     SET PSEUDO_THREAD_ID=
3322     for each query using temp tables.
3323   */
3324   int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
3325   int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
3326   buf[Q_DB_LEN_OFFSET] = (char) db_len;
3327   int2store(buf + Q_ERR_CODE_OFFSET, error_code);
3328 
3329   /*
3330     You MUST always write status vars in increasing order of code. This
3331     guarantees that a slightly older slave will be able to parse those he
3332     knows.
3333   */
3334   start_of_status= start= buf+QUERY_HEADER_LEN;
3335   if (flags2_inited)
3336   {
3337     *start++= Q_FLAGS2_CODE;
3338     int4store(start, flags2);
3339     start+= 4;
3340   }
3341   if (sql_mode_inited)
3342   {
3343     *start++= Q_SQL_MODE_CODE;
3344     int8store(start, sql_mode);
3345     start+= 8;
3346   }
3347   if (catalog_len) // i.e. this var is inited (false for 4.0 events)
3348   {
3349     write_str_with_code_and_len(&start,
3350                                 catalog, catalog_len, Q_CATALOG_NZ_CODE);
3351     /*
3352       In 5.0.x where x<4 masters we used to store the end zero here. This was
3353       a waste of one byte so we don't do it in x>=4 masters. We change code to
3354       Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
3355       of this x>=4 master segfault (expecting a zero when there is
3356       none). Remaining compatibility problems are: the older slave will not
3357       find the catalog; but it is will not crash, and it's not an issue
3358       that it does not find the catalog as catalogs were not used in these
3359       older MySQL versions (we store it in binlog and read it from relay log
3360       but do nothing useful with it). What is an issue is that the older slave
3361       will stop processing the Q_* blocks (and jumps to the db/query) as soon
3362       as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
3363       Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
3364       various ways. Documented that you should not mix alpha/beta versions if
3365       they are not exactly the same version, with example of 5.0.3->5.0.2 and
3366       5.0.4->5.0.3. If replication is from older to new, the new will
3367       recognize Q_CATALOG_CODE and have no problem.
3368     */
3369   }
3370   if (auto_increment_increment != 1 || auto_increment_offset != 1)
3371   {
3372     *start++= Q_AUTO_INCREMENT;
3373     int2store(start, auto_increment_increment);
3374     int2store(start+2, auto_increment_offset);
3375     start+= 4;
3376   }
3377   if (charset_inited)
3378   {
3379     *start++= Q_CHARSET_CODE;
3380     memcpy(start, charset, 6);
3381     start+= 6;
3382   }
3383   if (time_zone_len)
3384   {
3385     /* In the TZ sys table, column Name is of length 64 so this should be ok */
3386     DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
3387     write_str_with_code_and_len(&start,
3388                                 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
3389   }
3390   if (lc_time_names_number)
3391   {
3392     DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
3393     *start++= Q_LC_TIME_NAMES_CODE;
3394     int2store(start, lc_time_names_number);
3395     start+= 2;
3396   }
3397   if (charset_database_number)
3398   {
3399     DBUG_ASSERT(charset_database_number <= 0xFFFF);
3400     *start++= Q_CHARSET_DATABASE_CODE;
3401     int2store(start, charset_database_number);
3402     start+= 2;
3403   }
3404   if (table_map_for_update)
3405   {
3406     *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
3407     int8store(start, table_map_for_update);
3408     start+= 8;
3409   }
3410   if (master_data_written != 0)
3411   {
3412     /*
3413       Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
3414       has binlog_version<4 and the slave has binlog_version=4. See comment
3415       for master_data_written in log_event.h for details.
3416     */
3417     *start++= Q_MASTER_DATA_WRITTEN_CODE;
3418     int4store(start, master_data_written);
3419     start+= 4;
3420   }
3421 
3422   if (thd && thd->need_binlog_invoker())
3423   {
3424     LEX_STRING user;
3425     LEX_STRING host;
3426     memset(&user, 0, sizeof(user));
3427     memset(&host, 0, sizeof(host));
3428 
3429     if (thd->slave_thread && thd->has_invoker())
3430     {
3431       /* user will be null, if master is older than this patch */
3432       user= thd->get_invoker_user();
3433       host= thd->get_invoker_host();
3434     }
3435     else
3436     {
3437       Security_context *ctx= thd->security_ctx;
3438 
3439       user.length= strlen(ctx->priv_user);
3440       user.str= ctx->priv_user;
3441       if (ctx->priv_host[0] != '\0')
3442       {
3443         host.str= ctx->priv_host;
3444         host.length= strlen(ctx->priv_host);
3445       }
3446     }
3447 
3448     *start++= Q_INVOKER;
3449 
3450     /*
3451       Store user length and user. The max length of use is 16, so 1 byte is
3452       enough to store the user's length.
3453      */
3454     *start++= (uchar)user.length;
3455     memcpy(start, user.str, user.length);
3456     start+= user.length;
3457 
3458     /*
3459       Store host length and host. The max length of host is 60, so 1 byte is
3460       enough to store the host's length.
3461      */
3462     *start++= (uchar)host.length;
3463     memcpy(start, host.str, host.length);
3464     start+= host.length;
3465   }
3466 
3467   if (thd && thd->get_binlog_accessed_db_names() != NULL)
3468   {
3469     uchar dbs;
3470     *start++= Q_UPDATED_DB_NAMES;
3471 
3472     compile_time_assert(MAX_DBS_IN_EVENT_MTS <= OVER_MAX_DBS_IN_EVENT_MTS);
3473 
3474     /*
3475        In case of the number of db:s exceeds MAX_DBS_IN_EVENT_MTS
3476        no db:s is written and event will require the sequential applying on slave.
3477     */
3478     dbs=
3479       (thd->get_binlog_accessed_db_names()->elements <= MAX_DBS_IN_EVENT_MTS) ?
3480       thd->get_binlog_accessed_db_names()->elements : OVER_MAX_DBS_IN_EVENT_MTS;
3481 
3482     DBUG_ASSERT(dbs != 0);
3483 
3484     if (dbs <= MAX_DBS_IN_EVENT_MTS)
3485     {
3486       List_iterator_fast<char> it(*thd->get_binlog_accessed_db_names());
3487       char *db_name= it++;
3488       /*
3489          the single "" db in the acccessed db list corresponds to the same as
3490          exceeds MAX_DBS_IN_EVENT_MTS case, so dbs is set to the over-max.
3491       */
3492       if (dbs == 1 && !strcmp(db_name, ""))
3493         dbs= OVER_MAX_DBS_IN_EVENT_MTS;
3494       *start++= dbs;
3495       if (dbs != OVER_MAX_DBS_IN_EVENT_MTS)
3496         do
3497         {
3498           strcpy((char*) start, db_name);
3499           start += strlen(db_name) + 1;
3500         } while ((db_name= it++));
3501     }
3502     else
3503     {
3504       *start++= dbs;
3505     }
3506   }
3507 
3508   if (thd && thd->query_start_usec_used)
3509   {
3510     *start++= Q_MICROSECONDS;
3511     get_time();
3512     int3store(start, when.tv_usec);
3513     start+= 3;
3514   }
3515 
3516 #ifndef DBUG_OFF
3517   if (thd && thd->variables.query_exec_time > 0)
3518   {
3519     *start++= Q_QUERY_EXEC_TIME;
3520     int8store(start, thd->variables.query_exec_time);
3521     start+= 8;
3522   }
3523 #endif
3524 
3525 /*
3526     NOTE: When adding new status vars, please don't forget to update
3527     the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
3528     code_name() in this file.
3529 
3530     Here there could be code like
3531     if (command-line-option-which-says-"log_this_variable" && inited)
3532     {
3533     *start++= Q_THIS_VARIABLE_CODE;
3534     int4store(start, this_variable);
3535     start+= 4;
3536     }
3537   */
3538 
3539   /* Store length of status variables */
3540   status_vars_len= (uint) (start-start_of_status);
3541   DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
3542   int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
3543 
3544   /*
3545     Calculate length of whole event
3546     The "1" below is the \0 in the db's length
3547   */
3548   event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
3549 
3550   return (write_header(file, event_length) ||
3551           wrapper_my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
3552           write_post_header_for_derived(file) ||
3553           wrapper_my_b_safe_write(file, (uchar*) start_of_status,
3554                           (uint) (start-start_of_status)) ||
3555           wrapper_my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
3556           wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
3557 	  write_footer(file)) ? 1 : 0;
3558 }
3559 
3560 /**
3561   The simplest constructor that could possibly work.  This is used for
3562   creating static objects that have a special meaning and are invisible
3563   to the log.
3564 */
Query_log_event()3565 Query_log_event::Query_log_event()
3566   :Log_event(), data_buf(0)
3567 {
3568   memset(&user, 0, sizeof(user));
3569   memset(&host, 0, sizeof(host));
3570 }
3571 
3572 
3573 /**
3574   Creates a Query Log Event.
3575 
3576   @param thd_arg      Thread handle
3577   @param query_arg    Array of char representing the query
3578   @param query_length Size of the 'query_arg' array
3579   @param using_trans  Indicates that there are transactional changes.
3580   @param immediate    After being written to the binary log, the event
3581                       must be flushed immediately. This indirectly implies
3582                       the stmt-cache.
3583   @param suppress_use Suppress the generation of 'USE' statements
3584   @param errcode      The error code of the query
3585   @param ignore       Ignore user's statement, i.e. lex information, while
3586                       deciding which cache must be used.
3587 */
Query_log_event(THD * thd_arg,const char * query_arg,ulong query_length,bool using_trans,bool immediate,bool suppress_use,int errcode,bool ignore_cmd_internals)3588 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
3589 				 ulong query_length, bool using_trans,
3590 				 bool immediate, bool suppress_use,
3591                                  int errcode, bool ignore_cmd_internals)
3592 
3593   :Log_event(thd_arg,
3594              (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
3595               0) |
3596              (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
3597 	     using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
3598                           Log_event::EVENT_STMT_CACHE,
3599              Log_event::EVENT_NORMAL_LOGGING),
3600    data_buf(0), query(query_arg), catalog(thd_arg->catalog),
3601    db(thd_arg->db), q_len((uint32) query_length),
3602    thread_id(thd_arg->thread_id),
3603    /* save the original thread id; we already know the server id */
3604    slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3605    flags2_inited(1), sql_mode_inited(1), charset_inited(1),
3606    sql_mode(thd_arg->variables.sql_mode),
3607    auto_increment_increment(thd_arg->variables.auto_increment_increment),
3608    auto_increment_offset(thd_arg->variables.auto_increment_offset),
3609    lc_time_names_number(thd_arg->variables.lc_time_names->number),
3610    charset_database_number(0),
3611    table_map_for_update((ulonglong)thd_arg->table_map_for_update),
3612    master_data_written(0), mts_accessed_dbs(0)
3613 {
3614 
3615   memset(&user, 0, sizeof(user));
3616   memset(&host, 0, sizeof(host));
3617 
3618   error_code= errcode;
3619 
3620   /*
3621   exec_time calculation has changed to use the same method that is used
3622   to fill out "thd_arg->start_time"
3623   */
3624 
3625   struct timeval end_time;
3626   ulonglong micro_end_time= my_micro_time();
3627   my_micro_time_to_timeval(micro_end_time, &end_time);
3628 
3629   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
3630 
3631   /**
3632     @todo this means that if we have no catalog, then it is replicated
3633     as an existing catalog of length zero. is that safe? /sven
3634   */
3635   catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
3636   /* status_vars_len is set just before writing the event */
3637   db_len = (db) ? (uint32) strlen(db) : 0;
3638   if (thd_arg->variables.collation_database != thd_arg->db_charset)
3639     charset_database_number= thd_arg->variables.collation_database->number;
3640 
3641   /*
3642     We only replicate over the bits of flags2 that we need: the rest
3643     are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
3644 
3645     We also force AUTOCOMMIT=1.  Rationale (cf. BUG#29288): After
3646     fixing BUG#26395, we always write BEGIN and COMMIT around all
3647     transactions (even single statements in autocommit mode).  This is
3648     so that replication from non-transactional to transactional table
3649     and error recovery from XA to non-XA table should work as
3650     expected.  The BEGIN/COMMIT are added in log.cc. However, there is
3651     one exception: MyISAM bypasses log.cc and writes directly to the
3652     binlog.  So if autocommit is off, master has MyISAM, and slave has
3653     a transactional engine, then the slave will just see one long
3654     never-ending transaction.  The only way to bypass explicit
3655     BEGIN/COMMIT in the binlog is by using a non-transactional table.
3656     So setting AUTOCOMMIT=1 will make this work as expected.
3657 
3658     Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
3659     assume AUTOCOMMIT=1 on slave; the slave still reads the state of
3660     the autocommit flag as written by the master to the binlog. This
3661     behavior may change after WL#4162 has been implemented.
3662   */
3663   flags2= (uint32) (thd_arg->variables.option_bits &
3664                     (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
3665   DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
3666   DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
3667   DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
3668   DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
3669   int2store(charset, thd_arg->variables.character_set_client->number);
3670   int2store(charset+2, thd_arg->variables.collation_connection->number);
3671   int2store(charset+4, thd_arg->variables.collation_server->number);
3672   if (thd_arg->time_zone_used)
3673   {
3674     /*
3675       Note that our event becomes dependent on the Time_zone object
3676       representing the time zone. Fortunately such objects are never deleted
3677       or changed during mysqld's lifetime.
3678     */
3679     time_zone_len= thd_arg->variables.time_zone->get_name()->length();
3680     time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
3681   }
3682   else
3683     time_zone_len= 0;
3684 
3685   /*
3686     In what follows, we define in which cache, trx-cache or stmt-cache,
3687     this Query Log Event will be written to.
3688 
3689     If ignore_cmd_internals is defined, we rely on the is_trans flag to
3690     choose the cache and this is done in the base class Log_event. False
3691     means that the stmt-cache will be used and upon statement commit/rollback
3692     the cache will be flushed to disk. True means that the trx-cache will
3693     be used and upon transaction commit/rollback the cache will be flushed
3694     to disk.
3695 
3696     If set immediate cache is defined, for convenience, we automatically
3697     use the stmt-cache. This mean that the statement will be written
3698     to the stmt-cache and immediately flushed to disk without waiting
3699     for a commit/rollback notification.
3700 
3701     For example, the cluster/ndb captures a request to execute a DDL
3702     statement and synchronously propagate it to all available MySQL
3703     servers. Unfortunately, the current protocol assumes that the
3704     generated events are immediately written to diks and does not check
3705     for commit/rollback.
3706 
3707     Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are
3708     generated and in this case the statements have the immediate flag
3709     set because there is no commit/rollback.
3710 
3711     If the immediate flag is not set, the decision on the cache is based
3712     on the current statement and the flag is_trans, which indicates if
3713     a transactional engine was updated.
3714 
3715     Statements are classifed as row producers (i.e. can_generate_row_events())
3716     or non-row producers. Non-row producers, DDL in general, are treated
3717     as the immediate flag was set and for convenience are written to the
3718     stmt-cache and immediately flushed to disk.
3719 
3720     Row producers are handled in general according to the is_trans flag.
3721     False means that the stmt-cache will be used and upon statement
3722     commit/rollback the cache will be flushed to disk. True means that the
3723     trx-cache will be used and upon transaction commit/rollback the cache
3724     will be flushed to disk.
3725 
3726     Unfortunately, there are exceptions to this non-row and row producer
3727     rules:
3728 
3729       . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not
3730         have the flag is_trans set because there is no updated engine but
3731         must be written to the trx-cache.
3732 
3733       . SET If auto-commit is on, it must not go through a cache.
3734 
3735       . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY
3736         must be handled as row producer.
3737 
3738       . DROP TABLE is classfied as non-row producer but DROP TEMPORARY
3739         must be handled as row producer.
3740 
3741     Finally, some statements that does not have the flag is_trans set may
3742     be written to the trx-cache based on the following criteria:
3743 
3744       . updated both a transactional and a non-transactional engine (i.e.
3745         stmt_has_updated_trans_table()).
3746 
3747       . accessed both a transactional and a non-transactional engine and
3748         is classified as unsafe (i.e. is_mixed_stmt_unsafe()).
3749 
3750       . is executed within a transaction and previously a transactional
3751         engine was updated and the flag binlog_direct_non_trans_update
3752         is set.
3753   */
3754   if (ignore_cmd_internals)
3755     return;
3756 
3757   /*
3758     TRUE defines that the trx-cache must be used.
3759   */
3760   bool cmd_can_generate_row_events= FALSE;
3761   /*
3762     TRUE defines that the trx-cache must be used.
3763   */
3764   bool cmd_must_go_to_trx_cache= FALSE;
3765 
3766   LEX *lex= thd->lex;
3767   if (!immediate)
3768   {
3769     switch (lex->sql_command)
3770     {
3771       case SQLCOM_DROP_TABLE:
3772         cmd_can_generate_row_events= lex->drop_temporary &&
3773                                      thd->in_multi_stmt_transaction_mode();
3774       break;
3775       case SQLCOM_CREATE_TABLE:
3776         cmd_must_go_to_trx_cache= lex->select_lex.item_list.elements &&
3777                                   thd->is_current_stmt_binlog_format_row();
3778         cmd_can_generate_row_events=
3779           ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
3780             thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache;
3781         break;
3782       case SQLCOM_SET_OPTION:
3783         if (lex->autocommit)
3784           cmd_can_generate_row_events= cmd_must_go_to_trx_cache= FALSE;
3785         else
3786           cmd_can_generate_row_events= TRUE;
3787         break;
3788       case SQLCOM_RELEASE_SAVEPOINT:
3789       case SQLCOM_ROLLBACK_TO_SAVEPOINT:
3790       case SQLCOM_SAVEPOINT:
3791         cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE;
3792         break;
3793       default:
3794         cmd_can_generate_row_events=
3795           sqlcom_can_generate_row_events(thd->lex->sql_command);
3796         break;
3797     }
3798   }
3799 
3800   if (cmd_can_generate_row_events)
3801   {
3802     cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
3803     if (cmd_must_go_to_trx_cache ||
3804         stmt_has_updated_trans_table(thd->transaction.stmt.ha_list) ||
3805         thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
3806                                        thd->variables.binlog_direct_non_trans_update,
3807                                        trans_has_updated_trans_table(thd),
3808                                        thd->tx_isolation) ||
3809         (!thd->variables.binlog_direct_non_trans_update && trans_has_updated_trans_table(thd)))
3810     {
3811       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3812       event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
3813     }
3814     else
3815     {
3816       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3817       event_cache_type= Log_event::EVENT_STMT_CACHE;
3818     }
3819   }
3820   else
3821   {
3822     event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
3823     event_cache_type= Log_event::EVENT_STMT_CACHE;
3824   }
3825 
3826   DBUG_ASSERT(event_cache_type != Log_event::EVENT_INVALID_CACHE);
3827   DBUG_ASSERT(event_logging_type != Log_event::EVENT_INVALID_LOGGING);
3828   DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %llu",
3829                      (ulong) flags2, sql_mode));
3830 }
3831 #endif /* MYSQL_CLIENT */
3832 
3833 
3834 /* 2 utility functions for the next method */
3835 
3836 /**
3837    Read a string with length from memory.
3838 
3839    This function reads the string-with-length stored at
3840    <code>src</code> and extract the length into <code>*len</code> and
3841    a pointer to the start of the string into <code>*dst</code>. The
3842    string can then be copied using <code>memcpy()</code> with the
3843    number of bytes given in <code>*len</code>.
3844 
3845    @param src Pointer to variable holding a pointer to the memory to
3846               read the string from.
3847    @param dst Pointer to variable holding a pointer where the actual
3848               string starts. Starting from this position, the string
3849               can be copied using @c memcpy().
3850    @param len Pointer to variable where the length will be stored.
3851    @param end One-past-the-end of the memory where the string is
3852               stored.
3853 
3854    @return    Zero if the entire string can be copied successfully,
3855               @c UINT_MAX if the length could not be read from memory
3856               (that is, if <code>*src >= end</code>), otherwise the
3857               number of bytes that are missing to read the full
3858               string, which happends <code>*dst + *len >= end</code>.
3859 */
3860 static int
get_str_len_and_pointer(const Log_event::Byte ** src,const char ** dst,uint * len,const Log_event::Byte * end)3861 get_str_len_and_pointer(const Log_event::Byte **src,
3862                         const char **dst,
3863                         uint *len,
3864                         const Log_event::Byte *end)
3865 {
3866   if (*src >= end)
3867     return -1;       // Will be UINT_MAX in two-complement arithmetics
3868   uint length= **src;
3869   if (length > 0)
3870   {
3871     if (*src + length >= end)
3872       return *src + length - end + 1;       // Number of bytes missing
3873     *dst= (char *)*src + 1;                    // Will be copied later
3874   }
3875   *len= length;
3876   *src+= length + 1;
3877   return 0;
3878 }
3879 
copy_str_and_move(const char ** src,Log_event::Byte ** dst,uint len)3880 static void copy_str_and_move(const char **src,
3881                               Log_event::Byte **dst,
3882                               uint len)
3883 {
3884   memcpy(*dst, *src, len);
3885   *src= (const char *)*dst;
3886   (*dst)+= len;
3887   *(*dst)++= 0;
3888 }
3889 
3890 
3891 #ifndef DBUG_OFF
3892 static char const *
code_name(int code)3893 code_name(int code)
3894 {
3895   static char buf[255];
3896   switch (code) {
3897   case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
3898   case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
3899   case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
3900   case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
3901   case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
3902   case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
3903   case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
3904   case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
3905   case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
3906   case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
3907   case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
3908   case Q_UPDATED_DB_NAMES: return "Q_UPDATED_DB_NAMES";
3909   case Q_MICROSECONDS: return "Q_MICROSECONDS";
3910   }
3911   sprintf(buf, "CODE#%d", code);
3912   return buf;
3913 }
3914 #endif
3915 
3916 /**
3917    Macro to check that there is enough space to read from memory.
3918 
3919    @param PTR Pointer to memory
3920    @param END End of memory
3921    @param CNT Number of bytes that should be read.
3922  */
3923 #define CHECK_SPACE(PTR,END,CNT)                      \
3924   do {                                                \
3925     DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
3926     DBUG_ASSERT((PTR) + (CNT) <= (END));              \
3927     if ((PTR) + (CNT) > (END)) {                      \
3928       DBUG_PRINT("info", ("query= 0"));               \
3929       query= 0;                                       \
3930       DBUG_VOID_RETURN;                               \
3931     }                                                 \
3932   } while (0)
3933 
3934 
3935 /**
3936   This is used by the SQL slave thread to prepare the event before execution.
3937 */
Query_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event,Log_event_type event_type)3938 Query_log_event::Query_log_event(const char* buf, uint event_len,
3939                                  const Format_description_log_event
3940                                  *description_event,
3941                                  Log_event_type event_type)
3942   :Log_event(buf, description_event), data_buf(0), query(NullS),
3943    db(NullS), catalog_len(0), status_vars_len(0),
3944    flags2_inited(0), sql_mode_inited(0), charset_inited(0),
3945    auto_increment_increment(1), auto_increment_offset(1),
3946    time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
3947    table_map_for_update(0), master_data_written(0),
3948    mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS)
3949 {
3950   ulong data_len;
3951   uint32 tmp;
3952   uint8 common_header_len, post_header_len;
3953   Log_event::Byte *start;
3954   const Log_event::Byte *end;
3955   bool catalog_nz= 1;
3956   DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
3957 
3958   memset(&user, 0, sizeof(user));
3959   memset(&host, 0, sizeof(host));
3960   common_header_len= description_event->common_header_len;
3961   post_header_len= description_event->post_header_len[event_type-1];
3962   DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
3963                      event_len, common_header_len, post_header_len));
3964 
3965   /*
3966     We test if the event's length is sensible, and if so we compute data_len.
3967     We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
3968     We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
3969   */
3970   if (event_len < (uint)(common_header_len + post_header_len))
3971     DBUG_VOID_RETURN;
3972   data_len = event_len - (common_header_len + post_header_len);
3973   buf+= common_header_len;
3974 
3975   slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
3976   exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
3977   db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
3978   error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
3979 
3980   /*
3981     5.0 format starts here.
3982     Depending on the format, we may or not have affected/warnings etc
3983     The remnent post-header to be parsed has length:
3984   */
3985   tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
3986   if (tmp)
3987   {
3988     status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
3989     /*
3990       Check if status variable length is corrupt and will lead to very
3991       wrong data. We could be even more strict and require data_len to
3992       be even bigger, but this will suffice to catch most corruption
3993       errors that can lead to a crash.
3994     */
3995     if (status_vars_len > min<ulong>(data_len, MAX_SIZE_LOG_EVENT_STATUS))
3996     {
3997       DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
3998                           status_vars_len, data_len));
3999       query= 0;
4000       DBUG_VOID_RETURN;
4001     }
4002     data_len-= status_vars_len;
4003     DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
4004                         (uint) status_vars_len));
4005     tmp-= 2;
4006   }
4007   else
4008   {
4009     /*
4010       server version < 5.0 / binlog_version < 4 master's event is
4011       relay-logged with storing the original size of the event in
4012       Q_MASTER_DATA_WRITTEN_CODE status variable.
4013       The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
4014       event from the relay log.
4015     */
4016     DBUG_ASSERT(description_event->binlog_version < 4);
4017     master_data_written= data_written;
4018   }
4019   /*
4020     We have parsed everything we know in the post header for QUERY_EVENT,
4021     the rest of post header is either comes from older version MySQL or
4022     dedicated to derived events (e.g. Execute_load_query...)
4023   */
4024 
4025   /* variable-part: the status vars; only in MySQL 5.0  */
4026 
4027   start= (Log_event::Byte*) (buf+post_header_len);
4028   end= (const Log_event::Byte*) (start+status_vars_len);
4029   for (const Log_event::Byte* pos= start; pos < end;)
4030   {
4031     switch (*pos++) {
4032     case Q_FLAGS2_CODE:
4033       CHECK_SPACE(pos, end, 4);
4034       flags2_inited= 1;
4035       flags2= uint4korr(pos);
4036       DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
4037       pos+= 4;
4038       break;
4039     case Q_SQL_MODE_CODE:
4040     {
4041 #ifndef DBUG_OFF
4042       char buff[22];
4043 #endif
4044       CHECK_SPACE(pos, end, 8);
4045       sql_mode_inited= 1;
4046       sql_mode= uint8korr(pos);
4047       DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
4048 			 llstr(sql_mode, buff)));
4049       pos+= 8;
4050       break;
4051     }
4052     case Q_CATALOG_NZ_CODE:
4053       DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
4054                           (ulong) pos, (ulong) end));
4055       if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
4056       {
4057         DBUG_PRINT("info", ("query= 0"));
4058         query= 0;
4059         DBUG_VOID_RETURN;
4060       }
4061       break;
4062     case Q_AUTO_INCREMENT:
4063       CHECK_SPACE(pos, end, 4);
4064       auto_increment_increment= uint2korr(pos);
4065       auto_increment_offset=    uint2korr(pos+2);
4066       pos+= 4;
4067       break;
4068     case Q_CHARSET_CODE:
4069     {
4070       CHECK_SPACE(pos, end, 6);
4071       charset_inited= 1;
4072       memcpy(charset, pos, 6);
4073       pos+= 6;
4074       break;
4075     }
4076     case Q_TIME_ZONE_CODE:
4077     {
4078       if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
4079       {
4080         DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
4081         query= 0;
4082         DBUG_VOID_RETURN;
4083       }
4084       break;
4085     }
4086     case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
4087       CHECK_SPACE(pos, end, 1);
4088       if ((catalog_len= *pos))
4089         catalog= (char*) pos+1;                           // Will be copied later
4090       CHECK_SPACE(pos, end, catalog_len + 2);
4091       pos+= catalog_len+2; // leap over end 0
4092       catalog_nz= 0; // catalog has end 0 in event
4093       break;
4094     case Q_LC_TIME_NAMES_CODE:
4095       CHECK_SPACE(pos, end, 2);
4096       lc_time_names_number= uint2korr(pos);
4097       pos+= 2;
4098       break;
4099     case Q_CHARSET_DATABASE_CODE:
4100       CHECK_SPACE(pos, end, 2);
4101       charset_database_number= uint2korr(pos);
4102       pos+= 2;
4103       break;
4104     case Q_TABLE_MAP_FOR_UPDATE_CODE:
4105       CHECK_SPACE(pos, end, 8);
4106       table_map_for_update= uint8korr(pos);
4107       pos+= 8;
4108       break;
4109     case Q_MASTER_DATA_WRITTEN_CODE:
4110       CHECK_SPACE(pos, end, 4);
4111       data_written= master_data_written= uint4korr(pos);
4112       pos+= 4;
4113       break;
4114     case Q_MICROSECONDS:
4115       CHECK_SPACE(pos, end, 3);
4116       when.tv_usec= uint3korr(pos);
4117       pos+= 3;
4118       break;
4119 #if !defined(DBUG_OFF) && !defined(MYSQL_CLIENT)
4120     case Q_QUERY_EXEC_TIME:
4121     {
4122       THD *thd= current_thd;
4123       CHECK_SPACE(pos, end, 8);
4124       if (thd)
4125         thd->variables.query_exec_time= uint8korr(pos);
4126       pos+= 8;
4127       break;
4128     }
4129 #endif
4130     case Q_INVOKER:
4131     {
4132       CHECK_SPACE(pos, end, 1);
4133       user.length= *pos++;
4134       CHECK_SPACE(pos, end, user.length);
4135       user.str= (char *)pos;
4136       if (user.length == 0)
4137         user.str= (char *)"";
4138       pos+= user.length;
4139 
4140       CHECK_SPACE(pos, end, 1);
4141       host.length= *pos++;
4142       CHECK_SPACE(pos, end, host.length);
4143       host.str= (char *)pos;
4144       if (host.length == 0)
4145         host.str= (char *)"";
4146       pos+= host.length;
4147       break;
4148     }
4149     case Q_UPDATED_DB_NAMES:
4150     {
4151       uchar i= 0;
4152       CHECK_SPACE(pos, end, 1);
4153       mts_accessed_dbs= *pos++;
4154       /*
4155          Notice, the following check is positive also in case of
4156          the master's MAX_DBS_IN_EVENT_MTS > the slave's one and the event
4157          contains e.g the master's MAX_DBS_IN_EVENT_MTS db:s.
4158       */
4159       if (mts_accessed_dbs > MAX_DBS_IN_EVENT_MTS)
4160       {
4161         mts_accessed_dbs= OVER_MAX_DBS_IN_EVENT_MTS;
4162         break;
4163       }
4164 
4165       DBUG_ASSERT(mts_accessed_dbs != 0);
4166 
4167       for (i= 0; i < mts_accessed_dbs && pos < start + status_vars_len; i++)
4168       {
4169         DBUG_EXECUTE_IF("query_log_event_mts_corrupt_db_names",
4170                         {
4171                           if (mts_accessed_dbs == 2)
4172                           {
4173                             DBUG_ASSERT(pos[sizeof("d?") - 1] == 0);
4174                             ((char*) pos)[sizeof("d?") - 1]= 'a';
4175                           }});
4176         strncpy(mts_accessed_db_names[i], (char*) pos,
4177                 min<ulong>(NAME_LEN, start + status_vars_len - pos));
4178         mts_accessed_db_names[i][NAME_LEN - 1]= 0;
4179         pos+= 1 + strlen((const char*) pos);
4180       }
4181       if (i != mts_accessed_dbs || pos > start + status_vars_len)
4182         DBUG_VOID_RETURN;
4183       break;
4184     }
4185     default:
4186       /* That's why you must write status vars in growing order of code */
4187       DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
4188  code: %u), skipping the rest of them", (uint) *(pos-1)));
4189       pos= (const uchar*) end;                         // Break loop
4190     }
4191   }
4192 
4193   /**
4194     Layout for the data buffer is as follows
4195     +--------+-----------+------+------+---------+----+-------+
4196     | catlog | time_zone | user | host | db name | \0 | Query |
4197     +--------+-----------+------+------+---------+----+-------+
4198 
4199     To support the query cache we append the following buffer to the above
4200     +-------+----------------------------------------+-------+
4201     |db len | uninitiatlized space of size of db len | FLAGS |
4202     +-------+----------------------------------------+-------+
4203 
4204     The area of buffer starting from Query field all the way to the end belongs
4205     to the Query buffer and its structure is described in alloc_query() in
4206     sql_parse.cc
4207     */
4208 
4209 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4210   if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4211                                                     +  time_zone_len + 1
4212                                                     +  user.length + 1
4213                                                     +  host.length + 1
4214                                                     +  data_len + 1
4215                                                     +  sizeof(size_t)//for db_len
4216                                                     +  db_len + 1
4217                                                     +  QUERY_CACHE_FLAGS_SIZE,
4218                                                        MYF(MY_WME))))
4219 #else
4220   if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4221                                                     +  time_zone_len + 1
4222                                                     +  user.length + 1
4223                                                     +  host.length + 1
4224                                                     +  data_len + 1,
4225                                                        MYF(MY_WME))))
4226 #endif
4227       DBUG_VOID_RETURN;
4228   if (catalog_len)                                  // If catalog is given
4229   {
4230     /**
4231       @todo we should clean up and do only copy_str_and_move; it
4232       works for both cases.  Then we can remove the catalog_nz
4233       flag. /sven
4234     */
4235     if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
4236       copy_str_and_move(&catalog, &start, catalog_len);
4237     else
4238     {
4239       memcpy(start, catalog, catalog_len+1); // copy end 0
4240       catalog= (const char *)start;
4241       start+= catalog_len+1;
4242     }
4243   }
4244   if (time_zone_len)
4245     copy_str_and_move(&time_zone_str, &start, time_zone_len);
4246 
4247   if (user.length > 0)
4248     copy_str_and_move((const char **)&(user.str), &start, user.length);
4249   if (host.length > 0)
4250     copy_str_and_move((const char **)&(host.str), &start, host.length);
4251 
4252   /**
4253     if time_zone_len or catalog_len are 0, then time_zone and catalog
4254     are uninitialized at this point.  shouldn't they point to the
4255     zero-length null-terminated strings we allocated space for in the
4256     my_alloc call above? /sven
4257   */
4258 
4259   /* A 2nd variable part; this is common to all versions */
4260   memcpy((char*) start, end, data_len);          // Copy db and query
4261   start[data_len]= '\0';              // End query with \0 (For safetly)
4262   db= (char *)start;
4263   query= (char *)(start + db_len + 1);
4264   q_len= data_len - db_len -1;
4265 
4266   if (data_len && (data_len < db_len ||
4267                    data_len < q_len ||
4268                    data_len != (db_len + q_len + 1)))
4269   {
4270     q_len= 0;
4271     query= NULL;
4272     DBUG_VOID_RETURN;
4273   }
4274 
4275   unsigned int max_length;
4276   max_length= (event_len - ((const char*)(end + db_len + 1) -
4277                             (buf - common_header_len)));
4278   if (q_len != max_length)
4279   {
4280     q_len= 0;
4281     query= NULL;
4282     DBUG_VOID_RETURN;
4283   }
4284   /**
4285     Append the db length at the end of the buffer. This will be used by
4286     Query_cache::send_result_to_client() in case the query cache is On.
4287    */
4288 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4289   size_t db_length= (size_t)db_len;
4290   memcpy(start + data_len + 1, &db_length, sizeof(size_t));
4291 #endif
4292   DBUG_VOID_RETURN;
4293 }
4294 
4295 
4296 #ifdef MYSQL_CLIENT
4297 /**
4298   Query_log_event::print().
4299 
4300   @todo
4301     print the catalog ??
4302 */
print_query_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)4303 void Query_log_event::print_query_header(IO_CACHE* file,
4304 					 PRINT_EVENT_INFO* print_event_info)
4305 {
4306   // TODO: print the catalog ??
4307   char buff[48], *end;  // Enough for "SET TIMESTAMP=1305535348.123456"
4308   char quoted_id[1+ 2*FN_REFLEN+ 2];
4309   int quoted_len= 0;
4310   bool different_db= 1;
4311   uint32 tmp;
4312 
4313   if (!print_event_info->short_form)
4314   {
4315     print_header(file, print_event_info, FALSE);
4316     my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
4317                 get_type_str(), (ulong) thread_id, (ulong) exec_time,
4318                 error_code);
4319   }
4320 
4321   if ((flags & LOG_EVENT_SUPPRESS_USE_F))
4322   {
4323     if (!is_trans_keyword())
4324       print_event_info->db[0]= '\0';
4325   }
4326   else if (db)
4327   {
4328 #ifdef MYSQL_SERVER
4329     quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
4330 #else
4331     quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
4332 #endif
4333     quoted_id[quoted_len]= '\0';
4334     different_db= memcmp(print_event_info->db, db, db_len + 1);
4335     if (different_db)
4336       memcpy(print_event_info->db, db, db_len + 1);
4337     if (db[0] && different_db)
4338       my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
4339   }
4340 
4341   end=int10_to_str((long) when.tv_sec, strmov(buff,"SET TIMESTAMP="),10);
4342   if (when.tv_usec)
4343     end+= sprintf(end, ".%06d", (int) when.tv_usec);
4344   end= strmov(end, print_event_info->delimiter);
4345   *end++='\n';
4346   DBUG_ASSERT(end < buff + sizeof(buff));
4347   my_b_write(file, (uchar*) buff, (uint) (end-buff));
4348   if ((!print_event_info->thread_id_printed ||
4349        ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
4350         thread_id != print_event_info->thread_id)))
4351   {
4352     // If --short-form, print deterministic value instead of pseudo_thread_id.
4353     my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
4354                 short_form ? 999999999 : (ulong)thread_id,
4355                 print_event_info->delimiter);
4356     print_event_info->thread_id= thread_id;
4357     print_event_info->thread_id_printed= 1;
4358   }
4359 
4360   /*
4361     If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
4362     print (remember we don't produce mixed relay logs so there cannot be
4363     5.0 events before that one so there is nothing to reset).
4364   */
4365   if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
4366   {
4367     /* tmp is a bitmask of bits which have changed. */
4368     if (likely(print_event_info->flags2_inited))
4369       /* All bits which have changed */
4370       tmp= (print_event_info->flags2) ^ flags2;
4371     else /* that's the first Query event we read */
4372     {
4373       print_event_info->flags2_inited= 1;
4374       tmp= ~((uint32)0); /* all bits have changed */
4375     }
4376 
4377     if (unlikely(tmp)) /* some bits have changed */
4378     {
4379       bool need_comma= 0;
4380       my_b_printf(file, "SET ");
4381       print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
4382                        "@@session.foreign_key_checks", &need_comma);
4383       print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
4384                        "@@session.sql_auto_is_null", &need_comma);
4385       print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
4386                        "@@session.unique_checks", &need_comma);
4387       print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
4388                        "@@session.autocommit", &need_comma);
4389       my_b_printf(file,"%s\n", print_event_info->delimiter);
4390       print_event_info->flags2= flags2;
4391     }
4392   }
4393 
4394   /*
4395     Now the session variables;
4396     it's more efficient to pass SQL_MODE as a number instead of a
4397     comma-separated list.
4398     FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
4399     variables (they have no global version; they're not listed in
4400     sql_class.h), The tests below work for pure binlogs or pure relay
4401     logs. Won't work for mixed relay logs but we don't create mixed
4402     relay logs (that is, there is no relay log with a format change
4403     except within the 3 first events, which mysqlbinlog handles
4404     gracefully). So this code should always be good.
4405   */
4406 
4407   if (likely(sql_mode_inited) &&
4408       (unlikely(print_event_info->sql_mode != sql_mode ||
4409                 !print_event_info->sql_mode_inited)))
4410   {
4411     my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
4412                 (ulong)sql_mode, print_event_info->delimiter);
4413     print_event_info->sql_mode= sql_mode;
4414     print_event_info->sql_mode_inited= 1;
4415   }
4416   if (print_event_info->auto_increment_increment != auto_increment_increment ||
4417       print_event_info->auto_increment_offset != auto_increment_offset)
4418   {
4419     my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
4420                 auto_increment_increment,auto_increment_offset,
4421                 print_event_info->delimiter);
4422     print_event_info->auto_increment_increment= auto_increment_increment;
4423     print_event_info->auto_increment_offset=    auto_increment_offset;
4424   }
4425 
4426   /* TODO: print the catalog when we feature SET CATALOG */
4427 
4428   if (likely(charset_inited) &&
4429       (unlikely(!print_event_info->charset_inited ||
4430                 memcmp(print_event_info->charset, charset, 6))))
4431   {
4432     char *charset_p= charset; // Avoid type-punning warning.
4433     CHARSET_INFO *cs_info= get_charset(uint2korr(charset_p), MYF(MY_WME));
4434     if (cs_info)
4435     {
4436       /* for mysql client */
4437       my_b_printf(file, "/*!\\C %s */%s\n",
4438                   cs_info->csname, print_event_info->delimiter);
4439     }
4440     my_b_printf(file,"SET "
4441                 "@@session.character_set_client=%d,"
4442                 "@@session.collation_connection=%d,"
4443                 "@@session.collation_server=%d"
4444                 "%s\n",
4445                 uint2korr(charset_p),
4446                 uint2korr(charset+2),
4447                 uint2korr(charset+4),
4448                 print_event_info->delimiter);
4449     memcpy(print_event_info->charset, charset, 6);
4450     print_event_info->charset_inited= 1;
4451   }
4452   if (time_zone_len)
4453   {
4454     if (memcmp(print_event_info->time_zone_str,
4455                time_zone_str, time_zone_len+1))
4456     {
4457       my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
4458                   time_zone_str, print_event_info->delimiter);
4459       memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
4460     }
4461   }
4462   if (lc_time_names_number != print_event_info->lc_time_names_number)
4463   {
4464     my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
4465                 lc_time_names_number, print_event_info->delimiter);
4466     print_event_info->lc_time_names_number= lc_time_names_number;
4467   }
4468   if (charset_database_number != print_event_info->charset_database_number)
4469   {
4470     if (charset_database_number)
4471       my_b_printf(file, "SET @@session.collation_database=%d%s\n",
4472                   charset_database_number, print_event_info->delimiter);
4473     else
4474       my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
4475                   print_event_info->delimiter);
4476     print_event_info->charset_database_number= charset_database_number;
4477   }
4478 }
4479 
4480 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)4481 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4482 {
4483   IO_CACHE *const head= &print_event_info->head_cache;
4484 
4485   /**
4486     reduce the size of io cache so that the write function is called
4487     for every call to my_b_write().
4488    */
4489   DBUG_EXECUTE_IF ("simulate_file_write_error",
4490                    {head->write_pos= head->write_end- 500;});
4491   print_query_header(head, print_event_info);
4492   my_b_write(head, (uchar*) query, q_len);
4493   my_b_printf(head, "\n%s\n", print_event_info->delimiter);
4494 }
4495 #endif /* MYSQL_CLIENT */
4496 
4497 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4498 
4499 /**
4500    Associating slave Worker thread to a subset of temporary tables
4501    belonging to db-partitions the event accesses.
4502    The pointer if all entries is cleaned.
4503 
4504    @param thd   THD instance pointer
4505 */
attach_temp_tables_worker(THD * thd)4506 void Query_log_event::attach_temp_tables_worker(THD *thd)
4507 {
4508   if (!is_mts_worker(thd) || (ends_group() || starts_group()))
4509     return;
4510 
4511   // in over max-db:s case just one special partition is locked
4512   int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4513               1 : mts_accessed_dbs);
4514 
4515   DBUG_ASSERT(!thd->temporary_tables);
4516 
4517   for (int i= 0; i < parts; i++)
4518   {
4519     mts_move_temp_tables_to_thd(thd,
4520                                 mts_assigned_partitions[i]->temporary_tables);
4521     mts_assigned_partitions[i]->temporary_tables= NULL;
4522   }
4523 }
4524 
4525 /**
4526    Dissociating slave Worker thread from its thd->temporary_tables
4527    to possibly update the involved entries of db-to-worker hash
4528    with new values of temporary_tables.
4529 
4530    @param thd   THD instance pointer
4531 */
detach_temp_tables_worker(THD * thd)4532 void Query_log_event::detach_temp_tables_worker(THD *thd)
4533 {
4534   if (!is_mts_worker(thd))
4535     return;
4536 
4537   int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4538               1 : mts_accessed_dbs);
4539   /*
4540     todo: optimize for a case of
4541 
4542     a. one db
4543        Only detaching temporary_tables from thd to entry would require
4544        instead of the double-loop below.
4545 
4546     b. unchanged thd->temporary_tables.
4547        In such case the involved entries would continue to hold the
4548        unmodified lists provided that the attach_ method does not
4549        destroy references to them.
4550   */
4551   for (int i= 0; i < parts; i++)
4552   {
4553     mts_assigned_partitions[i]->temporary_tables= NULL;
4554   }
4555 
4556   for (TABLE *table= thd->temporary_tables; table;)
4557   {
4558     int i;
4559     char *db_name= NULL;
4560 
4561     // find which entry to go
4562     for (i= 0; i < parts; i++)
4563     {
4564       db_name= mts_accessed_db_names[i];
4565 
4566       if (!strlen(db_name))
4567         break;
4568 
4569       // Only default database is rewritten.
4570       if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
4571       {
4572         size_t dummy_len;
4573         const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
4574         // db_name != db_filtered means that db_name is rewritten.
4575         if (strcmp(db_name, db_filtered))
4576           db_name= (char*)db_filtered;
4577       }
4578 
4579       if (strcmp(table->s->db.str, db_name) < 0)
4580         continue;
4581       else
4582       {
4583         // When rewrite db rules are used we can not rely on
4584         // mts_accessed_db_names elements order.
4585         if (!rpl_filter->is_rewrite_empty() &&
4586             strcmp(table->s->db.str, db_name))
4587           continue;
4588         else
4589           break;
4590       }
4591     }
4592 
4593     DBUG_ASSERT(db_name && (
4594                 !strcmp(table->s->db.str, db_name) ||
4595                 !strlen(db_name))
4596                 );
4597     DBUG_ASSERT(i < mts_accessed_dbs);
4598 
4599     // table pointer is shifted inside the function
4600     table= mts_move_temp_table_to_entry(table, thd, mts_assigned_partitions[i]);
4601   }
4602 
4603   DBUG_ASSERT(!thd->temporary_tables);
4604 #ifndef DBUG_OFF
4605   for (int i= 0; i < parts; i++)
4606   {
4607     DBUG_ASSERT(!mts_assigned_partitions[i]->temporary_tables ||
4608                 !mts_assigned_partitions[i]->temporary_tables->prev);
4609   }
4610 #endif
4611 }
4612 
4613 /*
4614   Query_log_event::do_apply_event()
4615 */
do_apply_event(Relay_log_info const * rli)4616 int Query_log_event::do_apply_event(Relay_log_info const *rli)
4617 {
4618   return do_apply_event(rli, query, q_len);
4619 }
4620 
4621 /*
4622   is_silent_error
4623 
4624   Return true if the thread has an error which should be
4625   handled silently
4626 */
4627 
is_silent_error(THD * thd)4628 static bool is_silent_error(THD* thd)
4629 {
4630   DBUG_ENTER("is_silent_error");
4631   Diagnostics_area::Sql_condition_iterator it=
4632     thd->get_stmt_da()->sql_conditions();
4633   const Sql_condition *err;
4634   while ((err= it++))
4635   {
4636     DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
4637                         err->get_message_text()));
4638     switch (err->get_sql_errno())
4639     {
4640     case ER_SLAVE_SILENT_RETRY_TRANSACTION:
4641     {
4642       DBUG_RETURN(true);
4643     }
4644     default:
4645       break;
4646     }
4647   }
4648   DBUG_RETURN(false);
4649 }
4650 
4651 /**
4652   @todo
4653   Compare the values of "affected rows" around here. Something
4654   like:
4655   @code
4656      if ((uint32) affected_in_event != (uint32) affected_on_slave)
4657      {
4658      sql_print_error("Slave: did not get the expected number of affected \
4659      rows running query from master - expected %d, got %d (this numbers \
4660      should have matched modulo 4294967296).", 0, ...);
4661      thd->query_error = 1;
4662      }
4663   @endcode
4664   We may also want an option to tell the slave to ignore "affected"
4665   mismatch. This mismatch could be implemented with a new ER_ code, and
4666   to ignore it you would use --slave-skip-errors...
4667 */
do_apply_event(Relay_log_info const * rli,const char * query_arg,uint32 q_len_arg)4668 int Query_log_event::do_apply_event(Relay_log_info const *rli,
4669                                       const char *query_arg, uint32 q_len_arg)
4670 {
4671   DBUG_ENTER("Query_log_event::do_apply_event");
4672   int expected_error,actual_error= 0;
4673   HA_CREATE_INFO db_options;
4674 
4675   /*
4676     Colleagues: please never free(thd->catalog) in MySQL. This would
4677     lead to bugs as here thd->catalog is a part of an alloced block,
4678     not an entire alloced block (see
4679     Query_log_event::do_apply_event()). Same for thd->db.  Thank
4680     you.
4681   */
4682   thd->catalog= catalog_len ? (char *) catalog : (char *)"";
4683 
4684   size_t valid_len;
4685   bool len_error;
4686   bool is_invalid_db_name= validate_string(system_charset_info, db, db_len,
4687                                            &valid_len, &len_error);
4688 
4689   DBUG_PRINT("debug",("is_invalid_db_name= %s, valid_len=%zu, len_error=%s",
4690                       is_invalid_db_name ? "true" : "false",
4691                       valid_len,
4692                       len_error ? "true" : "false"));
4693 
4694   if (is_invalid_db_name || len_error)
4695   {
4696     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4697                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4698                 "Invalid database name in Query event.");
4699     thd->is_slave_error= true;
4700     goto end;
4701   }
4702 
4703   set_thd_db(thd, db, db_len);
4704 
4705   /*
4706     Setting the character set and collation of the current database thd->db.
4707    */
4708   load_db_opt_by_name(thd, thd->db, &db_options);
4709   if (db_options.default_table_charset)
4710     thd->db_charset= db_options.default_table_charset;
4711   thd->variables.auto_increment_increment= auto_increment_increment;
4712   thd->variables.auto_increment_offset=    auto_increment_offset;
4713 
4714   /*
4715     InnoDB internally stores the master log position it has executed so far,
4716     i.e. the position just after the COMMIT event.
4717     When InnoDB will want to store, the positions in rli won't have
4718     been updated yet, so group_master_log_* will point to old BEGIN
4719     and event_master_log* will point to the beginning of current COMMIT.
4720     But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
4721     END of the current log event (COMMIT). We save it in rli so that InnoDB can
4722     access it.
4723   */
4724   const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
4725   DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
4726 
4727   /*
4728     todo: such cleanup should not be specific to Query event and therefore
4729           is preferable at a common with other event pre-execution point
4730   */
4731   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4732   if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock != NULL)
4733   {
4734     /*
4735       Cleaning-up the last statement context:
4736       the terminal event of the current statement flagged with
4737       STMT_END_F got filtered out in ndb circular replication.
4738     */
4739     int error;
4740     char llbuff[22];
4741     if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
4742     {
4743       const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
4744                   "Error in cleaning up after an event preceeding the commit; "
4745                   "the group log file/position: %s %s",
4746                   const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
4747                   llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
4748                         llbuff));
4749     }
4750     /*
4751       Executing a part of rli->stmt_done() logics that does not deal
4752       with group position change. The part is redundant now but is
4753       future-change-proof addon, e.g if COMMIT handling will start checking
4754       invariants like IN_STMT flag must be off at committing the transaction.
4755     */
4756     const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
4757     const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
4758   }
4759   else
4760   {
4761     const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
4762   }
4763 
4764   /*
4765     Note:   We do not need to execute reset_one_shot_variables() if this
4766             db_ok() test fails.
4767     Reason: The db stored in binlog events is the same for SET and for
4768             its companion query.  If the SET is ignored because of
4769             db_ok(), the companion query will also be ignored, and if
4770             the companion query is ignored in the db_ok() test of
4771             ::do_apply_event(), then the companion SET also have so
4772             we don't need to reset_one_shot_variables().
4773   */
4774   {
4775     thd->set_time(&when);
4776     thd->set_query_and_id((char*)query_arg, q_len_arg,
4777                           thd->charset(), next_query_id());
4778     thd->set_query_for_display(query_arg, q_len_arg);
4779     thd->variables.pseudo_thread_id= thread_id;		// for temp tables
4780     attach_temp_tables_worker(thd);
4781     DBUG_PRINT("query",("%s", thd->query()));
4782 
4783     if (ignored_error_code((expected_error= error_code)) ||
4784 	!unexpected_error_code(expected_error))
4785     {
4786       if (flags2_inited)
4787         /*
4788           all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
4789           must take their value from flags2.
4790         */
4791         thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
4792       /*
4793         else, we are in a 3.23/4.0 binlog; we previously received a
4794         Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
4795         nothing to do.
4796       */
4797       /*
4798         We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
4799         slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
4800         force us to ignore the dir too. Imagine you are a ring of machines, and
4801         one has a disk problem so that you temporarily need
4802         MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
4803         elsewhere (you don't want all slaves to start ignoring the dirs).
4804       */
4805       if (sql_mode_inited)
4806         thd->variables.sql_mode=
4807           (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
4808                        (sql_mode & ~(ulonglong) MODE_NO_DIR_IN_CREATE));
4809       if (charset_inited)
4810       {
4811         if (rli->cached_charset_compare(charset))
4812         {
4813           char *charset_p= charset; // Avoid type-punning warning.
4814           /* Verify that we support the charsets found in the event. */
4815           if (!(thd->variables.character_set_client=
4816                 get_charset(uint2korr(charset_p), MYF(MY_WME))) ||
4817               !(thd->variables.collation_connection=
4818                 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
4819               !(thd->variables.collation_server=
4820                 get_charset(uint2korr(charset+4), MYF(MY_WME))))
4821           {
4822             /*
4823               We updated the thd->variables with nonsensical values (0). Let's
4824               set them to something safe (i.e. which avoids crash), and we'll
4825               stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
4826               ignore this error).
4827             */
4828             set_slave_thread_default_charset(thd, rli);
4829             goto compare_errors;
4830           }
4831           thd->update_charset(); // for the charset change to take effect
4832           /*
4833             Reset thd->query_string.cs to the newly set value.
4834             Note, there is a small flaw here. For a very short time frame
4835             if the new charset is different from the old charset and
4836             if another thread executes "SHOW PROCESSLIST" after
4837             the above thd->set_query_and_id() and before this thd->set_query(),
4838             and if the current query has some non-ASCII characters,
4839             the another thread may see some '?' marks in the PROCESSLIST
4840             result. This should be acceptable now. This is a reminder
4841             to fix this if any refactoring happens here sometime.
4842           */
4843           thd->set_query((char*) query_arg, q_len_arg, thd->charset());
4844           thd->reset_query_for_display();
4845         }
4846       }
4847       if (time_zone_len)
4848       {
4849         String tmp(time_zone_str, time_zone_len, &my_charset_bin);
4850         if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
4851         {
4852           my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
4853           thd->variables.time_zone= global_system_variables.time_zone;
4854           goto compare_errors;
4855         }
4856       }
4857       if (lc_time_names_number)
4858       {
4859         if (!(thd->variables.lc_time_names=
4860               my_locale_by_number(lc_time_names_number)))
4861         {
4862           my_printf_error(ER_UNKNOWN_ERROR,
4863                       "Unknown locale: '%d'", MYF(0), lc_time_names_number);
4864           thd->variables.lc_time_names= &my_locale_en_US;
4865           goto compare_errors;
4866         }
4867       }
4868       else
4869         thd->variables.lc_time_names= &my_locale_en_US;
4870       if (charset_database_number)
4871       {
4872         CHARSET_INFO *cs;
4873         if (!(cs= get_charset(charset_database_number, MYF(0))))
4874         {
4875           char buf[20];
4876           int10_to_str((int) charset_database_number, buf, -10);
4877           my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
4878           goto compare_errors;
4879         }
4880         thd->variables.collation_database= cs;
4881       }
4882       else
4883         thd->variables.collation_database= thd->db_charset;
4884 
4885       {
4886         const CHARSET_INFO *cs= thd->charset();
4887         /*
4888           We cannot ask for parsing a statement using a character set
4889           without state_maps (parser internal data).
4890         */
4891         if (!cs->state_map)
4892         {
4893           rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4894                       ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4895                       "character_set cannot be parsed");
4896           thd->is_slave_error= true;
4897           goto end;
4898         }
4899       }
4900 
4901       thd->table_map_for_update= (table_map)table_map_for_update;
4902       thd->set_invoker(&user, &host);
4903       /*
4904         Flag if we need to rollback the statement transaction on
4905         slave if it by chance succeeds.
4906         If we expected a non-zero error code and get nothing and,
4907         it is a concurrency issue or ignorable issue, effects
4908         of the statement should be rolled back.
4909       */
4910       if (expected_error &&
4911           (ignored_error_code(expected_error) ||
4912            concurrency_error_code(expected_error)))
4913       {
4914         thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
4915       }
4916       /* Execute the query (note that we bypass dispatch_command()) */
4917       Parser_state parser_state;
4918       if (!parser_state.init(thd, thd->query(), thd->query_length()))
4919       {
4920         DBUG_ASSERT(thd->m_digest == NULL);
4921         thd->m_digest= & thd->m_digest_state;
4922         DBUG_ASSERT(thd->m_statement_psi == NULL);
4923         thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
4924                                                     stmt_info_rpl.m_key,
4925                                                     thd->db, thd->db_length,
4926                                                     thd->charset());
4927         THD_STAGE_INFO(thd, stage_init);
4928         if (thd->m_digest != NULL)
4929           thd->m_digest->reset(thd->m_token_array, max_digest_length);
4930 
4931         mysql_parse(thd, thd->query(), thd->query_length(),
4932                     &parser_state, true);
4933         /* Finalize server status flags after executing a statement. */
4934         thd->update_server_status();
4935         log_slow_statement(thd);
4936       }
4937 
4938       thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
4939 
4940       /*
4941         Resetting the enable_slow_log thd variable.
4942 
4943         We need to reset it back to the opt_log_slow_slave_statements
4944         value after the statement execution (and slow logging
4945         is done). It might have changed if the statement was an
4946         admin statement (in which case, down in mysql_parse execution
4947         thd->enable_slow_log is set to the value of
4948         opt_log_slow_admin_statements).
4949       */
4950       thd->enable_slow_log= TRUE;
4951     }
4952     else
4953     {
4954       /*
4955         The query got a really bad error on the master (thread killed etc),
4956         which could be inconsistent. Parse it to test the table names: if the
4957         replicate-*-do|ignore-table rules say "this query must be ignored" then
4958         we exit gracefully; otherwise we warn about the bad error and tell DBA
4959         to check/fix it.
4960       */
4961       if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
4962         clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
4963       else
4964       {
4965         rli->report(ERROR_LEVEL, expected_error,
4966                           "\
4967 Query partially completed on the master (error on master: %d) \
4968 and was aborted. There is a chance that your master is inconsistent at this \
4969 point. If you are sure that your master is ok, run this query manually on the \
4970 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4971 START SLAVE; . Query: '%s'", expected_error, thd->query());
4972         thd->is_slave_error= 1;
4973       }
4974       goto end;
4975     }
4976 
4977     /* If the query was not ignored, it is printed to the general log */
4978     if (!thd->is_error() || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
4979     {
4980       /* log the rewritten query if the query was rewritten
4981          and the option to log raw was not set.
4982 
4983          There is an assumption here. We assume that query log
4984          events can never have multi-statement queries, thus the
4985          parsed statement is the same as the raw one.
4986        */
4987       if (opt_log_raw || thd->rewritten_query.length() == 0)
4988         general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
4989       else
4990         general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
4991                                           thd->rewritten_query.length());
4992     }
4993 
4994 compare_errors:
4995     /*
4996       In the slave thread, we may sometimes execute some DROP / * 40005
4997       TEMPORARY * / TABLE that come from parts of binlogs (likely if we
4998       use RESET SLAVE or CHANGE MASTER TO), while the temporary table
4999       has already been dropped. To ignore such irrelevant "table does
5000       not exist errors", we silently clear the error if TEMPORARY was used.
5001     */
5002     if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
5003         thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
5004         !expected_error)
5005       thd->get_stmt_da()->reset_diagnostics_area();
5006     /*
5007       If we expected a non-zero error code, and we don't get the same error
5008       code, and it should be ignored or is related to a concurrency issue.
5009     */
5010     actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
5011     DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
5012                        expected_error, actual_error));
5013 
5014     /*
5015       If a statement with expected error is received on slave and if the
5016       statement is not filtered on the slave, only then compare the expected
5017       error with the actual error that happened on slave.
5018     */
5019     if ((expected_error && rpl_filter->db_ok(thd->db) &&
5020          expected_error != actual_error &&
5021          !concurrency_error_code(expected_error)) &&
5022         !ignored_error_code(actual_error) &&
5023         !ignored_error_code(expected_error))
5024     {
5025       rli->report(ERROR_LEVEL, 0,
5026                       "\
5027 Query caused different errors on master and slave.     \
5028 Error on master: message (format)='%s' error code=%d ; \
5029 Error on slave: actual message='%s', error code=%d. \
5030 Default database: '%s'. Query: '%s'",
5031                       ER_SAFE(expected_error),
5032                       expected_error,
5033                       actual_error ? thd->get_stmt_da()->message() : "no error",
5034                       actual_error,
5035                       print_slave_db_safe(db), query_arg);
5036       thd->is_slave_error= 1;
5037     }
5038     /*
5039       If we get the same error code as expected and it is not a concurrency
5040       issue, or should be ignored.
5041     */
5042     else if ((expected_error == actual_error &&
5043               !concurrency_error_code(expected_error)) ||
5044              ignored_error_code(actual_error))
5045     {
5046       DBUG_PRINT("info",("error ignored"));
5047       if (actual_error && log_warnings > 1 && ignored_error_code(actual_error))
5048       {
5049         if (actual_error == ER_SLAVE_IGNORED_TABLE)
5050         {
5051           if (!slave_ignored_err_throttle.log(thd))
5052             rli->report(WARNING_LEVEL, actual_error,
5053                         "Could not execute %s event. Detailed error: %s;"
5054                         " Error log throttle is enabled. This error will not be"
5055                         " displayed for next %lu secs. It will be suppressed",
5056                         get_type_str(), thd->get_stmt_da()->message(),
5057                         (window_size / 1000000));
5058         }
5059         else
5060           rli->report(WARNING_LEVEL, actual_error,
5061                       "Could not execute %s event. Detailed error: %s;",
5062                       get_type_str(), thd->get_stmt_da()->message());
5063       }
5064       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
5065       thd->killed= THD::NOT_KILLED;
5066     }
5067     /*
5068       Other cases: mostly we expected no error and get one.
5069     */
5070     else if (thd->is_slave_error || thd->is_fatal_error)
5071     {
5072       if (!is_silent_error(thd))
5073       {
5074         rli->report(ERROR_LEVEL, actual_error,
5075                     "Error '%s' on query. Default database: '%s'. Query: '%s'",
5076                     (actual_error ? thd->get_stmt_da()->message() :
5077                      "unexpected success or fatal error"),
5078                     print_slave_db_safe(thd->db), query_arg);
5079       }
5080       thd->is_slave_error= 1;
5081     }
5082 
5083     /*
5084       TODO: compare the values of "affected rows" around here. Something
5085       like:
5086       if ((uint32) affected_in_event != (uint32) affected_on_slave)
5087       {
5088       sql_print_error("Slave: did not get the expected number of affected \
5089       rows running query from master - expected %d, got %d (this numbers \
5090       should have matched modulo 4294967296).", 0, ...);
5091       thd->is_slave_error = 1;
5092       }
5093       We may also want an option to tell the slave to ignore "affected"
5094       mismatch. This mismatch could be implemented with a new ER_ code, and
5095       to ignore it you would use --slave-skip-errors...
5096 
5097       To do the comparison we need to know the value of "affected" which the
5098       above mysql_parse() computed. And we need to know the value of
5099       "affected" in the master's binlog. Both will be implemented later. The
5100       important thing is that we now have the format ready to log the values
5101       of "affected" in the binlog. So we can release 5.0.0 before effectively
5102       logging "affected" and effectively comparing it.
5103     */
5104   } /* End of if (db_ok(... */
5105 
5106   {
5107     /**
5108       The following failure injecion works in cooperation with tests
5109       setting @@global.debug= 'd,stop_slave_middle_group'.
5110       The sql thread receives the killed status and will proceed
5111       to shutdown trying to finish incomplete events group.
5112     */
5113 
5114     // TODO: address the middle-group killing in MTS case
5115 
5116     DBUG_EXECUTE_IF("stop_slave_middle_group",
5117                     if (strcmp("COMMIT", query) != 0 &&
5118                         strcmp("BEGIN", query) != 0)
5119                     {
5120                       if (thd->transaction.all.cannot_safely_rollback())
5121                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;
5122                     };);
5123   }
5124 
5125 end:
5126 
5127   if (thd->temporary_tables)
5128     detach_temp_tables_worker(thd);
5129   /*
5130     Probably we have set thd->query, thd->db, thd->catalog to point to places
5131     in the data_buf of this event. Now the event is going to be deleted
5132     probably, so data_buf will be freed, so the thd->... listed above will be
5133     pointers to freed memory.
5134     So we must set them to 0, so that those bad pointers values are not later
5135     used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
5136     don't suffer from these assignments to 0 as DROP TEMPORARY
5137     TABLE uses the db.table syntax.
5138   */
5139   thd->catalog= 0;
5140   thd->set_db(NULL, 0);                 /* will free the current database */
5141   thd->reset_query();
5142   thd->lex->sql_command= SQLCOM_END;
5143   DBUG_PRINT("info", ("end: query= 0"));
5144 
5145   /* Mark the statement completed. */
5146   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
5147   thd->m_statement_psi= NULL;
5148   thd->m_digest= NULL;
5149 
5150   /*
5151     As a disk space optimization, future masters will not log an event for
5152     LAST_INSERT_ID() if that function returned 0 (and thus they will be able
5153     to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
5154     variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
5155     resetting below we are ready to support that.
5156   */
5157   thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
5158   thd->first_successful_insert_id_in_prev_stmt= 0;
5159   thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5160   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5161   DBUG_RETURN(thd->is_slave_error);
5162 }
5163 
do_update_pos(Relay_log_info * rli)5164 int Query_log_event::do_update_pos(Relay_log_info *rli)
5165 {
5166   /*
5167     Note that we will not increment group* positions if we are just
5168     after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
5169     from its following updating query.
5170   */
5171   int ret= 0;
5172   if (thd->one_shot_set)
5173   {
5174     rli->inc_event_relay_log_pos();
5175   }
5176   else
5177     ret= Log_event::do_update_pos(rli);
5178 
5179   DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
5180        if (!strcmp("COMMIT", query))
5181        {
5182          sql_print_information("Crashing crash_after_commit_and_update_pos.");
5183          rli->flush_info(true);
5184          ha_flush_logs(0);
5185          DBUG_SUICIDE();
5186        }
5187   );
5188 
5189   return ret;
5190 }
5191 
5192 
5193 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5194 Query_log_event::do_shall_skip(Relay_log_info *rli)
5195 {
5196   DBUG_ENTER("Query_log_event::do_shall_skip");
5197   DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
5198   DBUG_ASSERT(query && q_len > 0);
5199 
5200   if (rli->slave_skip_counter > 0)
5201   {
5202     if (strcmp("BEGIN", query) == 0)
5203     {
5204       thd->variables.option_bits|= OPTION_BEGIN;
5205       DBUG_RETURN(Log_event::continue_group(rli));
5206     }
5207 
5208     if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
5209     {
5210       thd->variables.option_bits&= ~OPTION_BEGIN;
5211       DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5212     }
5213   }
5214   DBUG_RETURN(Log_event::do_shall_skip(rli));
5215 }
5216 
5217 #endif
5218 
5219 
5220 /**************************************************************************
5221 	Start_log_event_v3 methods
5222 **************************************************************************/
5223 
5224 #ifndef MYSQL_CLIENT
Start_log_event_v3()5225 Start_log_event_v3::Start_log_event_v3()
5226   :Log_event(), created(0), binlog_version(BINLOG_VERSION),
5227    dont_set_created(0)
5228 {
5229   memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5230 }
5231 #endif
5232 
5233 /*
5234   Start_log_event_v3::pack_info()
5235 */
5236 
5237 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5238 int Start_log_event_v3::pack_info(Protocol *protocol)
5239 {
5240   char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5241   pos= strmov(buf, "Server ver: ");
5242   pos= strmov(pos, server_version);
5243   pos= strmov(pos, ", Binlog ver: ");
5244   pos= int10_to_str(binlog_version, pos, 10);
5245   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5246   return 0;
5247 }
5248 #endif
5249 
5250 
5251 /*
5252   Start_log_event_v3::print()
5253 */
5254 
5255 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5256 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5257 {
5258   DBUG_ENTER("Start_log_event_v3::print");
5259 
5260   IO_CACHE *const head= &print_event_info->head_cache;
5261 
5262   if (!print_event_info->short_form)
5263   {
5264     print_header(head, print_event_info, FALSE);
5265     my_b_printf(head, "\tStart: binlog v %d, server v %s created ",
5266                 binlog_version, server_version);
5267     print_timestamp(head, NULL);
5268     if (created)
5269       my_b_printf(head," at startup");
5270     my_b_printf(head, "\n");
5271     if (flags & LOG_EVENT_BINLOG_IN_USE_F)
5272       my_b_printf(head, "# Warning: this binlog is either in use or was not "
5273                   "closed properly.\n");
5274   }
5275   if (!is_artificial_event() && created)
5276   {
5277 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5278     /*
5279       This is for mysqlbinlog: like in replication, we want to delete the stale
5280       tmp files left by an unclean shutdown of mysqld (temporary tables)
5281       and rollback unfinished transaction.
5282       Probably this can be done with RESET CONNECTION (syntax to be defined).
5283     */
5284     my_b_printf(head,"RESET CONNECTION%s\n", print_event_info->delimiter);
5285 #else
5286     my_b_printf(head,"ROLLBACK%s\n", print_event_info->delimiter);
5287     if (print_event_info->is_gtid_next_set)
5288       print_event_info->is_gtid_next_valid= false;
5289 #endif
5290   }
5291   // set gtid_next=automatic if we have previously set it to uuid:number
5292   if (!print_event_info->is_gtid_next_valid)
5293   {
5294     my_b_printf(head, "%sAUTOMATIC'%s\n",
5295                 Gtid_log_event::SET_STRING_PREFIX,
5296                 print_event_info->delimiter);
5297     print_event_info->is_gtid_next_set= false;
5298     print_event_info->is_gtid_next_valid= true;
5299   }
5300   if (temp_buf &&
5301       print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5302       !print_event_info->short_form)
5303   {
5304     if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
5305       my_b_printf(head, "BINLOG '\n");
5306     print_base64(head, print_event_info, FALSE);
5307     print_event_info->printed_fd_event= TRUE;
5308   }
5309   DBUG_VOID_RETURN;
5310 }
5311 #endif /* MYSQL_CLIENT */
5312 
5313 /*
5314   Start_log_event_v3::Start_log_event_v3()
5315 */
5316 
Start_log_event_v3(const char * buf,uint event_len,const Format_description_log_event * description_event)5317 Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
5318                                        const Format_description_log_event
5319                                        *description_event)
5320   :Log_event(buf, description_event), binlog_version(BINLOG_VERSION)
5321 {
5322   if (event_len < (uint)description_event->common_header_len +
5323       ST_COMMON_HEADER_LEN_OFFSET)
5324   {
5325     server_version[0]= 0;
5326     return;
5327   }
5328   buf+= description_event->common_header_len;
5329   binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
5330   memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
5331 	 ST_SERVER_VER_LEN);
5332   // prevent overrun if log is corrupted on disk
5333   server_version[ST_SERVER_VER_LEN-1]= 0;
5334   created= uint4korr(buf+ST_CREATED_OFFSET);
5335   dont_set_created= 1;
5336 }
5337 
5338 
5339 /*
5340   Start_log_event_v3::write()
5341 */
5342 
5343 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5344 bool Start_log_event_v3::write(IO_CACHE* file)
5345 {
5346   char buff[START_V3_HEADER_LEN];
5347   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5348   memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5349   if (!dont_set_created)
5350     created= get_time();
5351   int4store(buff + ST_CREATED_OFFSET,created);
5352   return (write_header(file, sizeof(buff)) ||
5353           wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
5354 	  write_footer(file));
5355 }
5356 #endif
5357 
5358 
5359 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5360 
5361 /**
5362   Start_log_event_v3::do_apply_event() .
5363   The master started
5364 
5365     IMPLEMENTATION
5366     - To handle the case where the master died without having time to write
5367     DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
5368     TODO), we clean up all temporary tables that we got, if we are sure we
5369     can (see below).
5370 
5371   @todo
5372     - Remove all active user locks.
5373     Guilhem 2003-06: this is true but not urgent: the worst it can cause is
5374     the use of a bit of memory for a user lock which will not be used
5375     anymore. If the user lock is later used, the old one will be released. In
5376     other words, no deadlock problem.
5377 */
5378 
do_apply_event(Relay_log_info const * rli)5379 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
5380 {
5381   DBUG_ENTER("Start_log_event_v3::do_apply_event");
5382   int error= 0;
5383   switch (binlog_version)
5384   {
5385   case 3:
5386   case 4:
5387     /*
5388       This can either be 4.x (then a Start_log_event_v3 is only at master
5389       startup so we are sure the master has restarted and cleared his temp
5390       tables; the event always has 'created'>0) or 5.0 (then we have to test
5391       'created').
5392     */
5393     if (created)
5394     {
5395       error= close_temporary_tables(thd);
5396       cleanup_load_tmpdir();
5397     }
5398     else
5399     {
5400       /*
5401         Set all temporary tables thread references to the current thread
5402         as they may point to the "old" SQL slave thread in case of its
5403         restart.
5404       */
5405       TABLE *table;
5406       for (table= thd->temporary_tables; table; table= table->next)
5407         table->in_use= thd;
5408     }
5409     break;
5410 
5411     /*
5412        Now the older formats; in that case load_tmpdir is cleaned up by the I/O
5413        thread.
5414     */
5415   case 1:
5416     if (strncmp(rli->get_rli_description_event()->server_version,
5417                 "3.23.57",7) >= 0 && created)
5418     {
5419       /*
5420         Can distinguish, based on the value of 'created': this event was
5421         generated at master startup.
5422       */
5423       error= close_temporary_tables(thd);
5424     }
5425     /*
5426       Otherwise, can't distinguish a Start_log_event generated at
5427       master startup and one generated by master FLUSH LOGS, so cannot
5428       be sure temp tables have to be dropped. So do nothing.
5429     */
5430     break;
5431   default:
5432     /*
5433       This case is not expected. It can be either an event corruption or an
5434       unsupported binary log version.
5435     */
5436     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5437                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5438                 "Binlog version not supported");
5439     DBUG_RETURN(1);
5440   }
5441   DBUG_RETURN(error);
5442 }
5443 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5444 
5445 /***************************************************************************
5446        Format_description_log_event methods
5447 ****************************************************************************/
5448 
5449 /**
5450   Format_description_log_event 1st ctor.
5451 
5452     Ctor. Can be used to create the event to write to the binary log (when the
5453     server starts or when FLUSH LOGS), or to create artificial events to parse
5454     binlogs from MySQL 3.23 or 4.x.
5455     When in a client, only the 2nd use is possible.
5456 
5457   @param binlog_version         the binlog version for which we want to build
5458                                 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
5459                                 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
5460                                 old 4.0 (binlog version 2) is not supported;
5461                                 it should not be used for replication with
5462                                 5.0.
5463   @param server_ver             a string containing the server version.
5464 */
5465 
5466 Format_description_log_event::
Format_description_log_event(uint8 binlog_ver,const char * server_ver)5467 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
5468   :Start_log_event_v3(), event_type_permutation(0)
5469 {
5470   binlog_version= binlog_ver;
5471   switch (binlog_ver) {
5472   case 4: /* MySQL 5.0 */
5473     memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5474     DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
5475                     strmov(server_version, "5.0.34"););
5476     common_header_len= LOG_EVENT_HEADER_LEN;
5477     number_of_event_types= LOG_EVENT_TYPES;
5478     /* we'll catch my_malloc() error in is_valid() */
5479     post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
5480                                        + BINLOG_CHECKSUM_ALG_DESC_LEN,
5481                                        MYF(0));
5482     /*
5483       This long list of assignments is not beautiful, but I see no way to
5484       make it nicer, as the right members are #defines, not array members, so
5485       it's impossible to write a loop.
5486     */
5487     if (post_header_len)
5488     {
5489 #ifndef DBUG_OFF
5490       // Allows us to sanity-check that all events initialized their
5491       // events (see the end of this 'if' block).
5492       memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
5493 #endif
5494 
5495       /* Note: all event types must explicitly fill in their lengths here. */
5496       post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5497       post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
5498       post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
5499       post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
5500       post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
5501       post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5502       post_header_len[SLAVE_EVENT-1]= 0;   /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5503       post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5504       post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5505       post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5506       post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5507       post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
5508       post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
5509       post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
5510       post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
5511       post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
5512       post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
5513       post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
5514       /*
5515         The PRE_GA events are never be written to any binlog, but
5516         their lengths are included in Format_description_log_event.
5517         Hence, we need to be assign some value here, to avoid reading
5518         uninitialized memory when the array is written to disk.
5519       */
5520       post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
5521       post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
5522       post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
5523 
5524       post_header_len[TABLE_MAP_EVENT-1]=       TABLE_MAP_HEADER_LEN;
5525       post_header_len[WRITE_ROWS_EVENT_V1-1]=   ROWS_HEADER_LEN_V1;
5526       post_header_len[UPDATE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
5527       post_header_len[DELETE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
5528       /*
5529         We here have the possibility to simulate a master of before we changed
5530         the table map id to be stored in 6 bytes: when it was stored in 4
5531         bytes (=> post_header_len was 6). This is used to test backward
5532         compatibility.
5533         This code can be removed after a few months (today is Dec 21st 2005),
5534         when we know that the 4-byte masters are not deployed anymore (check
5535         with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
5536         too.
5537       */
5538       DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5539                       post_header_len[TABLE_MAP_EVENT-1]=
5540                       post_header_len[WRITE_ROWS_EVENT_V1-1]=
5541                       post_header_len[UPDATE_ROWS_EVENT_V1-1]=
5542                       post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
5543       post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
5544       post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
5545       post_header_len[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5546       post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5547       post_header_len[WRITE_ROWS_EVENT-1]=  ROWS_HEADER_LEN_V2;
5548       post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5549       post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5550       post_header_len[GTID_LOG_EVENT-1]=
5551         post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]=
5552         Gtid_log_event::POST_HEADER_LENGTH;
5553       post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5554 
5555       // Sanity-check that all post header lengths are initialized.
5556       int i;
5557       for (i=0; i<number_of_event_types; i++)
5558         DBUG_ASSERT(post_header_len[i] != 255);
5559     }
5560     break;
5561 
5562   case 1: /* 3.23 */
5563   case 3: /* 4.0.x x>=2 */
5564     /*
5565       We build an artificial (i.e. not sent by the master) event, which
5566       describes what those old master versions send.
5567     */
5568     if (binlog_ver==1)
5569       strmov(server_version, server_ver ? server_ver : "3.23");
5570     else
5571       strmov(server_version, server_ver ? server_ver : "4.0");
5572     common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
5573       LOG_EVENT_MINIMAL_HEADER_LEN;
5574     /*
5575       The first new event in binlog version 4 is Format_desc. So any event type
5576       after that does not exist in older versions. We use the events known by
5577       version 3, even if version 1 had only a subset of them (this is not a
5578       problem: it uses a few bytes for nothing but unifies code; it does not
5579       make the slave detect less corruptions).
5580     */
5581     number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
5582     post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
5583                                        MYF(0));
5584     if (post_header_len)
5585     {
5586       post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5587       post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
5588       post_header_len[STOP_EVENT-1]= 0;
5589       post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
5590       post_header_len[INTVAR_EVENT-1]= 0;
5591       post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5592       post_header_len[SLAVE_EVENT-1]= 0;  /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5593       post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5594       post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5595       post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5596       post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5597       post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
5598       post_header_len[RAND_EVENT-1]= 0;
5599       post_header_len[USER_VAR_EVENT-1]= 0;
5600     }
5601     break;
5602   default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
5603     post_header_len= 0; /* will make is_valid() fail */
5604     break;
5605   }
5606   calc_server_version_split();
5607   checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5608 }
5609 
5610 
5611 /**
5612   The problem with this constructor is that the fixed header may have a
5613   length different from this version, but we don't know this length as we
5614   have not read the Format_description_log_event which says it, yet. This
5615   length is in the post-header of the event, but we don't know where the
5616   post-header starts.
5617 
5618   So this type of event HAS to:
5619   - either have the header's length at the beginning (in the header, at a
5620   fixed position which will never be changed), not in the post-header. That
5621   would make the header be "shifted" compared to other events.
5622   - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
5623   versions, so that we know for sure.
5624 
5625   I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
5626   it is sent before Format_description_log_event).
5627 */
5628 
5629 Format_description_log_event::
Format_description_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5630 Format_description_log_event(const char* buf,
5631                              uint event_len,
5632                              const
5633                              Format_description_log_event*
5634                              description_event)
5635   :Start_log_event_v3(buf, event_len, description_event),
5636    common_header_len(0), post_header_len(NULL), event_type_permutation(0)
5637 {
5638   ulong ver_calc;
5639   DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
5640   if (!Start_log_event_v3::is_valid())
5641     DBUG_VOID_RETURN; /* sanity check */
5642   buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
5643   if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
5644     DBUG_VOID_RETURN; /* sanity check */
5645   number_of_event_types=
5646     event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
5647   DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
5648                       common_header_len, number_of_event_types));
5649   /* If alloc fails, we'll detect it in is_valid() */
5650 
5651   post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
5652                                       number_of_event_types*
5653                                       sizeof(*post_header_len),
5654                                       MYF(0));
5655   calc_server_version_split();
5656   if ((ver_calc= get_version_product()) >= checksum_version_product)
5657   {
5658     /* the last bytes are the checksum alg desc and value (or value's room) */
5659     number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
5660     /*
5661       FD from the checksum-home version server (ver_calc ==
5662       checksum_version_product) must have
5663       number_of_event_types == LOG_EVENT_TYPES.
5664     */
5665     DBUG_ASSERT(ver_calc != checksum_version_product ||
5666                 number_of_event_types == LOG_EVENT_TYPES);
5667     checksum_alg= post_header_len[number_of_event_types];
5668   }
5669   else
5670   {
5671     checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5672   }
5673 
5674   /*
5675     In some previous versions, the events were given other event type
5676     id numbers than in the present version. When replicating from such
5677     a version, we therefore set up an array that maps those id numbers
5678     to the id numbers of the present server.
5679 
5680     If post_header_len is null, it means malloc failed, and is_valid
5681     will fail, so there is no need to do anything.
5682 
5683     The trees in which events have wrong id's are:
5684 
5685     mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
5686     mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
5687     mysql-5.1-wl2325-no-dd
5688 
5689     (this was found by grepping for two lines in sequence where the
5690     first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
5691     "TABLE_MAP_EVENT," in log_event.h in all trees)
5692 
5693     In these trees, the following server_versions existed since
5694     TABLE_MAP_EVENT was introduced:
5695 
5696     5.1.1-a_drop5p3   5.1.1-a_drop5p4        5.1.1-alpha
5697     5.1.2-a_drop5p10  5.1.2-a_drop5p11       5.1.2-a_drop5p12
5698     5.1.2-a_drop5p13  5.1.2-a_drop5p14       5.1.2-a_drop5p15
5699     5.1.2-a_drop5p16  5.1.2-a_drop5p16b      5.1.2-a_drop5p16c
5700     5.1.2-a_drop5p17  5.1.2-a_drop5p4        5.1.2-a_drop5p5
5701     5.1.2-a_drop5p6   5.1.2-a_drop5p7        5.1.2-a_drop5p8
5702     5.1.2-a_drop5p9   5.1.3-a_drop5p17       5.1.3-a_drop5p17b
5703     5.1.3-a_drop5p17c 5.1.4-a_drop5p18       5.1.4-a_drop5p19
5704     5.1.4-a_drop5p20  5.1.4-a_drop6p0        5.1.4-a_drop6p1
5705     5.1.4-a_drop6p2   5.1.5-a_drop5p20       5.2.0-a_drop6p3
5706     5.2.0-a_drop6p4   5.2.0-a_drop6p5        5.2.0-a_drop6p6
5707     5.2.1-a_drop6p10  5.2.1-a_drop6p11       5.2.1-a_drop6p12
5708     5.2.1-a_drop6p6   5.2.1-a_drop6p7        5.2.1-a_drop6p8
5709     5.2.2-a_drop6p13  5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
5710     5.2.2-a_drop6p13c
5711 
5712     (this was found by grepping for "mysql," in all historical
5713     versions of configure.in in the trees listed above).
5714 
5715     There are 5.1.1-alpha versions that use the new event id's, so we
5716     do not test that version string.  So replication from 5.1.1-alpha
5717     with the other event id's to a new version does not work.
5718     Moreover, we can safely ignore the part after drop[56].  This
5719     allows us to simplify the big list above to the following regexes:
5720 
5721     5\.1\.[1-5]-a_drop5.*
5722     5\.1\.4-a_drop6.*
5723     5\.2\.[0-2]-a_drop6.*
5724 
5725     This is what we test for in the 'if' below.
5726   */
5727   if (post_header_len &&
5728       server_version[0] == '5' && server_version[1] == '.' &&
5729       server_version[3] == '.' &&
5730       strncmp(server_version + 5, "-a_drop", 7) == 0 &&
5731       ((server_version[2] == '1' &&
5732         server_version[4] >= '1' && server_version[4] <= '5' &&
5733         server_version[12] == '5') ||
5734        (server_version[2] == '1' &&
5735         server_version[4] == '4' &&
5736         server_version[12] == '6') ||
5737        (server_version[2] == '2' &&
5738         server_version[4] >= '0' && server_version[4] <= '2' &&
5739         server_version[12] == '6')))
5740   {
5741     if (number_of_event_types != 22)
5742     {
5743       DBUG_PRINT("info", (" number_of_event_types=%d",
5744                           number_of_event_types));
5745       /* this makes is_valid() return false. */
5746       my_free(post_header_len);
5747       post_header_len= NULL;
5748       DBUG_VOID_RETURN;
5749     }
5750     static const uint8 perm[EVENT_TYPE_PERMUTATION_NUM]=
5751       {
5752         UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
5753         INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
5754         APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
5755         NEW_LOAD_EVENT,
5756         RAND_EVENT, USER_VAR_EVENT,
5757         FORMAT_DESCRIPTION_EVENT,
5758         TABLE_MAP_EVENT,
5759         PRE_GA_WRITE_ROWS_EVENT,
5760         PRE_GA_UPDATE_ROWS_EVENT,
5761         PRE_GA_DELETE_ROWS_EVENT,
5762         XID_EVENT,
5763         BEGIN_LOAD_QUERY_EVENT,
5764         EXECUTE_LOAD_QUERY_EVENT,
5765       };
5766     event_type_permutation= perm;
5767     /*
5768       Since we use (permuted) event id's to index the post_header_len
5769       array, we need to permute the post_header_len array too.
5770     */
5771     uint8 post_header_len_temp[EVENT_TYPE_PERMUTATION_NUM];
5772     for (uint i= 1; i < EVENT_TYPE_PERMUTATION_NUM; i++)
5773       post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
5774     for (uint i= 0; i < EVENT_TYPE_PERMUTATION_NUM - 1; i++)
5775       post_header_len[i] = post_header_len_temp[i];
5776   }
5777   DBUG_VOID_RETURN;
5778 }
5779 
5780 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5781 bool Format_description_log_event::write(IO_CACHE* file)
5782 {
5783   bool ret;
5784   bool no_checksum;
5785   /*
5786     We don't call Start_log_event_v3::write() because this would make 2
5787     my_b_safe_write().
5788   */
5789   uchar buff[FORMAT_DESCRIPTION_HEADER_LEN + BINLOG_CHECKSUM_ALG_DESC_LEN];
5790   size_t rec_size= sizeof(buff);
5791   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5792   memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5793   if (!dont_set_created)
5794     created= get_time();
5795   int4store(buff + ST_CREATED_OFFSET,created);
5796   buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
5797   memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
5798          LOG_EVENT_TYPES);
5799   /*
5800     if checksum is requested
5801     record the checksum-algorithm descriptor next to
5802     post_header_len vector which will be followed by the checksum value.
5803     Master is supposed to trigger checksum computing by binlog_checksum_options,
5804     slave does it via marking the event according to
5805     FD_queue checksum_alg value.
5806   */
5807   compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
5808 #ifndef DBUG_OFF
5809   data_written= 0; // to prepare for need_checksum assert
5810 #endif
5811   buff[FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
5812     checksum_alg : (uint8) BINLOG_CHECKSUM_ALG_OFF;
5813   /*
5814      FD of checksum-aware server is always checksum-equipped, (V) is in,
5815      regardless of @@global.binlog_checksum policy.
5816      Thereby a combination of (A) == 0, (V) != 0 means
5817      it's the checksum-aware server's FD event that heads checksum-free binlog
5818      file.
5819      Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
5820      A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
5821      heading the checksummed binlog.
5822      (A), (V) presence in FD of the checksum-aware server makes the event
5823      1 + 4 bytes bigger comparing to the former FD.
5824   */
5825 
5826   if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
5827   {
5828     checksum_alg= BINLOG_CHECKSUM_ALG_CRC32;  // Forcing (V) room to fill anyway
5829   }
5830   ret= (write_header(file, rec_size) ||
5831         wrapper_my_b_safe_write(file, buff, rec_size) ||
5832         write_footer(file));
5833   if (no_checksum)
5834     checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
5835   return ret;
5836 }
5837 #endif
5838 
5839 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5840 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
5841 {
5842   int ret= 0;
5843   DBUG_ENTER("Format_description_log_event::do_apply_event");
5844 
5845   /*
5846     As a transaction NEVER spans on 2 or more binlogs:
5847     if we have an active transaction at this point, the master died
5848     while writing the transaction to the binary log, i.e. while
5849     flushing the binlog cache to the binlog. XA guarantees that master has
5850     rolled back. So we roll back.
5851     Note: this event could be sent by the master to inform us of the
5852     format of its binlog; in other words maybe it is not at its
5853     original place when it comes to us; we'll know this by checking
5854     log_pos ("artificial" events have log_pos == 0).
5855   */
5856   if (!thd->rli_fake && !is_artificial_event() && created
5857       && thd->transaction.all.ha_list)
5858   {
5859     /* This is not an error (XA is safe), just an information */
5860     rli->report(INFORMATION_LEVEL, 0,
5861                 "Rolling back unfinished transaction (no COMMIT "
5862                 "or ROLLBACK in relay log). A probable cause is that "
5863                 "the master died while writing the transaction to "
5864                 "its binary log, thus rolled back too.");
5865     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
5866   }
5867 
5868   /*
5869     If this event comes from ourselves, there is no cleaning task to
5870     perform, we don't call Start_log_event_v3::do_apply_event()
5871     (this was just to update the log's description event).
5872   */
5873   if (server_id != (uint32) ::server_id)
5874   {
5875     /*
5876       If the event was not requested by the slave i.e. the master sent
5877       it while the slave asked for a position >4, the event will make
5878       rli->group_master_log_pos advance. Say that the slave asked for
5879       position 1000, and the Format_desc event's end is 96. Then in
5880       the beginning of replication rli->group_master_log_pos will be
5881       0, then 96, then jump to first really asked event (which is
5882       >96). So this is ok.
5883     */
5884     ret= Start_log_event_v3::do_apply_event(rli);
5885   }
5886 
5887   if (!ret)
5888   {
5889     /* Save the information describing this binlog */
5890     const_cast<Relay_log_info *>(rli)->set_rli_description_event(this);
5891   }
5892 
5893   DBUG_RETURN(ret);
5894 }
5895 
do_update_pos(Relay_log_info * rli)5896 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
5897 {
5898   if (server_id == (uint32) ::server_id)
5899   {
5900     /*
5901       We only increase the relay log position if we are skipping
5902       events and do not touch any group_* variables, nor flush the
5903       relay log info.  If there is a crash, we will have to re-skip
5904       the events again, but that is a minor issue.
5905 
5906       If we do not skip stepping the group log position (and the
5907       server id was changed when restarting the server), it might well
5908       be that we start executing at a position that is invalid, e.g.,
5909       at a Rows_log_event or a Query_log_event preceeded by a
5910       Intvar_log_event instead of starting at a Table_map_log_event or
5911       the Intvar_log_event respectively.
5912      */
5913     rli->inc_event_relay_log_pos();
5914     return 0;
5915   }
5916   else
5917   {
5918     return Log_event::do_update_pos(rli);
5919   }
5920 }
5921 
5922 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5923 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
5924 {
5925   return Log_event::EVENT_SKIP_NOT;
5926 }
5927 
5928 #endif
5929 
5930 
5931 /**
5932    'server_version_split' is used for lookups to find if the server which
5933    created this event has some known bug.
5934 */
calc_server_version_split()5935 void Format_description_log_event::calc_server_version_split()
5936 {
5937   do_server_version_split(server_version, server_version_split);
5938 
5939   DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
5940                      " '%s' %d %d %d", server_version,
5941                      server_version_split[0],
5942                      server_version_split[1], server_version_split[2]));
5943 }
5944 
5945 /**
5946    @return integer representing the version of server that originated
5947    the current FD instance.
5948 */
get_version_product() const5949 ulong Format_description_log_event::get_version_product() const
5950 {
5951   return version_product(server_version_split);
5952 }
5953 
5954 /**
5955    @return TRUE is the event's version is earlier than one that introduced
5956    the replication event checksum. FALSE otherwise.
5957 */
is_version_before_checksum() const5958 bool Format_description_log_event::is_version_before_checksum() const
5959 {
5960   return get_version_product() < checksum_version_product;
5961 }
5962 
5963 /**
5964    @param buf buffer holding serialized FD event
5965    @param len netto (possible checksum is stripped off) length of the event buf
5966 
5967    @return  the version-safe checksum alg descriptor where zero
5968             designates no checksum, 255 - the orginator is
5969             checksum-unaware (effectively no checksum) and the actuall
5970             [1-254] range alg descriptor.
5971 */
get_checksum_alg(const char * buf,ulong len)5972 uint8 get_checksum_alg(const char* buf, ulong len)
5973 {
5974   uint8 ret;
5975   char version[ST_SERVER_VER_LEN];
5976   uchar version_split[3];
5977 
5978   DBUG_ENTER("get_checksum_alg");
5979   DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
5980 
5981   memcpy(version, buf +
5982          buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
5983          + ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
5984   version[ST_SERVER_VER_LEN - 1]= 0;
5985 
5986   do_server_version_split(version, version_split);
5987   ret= (version_product(version_split) < checksum_version_product) ?
5988     (uint8) BINLOG_CHECKSUM_ALG_UNDEF :
5989     * (uint8*) (buf + len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN);
5990   DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
5991               ret == BINLOG_CHECKSUM_ALG_UNDEF ||
5992               ret == BINLOG_CHECKSUM_ALG_CRC32);
5993   DBUG_RETURN(ret);
5994 }
5995 
5996 
5997   /**************************************************************************
5998         Load_log_event methods
5999    General note about Load_log_event: the binlogging of LOAD DATA INFILE is
6000    going to be changed in 5.0 (or maybe in 5.1; not decided yet).
6001    However, the 5.0 slave could still have to read such events (from a 4.x
6002    master), convert them (which just means maybe expand the header, when 5.0
6003    servers have a UID in events) (remember that whatever is after the header
6004    will be like in 4.x, as this event's format is not modified in 5.0 as we
6005    will use new types of events to log the new LOAD DATA INFILE features).
6006    To be able to read/convert, we just need to not assume that the common
6007    header is of length LOG_EVENT_HEADER_LEN (we must use the description
6008    event).
6009    Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
6010    between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
6011    positions displayed in SHOW SLAVE STATUS then are fine too).
6012   **************************************************************************/
6013 
6014 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_query_buffer_length()6015 uint Load_log_event::get_query_buffer_length()
6016 {
6017   return
6018     //the DB name may double if we escape the quote character
6019     5 + 2*db_len + 3 +
6020     18 + fname_len*4 + 2 +                    // "LOAD DATA INFILE 'file''"
6021     11 +                                    // "CONCURRENT "
6022     7 +					    // LOCAL
6023     9 +                                     // " REPLACE or IGNORE "
6024     13 + table_name_len*2 +                 // "INTO TABLE `table`"
6025     21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
6026     23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
6027     12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
6028     21 + sql_ex.line_term_len*4 + 2 +       // " LINES TERMINATED BY 'str'"
6029     19 + sql_ex.line_start_len*4 + 2 +      // " LINES STARTING BY 'str'"
6030     15 + 22 +                               // " IGNORE xxx  LINES"
6031     3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
6032 }
6033 
6034 
print_query(bool need_db,const char * cs,char * buf,char ** end,char ** fn_start,char ** fn_end)6035 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
6036                                  char **end, char **fn_start, char **fn_end)
6037 {
6038   char quoted_id[1 + NAME_LEN * 2 + 2];//quoted  length
6039   int  quoted_id_len= 0;
6040   char *pos= buf;
6041 
6042   if (need_db && db && db_len)
6043   {
6044     pos= strmov(pos, "use ");
6045 #ifdef MYSQL_SERVER
6046     quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
6047                                                db, 0);
6048 #else
6049     quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
6050 #endif
6051     quoted_id[quoted_id_len]= '\0';
6052     pos= strmov(pos, quoted_id);
6053     pos= strmov(pos, "; ");
6054   }
6055 
6056   pos= strmov(pos, "LOAD DATA ");
6057 
6058   if (is_concurrent)
6059     pos= strmov(pos, "CONCURRENT ");
6060 
6061   if (fn_start)
6062     *fn_start= pos;
6063 
6064   if (check_fname_outside_temp_buf())
6065     pos= strmov(pos, "LOCAL ");
6066   pos= strmov(pos, "INFILE ");
6067   pos= pretty_print_str(pos, fname, fname_len);
6068   pos= strmov(pos, " ");
6069 
6070   if (sql_ex.opt_flags & REPLACE_FLAG)
6071     pos= strmov(pos, "REPLACE ");
6072   else if (sql_ex.opt_flags & IGNORE_FLAG)
6073     pos= strmov(pos, "IGNORE ");
6074 
6075   pos= strmov(pos ,"INTO");
6076 
6077   if (fn_end)
6078     *fn_end= pos;
6079 
6080   pos= strmov(pos ," TABLE ");
6081   memcpy(pos, table_name, table_name_len);
6082   pos+= table_name_len;
6083 
6084   if (cs != NULL)
6085   {
6086     pos= strmov(pos ," CHARACTER SET ");
6087     pos= strmov(pos ,  cs);
6088   }
6089 
6090   /* We have to create all optional fields as the default is not empty */
6091   pos= strmov(pos, " FIELDS TERMINATED BY ");
6092   pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
6093   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6094     pos= strmov(pos, " OPTIONALLY ");
6095   pos= strmov(pos, " ENCLOSED BY ");
6096   pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
6097 
6098   pos= strmov(pos, " ESCAPED BY ");
6099   pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
6100 
6101   pos= strmov(pos, " LINES TERMINATED BY ");
6102   pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
6103   if (sql_ex.line_start_len)
6104   {
6105     pos= strmov(pos, " STARTING BY ");
6106     pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
6107   }
6108 
6109   if ((long) skip_lines > 0)
6110   {
6111     pos= strmov(pos, " IGNORE ");
6112     pos= longlong10_to_str((longlong) skip_lines, pos, 10);
6113     pos= strmov(pos," LINES ");
6114   }
6115 
6116   if (num_fields)
6117   {
6118     uint i;
6119     const char *field= fields;
6120     pos= strmov(pos, " (");
6121     for (i = 0; i < num_fields; i++)
6122     {
6123       if (i)
6124       {
6125         *pos++= ' ';
6126         *pos++= ',';
6127       }
6128       quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
6129                                                  0);
6130       memcpy(pos, quoted_id, quoted_id_len-1);
6131     }
6132     *pos++= ')';
6133   }
6134 
6135   *end= pos;
6136 }
6137 
6138 
pack_info(Protocol * protocol)6139 int Load_log_event::pack_info(Protocol *protocol)
6140 {
6141   char *buf, *end;
6142 
6143   if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
6144     return 1;
6145   print_query(TRUE, NULL, buf, &end, 0, 0);
6146   protocol->store(buf, end-buf, &my_charset_bin);
6147   my_free(buf);
6148   return 0;
6149 }
6150 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6151 
6152 
6153 #ifndef MYSQL_CLIENT
6154 
6155 /*
6156   Load_log_event::write_data_header()
6157 */
6158 
write_data_header(IO_CACHE * file)6159 bool Load_log_event::write_data_header(IO_CACHE* file)
6160 {
6161   char buf[LOAD_HEADER_LEN];
6162   int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
6163   int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
6164   int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
6165   buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
6166   buf[L_DB_LEN_OFFSET] = (char)db_len;
6167   int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
6168   return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
6169 }
6170 
6171 
6172 /*
6173   Load_log_event::write_data_body()
6174 */
6175 
write_data_body(IO_CACHE * file)6176 bool Load_log_event::write_data_body(IO_CACHE* file)
6177 {
6178   if (sql_ex.write_data(file))
6179     return 1;
6180   if (num_fields && fields && field_lens)
6181   {
6182     if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
6183 	my_b_safe_write(file, (uchar*)fields, field_block_len))
6184       return 1;
6185   }
6186   return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
6187 	  my_b_safe_write(file, (uchar*)db, db_len + 1) ||
6188 	  my_b_safe_write(file, (uchar*)fname, fname_len));
6189 }
6190 
6191 
6192 /*
6193   Load_log_event::Load_log_event()
6194 */
6195 
Load_log_event(THD * thd_arg,sql_exchange * ex,const char * db_arg,const char * table_name_arg,List<Item> & fields_arg,bool is_concurrent_arg,enum enum_duplicates handle_dup,bool ignore,bool using_trans)6196 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
6197 			       const char *db_arg, const char *table_name_arg,
6198 			       List<Item> &fields_arg,
6199                                bool is_concurrent_arg,
6200 			       enum enum_duplicates handle_dup,
6201 			       bool ignore, bool using_trans)
6202   :Log_event(thd_arg,
6203              thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
6204              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
6205                            Log_event::EVENT_STMT_CACHE,
6206              Log_event::EVENT_NORMAL_LOGGING),
6207    thread_id(thd_arg->thread_id),
6208    slave_proxy_id(thd_arg->variables.pseudo_thread_id),
6209    num_fields(0),fields(0),
6210    field_lens(0),field_block_len(0),
6211    table_name(table_name_arg ? table_name_arg : ""),
6212    db(db_arg), fname(ex->file_name), local_fname(FALSE),
6213    is_concurrent(is_concurrent_arg)
6214 {
6215 
6216   /*
6217   exec_time calculation has changed to use the same method that is used
6218   to fill out "thd_arg->start_time"
6219   */
6220 
6221   struct timeval end_time;
6222   ulonglong micro_end_time= my_micro_time();
6223   my_micro_time_to_timeval(micro_end_time, &end_time);
6224 
6225   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
6226 
6227   /* db can never be a zero pointer in 4.0 */
6228   db_len = (uint32) strlen(db);
6229   table_name_len = (uint32) strlen(table_name);
6230   fname_len = (fname) ? (uint) strlen(fname) : 0;
6231   sql_ex.field_term = (char*) ex->field_term->ptr();
6232   sql_ex.field_term_len = (uint8) ex->field_term->length();
6233   sql_ex.enclosed = (char*) ex->enclosed->ptr();
6234   sql_ex.enclosed_len = (uint8) ex->enclosed->length();
6235   sql_ex.line_term = (char*) ex->line_term->ptr();
6236   sql_ex.line_term_len = (uint8) ex->line_term->length();
6237   sql_ex.line_start = (char*) ex->line_start->ptr();
6238   sql_ex.line_start_len = (uint8) ex->line_start->length();
6239   sql_ex.escaped = (char*) ex->escaped->ptr();
6240   sql_ex.escaped_len = (uint8) ex->escaped->length();
6241   sql_ex.opt_flags = 0;
6242   sql_ex.cached_new_format = -1;
6243 
6244   if (ex->dumpfile)
6245     sql_ex.opt_flags|= DUMPFILE_FLAG;
6246   if (ex->opt_enclosed)
6247     sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
6248 
6249   sql_ex.empty_flags= 0;
6250 
6251   switch (handle_dup) {
6252   case DUP_REPLACE:
6253     sql_ex.opt_flags|= REPLACE_FLAG;
6254     break;
6255   case DUP_UPDATE:				// Impossible here
6256   case DUP_ERROR:
6257     break;
6258   }
6259   if (ignore)
6260     sql_ex.opt_flags|= IGNORE_FLAG;
6261 
6262   if (!ex->field_term->length())
6263     sql_ex.empty_flags |= FIELD_TERM_EMPTY;
6264   if (!ex->enclosed->length())
6265     sql_ex.empty_flags |= ENCLOSED_EMPTY;
6266   if (!ex->line_term->length())
6267     sql_ex.empty_flags |= LINE_TERM_EMPTY;
6268   if (!ex->line_start->length())
6269     sql_ex.empty_flags |= LINE_START_EMPTY;
6270   if (!ex->escaped->length())
6271     sql_ex.empty_flags |= ESCAPED_EMPTY;
6272 
6273   skip_lines = ex->skip_lines;
6274 
6275   List_iterator<Item> li(fields_arg);
6276   field_lens_buf.length(0);
6277   fields_buf.length(0);
6278   Item* item;
6279   while ((item = li++))
6280   {
6281     num_fields++;
6282     uchar len= (uchar) item->item_name.length();
6283     field_block_len += len + 1;
6284     fields_buf.append(item->item_name.ptr(), len + 1);
6285     field_lens_buf.append((char*)&len, 1);
6286   }
6287 
6288   field_lens = (const uchar*)field_lens_buf.ptr();
6289   fields = fields_buf.ptr();
6290 }
6291 #endif /* !MYSQL_CLIENT */
6292 
6293 
6294 /**
6295   @note
6296     The caller must do buf[event_len] = 0 before he starts using the
6297     constructed event.
6298 */
Load_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6299 Load_log_event::Load_log_event(const char *buf, uint event_len,
6300                                const Format_description_log_event *description_event)
6301   :Log_event(buf, description_event), num_fields(0), fields(0),
6302    field_lens(0),field_block_len(0),
6303    table_name(0), db(0), fname(0), local_fname(FALSE),
6304    /*
6305      Load_log_event which comes from the binary log does not contain
6306      information about the type of insert which was used on the master.
6307      Assume that it was an ordinary, non-concurrent LOAD DATA.
6308     */
6309    is_concurrent(FALSE)
6310 {
6311   DBUG_ENTER("Load_log_event");
6312   /*
6313     I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6314     4.0->5.0 and 5.0->5.0 and it works.
6315   */
6316   if (event_len)
6317     copy_log_event(buf, event_len,
6318                    ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
6319                     LOAD_HEADER_LEN +
6320                     description_event->common_header_len :
6321                     LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
6322                    description_event);
6323   /* otherwise it's a derived class, will call copy_log_event() itself */
6324   DBUG_VOID_RETURN;
6325 }
6326 
6327 
6328 /*
6329   Load_log_event::copy_log_event()
6330 */
6331 
copy_log_event(const char * buf,ulong event_len,int body_offset,const Format_description_log_event * description_event)6332 int Load_log_event::copy_log_event(const char *buf, ulong event_len,
6333                                    int body_offset,
6334                                    const Format_description_log_event *description_event)
6335 {
6336   DBUG_ENTER("Load_log_event::copy_log_event");
6337   uint data_len;
6338   char* buf_end = (char*)buf + event_len;
6339   /* this is the beginning of the post-header */
6340   const char* data_head = buf + description_event->common_header_len;
6341   slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
6342   exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
6343   skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
6344   table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
6345   db_len = (uint)data_head[L_DB_LEN_OFFSET];
6346   num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
6347 
6348   if ((int) event_len < body_offset)
6349     DBUG_RETURN(1);
6350   /*
6351     Sql_ex.init() on success returns the pointer to the first byte after
6352     the sql_ex structure, which is the start of field lengths array.
6353   */
6354   if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
6355                                         buf_end,
6356                                         buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
6357     DBUG_RETURN(1);
6358 
6359   data_len = event_len - body_offset;
6360   if (num_fields > data_len) // simple sanity check against corruption
6361     DBUG_RETURN(1);
6362   for (uint i = 0; i < num_fields; i++)
6363     field_block_len += (uint)field_lens[i] + 1;
6364 
6365   fields = (char*)field_lens + num_fields;
6366   table_name  = fields + field_block_len;
6367   if (strlen(table_name) > NAME_LEN)
6368     goto err;
6369 
6370   db = table_name + table_name_len + 1;
6371   DBUG_EXECUTE_IF ("simulate_invalid_address",
6372                    db_len = data_len;);
6373   fname = db + db_len + 1;
6374   if ((db_len > data_len) || (fname > buf_end))
6375     goto err;
6376   fname_len = (uint) strlen(fname);
6377   if ((fname_len > data_len) || (fname + fname_len > buf_end))
6378     goto err;
6379   // null termination is accomplished by the caller doing buf[event_len]=0
6380 
6381   DBUG_RETURN(0);
6382 
6383 err:
6384   // Invalid event.
6385   table_name = 0;
6386   DBUG_RETURN(1);
6387 }
6388 
6389 
6390 /*
6391   Load_log_event::print()
6392 */
6393 
6394 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6395 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6396 {
6397   print(file, print_event_info, 0);
6398 }
6399 
6400 
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info,bool commented)6401 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
6402 			   bool commented)
6403 {
6404   IO_CACHE *const head= &print_event_info->head_cache;
6405   size_t id_len= 0;
6406   char temp_buf[1 + 2*FN_REFLEN + 2];
6407 
6408   DBUG_ENTER("Load_log_event::print");
6409   if (!print_event_info->short_form)
6410   {
6411     print_header(head, print_event_info, FALSE);
6412     my_b_printf(head, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
6413                 thread_id, exec_time);
6414   }
6415 
6416   bool different_db= 1;
6417   if (db)
6418   {
6419     /*
6420       If the database is different from the one of the previous statement, we
6421       need to print the "use" command, and we update the last_db.
6422       But if commented, the "use" is going to be commented so we should not
6423       update the last_db.
6424     */
6425     if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
6426         !commented)
6427       memcpy(print_event_info->db, db, db_len + 1);
6428   }
6429 
6430   if (db && db[0] && different_db)
6431   {
6432 #ifdef MYSQL_SERVER
6433     id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
6434 #else
6435     id_len= my_strmov_quoted_identifier(temp_buf, db);
6436 #endif
6437     temp_buf[id_len]= '\0';
6438     my_b_printf(head, "%suse %s%s\n",
6439                 commented ? "# " : "", temp_buf, print_event_info->delimiter);
6440   }
6441   if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
6442     my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
6443             commented ? "# " : "", (ulong)thread_id,
6444             print_event_info->delimiter);
6445   my_b_printf(head, "%sLOAD DATA ",
6446               commented ? "# " : "");
6447   if (check_fname_outside_temp_buf())
6448     my_b_printf(head, "LOCAL ");
6449   my_b_printf(head, "INFILE '%-*s' ", fname_len, fname);
6450 
6451   if (sql_ex.opt_flags & REPLACE_FLAG)
6452     my_b_printf(head,"REPLACE ");
6453   else if (sql_ex.opt_flags & IGNORE_FLAG)
6454     my_b_printf(head,"IGNORE ");
6455 
6456 #ifdef MYSQL_SERVER
6457     id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
6458 #else
6459     id_len= my_strmov_quoted_identifier(temp_buf, table_name);
6460 #endif
6461   temp_buf[id_len]= '\0';
6462   my_b_printf(head, "INTO TABLE %s", temp_buf);
6463 
6464   my_b_printf(head, " FIELDS TERMINATED BY ");
6465   pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len);
6466 
6467   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6468     my_b_printf(head," OPTIONALLY ");
6469   my_b_printf(head, " ENCLOSED BY ");
6470   pretty_print_str(head, sql_ex.enclosed, sql_ex.enclosed_len);
6471 
6472   my_b_printf(head, " ESCAPED BY ");
6473   pretty_print_str(head, sql_ex.escaped, sql_ex.escaped_len);
6474 
6475   my_b_printf(head," LINES TERMINATED BY ");
6476   pretty_print_str(head, sql_ex.line_term, sql_ex.line_term_len);
6477 
6478 
6479   if (sql_ex.line_start)
6480   {
6481     my_b_printf(head," STARTING BY ");
6482     pretty_print_str(head, sql_ex.line_start, sql_ex.line_start_len);
6483   }
6484   if ((long) skip_lines > 0)
6485     my_b_printf(head, " IGNORE %ld LINES", (long) skip_lines);
6486 
6487   if (num_fields)
6488   {
6489     uint i;
6490     const char* field = fields;
6491     my_b_printf(head, " (");
6492     for (i = 0; i < num_fields; i++)
6493     {
6494       if (i)
6495         my_b_printf(head, ",");
6496       id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
6497       temp_buf[id_len]= '\0';
6498       my_b_printf(head, "%s", temp_buf);
6499 
6500       field += field_lens[i]  + 1;
6501     }
6502     my_b_printf(head, ")");
6503   }
6504 
6505   my_b_printf(head, "%s\n", print_event_info->delimiter);
6506   DBUG_VOID_RETURN;
6507 }
6508 #endif /* MYSQL_CLIENT */
6509 
6510 #ifndef MYSQL_CLIENT
6511 
6512 /**
6513   Load_log_event::set_fields()
6514 
6515   @note
6516     This function can not use the member variable
6517     for the database, since LOAD DATA INFILE on the slave
6518     can be for a different database than the current one.
6519     This is the reason for the affected_db argument to this method.
6520 */
6521 
set_fields(const char * affected_db,List<Item> & field_list,Name_resolution_context * context)6522 void Load_log_event::set_fields(const char* affected_db,
6523 				List<Item> &field_list,
6524                                 Name_resolution_context *context)
6525 {
6526   uint i;
6527   const char* field = fields;
6528   for (i= 0; i < num_fields; i++)
6529   {
6530     field_list.push_back(new Item_field(context,
6531                                         affected_db, table_name, field));
6532     field+= field_lens[i]  + 1;
6533   }
6534 }
6535 #endif /* !MYSQL_CLIENT */
6536 
6537 
6538 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6539 /**
6540   Does the data loading job when executing a LOAD DATA on the slave.
6541 
6542   @param net
6543   @param rli
6544   @param use_rli_only_for_errors     If set to 1, rli is provided to
6545                                      Load_log_event::exec_event only for this
6546                                      function to have rli->get_rpl_log_name and
6547                                      rli->last_slave_error, both being used by
6548                                      error reports. rli's position advancing
6549                                      is skipped (done by the caller which is
6550                                      Execute_load_log_event::exec_event).
6551                                      If set to 0, rli is provided for full use,
6552                                      i.e. for error reports and position
6553                                      advancing.
6554 
6555   @todo
6556     fix this; this can be done by testing rules in
6557     Create_file_log_event::exec_event() and then discarding Append_block and
6558     al.
6559   @todo
6560     this is a bug - this needs to be moved to the I/O thread
6561 
6562   @retval
6563     0           Success
6564   @retval
6565     1           Failure
6566 */
6567 
do_apply_event(NET * net,Relay_log_info const * rli,bool use_rli_only_for_errors)6568 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
6569                                    bool use_rli_only_for_errors)
6570 {
6571   DBUG_ASSERT(thd->query() == 0);
6572   thd->reset_query_inner();                    // Should not be needed
6573   set_thd_db(thd, db, db_len);
6574   thd->is_slave_error= 0;
6575   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
6576 
6577   /* see Query_log_event::do_apply_event() and BUG#13360 */
6578   DBUG_ASSERT(!rli->m_table_map.count());
6579   /*
6580     Usually lex_start() is called by mysql_parse(), but we need it here
6581     as the present method does not call mysql_parse().
6582   */
6583   lex_start(thd);
6584   thd->lex->local_file= local_fname;
6585   mysql_reset_thd_for_next_command(thd);
6586 
6587   if (!use_rli_only_for_errors)
6588   {
6589     /*
6590       Saved for InnoDB, see comment in
6591       Query_log_event::do_apply_event()
6592     */
6593     const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
6594     DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
6595   }
6596 
6597    /*
6598     We test replicate_*_db rules. Note that we have already prepared
6599     the file to load, even if we are going to ignore and delete it
6600     now. So it is possible that we did a lot of disk writes for
6601     nothing. In other words, a big LOAD DATA INFILE on the master will
6602     still consume a lot of space on the slave (space in the relay log
6603     + space of temp files: twice the space of the file to load...)
6604     even if it will finally be ignored.  TODO: fix this; this can be
6605     done by testing rules in Create_file_log_event::do_apply_event()
6606     and then discarding Append_block and al. Another way is do the
6607     filtering in the I/O thread (more efficient: no disk writes at
6608     all).
6609 
6610 
6611     Note:   We do not need to execute reset_one_shot_variables() if this
6612             db_ok() test fails.
6613     Reason: The db stored in binlog events is the same for SET and for
6614             its companion query.  If the SET is ignored because of
6615             db_ok(), the companion query will also be ignored, and if
6616             the companion query is ignored in the db_ok() test of
6617             ::do_apply_event(), then the companion SET also have so
6618             we don't need to reset_one_shot_variables().
6619   */
6620   if (rpl_filter->db_ok(thd->db))
6621   {
6622     thd->set_time(&when);
6623     thd->set_query_id(next_query_id());
6624     thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
6625 
6626     TABLE_LIST tables;
6627     char table_buf[NAME_LEN + 1];
6628     strmov(table_buf, table_name);
6629     if (lower_case_table_names == 1)
6630       my_casedn_str(system_charset_info, table_buf);
6631     tables.init_one_table(thd->strmake(thd->db, thd->db_length),
6632                           thd->db_length,
6633                           table_buf, strlen(table_buf),
6634                           table_buf, TL_WRITE);
6635     tables.updating= 1;
6636 
6637     // the table will be opened in mysql_load
6638     if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
6639     {
6640       // TODO: this is a bug - this needs to be moved to the I/O thread
6641       if (net)
6642         skip_load_data_infile(net);
6643     }
6644     else
6645     {
6646       char llbuff[22];
6647       char *end;
6648       enum enum_duplicates handle_dup;
6649       bool ignore= 0;
6650       char *load_data_query;
6651 
6652       /*
6653         Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
6654         and written to slave's binlog if binlogging is on.
6655       */
6656       if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
6657       {
6658         /*
6659           This will set thd->fatal_error in case of OOM. So we surely will notice
6660           that something is wrong.
6661         */
6662         goto error;
6663       }
6664 
6665       print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
6666       *end= 0;
6667       thd->set_query(load_data_query, (uint) (end - load_data_query));
6668 
6669       if (sql_ex.opt_flags & REPLACE_FLAG)
6670         handle_dup= DUP_REPLACE;
6671       else if (sql_ex.opt_flags & IGNORE_FLAG)
6672       {
6673         ignore= 1;
6674         handle_dup= DUP_ERROR;
6675       }
6676       else
6677       {
6678         /*
6679           When replication is running fine, if it was DUP_ERROR on the
6680           master then we could choose IGNORE here, because if DUP_ERROR
6681           suceeded on master, and data is identical on the master and slave,
6682           then there should be no uniqueness errors on slave, so IGNORE is
6683           the same as DUP_ERROR. But in the unlikely case of uniqueness errors
6684           (because the data on the master and slave happen to be different
6685           (user error or bug), we want LOAD DATA to print an error message on
6686           the slave to discover the problem.
6687 
6688           If reading from net (a 3.23 master), mysql_load() will change this
6689           to IGNORE.
6690         */
6691         handle_dup= DUP_ERROR;
6692       }
6693       /*
6694         We need to set thd->lex->sql_command and thd->lex->duplicates
6695         since InnoDB tests these variables to decide if this is a LOAD
6696         DATA ... REPLACE INTO ... statement even though mysql_parse()
6697         is not called.  This is not needed in 5.0 since there the LOAD
6698         DATA ... statement is replicated using mysql_parse(), which
6699         sets the thd->lex fields correctly.
6700       */
6701       thd->lex->sql_command= SQLCOM_LOAD;
6702       thd->lex->duplicates= handle_dup;
6703 
6704       sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
6705       String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
6706       String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
6707       String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
6708       String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
6709       String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
6710       const String empty_str("", 0, log_cs);
6711       ex.field_term= &field_term;
6712       ex.enclosed= &enclosed;
6713       ex.line_term= &line_term;
6714       ex.line_start= &line_start;
6715       ex.escaped= &escaped;
6716 
6717       ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
6718       if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
6719         ex.field_term= &empty_str;
6720 
6721       ex.skip_lines = skip_lines;
6722       List<Item> field_list;
6723       thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
6724       set_fields(tables.db, field_list, &thd->lex->select_lex.context);
6725       thd->variables.pseudo_thread_id= thread_id;
6726       if (net)
6727       {
6728         // mysql_load will use thd->net to read the file
6729         thd->net.vio = net->vio;
6730         // Make sure the client does not get confused about the packet sequence
6731         thd->net.pkt_nr = net->pkt_nr;
6732       }
6733       /*
6734         It is safe to use tmp_list twice because we are not going to
6735         update it inside mysql_load().
6736       */
6737       List<Item> tmp_list;
6738       if (open_temporary_tables(thd, &tables) ||
6739           mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
6740                      handle_dup, ignore, net != 0))
6741         thd->is_slave_error= 1;
6742       if (thd->cuted_fields)
6743       {
6744         /* log_pos is the position of the LOAD event in the master log */
6745         sql_print_warning("Slave: load data infile on table '%s' at "
6746                           "log position %s in log '%s' produced %ld "
6747                           "warning(s). Default database: '%s'",
6748                           (char*) table_name,
6749                           llstr(log_pos,llbuff),
6750                           const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
6751                           (ulong) thd->cuted_fields,
6752                           print_slave_db_safe(thd->db));
6753       }
6754       if (net)
6755         net->pkt_nr= thd->net.pkt_nr;
6756     }
6757   }
6758   else
6759   {
6760     /*
6761       We will just ask the master to send us /dev/null if we do not
6762       want to load the data.
6763       TODO: this a bug - needs to be done in I/O thread
6764     */
6765     if (net)
6766       skip_load_data_infile(net);
6767   }
6768 
6769 error:
6770   thd->net.vio = 0;
6771   const char *remember_db= thd->db;
6772   thd->catalog= 0;
6773   thd->set_db(NULL, 0);                   /* will free the current database */
6774   thd->reset_query();
6775   thd->get_stmt_da()->set_overwrite_status(true);
6776   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
6777   thd->get_stmt_da()->set_overwrite_status(false);
6778   close_thread_tables(thd);
6779   /*
6780     - If transaction rollback was requested due to deadlock
6781       perform it and release metadata locks.
6782     - If inside a multi-statement transaction,
6783     defer the release of metadata locks until the current
6784     transaction is either committed or rolled back. This prevents
6785     other statements from modifying the table for the entire
6786     duration of this transaction.  This provides commit ordering
6787     and guarantees serializability across multiple transactions.
6788     - If in autocommit mode, or outside a transactional context,
6789     automatically release metadata locks of the current statement.
6790   */
6791   if (thd->transaction_rollback_request)
6792   {
6793     trans_rollback_implicit(thd);
6794     thd->mdl_context.release_transactional_locks();
6795   }
6796   else if (! thd->in_multi_stmt_transaction_mode())
6797     thd->mdl_context.release_transactional_locks();
6798   else
6799     thd->mdl_context.release_statement_locks();
6800 
6801   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
6802                   thd->is_slave_error= 0; thd->is_fatal_error= 1;);
6803 
6804   if (thd->is_slave_error)
6805   {
6806     /* this err/sql_errno code is copy-paste from net_send_error() */
6807     const char *err;
6808     int sql_errno;
6809     if (thd->is_error())
6810     {
6811       err= thd->get_stmt_da()->message();
6812       sql_errno= thd->get_stmt_da()->sql_errno();
6813     }
6814     else
6815     {
6816       sql_errno=ER_UNKNOWN_ERROR;
6817       err=ER(sql_errno);
6818     }
6819     rli->report(ERROR_LEVEL, sql_errno,"\
6820 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
6821                     err, (char*)table_name, print_slave_db_safe(remember_db));
6822     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6823     return 1;
6824   }
6825   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6826 
6827   if (thd->is_fatal_error)
6828   {
6829     char buf[256];
6830     my_snprintf(buf, sizeof(buf),
6831                 "Running LOAD DATA INFILE on table '%-.64s'."
6832                 " Default database: '%-.64s'",
6833                 (char*)table_name,
6834                 print_slave_db_safe(remember_db));
6835 
6836     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6837                 ER(ER_SLAVE_FATAL_ERROR), buf);
6838     return 1;
6839   }
6840 
6841   return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
6842 }
6843 #endif
6844 
6845 
6846 /**************************************************************************
6847   Rotate_log_event methods
6848 **************************************************************************/
6849 
6850 /*
6851   Rotate_log_event::pack_info()
6852 */
6853 
6854 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6855 int Rotate_log_event::pack_info(Protocol *protocol)
6856 {
6857   char buf1[256], buf[22];
6858   String tmp(buf1, sizeof(buf1), log_cs);
6859   tmp.length(0);
6860   tmp.append(new_log_ident, ident_len);
6861   tmp.append(STRING_WITH_LEN(";pos="));
6862   tmp.append(llstr(pos,buf));
6863   protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
6864   return 0;
6865 }
6866 #endif
6867 
6868 
6869 /*
6870   Rotate_log_event::print()
6871 */
6872 
6873 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6874 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6875 {
6876   char buf[22];
6877   IO_CACHE *const head= &print_event_info->head_cache;
6878 
6879   if (print_event_info->short_form)
6880     return;
6881   print_header(head, print_event_info, FALSE);
6882   my_b_printf(head, "\tRotate to ");
6883   if (new_log_ident)
6884     my_b_write(head, (uchar*) new_log_ident, (uint)ident_len);
6885   my_b_printf(head, "  pos: %s\n", llstr(pos, buf));
6886 }
6887 #endif /* MYSQL_CLIENT */
6888 
6889 
6890 
6891 /*
6892   Rotate_log_event::Rotate_log_event() (2 constructors)
6893 */
6894 
6895 
6896 #ifndef MYSQL_CLIENT
Rotate_log_event(const char * new_log_ident_arg,uint ident_len_arg,ulonglong pos_arg,uint flags_arg)6897 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
6898                                    uint ident_len_arg, ulonglong pos_arg,
6899                                    uint flags_arg)
6900   :Log_event(Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING),
6901    new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ?
6902    ident_len_arg : (uint) strlen(new_log_ident_arg)), flags(flags_arg)
6903 {
6904 #ifndef DBUG_OFF
6905   char buff[22];
6906   DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
6907   DBUG_PRINT("enter",("new_log_ident: %s  pos: %s  flags: %lu", new_log_ident_arg,
6908                       llstr(pos_arg, buff), (ulong) flags));
6909 #endif
6910   if (flags & DUP_NAME)
6911     new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
6912   if (flags & RELAY_LOG)
6913     set_relay_log_event();
6914   DBUG_VOID_RETURN;
6915 }
6916 #endif
6917 
6918 
Rotate_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6919 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
6920                                    const Format_description_log_event* description_event)
6921   :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
6922 {
6923   DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
6924   // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
6925   uint8 header_size= description_event->common_header_len;
6926   uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
6927   uint ident_offset;
6928   if (event_len < header_size)
6929     DBUG_VOID_RETURN;
6930   buf += header_size;
6931   pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
6932   ident_len = (uint)(event_len -
6933                      (header_size+post_header_len));
6934   ident_offset = post_header_len;
6935   set_if_smaller(ident_len,FN_REFLEN-1);
6936   new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
6937   DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
6938   DBUG_VOID_RETURN;
6939 }
6940 
6941 
6942 /*
6943   Rotate_log_event::write()
6944 */
6945 
6946 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6947 bool Rotate_log_event::write(IO_CACHE* file)
6948 {
6949   char buf[ROTATE_HEADER_LEN];
6950   int8store(buf + R_POS_OFFSET, pos);
6951   return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
6952           wrapper_my_b_safe_write(file, (uchar*) buf, ROTATE_HEADER_LEN) ||
6953           wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
6954                                      (uint) ident_len) ||
6955           write_footer(file));
6956 }
6957 #endif
6958 
6959 
6960 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6961 
6962 /*
6963   Got a rotate log event from the master.
6964 
6965   This is mainly used so that we can later figure out the logname and
6966   position for the master.
6967 
6968   We can't rotate the slave's BINlog as this will cause infinitive rotations
6969   in a A -> B -> A setup.
6970   The NOTES below is a wrong comment which will disappear when 4.1 is merged.
6971 
6972   This must only be called from the Slave SQL thread, since it calls
6973   flush_relay_log_info().
6974 
6975   @retval
6976     0	ok
6977 */
do_update_pos(Relay_log_info * rli)6978 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
6979 {
6980   int error= 0;
6981   DBUG_ENTER("Rotate_log_event::do_update_pos");
6982 #ifndef DBUG_OFF
6983   char buf[32];
6984 #endif
6985 
6986   DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
6987                       (ulong) this->server_id, (ulong) ::server_id));
6988   DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
6989   DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
6990 
6991   /*
6992     If we are in a transaction or in a group: the only normal case is
6993     when the I/O thread was copying a big transaction, then it was
6994     stopped and restarted: we have this in the relay log:
6995 
6996     BEGIN
6997     ...
6998     ROTATE (a fake one)
6999     ...
7000     COMMIT or ROLLBACK
7001 
7002     In that case, we don't want to touch the coordinates which
7003     correspond to the beginning of the transaction.  Starting from
7004     5.0.0, there also are some rotates from the slave itself, in the
7005     relay log, which shall not change the group positions.
7006   */
7007 
7008   /*
7009     The way we check if SQL thread is currently in a group is different
7010     for STS and MTS.
7011   */
7012   bool in_group = rli->is_parallel_exec() ?
7013     (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) :
7014     rli->is_in_group();
7015 
7016   if ((server_id != ::server_id || rli->replicate_same_server_id) &&
7017       !is_relay_log_event() &&
7018       !in_group)
7019   {
7020     if (rli->is_parallel_exec())
7021     {
7022       /*
7023         Rotate events are special events that are handled as a
7024         synchronization point. For that reason, the checkpoint
7025         routine is being called here.
7026       */
7027       if ((error= mts_checkpoint_routine(rli, 0, false,
7028                                          true/*need_data_lock=true*/)))
7029         goto err;
7030     }
7031 
7032     /*
7033       Acquire protection against global BINLOG lock before rli->data_lock is
7034       locked (otherwise we would also block SHOW SLAVE STATUS).
7035     */
7036     DBUG_ASSERT(!thd->backup_binlog_lock.is_acquired());
7037     DBUG_PRINT("debug", ("Acquiring binlog protection lock"));
7038     mysql_mutex_assert_not_owner(&rli->data_lock);
7039     const ulong timeout= thd->variables.lock_wait_timeout;
7040     if (thd->backup_binlog_lock.acquire_protection(thd, MDL_EXPLICIT, timeout))
7041     {
7042       error= 1;
7043       goto err;
7044     }
7045 
7046     mysql_mutex_lock(&rli->data_lock);
7047     DBUG_PRINT("info", ("old group_master_log_name: '%s'  "
7048                         "old group_master_log_pos: %lu",
7049                         rli->get_group_master_log_name(),
7050                         (ulong) rli->get_group_master_log_pos()));
7051 
7052     memcpy((void *)rli->get_group_master_log_name(),
7053            new_log_ident, ident_len + 1);
7054     rli->notify_group_master_log_name_update();
7055     if ((error= rli->inc_group_relay_log_pos(pos,
7056                                              false/*need_data_lock=false*/)))
7057     {
7058       mysql_mutex_unlock(&rli->data_lock);
7059       DBUG_PRINT("debug", ("Releasing binlog protection lock"));
7060       thd->backup_binlog_lock.release_protection(thd);
7061       goto err;
7062     }
7063 
7064     DBUG_PRINT("info", ("new group_master_log_name: '%s'  "
7065                         "new group_master_log_pos: %lu",
7066                         rli->get_group_master_log_name(),
7067                         (ulong) rli->get_group_master_log_pos()));
7068     mysql_mutex_unlock(&rli->data_lock);
7069 
7070     DBUG_PRINT("debug", ("Releasing binlog protection lock"));
7071     thd->backup_binlog_lock.release_protection(thd);
7072 
7073     if (rli->is_parallel_exec())
7074     {
7075       bool real_event= server_id && !is_artificial_event();
7076       time_t ts= when.tv_sec + static_cast<time_t>(exec_time);
7077       rli->reset_notified_checkpoint(0,
7078                                      real_event ? &ts : NULL,
7079                                      true/*need_data_lock=true*/);
7080     }
7081 
7082     /*
7083       Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
7084       a master's downgrade from 5.0 to 4.0.
7085       However, no need to reset rli_description_event: indeed, if the next
7086       master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
7087       master is 4.0 then the events are in the slave's format (conversion).
7088     */
7089     set_slave_thread_options(thd);
7090     set_slave_thread_default_charset(thd, rli);
7091     thd->variables.sql_mode= global_system_variables.sql_mode;
7092     thd->variables.auto_increment_increment=
7093       thd->variables.auto_increment_offset= 1;
7094   }
7095   else
7096     rli->inc_event_relay_log_pos();
7097 
7098 err:
7099   DBUG_RETURN(error);
7100 }
7101 
7102 
7103 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7104 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
7105 {
7106   enum_skip_reason reason= Log_event::do_shall_skip(rli);
7107 
7108   switch (reason) {
7109   case Log_event::EVENT_SKIP_NOT:
7110   case Log_event::EVENT_SKIP_COUNT:
7111     return Log_event::EVENT_SKIP_NOT;
7112 
7113   case Log_event::EVENT_SKIP_IGNORE:
7114     return Log_event::EVENT_SKIP_IGNORE;
7115   }
7116   DBUG_ASSERT(0);
7117   return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
7118 }
7119 
7120 #endif
7121 
7122 
7123 /**************************************************************************
7124 	Intvar_log_event methods
7125 **************************************************************************/
7126 
7127 /*
7128   Intvar_log_event::pack_info()
7129 */
7130 
7131 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7132 int Intvar_log_event::pack_info(Protocol *protocol)
7133 {
7134   char buf[256], *pos;
7135   pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
7136   *pos++= '=';
7137   pos= longlong10_to_str(val, pos, -10);
7138   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7139   return 0;
7140 }
7141 #endif
7142 
7143 
7144 /*
7145   Intvar_log_event::Intvar_log_event()
7146 */
7147 
Intvar_log_event(const char * buf,const Format_description_log_event * description_event)7148 Intvar_log_event::Intvar_log_event(const char* buf,
7149                                    const Format_description_log_event* description_event)
7150   :Log_event(buf, description_event)
7151 {
7152   /* The Post-Header is empty. The Varible Data part begins immediately. */
7153   buf+= description_event->common_header_len +
7154     description_event->post_header_len[INTVAR_EVENT-1];
7155   type= buf[I_TYPE_OFFSET];
7156   val= uint8korr(buf+I_VAL_OFFSET);
7157 }
7158 
7159 
7160 /*
7161   Intvar_log_event::get_var_type_name()
7162 */
7163 
get_var_type_name()7164 const char* Intvar_log_event::get_var_type_name()
7165 {
7166   switch(type) {
7167   case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
7168   case INSERT_ID_EVENT: return "INSERT_ID";
7169   default: /* impossible */ return "UNKNOWN";
7170   }
7171 }
7172 
7173 
7174 /*
7175   Intvar_log_event::write()
7176 */
7177 
7178 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7179 bool Intvar_log_event::write(IO_CACHE* file)
7180 {
7181   uchar buf[9];
7182   buf[I_TYPE_OFFSET]= (uchar) type;
7183   int8store(buf + I_VAL_OFFSET, val);
7184   return (write_header(file, sizeof(buf)) ||
7185           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7186 	  write_footer(file));
7187 }
7188 #endif
7189 
7190 
7191 /*
7192   Intvar_log_event::print()
7193 */
7194 
7195 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7196 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7197 {
7198   char llbuff[22];
7199   const char *msg;
7200   LINT_INIT(msg);
7201   IO_CACHE *const head= &print_event_info->head_cache;
7202 
7203   if (!print_event_info->short_form)
7204   {
7205     print_header(head, print_event_info, FALSE);
7206     my_b_printf(head, "\tIntvar\n");
7207   }
7208 
7209   my_b_printf(head, "SET ");
7210   switch (type) {
7211   case LAST_INSERT_ID_EVENT:
7212     msg="LAST_INSERT_ID";
7213     break;
7214   case INSERT_ID_EVENT:
7215     msg="INSERT_ID";
7216     break;
7217   case INVALID_INT_EVENT:
7218   default: // cannot happen
7219     msg="INVALID_INT";
7220     break;
7221   }
7222   my_b_printf(head, "%s=%s%s\n",
7223               msg, llstr(val,llbuff), print_event_info->delimiter);
7224 }
7225 #endif
7226 
7227 
7228 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
7229 
7230 /*
7231   Intvar_log_event::do_apply_event()
7232 */
7233 
do_apply_event(Relay_log_info const * rli)7234 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
7235 {
7236   /*
7237     We are now in a statement until the associated query log event has
7238     been processed.
7239    */
7240   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7241 
7242   if (rli->deferred_events_collecting)
7243     return rli->deferred_events->add(this);
7244 
7245   switch (type) {
7246   case LAST_INSERT_ID_EVENT:
7247     thd->first_successful_insert_id_in_prev_stmt= val;
7248     break;
7249   case INSERT_ID_EVENT:
7250     thd->force_one_auto_inc_interval(val);
7251     break;
7252   }
7253   return 0;
7254 }
7255 
do_update_pos(Relay_log_info * rli)7256 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
7257 {
7258   rli->inc_event_relay_log_pos();
7259   return 0;
7260 }
7261 
7262 
7263 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7264 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
7265 {
7266   /*
7267     It is a common error to set the slave skip counter to 1 instead of
7268     2 when recovering from an insert which used a auto increment,
7269     rand, or user var.  Therefore, if the slave skip counter is 1, we
7270     just say that this event should be skipped by ignoring it, meaning
7271     that we do not change the value of the slave skip counter since it
7272     will be decreased by the following insert event.
7273   */
7274   return continue_group(rli);
7275 }
7276 
7277 #endif
7278 
7279 
7280 /**************************************************************************
7281   Rand_log_event methods
7282 **************************************************************************/
7283 
7284 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7285 int Rand_log_event::pack_info(Protocol *protocol)
7286 {
7287   char buf1[256], *pos;
7288   pos= strmov(buf1,"rand_seed1=");
7289   pos= int10_to_str((long) seed1, pos, 10);
7290   pos= strmov(pos, ",rand_seed2=");
7291   pos= int10_to_str((long) seed2, pos, 10);
7292   protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
7293   return 0;
7294 }
7295 #endif
7296 
7297 
Rand_log_event(const char * buf,const Format_description_log_event * description_event)7298 Rand_log_event::Rand_log_event(const char* buf,
7299                                const Format_description_log_event* description_event)
7300   :Log_event(buf, description_event)
7301 {
7302   /* The Post-Header is empty. The Variable Data part begins immediately. */
7303   buf+= description_event->common_header_len +
7304     description_event->post_header_len[RAND_EVENT-1];
7305   seed1= uint8korr(buf+RAND_SEED1_OFFSET);
7306   seed2= uint8korr(buf+RAND_SEED2_OFFSET);
7307 }
7308 
7309 
7310 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7311 bool Rand_log_event::write(IO_CACHE* file)
7312 {
7313   uchar buf[16];
7314   int8store(buf + RAND_SEED1_OFFSET, seed1);
7315   int8store(buf + RAND_SEED2_OFFSET, seed2);
7316   return (write_header(file, sizeof(buf)) ||
7317           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7318 	  write_footer(file));
7319 }
7320 #endif
7321 
7322 
7323 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7324 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7325 {
7326   IO_CACHE *const head= &print_event_info->head_cache;
7327 
7328   char llbuff[22],llbuff2[22];
7329   if (!print_event_info->short_form)
7330   {
7331     print_header(head, print_event_info, FALSE);
7332     my_b_printf(head, "\tRand\n");
7333   }
7334   my_b_printf(head, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
7335               llstr(seed1, llbuff),llstr(seed2, llbuff2),
7336               print_event_info->delimiter);
7337 }
7338 #endif /* MYSQL_CLIENT */
7339 
7340 
7341 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)7342 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
7343 {
7344   /*
7345     We are now in a statement until the associated query log event has
7346     been processed.
7347    */
7348   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7349 
7350   if (rli->deferred_events_collecting)
7351     return rli->deferred_events->add(this);
7352 
7353   thd->rand.seed1= (ulong) seed1;
7354   thd->rand.seed2= (ulong) seed2;
7355   return 0;
7356 }
7357 
do_update_pos(Relay_log_info * rli)7358 int Rand_log_event::do_update_pos(Relay_log_info *rli)
7359 {
7360   rli->inc_event_relay_log_pos();
7361   return 0;
7362 }
7363 
7364 
7365 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7366 Rand_log_event::do_shall_skip(Relay_log_info *rli)
7367 {
7368   /*
7369     It is a common error to set the slave skip counter to 1 instead of
7370     2 when recovering from an insert which used a auto increment,
7371     rand, or user var.  Therefore, if the slave skip counter is 1, we
7372     just say that this event should be skipped by ignoring it, meaning
7373     that we do not change the value of the slave skip counter since it
7374     will be decreased by the following insert event.
7375   */
7376   return continue_group(rli);
7377 }
7378 
7379 /**
7380    Exec deferred Int-, Rand- and User- var events prefixing
7381    a Query-log-event event.
7382 
7383    @param thd THD handle
7384 
7385    @return false on success, true if a failure in an event applying occurred.
7386 */
slave_execute_deferred_events(THD * thd)7387 bool slave_execute_deferred_events(THD *thd)
7388 {
7389   bool res= false;
7390   Relay_log_info *rli= thd->rli_slave;
7391 
7392   DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
7393 
7394   if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
7395     return res;
7396 
7397   res= rli->deferred_events->execute(rli);
7398 
7399   return res;
7400 }
7401 
7402 #endif /* !MYSQL_CLIENT */
7403 
7404 
7405 /**************************************************************************
7406   Xid_log_event methods
7407 **************************************************************************/
7408 
7409 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7410 int Xid_log_event::pack_info(Protocol *protocol)
7411 {
7412   char buf[128], *pos;
7413   pos= strmov(buf, "COMMIT /* xid=");
7414   pos= longlong10_to_str(xid, pos, 10);
7415   pos= strmov(pos, " */");
7416   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7417   return 0;
7418 }
7419 #endif
7420 
7421 /**
7422   @note
7423   It's ok not to use int8store here,
7424   as long as xid_t::set(ulonglong) and
7425   xid_t::get_my_xid doesn't do it either.
7426   We don't care about actual values of xids as long as
7427   identical numbers compare identically
7428 */
7429 
7430 Xid_log_event::
Xid_log_event(const char * buf,const Format_description_log_event * description_event)7431 Xid_log_event(const char* buf,
7432               const Format_description_log_event *description_event)
7433   :Log_event(buf, description_event)
7434 {
7435   /* The Post-Header is empty. The Variable Data part begins immediately. */
7436   buf+= description_event->common_header_len +
7437     description_event->post_header_len[XID_EVENT-1];
7438   memcpy((char*) &xid, buf, sizeof(xid));
7439 }
7440 
7441 
7442 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7443 bool Xid_log_event::write(IO_CACHE* file)
7444 {
7445   DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
7446   return (write_header(file, sizeof(xid)) ||
7447 	  wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
7448 	  write_footer(file));
7449 }
7450 #endif
7451 
7452 
7453 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7454 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7455 {
7456   IO_CACHE *const head= &print_event_info->head_cache;
7457 
7458   if (!print_event_info->short_form)
7459   {
7460     char buf[64];
7461     longlong10_to_str(xid, buf, 10);
7462 
7463     print_header(head, print_event_info, FALSE);
7464     my_b_printf(head, "\tXid = %s\n", buf);
7465   }
7466   my_b_printf(head, "COMMIT%s\n", print_event_info->delimiter);
7467 }
7468 #endif /* MYSQL_CLIENT */
7469 
7470 
7471 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7472 /**
7473    The methods combines few commit actions to make it useable
7474    as in the single- so multi- threaded case.
7475 
7476    @param  thd    a pointer to THD handle
7477    @return false  as success and
7478            true   as an error
7479 */
7480 
do_commit(THD * thd)7481 bool Xid_log_event::do_commit(THD *thd)
7482 {
7483   DBUG_EXECUTE_IF("dbug.reached_commit",
7484                   {DBUG_SET("+d,dbug.enabled_commit");});
7485   bool error= trans_commit(thd); /* Automatically rolls back on error. */
7486   DBUG_EXECUTE_IF("crash_after_apply",
7487                   sql_print_information("Crashing crash_after_apply.");
7488                   DBUG_SUICIDE(););
7489   thd->mdl_context.release_transactional_locks();
7490 
7491   if (thd->variables.gtid_next.type == GTID_GROUP &&
7492       thd->owned_gtid.sidno != 0)
7493   {
7494     // GTID logging and cleanup runs regardless of the current res
7495     error |= gtid_empty_group_log_and_cleanup(thd);
7496   }
7497 
7498   /*
7499     Increment the global status commit count variable
7500   */
7501   if (!error)
7502     status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
7503 
7504   return error;
7505 }
7506 
7507 /**
7508    Worker commits Xid transaction and in case of its transactional
7509    info table marks the current group as done in the Coordnator's
7510    Group Assigned Queue.
7511 
7512    @return zero as success or non-zero as an error
7513 */
do_apply_event_worker(Slave_worker * w)7514 int Xid_log_event::do_apply_event_worker(Slave_worker *w)
7515 {
7516   int error= 0;
7517   lex_start(thd);
7518   mysql_reset_thd_for_next_command(thd);
7519   Slave_committed_queue *coordinator_gaq= w->c_rli->gaq;
7520 
7521   /* For a slave Xid_log_event is COMMIT */
7522   general_log_print(thd, COM_QUERY,
7523                     "COMMIT /* implicit, from Xid_log_event */");
7524 
7525   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7526                      w->get_group_master_log_name(),
7527                      w->get_group_master_log_pos(),
7528                      w->get_group_relay_log_name(),
7529                      w->get_group_relay_log_pos(),
7530                      w->get_event_relay_log_name(),
7531                      w->get_event_relay_log_pos()));
7532 
7533   DBUG_EXECUTE_IF("crash_before_update_pos",
7534                   sql_print_information("Crashing crash_before_update_pos.");
7535                   DBUG_SUICIDE(););
7536 
7537   ulong gaq_idx= mts_group_idx;
7538   Slave_job_group *ptr_group= coordinator_gaq->get_job_group(gaq_idx);
7539 
7540   if ((error= w->commit_positions(this, ptr_group,
7541                                   w->c_rli->is_transactional())))
7542     goto err;
7543 
7544   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7545                      w->get_group_master_log_name(),
7546                      w->get_group_master_log_pos(),
7547                      w->get_group_relay_log_name(),
7548                      w->get_group_relay_log_pos(),
7549                      w->get_event_relay_log_name(),
7550                      w->get_event_relay_log_pos()));
7551 
7552   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7553                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7554                   DBUG_SUICIDE(););
7555 
7556   error= do_commit(thd);
7557   if (error)
7558     w->rollback_positions(ptr_group);
7559 err:
7560   return error;
7561 }
7562 
do_apply_event(Relay_log_info const * rli)7563 int Xid_log_event::do_apply_event(Relay_log_info const *rli)
7564 {
7565   DBUG_ENTER("Xid_log_event::do_apply_event");
7566   int error= 0;
7567   char saved_group_master_log_name[FN_REFLEN];
7568   char saved_group_relay_log_name[FN_REFLEN];
7569   volatile my_off_t saved_group_master_log_pos;
7570   volatile my_off_t saved_group_relay_log_pos;
7571 
7572   char new_group_master_log_name[FN_REFLEN];
7573   char new_group_relay_log_name[FN_REFLEN];
7574   volatile my_off_t new_group_master_log_pos;
7575   volatile my_off_t new_group_relay_log_pos;
7576 
7577   lex_start(thd);
7578   mysql_reset_thd_for_next_command(thd);
7579   Relay_log_info *rli_ptr= const_cast<Relay_log_info *>(rli);
7580   bool binlog_prot_acquired= false;
7581 
7582   /* For a slave Xid_log_event is COMMIT */
7583   general_log_print(thd, COM_QUERY,
7584                     "COMMIT /* implicit, from Xid_log_event */");
7585 
7586   if (!thd->backup_binlog_lock.is_acquired())
7587   {
7588     const ulong timeout= thd->variables.lock_wait_timeout;
7589 
7590     DBUG_PRINT("debug", ("Acquiring binlog protection lock"));
7591     mysql_mutex_assert_not_owner(&rli->data_lock);
7592     if (thd->backup_binlog_lock.acquire_protection(thd, MDL_EXPLICIT,
7593                                                    timeout))
7594       DBUG_RETURN(1);
7595 
7596     binlog_prot_acquired= true;
7597   }
7598 
7599   mysql_mutex_lock(&rli_ptr->data_lock);
7600 
7601   /*
7602     Save the rli positions. We need them to temporarily reset the positions
7603     just before the commit.
7604    */
7605   strmake(saved_group_master_log_name, rli_ptr->get_group_master_log_name(),
7606           FN_REFLEN - 1);
7607   saved_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7608   strmake(saved_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7609           FN_REFLEN - 1);
7610   saved_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7611 
7612   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7613     rli_ptr->get_group_master_log_name(),
7614     rli_ptr->get_group_master_log_pos(),
7615     rli_ptr->get_group_relay_log_name(),
7616     rli_ptr->get_group_relay_log_pos(),
7617     rli_ptr->get_event_relay_log_name(),
7618     rli_ptr->get_event_relay_log_pos()));
7619 
7620   DBUG_EXECUTE_IF("crash_before_update_pos",
7621                   sql_print_information("Crashing crash_before_update_pos.");
7622                   DBUG_SUICIDE(););
7623 
7624   /*
7625     We need to update the positions in here to make it transactional.
7626   */
7627   rli_ptr->inc_event_relay_log_pos();
7628   rli_ptr->set_group_relay_log_pos(rli_ptr->get_event_relay_log_pos());
7629   rli_ptr->set_group_relay_log_name(rli_ptr->get_event_relay_log_name());
7630 
7631   rli_ptr->notify_group_relay_log_name_update();
7632 
7633   if (log_pos) // 3.23 binlogs don't have log_posx
7634     rli_ptr->set_group_master_log_pos(log_pos);
7635 
7636   /*
7637     rli repository being transactional means replication is crash safe.
7638     Positions are written into transactional tables ahead of commit and the
7639     changes are made permanent during commit.
7640    */
7641   if (rli_ptr->is_transactional())
7642   {
7643     if ((error= rli_ptr->flush_info(true)))
7644       goto err;
7645   }
7646 
7647   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7648                       rli_ptr->get_group_master_log_name(),
7649                       rli_ptr->get_group_master_log_pos(),
7650                       rli_ptr->get_group_relay_log_name(),
7651                       rli_ptr->get_group_relay_log_pos(),
7652                       rli_ptr->get_event_relay_log_name(),
7653                       rli_ptr->get_event_relay_log_pos()));
7654 
7655   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7656                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7657                   DBUG_SUICIDE(););
7658 
7659   /**
7660     Commit operation expects the global transaction state variable 'xa_state'to
7661     be set to 'XA_NOTR'. In order to simulate commit failure we set
7662     the 'xa_state' to 'XA_IDLE' so that the commit reports 'ER_XAER_RMFAIL'
7663     error.
7664    */
7665   DBUG_EXECUTE_IF("simulate_commit_failure",
7666                   {
7667                   thd->transaction.xid_state.xa_state = XA_IDLE;
7668                   });
7669 
7670   /*
7671     Save the new rli positions. These positions will be set back to group*
7672     positions on successful completion of the commit operation.
7673    */
7674   strmake(new_group_master_log_name, rli_ptr->get_group_master_log_name(),
7675           FN_REFLEN - 1);
7676   new_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7677   strmake(new_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7678           FN_REFLEN - 1);
7679   new_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7680   /*
7681     Rollback positions in memory just before commit. Position values will be
7682     reset to their new values only on successful commit operation.
7683    */
7684   rli_ptr->set_group_master_log_name(saved_group_master_log_name);
7685   rli_ptr->notify_group_master_log_name_update();
7686   rli_ptr->set_group_master_log_pos(saved_group_master_log_pos);
7687   rli_ptr->set_group_relay_log_name(saved_group_relay_log_name);
7688   rli_ptr->notify_group_relay_log_name_update();
7689   rli_ptr->set_group_relay_log_pos(saved_group_relay_log_pos);
7690 
7691   DBUG_PRINT("info", ("Rolling back to group master %s %llu  group relay %s"
7692                       " %llu\n", rli_ptr->get_group_master_log_name(),
7693                       rli_ptr->get_group_master_log_pos(),
7694                       rli_ptr->get_group_relay_log_name(),
7695                       rli_ptr->get_group_relay_log_pos()));
7696   mysql_mutex_unlock(&rli_ptr->data_lock);
7697   error= do_commit(thd);
7698   mysql_mutex_lock(&rli_ptr->data_lock);
7699   if (error)
7700   {
7701     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
7702                 "Error in Xid_log_event: Commit could not be completed, '%s'",
7703                 thd->get_stmt_da()->message());
7704   }
7705   else
7706   {
7707     DBUG_EXECUTE_IF("crash_after_commit_before_update_pos",
7708                     sql_print_information("Crashing "
7709                                           "crash_after_commit_before_update_pos.");
7710                     DBUG_SUICIDE(););
7711     /* Update positions on successful commit */
7712     rli_ptr->set_group_master_log_name(new_group_master_log_name);
7713     rli_ptr->notify_group_master_log_name_update();
7714     rli_ptr->set_group_master_log_pos(new_group_master_log_pos);
7715     rli_ptr->set_group_relay_log_name(new_group_relay_log_name);
7716     rli_ptr->notify_group_relay_log_name_update();
7717     rli_ptr->set_group_relay_log_pos(new_group_relay_log_pos);
7718 
7719     DBUG_PRINT("info", ("Updating positions on succesful commit to group master"
7720                         " %s %llu  group relay %s %llu\n",
7721                         rli_ptr->get_group_master_log_name(),
7722                         rli_ptr->get_group_master_log_pos(),
7723                         rli_ptr->get_group_relay_log_name(),
7724                         rli_ptr->get_group_relay_log_pos()));
7725 
7726     /*
7727       For transactional repository the positions are flushed ahead of commit.
7728       Where as for non transactional rli repository the positions are flushed
7729       only on succesful commit.
7730      */
7731     if (!rli_ptr->is_transactional())
7732       rli_ptr->flush_info(false);
7733   }
7734 err:
7735   mysql_cond_broadcast(&rli_ptr->data_cond);
7736   mysql_mutex_unlock(&rli_ptr->data_lock);
7737 
7738   if (binlog_prot_acquired)
7739   {
7740       DBUG_PRINT("debug", ("Releasing binlog protection lock"));
7741       thd->backup_binlog_lock.release_protection(thd);
7742   }
7743 
7744   DBUG_RETURN(error);
7745 }
7746 
7747 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7748 Xid_log_event::do_shall_skip(Relay_log_info *rli)
7749 {
7750   DBUG_ENTER("Xid_log_event::do_shall_skip");
7751   if (rli->slave_skip_counter > 0) {
7752     thd->variables.option_bits&= ~OPTION_BEGIN;
7753     DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
7754   }
7755   DBUG_RETURN(Log_event::do_shall_skip(rli));
7756 }
7757 #endif /* !MYSQL_CLIENT */
7758 
7759 
7760 /**************************************************************************
7761   User_var_log_event methods
7762 **************************************************************************/
7763 
7764 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7765 int User_var_log_event::pack_info(Protocol* protocol)
7766 {
7767   char *buf= 0;
7768   char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
7769   int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len);
7770   quoted_id[id_len]= '\0';
7771   uint val_offset= 2 + id_len;
7772   uint event_len= val_offset;
7773 
7774   if (is_null)
7775   {
7776     if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
7777       return 1;
7778     strmov(buf + val_offset, "NULL");
7779     event_len= val_offset + 4;
7780   }
7781   else
7782   {
7783     switch (type) {
7784     case REAL_RESULT:
7785       double real_val;
7786       float8get(real_val, val);
7787       if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
7788                                    MYF(MY_WME))))
7789         return 1;
7790       event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
7791                           buf + val_offset, NULL);
7792       break;
7793     case INT_RESULT:
7794       if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
7795         return 1;
7796       event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
7797                                    ((flags & User_var_log_event::UNSIGNED_F) ?
7798                                     10 : -10))-buf;
7799       break;
7800     case DECIMAL_RESULT:
7801     {
7802       if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH + 1,
7803                                    MYF(MY_WME))))
7804         return 1;
7805       String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin);
7806       my_decimal dec;
7807       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
7808                         val[1]);
7809       my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
7810       event_len= str.length() + val_offset;
7811       break;
7812     }
7813     case STRING_RESULT:
7814       /* 15 is for 'COLLATE' and other chars */
7815       buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
7816                              MYF(MY_WME));
7817       CHARSET_INFO *cs;
7818       if (!buf)
7819         return 1;
7820       if (!(cs= get_charset(charset_number, MYF(0))))
7821       {
7822         strmov(buf+val_offset, "???");
7823         event_len+= 3;
7824       }
7825       else
7826       {
7827         char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
7828         p= str_to_hex(p, val, val_len);
7829         p= strxmov(p, " COLLATE ", cs->name, NullS);
7830         event_len= p-buf;
7831       }
7832       break;
7833     case ROW_RESULT:
7834     default:
7835       DBUG_ASSERT(1);
7836       return 1;
7837     }
7838   }
7839   buf[0]= '@';
7840   memcpy(buf + 1, quoted_id, id_len);
7841   buf[1 + id_len]= '=';
7842   protocol->store(buf, event_len, &my_charset_bin);
7843   my_free(buf);
7844   return 0;
7845 }
7846 #endif /* !MYSQL_CLIENT */
7847 
7848 
7849 User_var_log_event::
User_var_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)7850 User_var_log_event(const char* buf, uint event_len,
7851                    const Format_description_log_event* description_event)
7852   :Log_event(buf, description_event)
7853 #ifndef MYSQL_CLIENT
7854   , deferred(false), query_id(0)
7855 #endif
7856 {
7857   bool error= false;
7858   const char* buf_start= buf;
7859   /* The Post-Header is empty. The Variable Data part begins immediately. */
7860   const char *start= buf;
7861   buf+= description_event->common_header_len +
7862     description_event->post_header_len[USER_VAR_EVENT-1];
7863   name_len= uint4korr(buf);
7864   /* Avoid reading out of buffer */
7865   if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
7866   {
7867     error= true;
7868     goto err;
7869   }
7870 
7871   name= (char *) buf + UV_NAME_LEN_SIZE;
7872 
7873   /*
7874     We don't know yet is_null value, so we must assume that name_len
7875     may have the bigger value possible, is_null= True and there is no
7876     payload for val, or even that name_len is 0.
7877   */
7878   if (!valid_buffer_range<uint>(name_len, buf_start, name,
7879                                 event_len - UV_VAL_IS_NULL))
7880   {
7881     error= true;
7882     goto err;
7883   }
7884 
7885   buf+= UV_NAME_LEN_SIZE + name_len;
7886   is_null= (bool) *buf;
7887   flags= User_var_log_event::UNDEF_F;    // defaults to UNDEF_F
7888   if (is_null)
7889   {
7890     type= STRING_RESULT;
7891     charset_number= my_charset_bin.number;
7892     val_len= 0;
7893     val= 0;
7894   }
7895   else
7896   {
7897     if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
7898                                   + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
7899                                   buf_start, buf, event_len))
7900     {
7901       error= true;
7902       goto err;
7903     }
7904 
7905     type= (Item_result) buf[UV_VAL_IS_NULL];
7906     charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
7907     val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7908                        UV_CHARSET_NUMBER_SIZE);
7909     val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7910                    UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
7911 
7912     if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
7913     {
7914       error= true;
7915       goto err;
7916     }
7917 
7918     /**
7919       We need to check if this is from an old server
7920       that did not pack information for flags.
7921       We do this by checking if there are extra bytes
7922       after the packed value. If there are we take the
7923       extra byte and it's value is assumed to contain
7924       the flags value.
7925 
7926       Old events will not have this extra byte, thence,
7927       we keep the flags set to UNDEF_F.
7928     */
7929     uint bytes_read= ((val + val_len) - start);
7930     if (bytes_read > event_len)
7931     {
7932       error= true;
7933       goto err;
7934     }
7935 #ifndef DBUG_OFF
7936     bool old_pre_checksum_fd= description_event->is_version_before_checksum();
7937     const int checksum_length = (old_pre_checksum_fd || description_event->checksum_alg == BINLOG_CHECKSUM_ALG_OFF) ? 0 : BINLOG_CHECKSUM_LEN;
7938 #endif
7939     DBUG_ASSERT(bytes_read == data_written - checksum_length || bytes_read == data_written - checksum_length - 1);
7940     if ((data_written - bytes_read) > 0)
7941     {
7942       flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7943                     UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
7944                     val_len);
7945     }
7946   }
7947 
7948 err:
7949   if (error)
7950     name= 0;
7951 }
7952 
7953 
7954 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7955 bool User_var_log_event::write(IO_CACHE* file)
7956 {
7957   char buf[UV_NAME_LEN_SIZE];
7958   char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7959 	    UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
7960   uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
7961   uint unsigned_len= 0;
7962   uint buf1_length;
7963   ulong event_length;
7964 
7965   int4store(buf, name_len);
7966 
7967   if ((buf1[0]= is_null))
7968   {
7969     buf1_length= 1;
7970     val_len= 0;                                 // Length of 'pos'
7971   }
7972   else
7973   {
7974     buf1[1]= type;
7975     int4store(buf1 + 2, charset_number);
7976 
7977     switch (type) {
7978     case REAL_RESULT:
7979       float8store(buf2, *(double*) val);
7980       break;
7981     case INT_RESULT:
7982       int8store(buf2, *(longlong*) val);
7983       unsigned_len= 1;
7984       break;
7985     case DECIMAL_RESULT:
7986     {
7987       my_decimal *dec= (my_decimal *)val;
7988       dec->fix_buffer_pointer();
7989       buf2[0]= (char)(dec->intg + dec->frac);
7990       buf2[1]= (char)dec->frac;
7991       decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
7992       val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
7993       break;
7994     }
7995     case STRING_RESULT:
7996       pos= (uchar*) val;
7997       break;
7998     case ROW_RESULT:
7999     default:
8000       DBUG_ASSERT(1);
8001       return 0;
8002     }
8003     int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
8004     buf1_length= 10;
8005   }
8006 
8007   /* Length of the whole event */
8008   event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
8009 
8010   return (write_header(file, event_length) ||
8011           wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
8012 	  wrapper_my_b_safe_write(file, (uchar*) name, name_len)     ||
8013 	  wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
8014 	  wrapper_my_b_safe_write(file, pos, val_len) ||
8015           wrapper_my_b_safe_write(file, &flags, unsigned_len) ||
8016 	  write_footer(file));
8017 }
8018 #endif
8019 
8020 
8021 /*
8022   User_var_log_event::print()
8023 */
8024 
8025 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8026 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8027 {
8028   IO_CACHE *const head= &print_event_info->head_cache;
8029   char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
8030   char name_id[NAME_LEN];
8031   int quoted_len= 0;
8032 
8033   if (!print_event_info->short_form)
8034   {
8035     print_header(head, print_event_info, FALSE);
8036     my_b_printf(head, "\tUser_var\n");
8037   }
8038   strmov(name_id, name);
8039   name_id[name_len]= '\0';
8040   my_b_printf(head, "SET @");
8041   quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
8042                                           (const char *) name_id);
8043   quoted_id[quoted_len]= '\0';
8044   my_b_write(head, (uchar*) quoted_id, quoted_len);
8045 
8046   if (is_null)
8047   {
8048     my_b_printf(head, ":=NULL%s\n", print_event_info->delimiter);
8049   }
8050   else
8051   {
8052     switch (type) {
8053     case REAL_RESULT:
8054       double real_val;
8055       char real_buf[FMT_G_BUFSIZE(14)];
8056       float8get(real_val, val);
8057       sprintf(real_buf, "%.14g", real_val);
8058       my_b_printf(head, ":=%s%s\n", real_buf, print_event_info->delimiter);
8059       break;
8060     case INT_RESULT:
8061       char int_buf[22];
8062       longlong10_to_str(uint8korr(val), int_buf,
8063                         ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
8064       my_b_printf(head, ":=%s%s\n", int_buf, print_event_info->delimiter);
8065       break;
8066     case DECIMAL_RESULT:
8067     {
8068       char str_buf[200];
8069       int str_len= sizeof(str_buf) - 1;
8070       int precision= (int)val[0];
8071       int scale= (int)val[1];
8072       decimal_digit_t dec_buf[10];
8073       decimal_t dec;
8074       dec.len= 10;
8075       dec.buf= dec_buf;
8076 
8077       bin2decimal((uchar*) val+2, &dec, precision, scale);
8078       decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
8079       str_buf[str_len]= 0;
8080       my_b_printf(head, ":=%s%s\n", str_buf, print_event_info->delimiter);
8081       break;
8082     }
8083     case STRING_RESULT:
8084     {
8085       /*
8086         Let's express the string in hex. That's the most robust way. If we
8087         print it in character form instead, we need to escape it with
8088         character_set_client which we don't know (we will know it in 5.0, but
8089         in 4.1 we don't know it easily when we are printing
8090         User_var_log_event). Explanation why we would need to bother with
8091         character_set_client (quoting Bar):
8092         > Note, the parser doesn't switch to another unescaping mode after
8093         > it has met a character set introducer.
8094         > For example, if an SJIS client says something like:
8095         > SET @a= _ucs2 \0a\0b'
8096         > the string constant is still unescaped according to SJIS, not
8097         > according to UCS2.
8098       */
8099       char *hex_str;
8100       CHARSET_INFO *cs;
8101 
8102       hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
8103       if (!hex_str)
8104         return;
8105       str_to_hex(hex_str, val, val_len);
8106       /*
8107         For proper behaviour when mysqlbinlog|mysql, we need to explicitely
8108         specify the variable's collation. It will however cause problems when
8109         people want to mysqlbinlog|mysql into another server not supporting the
8110         character set. But there's not much to do about this and it's unlikely.
8111       */
8112       if (!(cs= get_charset(charset_number, MYF(0))))
8113         /*
8114           Generate an unusable command (=> syntax error) is probably the best
8115           thing we can do here.
8116         */
8117         my_b_printf(head, ":=???%s\n", print_event_info->delimiter);
8118       else
8119         my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n",
8120                     cs->csname, hex_str, cs->name,
8121                     print_event_info->delimiter);
8122       my_free(hex_str);
8123     }
8124       break;
8125     case ROW_RESULT:
8126     default:
8127       DBUG_ASSERT(1);
8128       return;
8129     }
8130   }
8131 }
8132 #endif
8133 
8134 
8135 /*
8136   User_var_log_event::do_apply_event()
8137 */
8138 
8139 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8140 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
8141 {
8142   Item *it= 0;
8143   CHARSET_INFO *charset;
8144   query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
8145 
8146   if (rli->deferred_events_collecting)
8147   {
8148     set_deferred(current_thd->query_id);
8149     return rli->deferred_events->add(this);
8150   } else if (is_deferred())
8151   {
8152     sav_query_id= current_thd->query_id;
8153     current_thd->query_id= query_id; /* recreating original time context */
8154   }
8155 
8156   if (!(charset= get_charset(charset_number, MYF(MY_WME))))
8157   {
8158     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8159                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8160                 "Invalid character set for User var event");
8161     return 1;
8162   }
8163   double real_val;
8164   longlong int_val;
8165 
8166   /*
8167     We are now in a statement until the associated query log event has
8168     been processed.
8169    */
8170   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
8171 
8172   if (is_null)
8173   {
8174     it= new Item_null();
8175   }
8176   else
8177   {
8178     switch (type) {
8179     case REAL_RESULT:
8180       if (val_len != 8)
8181       {
8182         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8183                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8184                     "Invalid variable length at User var event");
8185         return 1;
8186       }
8187       float8get(real_val, val);
8188       it= new Item_float(real_val, 0);
8189       val= (char*) &real_val;		// Pointer to value in native format
8190       val_len= 8;
8191       break;
8192     case INT_RESULT:
8193       if (val_len != 8)
8194       {
8195         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8196                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8197                     "Invalid variable length at User var event");
8198         return 1;
8199       }
8200       int_val= (longlong) uint8korr(val);
8201       it= new Item_int(int_val);
8202       val= (char*) &int_val;		// Pointer to value in native format
8203       val_len= 8;
8204       break;
8205     case DECIMAL_RESULT:
8206     {
8207       if (val_len < 3)
8208       {
8209         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8210                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8211                     "Invalid variable length at User var event");
8212         return 1;
8213       }
8214       Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
8215       it= dec;
8216       val= (char *)dec->val_decimal(NULL);
8217       val_len= sizeof(my_decimal);
8218       break;
8219     }
8220     case STRING_RESULT:
8221       it= new Item_string(val, val_len, charset);
8222       break;
8223     case ROW_RESULT:
8224     default:
8225       DBUG_ASSERT(1);
8226       return 0;
8227     }
8228   }
8229   Item_func_set_user_var *e=
8230     new Item_func_set_user_var(Name_string(name, name_len, false), it, false);
8231   /*
8232     Item_func_set_user_var can't substitute something else on its place =>
8233     0 can be passed as last argument (reference on item)
8234 
8235     Fix_fields() can fail, in which case a call of update_hash() might
8236     crash the server, so if fix fields fails, we just return with an
8237     error.
8238   */
8239   if (e->fix_fields(thd, 0))
8240     return 1;
8241 
8242   /*
8243     A variable can just be considered as a table with
8244     a single record and with a single column. Thus, like
8245     a column value, it could always have IMPLICIT derivation.
8246    */
8247   e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
8248                  (flags & User_var_log_event::UNSIGNED_F));
8249   if (!is_deferred())
8250     free_root(thd->mem_root, 0);
8251   else
8252     current_thd->query_id= sav_query_id; /* restore current query's context */
8253 
8254   return 0;
8255 }
8256 
do_update_pos(Relay_log_info * rli)8257 int User_var_log_event::do_update_pos(Relay_log_info *rli)
8258 {
8259   rli->inc_event_relay_log_pos();
8260   return 0;
8261 }
8262 
8263 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)8264 User_var_log_event::do_shall_skip(Relay_log_info *rli)
8265 {
8266   /*
8267     It is a common error to set the slave skip counter to 1 instead
8268     of 2 when recovering from an insert which used a auto increment,
8269     rand, or user var.  Therefore, if the slave skip counter is 1, we
8270     just say that this event should be skipped by ignoring it, meaning
8271     that we do not change the value of the slave skip counter since it
8272     will be decreased by the following insert event.
8273   */
8274   return continue_group(rli);
8275 }
8276 #endif /* !MYSQL_CLIENT */
8277 
8278 
8279 /**************************************************************************
8280   Unknown_log_event methods
8281 **************************************************************************/
8282 
8283 #ifdef HAVE_REPLICATION
8284 #ifdef MYSQL_CLIENT
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info)8285 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
8286 {
8287   if (print_event_info->short_form)
8288     return;
8289   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8290   my_b_printf(&print_event_info->head_cache, "\n# %s", "Unknown event\n");
8291 }
8292 #endif
8293 
8294 /**************************************************************************
8295 	Stop_log_event methods
8296 **************************************************************************/
8297 
8298 /*
8299   Stop_log_event::print()
8300 */
8301 
8302 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8303 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8304 {
8305   if (print_event_info->short_form)
8306     return;
8307 
8308   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8309   my_b_printf(&print_event_info->head_cache, "\tStop\n");
8310 }
8311 #endif /* MYSQL_CLIENT */
8312 
8313 
8314 #ifndef MYSQL_CLIENT
8315 /*
8316   The master stopped.  We used to clean up all temporary tables but
8317   this is useless as, as the master has shut down properly, it has
8318   written all DROP TEMPORARY TABLE (prepared statements' deletion is
8319   TODO only when we binlog prep stmts).  We used to clean up
8320   slave_load_tmpdir, but this is useless as it has been cleared at the
8321   end of LOAD DATA INFILE.  So we have nothing to do here.  The place
8322   were we must do this cleaning is in
8323   Start_log_event_v3::do_apply_event(), not here. Because if we come
8324   here, the master was sane.
8325 
8326   This must only be called from the Slave SQL thread, since it calls
8327   flush_relay_log_info().
8328 */
do_update_pos(Relay_log_info * rli)8329 int Stop_log_event::do_update_pos(Relay_log_info *rli)
8330 {
8331   int error_inc= 0;
8332   int error_flush= 0;
8333   /*
8334     We do not want to update master_log pos because we get a rotate event
8335     before stop, so by now group_master_log_name is set to the next log.
8336     If we updated it, we will have incorrect master coordinates and this
8337     could give false triggers in MASTER_POS_WAIT() that we have reached
8338     the target position when in fact we have not.
8339     The group position is always unchanged in MTS mode because the event
8340     is never executed so can't be scheduled to a Worker.
8341   */
8342   if ((thd->variables.option_bits & OPTION_BEGIN) || rli->is_parallel_exec())
8343     rli->inc_event_relay_log_pos();
8344   else
8345   {
8346     error_inc= rli->inc_group_relay_log_pos(0, true/*need_data_lock=true*/);
8347     error_flush= rli->flush_info(TRUE);
8348   }
8349   return (error_inc || error_flush);
8350 }
8351 
8352 #endif /* !MYSQL_CLIENT */
8353 #endif /* HAVE_REPLICATION */
8354 
8355 
8356 /**************************************************************************
8357 	Create_file_log_event methods
8358 **************************************************************************/
8359 
8360 /*
8361   Create_file_log_event ctor
8362 */
8363 
8364 #ifndef MYSQL_CLIENT
8365 Create_file_log_event::
Create_file_log_event(THD * thd_arg,sql_exchange * ex,const char * db_arg,const char * table_name_arg,List<Item> & fields_arg,bool is_concurrent_arg,enum enum_duplicates handle_dup,bool ignore,uchar * block_arg,uint block_len_arg,bool using_trans)8366 Create_file_log_event(THD* thd_arg, sql_exchange* ex,
8367 		      const char* db_arg, const char* table_name_arg,
8368                       List<Item>& fields_arg,
8369                       bool is_concurrent_arg,
8370                       enum enum_duplicates handle_dup,
8371                       bool ignore,
8372 		      uchar* block_arg, uint block_len_arg, bool using_trans)
8373   :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
8374                   is_concurrent_arg,
8375                   handle_dup, ignore, using_trans),
8376    fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
8377    file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
8378 {
8379   DBUG_ENTER("Create_file_log_event");
8380   sql_ex.force_new_format();
8381   DBUG_VOID_RETURN;
8382 }
8383 
8384 
8385 /*
8386   Create_file_log_event::write_data_body()
8387 */
8388 
write_data_body(IO_CACHE * file)8389 bool Create_file_log_event::write_data_body(IO_CACHE* file)
8390 {
8391   bool res;
8392   if ((res= Load_log_event::write_data_body(file)) || fake_base)
8393     return res;
8394   return (my_b_safe_write(file, (uchar*) "", 1) ||
8395           my_b_safe_write(file, (uchar*) block, block_len));
8396 }
8397 
8398 
8399 /*
8400   Create_file_log_event::write_data_header()
8401 */
8402 
write_data_header(IO_CACHE * file)8403 bool Create_file_log_event::write_data_header(IO_CACHE* file)
8404 {
8405   bool res;
8406   uchar buf[CREATE_FILE_HEADER_LEN];
8407   if ((res= Load_log_event::write_data_header(file)) || fake_base)
8408     return res;
8409   int4store(buf + CF_FILE_ID_OFFSET, file_id);
8410   return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
8411 }
8412 
8413 
8414 /*
8415   Create_file_log_event::write_base()
8416 */
8417 
write_base(IO_CACHE * file)8418 bool Create_file_log_event::write_base(IO_CACHE* file)
8419 {
8420   bool res;
8421   fake_base= 1;                                 // pretend we are Load event
8422   res= write(file);
8423   fake_base= 0;
8424   return res;
8425 }
8426 
8427 #endif /* !MYSQL_CLIENT */
8428 
8429 /*
8430   Create_file_log_event ctor
8431 */
8432 
Create_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8433 Create_file_log_event::Create_file_log_event(const char* buf, uint len,
8434                                              const Format_description_log_event* description_event)
8435   :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
8436 {
8437   DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
8438   uint block_offset;
8439   uint header_len= description_event->common_header_len;
8440   uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
8441   uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
8442   if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
8443       copy_log_event(event_buf,len,
8444                      ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
8445                       load_header_len + header_len :
8446                       (fake_base ? (header_len+load_header_len) :
8447                        (header_len+load_header_len) +
8448                        create_file_header_len)),
8449                      description_event))
8450     DBUG_VOID_RETURN;
8451   if (description_event->binlog_version!=1)
8452   {
8453     file_id= uint4korr(buf +
8454                        header_len +
8455 		       load_header_len + CF_FILE_ID_OFFSET);
8456     /*
8457       Note that it's ok to use get_data_size() below, because it is computed
8458       with values we have already read from this event (because we called
8459       copy_log_event()); we are not using slave's format info to decode
8460       master's format, we are really using master's format info.
8461       Anyway, both formats should be identical (except the common_header_len)
8462       as these Load events are not changed between 4.0 and 5.0 (as logging of
8463       LOAD DATA INFILE does not use Load_log_event in 5.0).
8464 
8465       The + 1 is for \0 terminating fname
8466     */
8467     block_offset= (description_event->common_header_len +
8468                    Load_log_event::get_data_size() +
8469                    create_file_header_len + 1);
8470     if (len < block_offset)
8471       DBUG_VOID_RETURN;
8472     block = (uchar*)buf + block_offset;
8473     block_len = len - block_offset;
8474   }
8475   else
8476   {
8477     sql_ex.force_new_format();
8478     inited_from_old = 1;
8479   }
8480   DBUG_VOID_RETURN;
8481 }
8482 
8483 
8484 /*
8485   Create_file_log_event::print()
8486 */
8487 
8488 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info,bool enable_local)8489 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
8490 				  bool enable_local)
8491 {
8492   if (print_event_info->short_form)
8493   {
8494     if (enable_local && check_fname_outside_temp_buf())
8495       Load_log_event::print(file, print_event_info);
8496     return;
8497   }
8498 
8499   if (enable_local)
8500   {
8501     Load_log_event::print(file, print_event_info,
8502 			  !check_fname_outside_temp_buf());
8503     /**
8504       reduce the size of io cache so that the write function is called
8505       for every call to my_b_printf().
8506      */
8507     DBUG_EXECUTE_IF ("simulate_create_event_write_error",
8508                      {(&print_event_info->head_cache)->write_pos=
8509                      (&print_event_info->head_cache)->write_end;
8510                      DBUG_SET("+d,simulate_file_write_error");});
8511     /*
8512        That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
8513        SHOW BINLOG EVENTS we don't.
8514     */
8515     my_b_printf(&print_event_info->head_cache, "#");
8516   }
8517 
8518   my_b_printf(&print_event_info->head_cache,
8519               " file_id: %d  block_len: %d\n", file_id, block_len);
8520 }
8521 
8522 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8523 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8524 {
8525   print(file, print_event_info, 0);
8526 }
8527 #endif /* MYSQL_CLIENT */
8528 
8529 
8530 /*
8531   Create_file_log_event::pack_info()
8532 */
8533 
8534 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8535 int Create_file_log_event::pack_info(Protocol *protocol)
8536 {
8537   char buf[NAME_LEN*2 + 30 + 21*2], *pos;
8538   pos= strmov(buf, "db=");
8539   memcpy(pos, db, db_len);
8540   pos= strmov(pos + db_len, ";table=");
8541   memcpy(pos, table_name, table_name_len);
8542   pos= strmov(pos + table_name_len, ";file_id=");
8543   pos= int10_to_str((long) file_id, pos, 10);
8544   pos= strmov(pos, ";block_len=");
8545   pos= int10_to_str((long) block_len, pos, 10);
8546   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8547   return 0;
8548 }
8549 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8550 
8551 
8552 /**
8553   Create_file_log_event::do_apply_event()
8554   Constructor for Create_file_log_event to intantiate an event
8555   from the relay log on the slave.
8556 
8557   @retval
8558     0           Success
8559   @retval
8560     1           Failure
8561 */
8562 
8563 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8564 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
8565 {
8566   char fname_buf[FN_REFLEN+TEMP_FILE_MAX_LEN];
8567   char *ext;
8568   int fd = -1;
8569   IO_CACHE file;
8570   int error = 1;
8571 
8572   lex_start(thd);
8573   mysql_reset_thd_for_next_command(thd);
8574   THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
8575   memset(&file, 0, sizeof(file));
8576   ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
8577   /* old copy may exist already */
8578   mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8579   /**
8580     To simulate file creation failure, convert the file name to a
8581     directory by appending a "/" to the file name.
8582    */
8583   DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event",
8584                   {
8585                   strcat(fname_buf,"/");
8586                   });
8587   if ((fd= mysql_file_create(key_file_log_event_info,
8588                              fname_buf, CREATE_MODE,
8589                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8590                              MYF(MY_WME))) < 0 ||
8591       init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
8592 		    MYF(MY_WME|MY_NABP)))
8593   {
8594     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8595                 "Error in Create_file event: could not open file '%s'",
8596                 fname_buf);
8597     goto err;
8598   }
8599 
8600   // a trick to avoid allocating another buffer
8601   fname= fname_buf;
8602   fname_len= (uint) (strmov(ext, ".data") - fname);
8603   if (write_base(&file))
8604   {
8605     strmov(ext, ".info"); // to have it right in the error message
8606     rli->report(ERROR_LEVEL, my_errno,
8607                 "Error in Create_file event: could not write to file '%s'",
8608                 fname_buf);
8609     goto err;
8610   }
8611   end_io_cache(&file);
8612   mysql_file_close(fd, MYF(0));
8613 
8614   // fname_buf now already has .data, not .info, because we did our trick
8615   /* old copy may exist already */
8616   mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8617   if ((fd= mysql_file_create(key_file_log_event_data,
8618                              fname_buf, CREATE_MODE,
8619                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8620                              MYF(MY_WME))) < 0)
8621   {
8622     rli->report(ERROR_LEVEL, my_errno,
8623                 "Error in Create_file event: could not open file '%s'",
8624                 fname_buf);
8625     goto err;
8626   }
8627   /**
8628     To simulate file write failure,close the file before the write operation.
8629     Write will fail with an error reporting file is UNOPENED.
8630    */
8631   DBUG_EXECUTE_IF("simulate_file_write_error_create_log_event",
8632                   {
8633                   mysql_file_close(fd, MYF(0));
8634                   });
8635   if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8636   {
8637     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8638                 "Error in Create_file event: write to '%s' failed",
8639                 fname_buf);
8640     goto err;
8641   }
8642   error=0;					// Everything is ok
8643 
8644 err:
8645   if (error)
8646     end_io_cache(&file);
8647   if (fd >= 0)
8648     mysql_file_close(fd, MYF(0));
8649   return error != 0;
8650 }
8651 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8652 
8653 
8654 /**************************************************************************
8655 	Append_block_log_event methods
8656 **************************************************************************/
8657 
8658 /*
8659   Append_block_log_event ctor
8660 */
8661 
8662 #ifndef MYSQL_CLIENT
Append_block_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)8663 Append_block_log_event::Append_block_log_event(THD *thd_arg,
8664                                                const char *db_arg,
8665 					       uchar *block_arg,
8666 					       uint block_len_arg,
8667 					       bool using_trans)
8668   :Log_event(thd_arg, 0,
8669              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8670                            Log_event::EVENT_STMT_CACHE,
8671              Log_event::EVENT_NORMAL_LOGGING),
8672    block(block_arg),
8673    block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
8674 {
8675 }
8676 #endif
8677 
8678 
8679 /*
8680   Append_block_log_event ctor
8681 */
8682 
Append_block_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8683 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
8684                                                const Format_description_log_event* description_event)
8685   :Log_event(buf, description_event),block(0)
8686 {
8687   DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
8688   uint8 common_header_len= description_event->common_header_len;
8689   uint8 append_block_header_len=
8690     description_event->post_header_len[APPEND_BLOCK_EVENT-1];
8691   uint total_header_len= common_header_len+append_block_header_len;
8692   if (len < total_header_len)
8693     DBUG_VOID_RETURN;
8694   file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
8695   block= (uchar*)buf + total_header_len;
8696   block_len= len - total_header_len;
8697   DBUG_VOID_RETURN;
8698 }
8699 
8700 
8701 /*
8702   Append_block_log_event::write()
8703 */
8704 
8705 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8706 bool Append_block_log_event::write(IO_CACHE* file)
8707 {
8708   uchar buf[APPEND_BLOCK_HEADER_LEN];
8709   int4store(buf + AB_FILE_ID_OFFSET, file_id);
8710   return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
8711           wrapper_my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
8712 	  wrapper_my_b_safe_write(file, (uchar*) block, block_len) ||
8713 	  write_footer(file));
8714 }
8715 #endif
8716 
8717 
8718 /*
8719   Append_block_log_event::print()
8720 */
8721 
8722 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8723 void Append_block_log_event::print(FILE* file,
8724 				   PRINT_EVENT_INFO* print_event_info)
8725 {
8726   if (print_event_info->short_form)
8727     return;
8728   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8729   my_b_printf(&print_event_info->head_cache,
8730               "\n#%s: file_id: %d  block_len: %d\n",
8731               get_type_str(), file_id, block_len);
8732 }
8733 #endif /* MYSQL_CLIENT */
8734 
8735 
8736 /*
8737   Append_block_log_event::pack_info()
8738 */
8739 
8740 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8741 int Append_block_log_event::pack_info(Protocol *protocol)
8742 {
8743   char buf[256];
8744   size_t length;
8745   length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
8746                       file_id, block_len);
8747   protocol->store(buf, length, &my_charset_bin);
8748   return 0;
8749 }
8750 
8751 
8752 /*
8753   Append_block_log_event::get_create_or_append()
8754 */
8755 
get_create_or_append() const8756 int Append_block_log_event::get_create_or_append() const
8757 {
8758   return 0; /* append to the file, fail if not exists */
8759 }
8760 
8761 /*
8762   Append_block_log_event::do_apply_event()
8763 */
8764 
do_apply_event(Relay_log_info const * rli)8765 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
8766 {
8767   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8768   int fd;
8769   int error = 1;
8770   DBUG_ENTER("Append_block_log_event::do_apply_event");
8771 
8772   THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
8773   slave_load_file_stem(fname, file_id, server_id, ".data");
8774   if (get_create_or_append())
8775   {
8776     /*
8777       Usually lex_start() is called by mysql_parse(), but we need it here
8778       as the present method does not call mysql_parse().
8779     */
8780     lex_start(thd);
8781     mysql_reset_thd_for_next_command(thd);
8782     /* old copy may exist already */
8783     mysql_file_delete(key_file_log_event_data, fname, MYF(0));
8784     if ((fd= mysql_file_create(key_file_log_event_data,
8785                                fname, CREATE_MODE,
8786                                O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8787                                MYF(MY_WME))) < 0)
8788     {
8789       rli->report(ERROR_LEVEL, my_errno,
8790                   "Error in %s event: could not create file '%s'",
8791                   get_type_str(), fname);
8792       goto err;
8793     }
8794   }
8795   else if ((fd= mysql_file_open(key_file_log_event_data,
8796                                 fname,
8797                                 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
8798                                 MYF(MY_WME))) < 0)
8799   {
8800     rli->report(ERROR_LEVEL, my_errno,
8801                 "Error in %s event: could not open file '%s'",
8802                 get_type_str(), fname);
8803     goto err;
8804   }
8805 
8806   DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
8807                   {
8808                     my_delete_allow_opened(fname, MYF(0));
8809                   });
8810 
8811   if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8812   {
8813     rli->report(ERROR_LEVEL, my_errno,
8814                 "Error in %s event: write to '%s' failed",
8815                 get_type_str(), fname);
8816     goto err;
8817   }
8818   error=0;
8819 
8820 err:
8821   if (fd >= 0)
8822     mysql_file_close(fd, MYF(0));
8823   DBUG_RETURN(error);
8824 }
8825 #endif
8826 
8827 
8828 /**************************************************************************
8829 	Delete_file_log_event methods
8830 **************************************************************************/
8831 
8832 /*
8833   Delete_file_log_event ctor
8834 */
8835 
8836 #ifndef MYSQL_CLIENT
Delete_file_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8837 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
8838 					     bool using_trans)
8839   :Log_event(thd_arg, 0,
8840              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8841                            Log_event::EVENT_STMT_CACHE,
8842              Log_event::EVENT_NORMAL_LOGGING),
8843   file_id(thd_arg->file_id), db(db_arg)
8844 {
8845 }
8846 #endif
8847 
8848 /*
8849   Delete_file_log_event ctor
8850 */
8851 
Delete_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8852 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
8853                                              const Format_description_log_event* description_event)
8854   :Log_event(buf, description_event),file_id(0)
8855 {
8856   uint8 common_header_len= description_event->common_header_len;
8857   uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
8858   if (len < (uint)(common_header_len + delete_file_header_len))
8859     return;
8860   file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
8861 }
8862 
8863 
8864 /*
8865   Delete_file_log_event::write()
8866 */
8867 
8868 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8869 bool Delete_file_log_event::write(IO_CACHE* file)
8870 {
8871  uchar buf[DELETE_FILE_HEADER_LEN];
8872  int4store(buf + DF_FILE_ID_OFFSET, file_id);
8873  return (write_header(file, sizeof(buf)) ||
8874          wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8875 	 write_footer(file));
8876 }
8877 #endif
8878 
8879 
8880 /*
8881   Delete_file_log_event::print()
8882 */
8883 
8884 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8885 void Delete_file_log_event::print(FILE* file,
8886 				  PRINT_EVENT_INFO* print_event_info)
8887 {
8888   if (print_event_info->short_form)
8889     return;
8890   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8891   my_b_printf(&print_event_info->head_cache,
8892               "\n#Delete_file: file_id=%u\n", file_id);
8893 }
8894 #endif /* MYSQL_CLIENT */
8895 
8896 /*
8897   Delete_file_log_event::pack_info()
8898 */
8899 
8900 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8901 int Delete_file_log_event::pack_info(Protocol *protocol)
8902 {
8903   char buf[64];
8904   size_t length;
8905   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8906   protocol->store(buf, length, &my_charset_bin);
8907   return 0;
8908 }
8909 #endif
8910 
8911 /*
8912   Delete_file_log_event::do_apply_event()
8913 */
8914 
8915 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8916 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
8917 {
8918   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8919   lex_start(thd);
8920   mysql_reset_thd_for_next_command(thd);
8921   char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
8922   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8923   strmov(ext, ".info");
8924   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8925   return 0;
8926 }
8927 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8928 
8929 
8930 /**************************************************************************
8931 	Execute_load_log_event methods
8932 **************************************************************************/
8933 
8934 /*
8935   Execute_load_log_event ctor
8936 */
8937 
8938 #ifndef MYSQL_CLIENT
Execute_load_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8939 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
8940                                                const char* db_arg,
8941 					       bool using_trans)
8942   :Log_event(thd_arg, 0,
8943              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8944                            Log_event::EVENT_STMT_CACHE,
8945              Log_event::EVENT_NORMAL_LOGGING),
8946   file_id(thd_arg->file_id), db(db_arg)
8947 {
8948 }
8949 #endif
8950 
8951 
8952 /*
8953   Execute_load_log_event ctor
8954 */
8955 
Execute_load_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8956 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
8957                                                const Format_description_log_event* description_event)
8958   :Log_event(buf, description_event), file_id(0)
8959 {
8960   uint8 common_header_len= description_event->common_header_len;
8961   uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
8962   if (len < (uint)(common_header_len+exec_load_header_len))
8963     return;
8964   file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
8965 }
8966 
8967 
8968 /*
8969   Execute_load_log_event::write()
8970 */
8971 
8972 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8973 bool Execute_load_log_event::write(IO_CACHE* file)
8974 {
8975   uchar buf[EXEC_LOAD_HEADER_LEN];
8976   int4store(buf + EL_FILE_ID_OFFSET, file_id);
8977   return (write_header(file, sizeof(buf)) ||
8978           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8979 	  write_footer(file));
8980 }
8981 #endif
8982 
8983 
8984 /*
8985   Execute_load_log_event::print()
8986 */
8987 
8988 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8989 void Execute_load_log_event::print(FILE* file,
8990 				   PRINT_EVENT_INFO* print_event_info)
8991 {
8992   if (print_event_info->short_form)
8993     return;
8994   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8995   my_b_printf(&print_event_info->head_cache, "\n#Exec_load: file_id=%d\n",
8996               file_id);
8997 }
8998 #endif
8999 
9000 /*
9001   Execute_load_log_event::pack_info()
9002 */
9003 
9004 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9005 int Execute_load_log_event::pack_info(Protocol *protocol)
9006 {
9007   char buf[64];
9008   size_t length;
9009   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
9010   protocol->store(buf, length, &my_charset_bin);
9011   return 0;
9012 }
9013 
9014 
9015 /*
9016   Execute_load_log_event::do_apply_event()
9017 */
9018 
do_apply_event(Relay_log_info const * rli)9019 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
9020 {
9021   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
9022   char *ext;
9023   int fd;
9024   int error= 1;
9025   IO_CACHE file;
9026   Load_log_event *lev= 0;
9027 
9028   lex_start(thd);
9029   mysql_reset_thd_for_next_command(thd);
9030   ext= slave_load_file_stem(fname, file_id, server_id, ".info");
9031   /**
9032     To simulate file open failure, convert the file name to a
9033     directory by appending a "/" to the file name. File open
9034     will fail with an error reporting it is not a directory.
9035    */
9036   DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
9037                   {
9038                   strcat(fname,"/");
9039                   });
9040   if ((fd= mysql_file_open(key_file_log_event_info,
9041                            fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
9042                            MYF(MY_WME))) < 0 ||
9043       init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
9044 		    MYF(MY_WME|MY_NABP)))
9045   {
9046     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
9047                 "Error in Exec_load event: could not open file '%s'",
9048                 fname);
9049     goto err;
9050   }
9051   if (!(lev= (Load_log_event*)
9052         Log_event::read_log_event(&file,
9053                                   (mysql_mutex_t*) 0,
9054                                   rli->get_rli_description_event(),
9055                                   opt_slave_sql_verify_checksum)) ||
9056       lev->get_type_code() != NEW_LOAD_EVENT)
9057   {
9058     rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
9059                     "file '%s' appears corrupted", fname);
9060     goto err;
9061   }
9062   lev->thd = thd;
9063   /*
9064     lev->do_apply_event should use rli only for errors i.e. should
9065     not advance rli's position.
9066 
9067     lev->do_apply_event is the place where the table is loaded (it
9068     calls mysql_load()).
9069   */
9070   const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
9071   if (lev->do_apply_event(0,rli,1))
9072   {
9073     /*
9074       We want to indicate the name of the file that could not be loaded
9075       (SQL_LOADxxx).
9076       But as we are here we are sure the error is in rli->last_slave_error and
9077       rli->last_slave_errno (example of error: duplicate entry for key), so we
9078       don't want to overwrite it with the filename.
9079       What we want instead is add the filename to the current error message.
9080     */
9081     char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
9082     if (tmp)
9083     {
9084       rli->report(ERROR_LEVEL, rli->last_error().number,
9085                   "%s. Failed executing load from '%s'", tmp, fname);
9086       my_free(tmp);
9087     }
9088     goto err;
9089   }
9090   /*
9091     We have an open file descriptor to the .info file; we need to close it
9092     or Windows will refuse to delete the file in mysql_file_delete().
9093   */
9094   if (fd >= 0)
9095   {
9096     mysql_file_close(fd, MYF(0));
9097     end_io_cache(&file);
9098     fd= -1;
9099   }
9100   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
9101   memcpy(ext, ".data", 6);
9102   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9103   error = 0;
9104 
9105 err:
9106   delete lev;
9107   if (fd >= 0)
9108   {
9109     mysql_file_close(fd, MYF(0));
9110     end_io_cache(&file);
9111   }
9112   return error;
9113 }
9114 
9115 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9116 
9117 
9118 /**************************************************************************
9119 	Begin_load_query_log_event methods
9120 **************************************************************************/
9121 
9122 #ifndef MYSQL_CLIENT
9123 Begin_load_query_log_event::
Begin_load_query_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)9124 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
9125                            uint block_len_arg, bool using_trans)
9126   :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
9127                           using_trans)
9128 {
9129    file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
9130 }
9131 #endif
9132 
9133 
9134 Begin_load_query_log_event::
Begin_load_query_log_event(const char * buf,uint len,const Format_description_log_event * desc_event)9135 Begin_load_query_log_event(const char* buf, uint len,
9136                            const Format_description_log_event* desc_event)
9137   :Append_block_log_event(buf, len, desc_event)
9138 {
9139 }
9140 
9141 
9142 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_create_or_append() const9143 int Begin_load_query_log_event::get_create_or_append() const
9144 {
9145   return 1; /* create the file */
9146 }
9147 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9148 
9149 
9150 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9151 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)9152 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
9153 {
9154   /*
9155     If the slave skip counter is 1, then we should not start executing
9156     on the next event.
9157   */
9158   return continue_group(rli);
9159 }
9160 #endif
9161 
9162 
9163 /**************************************************************************
9164 	Execute_load_query_log_event methods
9165 **************************************************************************/
9166 
9167 
9168 #ifndef MYSQL_CLIENT
9169 Execute_load_query_log_event::
Execute_load_query_log_event(THD * thd_arg,const char * query_arg,ulong query_length_arg,uint fn_pos_start_arg,uint fn_pos_end_arg,enum_load_dup_handling dup_handling_arg,bool using_trans,bool immediate,bool suppress_use,int errcode)9170 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
9171                              ulong query_length_arg, uint fn_pos_start_arg,
9172                              uint fn_pos_end_arg,
9173                              enum_load_dup_handling dup_handling_arg,
9174                              bool using_trans, bool immediate, bool suppress_use,
9175                              int errcode):
9176   Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
9177                   suppress_use, errcode),
9178   file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
9179   fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
9180 {
9181 }
9182 #endif /* !MYSQL_CLIENT */
9183 
9184 
9185 Execute_load_query_log_event::
Execute_load_query_log_event(const char * buf,uint event_len,const Format_description_log_event * desc_event)9186 Execute_load_query_log_event(const char* buf, uint event_len,
9187                              const Format_description_log_event* desc_event):
9188   Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
9189   file_id(0), fn_pos_start(0), fn_pos_end(0)
9190 {
9191   if (!Query_log_event::is_valid())
9192     return;
9193 
9194   buf+= desc_event->common_header_len;
9195 
9196   fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
9197   fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
9198   dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
9199 
9200   if (fn_pos_start > q_len || fn_pos_end > q_len ||
9201       dup_handling > LOAD_DUP_REPLACE)
9202     return;
9203 
9204   file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
9205 }
9206 
9207 
get_post_header_size_for_derived()9208 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
9209 {
9210   return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
9211 }
9212 
9213 
9214 #ifndef MYSQL_CLIENT
9215 bool
write_post_header_for_derived(IO_CACHE * file)9216 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
9217 {
9218   uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
9219   int4store(buf, file_id);
9220   int4store(buf + 4, fn_pos_start);
9221   int4store(buf + 4 + 4, fn_pos_end);
9222   *(buf + 4 + 4 + 4)= (uchar) dup_handling;
9223   return wrapper_my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
9224 }
9225 #endif
9226 
9227 
9228 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)9229 void Execute_load_query_log_event::print(FILE* file,
9230                                          PRINT_EVENT_INFO* print_event_info)
9231 {
9232   print(file, print_event_info, 0);
9233 }
9234 
9235 /**
9236   Prints the query as LOAD DATA LOCAL and with rewritten filename.
9237 */
print(FILE * file,PRINT_EVENT_INFO * print_event_info,const char * local_fname)9238 void Execute_load_query_log_event::print(FILE* file,
9239                                          PRINT_EVENT_INFO* print_event_info,
9240                                          const char *local_fname)
9241 {
9242   IO_CACHE *const head= &print_event_info->head_cache;
9243 
9244   print_query_header(head, print_event_info);
9245   /**
9246     reduce the size of io cache so that the write function is called
9247     for every call to my_b_printf().
9248    */
9249   DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
9250                    {head->write_pos= head->write_end;
9251                    DBUG_SET("+d,simulate_file_write_error");});
9252 
9253   if (local_fname)
9254   {
9255     my_b_write(head, (uchar*) query, fn_pos_start);
9256     my_b_printf(head, " LOCAL INFILE ");
9257     pretty_print_str(head, local_fname, strlen(local_fname));
9258 
9259     if (dup_handling == LOAD_DUP_REPLACE)
9260       my_b_printf(head, " REPLACE");
9261     my_b_printf(head, " INTO");
9262     my_b_write(head, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
9263     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9264   }
9265   else
9266   {
9267     my_b_write(head, (uchar*) query, q_len);
9268     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9269   }
9270 
9271   if (!print_event_info->short_form)
9272     my_b_printf(head, "# file_id: %d \n", file_id);
9273 }
9274 #endif
9275 
9276 
9277 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9278 int Execute_load_query_log_event::pack_info(Protocol *protocol)
9279 {
9280   char *buf, *pos;
9281   if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
9282                                MYF(MY_WME))))
9283     return 1;
9284   pos= buf;
9285   if (db && db_len)
9286   {
9287     /*
9288       Statically allocates room to store '\0' and an identifier
9289       that may have NAME_LEN * 2 due to quoting and there are
9290       two quoting characters that wrap them.
9291     */
9292     char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
9293     size_t size= 0;
9294     size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
9295     pos= strmov(buf, "use ");
9296     memcpy(pos, quoted_db, size);
9297     pos= strmov(pos + size, "; ");
9298   }
9299   if (query && q_len)
9300   {
9301     memcpy(pos, query, q_len);
9302     pos+= q_len;
9303   }
9304   pos= strmov(pos, " ;file_id=");
9305   pos= int10_to_str((long) file_id, pos, 10);
9306   protocol->store(buf, pos-buf, &my_charset_bin);
9307   my_free(buf);
9308   return 0;
9309 }
9310 
9311 
9312 int
do_apply_event(Relay_log_info const * rli)9313 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
9314 {
9315   char *p;
9316   char *buf;
9317   char *fname;
9318   char *fname_end;
9319   int error;
9320 
9321   buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
9322                          (FN_REFLEN + TEMP_FILE_MAX_LEN) + 10 + 8 + 5, MYF(MY_WME));
9323 
9324   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
9325 
9326   /* Replace filename and LOCAL keyword in query before executing it */
9327   if (buf == NULL)
9328   {
9329     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9330                 ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
9331     return 1;
9332   }
9333 
9334   p= buf;
9335   memcpy(p, query, fn_pos_start);
9336   p+= fn_pos_start;
9337   fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
9338   p= slave_load_file_stem(p, file_id, server_id, ".data");
9339   fname_end= p= strend(p);                      // Safer than p=p+5
9340   *(p++)='\'';
9341   switch (dup_handling) {
9342   case LOAD_DUP_IGNORE:
9343     p= strmake(p, STRING_WITH_LEN(" IGNORE"));
9344     break;
9345   case LOAD_DUP_REPLACE:
9346     p= strmake(p, STRING_WITH_LEN(" REPLACE"));
9347     break;
9348   default:
9349     /* Ordinary load data */
9350     break;
9351   }
9352   p= strmake(p, STRING_WITH_LEN(" INTO "));
9353   p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
9354 
9355   error= Query_log_event::do_apply_event(rli, buf, p-buf);
9356 
9357   /* Forging file name for deletion in same buffer */
9358   *fname_end= 0;
9359 
9360   /*
9361     If there was an error the slave is going to stop, leave the
9362     file so that we can re-execute this event at START SLAVE.
9363   */
9364   if (!error)
9365     mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9366 
9367   my_free(buf);
9368   return error;
9369 }
9370 #endif
9371 
9372 
9373 /**************************************************************************
9374 	sql_ex_info methods
9375 **************************************************************************/
9376 
9377 /*
9378   sql_ex_info::write_data()
9379 */
9380 
write_data(IO_CACHE * file)9381 bool sql_ex_info::write_data(IO_CACHE* file)
9382 {
9383   if (new_format())
9384   {
9385     return (write_str_at_most_255_bytes(file, field_term, (uint) field_term_len) ||
9386 	    write_str_at_most_255_bytes(file, enclosed,   (uint) enclosed_len) ||
9387 	    write_str_at_most_255_bytes(file, line_term,  (uint) line_term_len) ||
9388 	    write_str_at_most_255_bytes(file, line_start, (uint) line_start_len) ||
9389 	    write_str_at_most_255_bytes(file, escaped,    (uint) escaped_len) ||
9390 	    my_b_safe_write(file,(uchar*) &opt_flags,1));
9391   }
9392   else
9393   {
9394     /**
9395       @todo This is sensitive to field padding. We should write a
9396       char[7], not an old_sql_ex. /sven
9397     */
9398     old_sql_ex old_ex;
9399     old_ex.field_term= *field_term;
9400     old_ex.enclosed=   *enclosed;
9401     old_ex.line_term=  *line_term;
9402     old_ex.line_start= *line_start;
9403     old_ex.escaped=    *escaped;
9404     old_ex.opt_flags=  opt_flags;
9405     old_ex.empty_flags=empty_flags;
9406     return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
9407   }
9408 }
9409 
9410 
9411 /*
9412   sql_ex_info::init()
9413 */
9414 
init(const char * buf,const char * buf_end,bool use_new_format)9415 const char *sql_ex_info::init(const char *buf, const char *buf_end,
9416                               bool use_new_format)
9417 {
9418   cached_new_format = use_new_format;
9419   if (use_new_format)
9420   {
9421     empty_flags=0;
9422     /*
9423       The code below assumes that buf will not disappear from
9424       under our feet during the lifetime of the event. This assumption
9425       holds true in the slave thread if the log is in new format, but is not
9426       the case when we have old format because we will be reusing net buffer
9427       to read the actual file before we write out the Create_file event.
9428     */
9429     if (read_str_at_most_255_bytes(&buf, buf_end, &field_term, &field_term_len) ||
9430         read_str_at_most_255_bytes(&buf, buf_end, &enclosed,   &enclosed_len) ||
9431         read_str_at_most_255_bytes(&buf, buf_end, &line_term,  &line_term_len) ||
9432         read_str_at_most_255_bytes(&buf, buf_end, &line_start, &line_start_len) ||
9433         read_str_at_most_255_bytes(&buf, buf_end, &escaped,    &escaped_len))
9434       return 0;
9435     opt_flags = *buf++;
9436   }
9437   else
9438   {
9439     field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
9440     field_term = buf++;			// Use first byte in string
9441     enclosed=	 buf++;
9442     line_term=   buf++;
9443     line_start=  buf++;
9444     escaped=     buf++;
9445     opt_flags =  *buf++;
9446     empty_flags= *buf++;
9447     if (empty_flags & FIELD_TERM_EMPTY)
9448       field_term_len=0;
9449     if (empty_flags & ENCLOSED_EMPTY)
9450       enclosed_len=0;
9451     if (empty_flags & LINE_TERM_EMPTY)
9452       line_term_len=0;
9453     if (empty_flags & LINE_START_EMPTY)
9454       line_start_len=0;
9455     if (empty_flags & ESCAPED_EMPTY)
9456       escaped_len=0;
9457   }
9458   return buf;
9459 }
9460 
9461 #ifndef DBUG_OFF
9462 #ifndef MYSQL_CLIENT
9463 static uchar dbug_extra_row_data_val= 0;
9464 
9465 /**
9466    set_extra_data
9467 
9468    Called during self-test to generate various
9469    self-consistent binlog row event extra
9470    thread data structures which can be checked
9471    when reading the binlog.
9472 
9473    @param arr  Buffer to use
9474 */
set_extra_data(uchar * arr)9475 const uchar* set_extra_data(uchar* arr)
9476 {
9477   uchar val= (dbug_extra_row_data_val++) %
9478     (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
9479   arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
9480   arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
9481   for (uchar i=0; i<val; i++)
9482     arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
9483 
9484   return arr;
9485 }
9486 
9487 #endif // #ifndef MYSQL_CLIENT
9488 
9489 /**
9490    check_extra_data
9491 
9492    Called during self-test to check that
9493    binlog row event extra data is self-
9494    consistent as defined by the set_extra_data
9495    function above.
9496 
9497    Will assert(false) if not.
9498 
9499    @param extra_row_data
9500 */
check_extra_data(uchar * extra_row_data)9501 void check_extra_data(uchar* extra_row_data)
9502 {
9503   assert(extra_row_data);
9504   uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
9505   uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
9506   assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
9507   for (uint16 i= 0; i < val; i++)
9508   {
9509     assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
9510   }
9511 }
9512 
9513 #endif  // #ifndef DBUG_OFF
9514 
9515 /**************************************************************************
9516 	Rows_log_event member functions
9517 **************************************************************************/
9518 
9519 #ifndef MYSQL_CLIENT
Rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,MY_BITMAP const * cols,bool using_trans,Log_event_type event_type,const uchar * extra_row_info)9520 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, const Table_id& tid,
9521                                MY_BITMAP const *cols, bool using_trans,
9522                                Log_event_type event_type,
9523                                const uchar* extra_row_info)
9524   : Log_event(thd_arg, 0,
9525              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
9526                            Log_event::EVENT_STMT_CACHE,
9527              Log_event::EVENT_NORMAL_LOGGING),
9528     m_row_count(0),
9529     m_table(tbl_arg),
9530     m_table_id(tid),
9531     m_width(tbl_arg ? tbl_arg->s->fields : 1),
9532     m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
9533     m_type(event_type), m_extra_row_data(0)
9534 #ifdef HAVE_REPLICATION
9535     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9536     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9537 #endif
9538 {
9539   DBUG_ASSERT(tbl_arg && tbl_arg->s && tid.is_valid());
9540 
9541   if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
9542       set_flags(NO_FOREIGN_KEY_CHECKS_F);
9543   if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
9544       set_flags(RELAXED_UNIQUE_CHECKS_F);
9545 #ifndef DBUG_OFF
9546   uchar extra_data[255];
9547   DBUG_EXECUTE_IF("extra_row_data_set",
9548                   /* Set extra row data to a known value */
9549                   extra_row_info = set_extra_data(extra_data););
9550 #endif
9551   if (extra_row_info)
9552   {
9553     /* Copy Extra data from thd into new event */
9554     uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
9555     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
9556 
9557     m_extra_row_data= (uchar*) my_malloc(extra_data_len, MYF(MY_WME));
9558 
9559     if (likely(m_extra_row_data != NULL))
9560     {
9561       memcpy(m_extra_row_data, extra_row_info,
9562              extra_data_len);
9563     }
9564   }
9565 
9566   /* if bitmap_init fails, caught in is_valid() */
9567   if (likely(!bitmap_init(&m_cols,
9568                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9569                           m_width,
9570                           false)))
9571   {
9572     /* Cols can be zero if this is a dummy binrows event */
9573     if (likely(cols != NULL))
9574     {
9575       memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
9576       create_last_word_mask(&m_cols);
9577     }
9578   }
9579   else
9580   {
9581     // Needed because bitmap_init() does not set it to null on failure
9582     m_cols.bitmap= 0;
9583   }
9584 }
9585 #endif
9586 
Rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)9587 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
9588                                const Format_description_log_event
9589                                *description_event)
9590   : Log_event(buf, description_event),
9591     m_row_count(0),
9592 #ifndef MYSQL_CLIENT
9593     m_table(NULL),
9594 #endif
9595     m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
9596     m_extra_row_data(0)
9597 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9598     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9599     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9600 #endif
9601 {
9602   DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
9603   uint8 const common_header_len= description_event->common_header_len;
9604   Log_event_type event_type= (Log_event_type) buf[EVENT_TYPE_OFFSET];
9605   m_type= event_type;
9606 
9607   uint8 const post_header_len= description_event->post_header_len[event_type-1];
9608 
9609   DBUG_PRINT("enter",("event_len: %u  common_header_len: %d  "
9610 		      "post_header_len: %d",
9611 		      event_len, common_header_len,
9612 		      post_header_len));
9613 
9614   const char *post_start= buf + common_header_len;
9615   post_start+= RW_MAPID_OFFSET;
9616   if (post_header_len == 6)
9617   {
9618     /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
9619     m_table_id= uint4korr(post_start);
9620     post_start+= 4;
9621   }
9622   else
9623   {
9624     m_table_id= uint6korr(post_start);
9625     post_start+= RW_FLAGS_OFFSET;
9626   }
9627 
9628   m_flags= uint2korr(post_start);
9629   post_start+= 2;
9630 
9631   uint16 var_header_len= 0;
9632   if (post_header_len == ROWS_HEADER_LEN_V2)
9633   {
9634     /*
9635       Have variable length header, check length,
9636       which includes length bytes
9637     */
9638     var_header_len= uint2korr(post_start);
9639     /* Check length and also avoid out of buffer read */
9640     if (var_header_len < 2 ||
9641         event_len < static_cast<unsigned int>(var_header_len +
9642                                               (post_start - buf)))
9643     {
9644       m_cols.bitmap= NULL;
9645       DBUG_VOID_RETURN;
9646     }
9647 
9648     var_header_len-= 2;
9649 
9650     /* Iterate over var-len header, extracting 'chunks' */
9651     const char* start= post_start + 2;
9652     const char* end= start + var_header_len;
9653     for (const char* pos= start; pos < end;)
9654     {
9655       switch(*pos++)
9656       {
9657       case RW_V_EXTRAINFO_TAG:
9658       {
9659         /* Have an 'extra info' section, read it in */
9660         assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
9661         uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
9662         assert((end - pos) >= infoLen);
9663         /* Just store/use the first tag of this type, skip others */
9664         if (likely(!m_extra_row_data))
9665         {
9666           m_extra_row_data= (uchar*) my_malloc(infoLen,
9667                                                MYF(MY_WME));
9668           if (likely(m_extra_row_data != NULL))
9669           {
9670             memcpy(m_extra_row_data, pos, infoLen);
9671           }
9672           DBUG_EXECUTE_IF("extra_row_data_check",
9673                           /* Check extra data has expected value */
9674                           check_extra_data(m_extra_row_data););
9675         }
9676         pos+= infoLen;
9677         break;
9678       }
9679       default:
9680         /* Unknown code, we will not understand anything further here */
9681         pos= end; /* Break loop */
9682       }
9683     }
9684   }
9685 
9686   uchar const *const var_start=
9687     (const uchar *)buf + common_header_len + post_header_len + var_header_len;
9688   uchar const *const ptr_width= var_start;
9689   uchar *ptr_after_width= (uchar*) ptr_width;
9690   DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9691   m_width = net_field_length(&ptr_after_width);
9692   DBUG_PRINT("debug", ("m_width=%lu", m_width));
9693   /* Avoid reading out of buffer */
9694   if (static_cast<unsigned int>((ptr_after_width +
9695                                  (m_width + 7) / 8) -
9696                                  (uchar*)buf) > event_len)
9697   {
9698     m_cols.bitmap= NULL;
9699     DBUG_VOID_RETURN;
9700   }
9701 
9702   /* if bitmap_init fails, catched in is_valid() */
9703   if (likely(!bitmap_init(&m_cols,
9704                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9705                           m_width,
9706                           false)))
9707   {
9708     DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9709     memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
9710     create_last_word_mask(&m_cols);
9711     ptr_after_width+= (m_width + 7) / 8;
9712     DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
9713   }
9714   else
9715   {
9716     // Needed because bitmap_init() does not set it to null on failure
9717     m_cols.bitmap= NULL;
9718     DBUG_VOID_RETURN;
9719   }
9720 
9721   m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
9722 
9723   if ((event_type == UPDATE_ROWS_EVENT) ||
9724       (event_type == UPDATE_ROWS_EVENT_V1))
9725   {
9726     DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9727 
9728     /* if bitmap_init fails, caught in is_valid() */
9729     if (likely(!bitmap_init(&m_cols_ai,
9730                             m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
9731                             m_width,
9732                             false)))
9733     {
9734       DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9735       memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
9736       create_last_word_mask(&m_cols_ai);
9737       ptr_after_width+= (m_width + 7) / 8;
9738       DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
9739                 no_bytes_in_map(&m_cols_ai));
9740     }
9741     else
9742     {
9743       // Needed because bitmap_init() does not set it to null on failure
9744       m_cols_ai.bitmap= 0;
9745       DBUG_VOID_RETURN;
9746     }
9747   }
9748 
9749   const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
9750 
9751   size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
9752   if (read_size > event_len)
9753   {
9754     DBUG_VOID_RETURN;
9755   }
9756 
9757   size_t const data_size= event_len - read_size;
9758   DBUG_PRINT("info",("m_table_id: %llu  m_flags: %d  m_width: %lu  data_size: %lu",
9759                      m_table_id.id(), m_flags, m_width, (ulong) data_size));
9760 
9761   m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
9762   if (likely((bool)m_rows_buf))
9763   {
9764 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9765     m_curr_row= m_rows_buf;
9766 #endif
9767     m_rows_end= m_rows_buf + data_size;
9768     m_rows_cur= m_rows_end;
9769     memcpy(m_rows_buf, ptr_rows_data, data_size);
9770   }
9771   else
9772     m_cols.bitmap= 0; // to not free it
9773 
9774   DBUG_VOID_RETURN;
9775 }
9776 
~Rows_log_event()9777 Rows_log_event::~Rows_log_event()
9778 {
9779   if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
9780     m_cols.bitmap= 0; // so no my_free in bitmap_free
9781   bitmap_free(&m_cols); // To pair with bitmap_init().
9782   my_free(m_rows_buf);
9783   my_free(m_extra_row_data);
9784 }
9785 
get_data_size()9786 int Rows_log_event::get_data_size()
9787 {
9788   int const general_type_code= get_general_type_code();
9789 
9790   uchar buf[sizeof(m_width) + 1];
9791   uchar *end= net_store_length(buf, m_width);
9792 
9793   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9794                   return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
9795                   (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
9796                   (m_rows_cur - m_rows_buf););
9797 
9798   int data_size= 0;
9799   bool is_v2_event= get_type_code() > DELETE_ROWS_EVENT_V1;
9800   if (is_v2_event)
9801   {
9802     data_size= ROWS_HEADER_LEN_V2 +
9803       (m_extra_row_data ?
9804        RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
9805        0);
9806   }
9807   else
9808   {
9809     data_size= ROWS_HEADER_LEN_V1;
9810   }
9811   data_size+= no_bytes_in_map(&m_cols);
9812   data_size+= (uint) (end - buf);
9813 
9814   if (general_type_code == UPDATE_ROWS_EVENT)
9815     data_size+= no_bytes_in_map(&m_cols_ai);
9816 
9817   data_size+= (uint) (m_rows_cur - m_rows_buf);
9818   return data_size;
9819 }
9820 
9821 
9822 #ifndef MYSQL_CLIENT
do_add_row_data(uchar * row_data,size_t length)9823 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
9824 {
9825   /*
9826     When the table has a primary key, we would probably want, by default, to
9827     log only the primary key value instead of the entire "before image". This
9828     would save binlog space. TODO
9829   */
9830   DBUG_ENTER("Rows_log_event::do_add_row_data");
9831   DBUG_PRINT("enter", ("row_data: 0x%lx  length: %lu", (ulong) row_data,
9832                        (ulong) length));
9833 
9834   /*
9835     If length is zero, there is nothing to write, so we just
9836     return. Note that this is not an optimization, since calling
9837     realloc() with size 0 means free().
9838    */
9839   if (length == 0)
9840   {
9841     m_row_count++;
9842     DBUG_RETURN(0);
9843   }
9844 
9845   /*
9846     Don't print debug messages when running valgrind since they can
9847     trigger false warnings.
9848    */
9849 #ifndef HAVE_purify
9850   DBUG_DUMP("row_data", row_data, min<size_t>(length, 32));
9851 #endif
9852 
9853   DBUG_ASSERT(m_rows_buf <= m_rows_cur);
9854   DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
9855   DBUG_ASSERT(m_rows_cur <= m_rows_end);
9856 
9857   /* The cast will always work since m_rows_cur <= m_rows_end */
9858   if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
9859   {
9860     size_t const block_size= 1024;
9861     ulong cur_size= m_rows_cur - m_rows_buf;
9862     DBUG_EXECUTE_IF("simulate_too_big_row_case1",
9863                      cur_size= UINT_MAX32 - (block_size * 10);
9864                      length= UINT_MAX32 - (block_size * 10););
9865     DBUG_EXECUTE_IF("simulate_too_big_row_case2",
9866                      cur_size= UINT_MAX32 - (block_size * 10);
9867                      length= block_size * 10;);
9868     DBUG_EXECUTE_IF("simulate_too_big_row_case3",
9869                      cur_size= block_size * 10;
9870                      length= UINT_MAX32 - (block_size * 10););
9871     DBUG_EXECUTE_IF("simulate_too_big_row_case4",
9872                      cur_size= UINT_MAX32 - (block_size * 10);
9873                      length= (block_size * 10) - block_size + 1;);
9874     ulong remaining_space= UINT_MAX32 - cur_size;
9875     /* Check that the new data fits within remaining space and we can add
9876        block_size without wrapping.
9877      */
9878     if (length > remaining_space ||
9879         ((length + block_size) > remaining_space))
9880     {
9881       sql_print_error("The row data is greater than 4GB, which is too big to "
9882                       "write to the binary log.");
9883       DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
9884     }
9885     ulong const new_alloc=
9886         block_size * ((cur_size + length + block_size - 1) / block_size);
9887 
9888     uchar* const new_buf=
9889       (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
9890                          MYF(MY_ALLOW_ZERO_PTR|MY_WME));
9891     if (unlikely(!new_buf))
9892       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
9893 
9894     /* If the memory moved, we need to move the pointers */
9895     if (new_buf != m_rows_buf)
9896     {
9897       m_rows_buf= new_buf;
9898       m_rows_cur= m_rows_buf + cur_size;
9899     }
9900 
9901     /*
9902        The end pointer should always be changed to point to the end of
9903        the allocated memory.
9904     */
9905     m_rows_end= m_rows_buf + new_alloc;
9906   }
9907 
9908   DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
9909   memcpy(m_rows_cur, row_data, length);
9910   m_rows_cur+= length;
9911   m_row_count++;
9912   DBUG_RETURN(0);
9913 }
9914 #endif
9915 
9916 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9917 
9918 /**
9919   Checks if any of the columns in the given table is
9920   signaled in the bitmap.
9921 
9922   For each column in the given table checks if it is
9923   signaled in the bitmap. This is most useful when deciding
9924   whether a before image (BI) can be used or not for
9925   searching a row. If no column is signaled, then the
9926   image cannot be used for searching a record (regardless
9927   of using position(), index scan or table scan). Here is
9928   an example:
9929 
9930   MASTER> SET @@binlog_row_image='MINIMAL';
9931   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9932   SLAVE>  CREATE TABLE t1 (a int, b int);
9933   MASTER> INSERT INTO t1 VALUES (1,2,3);
9934   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9935 
9936   For the update statement only the PK (column c) is
9937   logged in the before image (BI). As such, given that
9938   the slave has no column c, it will not be able to
9939   find the row, because BI has no values for the columns
9940   the slave knows about (column a and b).
9941 
9942   @param table   the table reference on the slave.
9943   @param cols the bitmap signaling columns available in
9944                  the BI.
9945 
9946   @return TRUE if BI contains usable colums for searching,
9947           FALSE otherwise.
9948 */
9949 static
is_any_column_signaled_for_table(TABLE * table,MY_BITMAP * cols)9950 my_bool is_any_column_signaled_for_table(TABLE *table, MY_BITMAP *cols)
9951 {
9952   DBUG_ENTER("is_any_column_signaled_for_table");
9953 
9954   for (Field **ptr= table->field ;
9955        *ptr && ((*ptr)->field_index < cols->n_bits);
9956        ptr++)
9957   {
9958     if (bitmap_is_set(cols, (*ptr)->field_index))
9959       DBUG_RETURN(TRUE);
9960   }
9961 
9962   DBUG_RETURN (FALSE);
9963 }
9964 
9965 /**
9966   Checks if the fields in the given key are signaled in
9967   the bitmap.
9968 
9969   Validates whether the before image is usable for the
9970   given key. It can be the case that the before image
9971   does not contain values for the key (eg, master was
9972   using 'minimal' option for image logging and slave has
9973   different index structure on the table). Here is an
9974   example:
9975 
9976   MASTER> SET @@binlog_row_image='MINIMAL';
9977   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9978   SLAVE> CREATE TABLE t1 (a int, b int, c int, key(a,c));
9979   MASTER> INSERT INTO t1 VALUES (1,2,3);
9980   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9981 
9982   When finding the row on the slave, one cannot use the
9983   index (a,c) to search for the row, because there is only
9984   data in the before image for column c. This function
9985   checks the fields needed for a given key and searches
9986   the bitmap to see if all the fields required are
9987   signaled.
9988 
9989   @param keyinfo  reference to key.
9990   @param cols     the bitmap signaling which columns
9991                   have available data.
9992 
9993   @return TRUE if all fields are signaled in the bitmap
9994           for the given key, FALSE otherwise.
9995 */
9996 static
are_all_columns_signaled_for_key(KEY * keyinfo,MY_BITMAP * cols)9997 my_bool are_all_columns_signaled_for_key(KEY *keyinfo, MY_BITMAP *cols)
9998 {
9999   DBUG_ENTER("are_all_columns_signaled_for_key");
10000 
10001   for (uint i=0 ; i < keyinfo->user_defined_key_parts ;i++)
10002   {
10003     uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
10004     if (fieldnr >= cols->n_bits ||
10005         !bitmap_is_set(cols, fieldnr))
10006       DBUG_RETURN(FALSE);
10007   }
10008 
10009   DBUG_RETURN(TRUE);
10010 }
10011 
10012 /**
10013   Searches the table for a given key that can be used
10014   according to the existing values, ie, columns set
10015   in the bitmap.
10016 
10017   The caller can specify which type of key to find by
10018   setting the following flags in the key_type parameter:
10019 
10020     - PRI_KEY_FLAG
10021       Returns the primary key.
10022 
10023     - UNIQUE_KEY_FLAG
10024       Returns a unique key (flagged with HA_NOSAME)
10025 
10026     - MULTIPLE_KEY_FLAG
10027       Returns a key that is not unique (flagged with HA_NOSAME
10028       and without HA_NULL_PART_KEY) nor PK.
10029 
10030   The above flags can be used together, in which case, the
10031   search is conducted in the above listed order. Eg, the
10032   following flag:
10033 
10034     (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG)
10035 
10036   means that a primary key is returned if it is suitable. If
10037   not then the unique keys are searched. If no unique key is
10038   suitable, then the keys are searched. Finally, if no key
10039   is suitable, MAX_KEY is returned.
10040 
10041   @param table    reference to the table.
10042   @param bi_cols  a bitmap that filters out columns that should
10043                   not be considered while searching the key.
10044                   Columns that should be considered are set.
10045   @param key_type the type of key to search for.
10046 
10047   @return MAX_KEY if no key, according to the key_type specified
10048           is suitable. Returns the key otherwise.
10049 
10050 */
10051 static
10052 uint
search_key_in_table(TABLE * table,MY_BITMAP * bi_cols,uint key_type)10053 search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type)
10054 {
10055   DBUG_ENTER("search_key_in_table");
10056 
10057   KEY *keyinfo;
10058   uint res= MAX_KEY;
10059   uint key;
10060 
10061   if (key_type & PRI_KEY_FLAG &&
10062       (table->s->primary_key < MAX_KEY))
10063   {
10064     DBUG_PRINT("debug", ("Searching for PK"));
10065     keyinfo= table->s->key_info + (uint) table->s->primary_key;
10066     if (are_all_columns_signaled_for_key(keyinfo, bi_cols))
10067       DBUG_RETURN(table->s->primary_key);
10068   }
10069 
10070   DBUG_PRINT("debug", ("Unique keys count: %u", table->s->uniques));
10071 
10072   if (key_type & UNIQUE_KEY_FLAG && table->s->uniques)
10073   {
10074     DBUG_PRINT("debug", ("Searching for UK"));
10075     for (key=0,keyinfo= table->key_info ;
10076          (key < table->s->keys) && (res == MAX_KEY);
10077          key++,keyinfo++)
10078     {
10079       /*
10080         - Unique keys cannot be disabled, thence we skip the check.
10081         - Skip unique keys with nullable parts
10082         - Skip primary keys
10083       */
10084       if (!((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10085           (key == table->s->primary_key))
10086         continue;
10087       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10088            key : MAX_KEY;
10089 
10090       if (res < MAX_KEY)
10091         DBUG_RETURN(res);
10092     }
10093     DBUG_PRINT("debug", ("UK has NULLABLE parts or not all columns signaled."));
10094   }
10095 
10096   if (key_type & MULTIPLE_KEY_FLAG && table->s->keys)
10097   {
10098     DBUG_PRINT("debug", ("Searching for K."));
10099     for (key=0,keyinfo= table->key_info ;
10100          (key < table->s->keys) && (res == MAX_KEY);
10101          key++,keyinfo++)
10102     {
10103       /*
10104         - Skip innactive keys
10105         - Skip unique keys without nullable parts
10106         - Skip indices that do not support ha_index_next() e.g. full-text
10107         - Skip primary keys
10108       */
10109       if (!(table->s->keys_in_use.is_set(key)) ||
10110           ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10111           !(table->file->index_flags(key, 0, true) & HA_READ_NEXT) ||
10112           (key == table->s->primary_key))
10113         continue;
10114 
10115       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10116            key : MAX_KEY;
10117 
10118       if (res < MAX_KEY)
10119         DBUG_RETURN(res);
10120     }
10121     DBUG_PRINT("debug", ("Not all columns signaled for K."));
10122   }
10123 
10124   DBUG_RETURN(res);
10125 }
10126 
10127 void
decide_row_lookup_algorithm_and_key()10128 Rows_log_event::decide_row_lookup_algorithm_and_key()
10129 {
10130 
10131   DBUG_ENTER("decide_row_lookup_algorithm_and_key");
10132 
10133   /*
10134     Decision table:
10135     - I  --> Index scan / search
10136     - T  --> Table scan
10137     - Hi --> Hash over index
10138     - Ht --> Hash over the entire table
10139 
10140     |--------------+-----------+------+------+------|
10141     | Index\Option | I , T , H | I, T | I, H | T, H |
10142     |--------------+-----------+------+------+------|
10143     | PK / UK      | I         | I    | I    | Hi   |
10144     | K            | Hi        | I    | Hi   | Hi   |
10145     | No Index     | Ht        | T    | Ht   | Ht   |
10146     |--------------+-----------+------+------+------|
10147 
10148   */
10149 
10150   TABLE *table= this->m_table;
10151   uint event_type= this->get_general_type_code();
10152   MY_BITMAP *cols= &this->m_cols;
10153   bool delete_update_lookup_condition= false;
10154   this->m_rows_lookup_algorithm= ROW_LOOKUP_NOT_NEEDED;
10155   this->m_key_index= MAX_KEY;
10156   this->m_key_info= NULL;
10157 
10158   // row lookup not needed
10159   if (event_type == WRITE_ROWS_EVENT ||
10160      (delete_update_lookup_condition= ((event_type == DELETE_ROWS_EVENT ||
10161                                         event_type == UPDATE_ROWS_EVENT) &&
10162                                       get_flags(COMPLETE_ROWS_F) &&
10163                                       !m_table->file->rpl_lookup_rows())))
10164   {
10165     /**
10166        Only TokuDB engine can satisfy delete/update row lookup optimization,
10167        so we don't need to check engine type here.
10168     */
10169     if (delete_update_lookup_condition &&
10170         table->s->primary_key == MAX_KEY)
10171     {
10172         if (!table->s->rfr_lookup_warning)
10173         {
10174           sql_print_warning("Slave: read free replication is disabled "
10175                             "for tokudb table `%s.%s` "
10176                             "as it does not have implicit primary key, "
10177                             "continue with rows lookup",
10178                             print_slave_db_safe(table->s->db.str),
10179                             m_table->s->table_name.str);
10180           table->s->rfr_lookup_warning= true;
10181         }
10182     }
10183     else
10184       DBUG_VOID_RETURN;
10185   }
10186 
10187   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN))
10188     goto TABLE_OR_INDEX_HASH_SCAN;
10189 
10190   /* PK or UK => use LOOKUP_INDEX_SCAN */
10191   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG));
10192   if (this->m_key_index != MAX_KEY)
10193   {
10194     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10195     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10196     goto end;
10197   }
10198 
10199 TABLE_OR_INDEX_HASH_SCAN:
10200 
10201   /*
10202      NOTE: Engines like Blackhole cannot use HASH_SCAN, because
10203            they do not syncronize reads .
10204    */
10205   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_HASH_SCAN) ||
10206       (table->file->ha_table_flags() & HA_READ_OUT_OF_SYNC))
10207     goto TABLE_OR_INDEX_FULL_SCAN;
10208 
10209   /* search for a key to see if we can narrow the lookup domain further. */
10210   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10211   this->m_rows_lookup_algorithm= ROW_LOOKUP_HASH_SCAN;
10212   if (m_key_index < MAX_KEY)
10213     m_distinct_key_spare_buf= (uchar*) thd->alloc(table->key_info[m_key_index].key_length);
10214   DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - HASH_SCAN"));
10215   goto end;
10216 
10217 TABLE_OR_INDEX_FULL_SCAN:
10218 
10219   this->m_key_index= MAX_KEY;
10220 
10221   /* If we can use an index, try to narrow the scan a bit further. */
10222   if (slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN)
10223     this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10224 
10225   if (this->m_key_index != MAX_KEY)
10226   {
10227     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10228     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10229   }
10230   else
10231   {
10232     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - TABLE_SCAN"));
10233     this->m_rows_lookup_algorithm= ROW_LOOKUP_TABLE_SCAN;
10234   }
10235 
10236 end:
10237 
10238   /* m_key_index is ready, set m_key_info now. */
10239   m_key_info= m_table->key_info + m_key_index;
10240   /*
10241     m_key_info will influence key comparison code in HASH_SCAN mode,
10242     so the m_distinct_keys set should still be empty.
10243   */
10244   DBUG_ASSERT(m_distinct_keys.empty());
10245 
10246 #ifndef DBUG_OFF
10247   const char* s= ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
10248                   ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
10249                    "INDEX_SCAN"));
10250 
10251   // only for testing purposes
10252   slave_rows_last_search_algorithm_used= m_rows_lookup_algorithm;
10253   DBUG_PRINT("debug", ("Row lookup method: %s", s));
10254 #endif
10255 
10256   DBUG_VOID_RETURN;
10257 }
10258 
10259 /*
10260   Encapsulates the  operations to be done before applying
10261   row events for update and delete.
10262 
10263   @ret value error code
10264              0 success
10265 */
10266 int
row_operations_scan_and_key_setup()10267 Rows_log_event::row_operations_scan_and_key_setup()
10268 {
10269   int error= 0;
10270   DBUG_ENTER("Row_log_event::row_operations_scan_and_key_setup");
10271 
10272   /*
10273      Prepare memory structures for search operations. If
10274      search is performed:
10275 
10276      1. using hash search => initialize the hash
10277      2. using key => decide on key to use and allocate mem structures
10278      3. using table scan => do nothing
10279    */
10280   decide_row_lookup_algorithm_and_key();
10281 
10282   switch (m_rows_lookup_algorithm)
10283   {
10284   case ROW_LOOKUP_HASH_SCAN:
10285     {
10286       if (m_hash.init())
10287         error= HA_ERR_OUT_OF_MEM;
10288       goto err;
10289     }
10290   case ROW_LOOKUP_INDEX_SCAN:
10291     {
10292       DBUG_ASSERT (m_key_index < MAX_KEY);
10293       // Allocate buffer for key searches
10294       m_key= (uchar*)my_malloc(m_key_info->key_length, MYF(MY_WME));
10295       if (!m_key)
10296         error= HA_ERR_OUT_OF_MEM;
10297       goto err;
10298     }
10299   case ROW_LOOKUP_TABLE_SCAN:
10300   default: break;
10301   }
10302 err:
10303   DBUG_RETURN(error);
10304 }
10305 
10306 /*
10307   Encapsulates the  operations to be done after applying
10308   row events for update and delete.
10309 
10310   @ret value error code
10311              0 success
10312 */
10313 
10314 int
row_operations_scan_and_key_teardown(int error)10315 Rows_log_event::row_operations_scan_and_key_teardown(int error)
10316 {
10317   DBUG_ENTER("Rows_log_event::row_operations_scan_and_key_teardown");
10318 
10319   DBUG_ASSERT(!m_table->file->inited);
10320   switch (m_rows_lookup_algorithm)
10321   {
10322   case ROW_LOOKUP_HASH_SCAN:
10323     {
10324       m_hash.deinit(); // we don't need the hash anymore.
10325       goto err;
10326     }
10327 
10328   case ROW_LOOKUP_INDEX_SCAN:
10329     {
10330       if (m_table->s->keys > 0)
10331       {
10332         my_free(m_key); // Free for multi_malloc
10333         m_key= NULL;
10334         m_key_index= MAX_KEY;
10335         m_key_info= NULL;
10336       }
10337      goto err;
10338     }
10339 
10340   case ROW_LOOKUP_TABLE_SCAN:
10341   default: break;
10342   }
10343 
10344 err:
10345   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
10346   DBUG_RETURN(error);
10347 }
10348 
10349 /*
10350   Compares table->record[0] and table->record[1]
10351 
10352   Returns TRUE if different.
10353 */
record_compare(TABLE * table,MY_BITMAP * cols)10354 static bool record_compare(TABLE *table, MY_BITMAP *cols)
10355 {
10356   DBUG_ENTER("record_compare");
10357 
10358   /*
10359     Need to set the X bit and the filler bits in both records since
10360     there are engines that do not set it correctly.
10361 
10362     In addition, since MyISAM checks that one hasn't tampered with the
10363     record, it is necessary to restore the old bytes into the record
10364     after doing the comparison.
10365 
10366     TODO[record format ndb]: Remove it once NDB returns correct
10367     records. Check that the other engines also return correct records.
10368    */
10369 
10370   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10371   DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
10372 
10373   bool result= false;
10374   uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
10375 
10376   if (table->s->null_bytes > 0)
10377   {
10378     for (int i = 0 ; i < 2 ; ++i)
10379     {
10380       /*
10381         If we have an X bit then we need to take care of it.
10382       */
10383       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10384       {
10385         saved_x[i]= table->record[i][0];
10386         table->record[i][0]|= 1U;
10387       }
10388 
10389       /*
10390          If (last_null_bit_pos == 0 && null_bytes > 1), then:
10391 
10392          X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
10393 
10394          Ie, the entire byte is used.
10395       */
10396       if (table->s->last_null_bit_pos > 0)
10397       {
10398         saved_filler[i]= table->record[i][table->s->null_bytes - 1];
10399         table->record[i][table->s->null_bytes - 1]|=
10400           256U - (1U << table->s->last_null_bit_pos);
10401       }
10402     }
10403   }
10404 
10405   /**
10406     Compare full record only if:
10407     - there are no blob fields (otherwise we would also need
10408       to compare blobs contents as well);
10409     - there are no varchar fields (otherwise we would also need
10410       to compare varchar contents as well);
10411     - there are no null fields, otherwise NULLed fields
10412       contents (i.e., the don't care bytes) may show arbitrary
10413       values, depending on how each engine handles internally.
10414     - if all the bitmap is set (both are full rows)
10415     */
10416   if ((table->s->blob_fields +
10417        table->s->varchar_fields +
10418        table->s->null_fields) == 0 &&
10419       bitmap_is_set_all(cols))
10420   {
10421     result= cmp_record(table,record[1]);
10422   }
10423 
10424   /*
10425     Fallback to field-by-field comparison:
10426     1. start by checking if the field is signaled:
10427     2. if it is, first compare the null bit if the field is nullable
10428     3. then compare the contents of the field, if it is not
10429        set to null
10430    */
10431   else
10432   {
10433     for (Field **ptr=table->field ;
10434          *ptr && ((*ptr)->field_index < cols->n_bits) && !result;
10435          ptr++)
10436     {
10437       Field *field= *ptr;
10438       if (bitmap_is_set(cols, field->field_index))
10439       {
10440         /* compare null bit */
10441         if (field->is_null() != field->is_null_in_record(table->record[1]))
10442           result= true;
10443 
10444         /* compare content, only if fields are not set to NULL */
10445         else if (!field->is_null())
10446           result= field->cmp_binary_offset(table->s->rec_buff_length);
10447       }
10448     }
10449   }
10450 
10451   /*
10452     Restore the saved bytes.
10453 
10454     TODO[record format ndb]: Remove this code once NDB returns the
10455     correct record format.
10456   */
10457   if (table->s->null_bytes > 0)
10458   {
10459     for (int i = 0 ; i < 2 ; ++i)
10460     {
10461       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10462         table->record[i][0]= saved_x[i];
10463 
10464       if (table->s->last_null_bit_pos)
10465         table->record[i][table->s->null_bytes - 1]= saved_filler[i];
10466     }
10467   }
10468 
10469   DBUG_RETURN(result);
10470 }
10471 
do_post_row_operations(Relay_log_info const * rli,int error)10472 void Rows_log_event::do_post_row_operations(Relay_log_info const *rli, int error)
10473 {
10474 
10475   /*
10476     If m_curr_row_end  was not set during event execution (e.g., because
10477     of errors) we can't proceed to the next row. If the error is transient
10478     (i.e., error==0 at this point) we must call unpack_current_row() to set
10479     m_curr_row_end.
10480   */
10481 
10482   DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
10483                       (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
10484 
10485   if (!m_curr_row_end && !error)
10486   {
10487     const uchar *previous_m_curr_row= m_curr_row;
10488     error= unpack_current_row(rli, &m_cols);
10489 
10490     if (!error && previous_m_curr_row == m_curr_row)
10491     {
10492       error= 1;
10493     }
10494   }
10495 
10496   // at this moment m_curr_row_end should be set
10497   DBUG_ASSERT(error || m_curr_row_end != NULL);
10498   DBUG_ASSERT(error || m_curr_row <= m_curr_row_end);
10499   DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
10500 
10501   m_curr_row= m_curr_row_end;
10502 
10503   if (error == 0 && !m_table->file->has_transactions())
10504   {
10505     thd->transaction.all.set_unsafe_rollback_flags(TRUE);
10506     thd->transaction.stmt.set_unsafe_rollback_flags(TRUE);
10507   }
10508 }
10509 
handle_idempotent_and_ignored_errors(Relay_log_info const * rli,int * err)10510 int Rows_log_event::handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err)
10511 {
10512   int error= *err;
10513   if (error)
10514   {
10515     int actual_error= convert_handler_error(error, thd, m_table);
10516     bool idempotent_error= (idempotent_error_code(error) &&
10517                            (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
10518     bool ignored_error= (idempotent_error == 0 ?
10519                          ignored_error_code(actual_error) : 0);
10520 
10521     if (idempotent_error || ignored_error)
10522     {
10523       if ( (idempotent_error && log_warnings) ||
10524 		(ignored_error && log_warnings > 1) )
10525         slave_rows_error_report(WARNING_LEVEL, error, rli, thd, m_table,
10526                                 get_type_str(),
10527                                 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
10528                                 (ulong) log_pos);
10529       thd->get_stmt_da()->clear_warning_info(thd->query_id);
10530       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
10531       *err= 0;
10532       if (idempotent_error == 0)
10533         return ignored_error;
10534     }
10535   }
10536 
10537   return *err;
10538 }
10539 
do_apply_row(Relay_log_info const * rli)10540 int Rows_log_event::do_apply_row(Relay_log_info const *rli)
10541 {
10542   DBUG_ENTER("Rows_log_event::do_apply_row");
10543 
10544   int error= 0;
10545 
10546   /* in_use can have been set to NULL in close_tables_for_reopen */
10547   THD* old_thd= m_table->in_use;
10548   if (!m_table->in_use)
10549     m_table->in_use= thd;
10550 
10551   error= do_exec_row(rli);
10552 
10553   if(error)
10554   {
10555     DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10556     DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10557   }
10558 
10559   m_table->in_use = old_thd;
10560 
10561   DBUG_RETURN(error);
10562 }
10563 
10564 /**
10565    Does the cleanup
10566      -  closes the index if opened by open_record_scan
10567      -  closes the table if opened for scanning.
10568 */
10569 int
close_record_scan()10570 Rows_log_event::close_record_scan()
10571 {
10572   DBUG_ENTER("Rows_log_event::close_record_scan");
10573   int error= 0;
10574 
10575   // if there is something to actually close
10576   if (m_key_index < MAX_KEY)
10577   {
10578     if (m_table->file->inited)
10579       error= m_table->file->ha_index_end();
10580   }
10581   else if (m_table->file->inited)
10582     error= m_table->file->ha_rnd_end();
10583 
10584   DBUG_RETURN(error);
10585 }
10586 
10587 /**
10588   Fetches next row. If it is a HASH_SCAN over an index, it populates
10589   table->record[0] with the next row corresponding to the index. If
10590   the indexes are in non-contigous ranges it fetches record corresponding
10591   to the key value in the next range.
10592 
10593   @parms: bool first_read : signifying if this is the first time we are reading a row
10594           over an index.
10595   @return_value: -  error code when there are no more reeords to be fetched or some other
10596                     error occured,
10597                  -  0 otherwise.
10598 */
10599 int
next_record_scan(bool first_read)10600 Rows_log_event::next_record_scan(bool first_read)
10601 {
10602   DBUG_ENTER("Rows_log_event::next_record_scan");
10603   DBUG_ASSERT(m_table->file->inited);
10604   TABLE *table= m_table;
10605   int error= 0;
10606 
10607   if (m_key_index >= MAX_KEY)
10608     error= table->file->ha_rnd_next(table->record[0]);
10609   else
10610   {
10611     /*
10612       We need to set the null bytes to ensure that the filler bit are
10613       all set when returning.  There are storage engines that just set
10614       the necessary bits on the bytes and don't set the filler bits
10615       correctly.
10616     */
10617     if (table->s->null_bytes > 0)
10618       table->record[0][table->s->null_bytes - 1]|=
10619         256U - (1U << table->s->last_null_bit_pos);
10620 
10621     if (!first_read)
10622     {
10623       /*
10624         if we fail to fetch next record corresponding to a key value, we
10625         move to the next key value. If we are out of key values as well an error
10626         will be returned.
10627        */
10628       error= table->file->ha_index_next_same(table->record[0], m_key,
10629                                              m_key_info->key_length);
10630       if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10631       {
10632         /*
10633           if we are out of rows for this particular key value, we reposition the
10634           marker according to the next key value that we have in the list.
10635          */
10636         if (error)
10637         {
10638           if (m_itr != m_distinct_keys.end())
10639           {
10640             m_key= *m_itr;
10641             m_itr++;
10642             first_read= true;
10643           }
10644           else
10645             error= HA_ERR_KEY_NOT_FOUND;
10646         }
10647       }
10648     }
10649 
10650     if (first_read)
10651       if ((error= table->file->ha_index_read_map(table->record[0], m_key,
10652                                                  HA_WHOLE_KEY,
10653                                                  HA_READ_KEY_EXACT)))
10654       {
10655         DBUG_PRINT("info",("no record matching the key found in the table"));
10656         if (error == HA_ERR_RECORD_DELETED)
10657           error= HA_ERR_KEY_NOT_FOUND;
10658       }
10659   }
10660 
10661   DBUG_RETURN(error);
10662 }
10663 
10664 /**
10665   Initializes scanning of rows. Opens an index and initializes an iterator
10666   over a list of distinct keys (m_distinct_keys) if it is a HASH_SCAN
10667   over an index or the table if its a HASH_SCAN over the table.
10668 */
10669 int
open_record_scan()10670 Rows_log_event::open_record_scan()
10671 {
10672   int error= 0;
10673   TABLE *table= m_table;
10674   DBUG_ENTER("Rows_log_event::open_record_scan");
10675 
10676   if (m_key_index < MAX_KEY )
10677   {
10678     if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10679     {
10680       /* initialize the iterator over the list of distinct keys that we have */
10681       m_itr= m_distinct_keys.begin();
10682 
10683       /* get the first element from the list of keys and increment the
10684          iterator
10685        */
10686       m_key= *m_itr;
10687       m_itr++;
10688     }
10689     else {
10690       /* this is an INDEX_SCAN we need to store the key in m_key */
10691       DBUG_ASSERT((m_rows_lookup_algorithm == ROW_LOOKUP_INDEX_SCAN) && m_key);
10692       key_copy(m_key, m_table->record[0], m_key_info, 0);
10693     }
10694 
10695     /*
10696       Save copy of the record in table->record[1]. It might be needed
10697       later if linear search is used to find exact match.
10698      */
10699     store_record(table,record[1]);
10700 
10701     DBUG_PRINT("info",("locating record using a key (index_read)"));
10702 
10703     /* The m_key_index'th key is active and usable: search the table using the index */
10704     if (!table->file->inited && (error= table->file->ha_index_init(m_key_index, FALSE)))
10705     {
10706       DBUG_PRINT("info",("ha_index_init returns error %d",error));
10707       goto end;
10708     }
10709 
10710     /*
10711       Don't print debug messages when running valgrind since they can
10712       trigger false warnings.
10713      */
10714 #ifndef HAVE_purify
10715     DBUG_DUMP("key data", m_key, m_key_info->key_length);
10716 #endif
10717   }
10718   else
10719   {
10720     if ((error= table->file->ha_rnd_init(1)))
10721     {
10722       DBUG_PRINT("info",("error initializing table scan"
10723           " (ha_rnd_init returns %d)",error));
10724       table->file->print_error(error, MYF(0));
10725     }
10726   }
10727 
10728 end:
10729   DBUG_RETURN(error);
10730 }
10731 
10732 /**
10733   Populates the m_distinct_keys with unique keys to be modified
10734   during HASH_SCAN over keys.
10735   @return_value -0 success
10736                 -Err_code
10737 */
10738 int
add_key_to_distinct_keyset()10739 Rows_log_event::add_key_to_distinct_keyset()
10740 {
10741   int error= 0;
10742   DBUG_ENTER("Rows_log_event::add_key_to_distinct_keyset");
10743   DBUG_ASSERT(m_key_index < MAX_KEY);
10744   key_copy(m_distinct_key_spare_buf, m_table->record[0], m_key_info, 0);
10745   std::pair<std::set<uchar *, Key_compare>::iterator,bool> ret=
10746     m_distinct_keys.insert(m_distinct_key_spare_buf);
10747   if (ret.second)
10748   {
10749     /* Insert is successful, so allocate a new buffer for next key */
10750     m_distinct_key_spare_buf= (uchar*) thd->alloc(m_key_info->key_length);
10751     if (!m_distinct_key_spare_buf)
10752     {
10753       error= HA_ERR_OUT_OF_MEM;
10754       goto err;
10755     }
10756   }
10757 err:
10758   DBUG_RETURN(error);
10759 }
10760 
10761 
do_index_scan_and_update(Relay_log_info const * rli)10762 int Rows_log_event::do_index_scan_and_update(Relay_log_info const *rli)
10763 {
10764   DBUG_ENTER("Rows_log_event::do_index_scan_and_update");
10765   DBUG_ASSERT(m_table && m_table->in_use != NULL);
10766 
10767   int error= 0;
10768   const uchar *saved_m_curr_row= m_curr_row;
10769 
10770   /*
10771     rpl_row_tabledefs.test specifies that
10772     if the extra field on the slave does not have a default value
10773     and this is okay with Delete or Update events.
10774     Todo: fix wl3228 hld that requires defaults for all types of events
10775   */
10776 
10777   prepare_record(m_table, &m_cols, FALSE);
10778   if ((error= unpack_current_row(rli, &m_cols)))
10779     goto end;
10780 
10781   // Temporary fix to find out why it fails [/Matz]
10782   memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
10783 
10784   /*
10785     Trying to do an index scan without a usable key
10786     This is a valid state because we allow the user
10787     to set Slave_rows_search_algorithm= 'INDEX_SCAN'.
10788 
10789     Therefore on tables with no indexes we will end
10790     up here.
10791    */
10792   if (m_key_index >= MAX_KEY)
10793   {
10794     error= HA_ERR_END_OF_FILE;
10795     goto end;
10796   }
10797 
10798 #ifndef DBUG_OFF
10799   DBUG_PRINT("info",("looking for the following record"));
10800   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10801 #endif
10802 
10803   if (m_key_index != m_table->s->primary_key)
10804     /* we dont have a PK, or PK is not usable */
10805     goto INDEX_SCAN;
10806 
10807   if ((m_table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL))
10808   {
10809     /*
10810       Read removal is possible since the engine supports write without
10811       previous read using full primary key
10812     */
10813     DBUG_PRINT("info", ("using read before write removal"));
10814     DBUG_ASSERT(m_key_index == m_table->s->primary_key);
10815 
10816     /*
10817       Tell the handler to ignore if key exists or not, since it's
10818       not yet known if the key does exist(when using rbwr)
10819     */
10820     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
10821 
10822     goto end;
10823   }
10824 
10825   if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION))
10826   {
10827     /*
10828       Use a more efficient method to fetch the record given by
10829       table->record[0] if the engine allows it.  We first compute a
10830       row reference using the position() member function (it will be
10831       stored in table->file->ref) and then use rnd_pos() to position
10832       the "cursor" (i.e., record[0] in this case) at the correct row.
10833 
10834       TODO: Check that the correct record has been fetched by
10835       comparing it with the original record. Take into account that the
10836       record on the master and slave can be of different
10837       length. Something along these lines should work:
10838 
10839       ADD>>>  store_record(table,record[1]);
10840               int error= table->file->rnd_pos(table->record[0], table->file->ref);
10841       ADD>>>  DBUG_ASSERT(memcmp(table->record[1], table->record[0],
10842                                  table->s->reclength) == 0);
10843 
10844     */
10845 
10846     DBUG_PRINT("info",("locating record using primary key (position)"));
10847     if (m_table->file->inited && (error= m_table->file->ha_index_end()))
10848       goto end;
10849 
10850     error= m_table->file->rnd_pos_by_record(m_table->record[0]);
10851     if (error)
10852     {
10853       DBUG_PRINT("info",("rnd_pos returns error %d",error));
10854       if (error == HA_ERR_RECORD_DELETED)
10855         error= HA_ERR_KEY_NOT_FOUND;
10856     }
10857 
10858     goto end;
10859   }
10860 
10861   // We can't use position() - try other methods.
10862 
10863 INDEX_SCAN:
10864 
10865   /* Use the m_key_index'th key */
10866 
10867   if ((error= open_record_scan()))
10868     goto end;
10869 
10870   error= next_record_scan(true);
10871   if (error)
10872   {
10873     DBUG_PRINT("info",("no record matching the key found in the table"));
10874     if (error == HA_ERR_RECORD_DELETED)
10875       error= HA_ERR_KEY_NOT_FOUND;
10876     goto end;
10877   }
10878 
10879 
10880   /*
10881     Don't print debug messages when running valgrind since they can
10882     trigger false warnings.
10883    */
10884 #ifndef HAVE_purify
10885   DBUG_PRINT("info",("found first matching record"));
10886   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10887 #endif
10888   /*
10889     Below is a minor "optimization".  If the key (i.e., key number
10890     0) has the HA_NOSAME flag set, we know that we have found the
10891     correct record (since there can be no duplicates); otherwise, we
10892     have to compare the record with the one found to see if it is
10893     the correct one.
10894 
10895     CAVEAT! This behaviour is essential for the replication of,
10896     e.g., the mysql.proc table since the correct record *shall* be
10897     found using the primary key *only*.  There shall be no
10898     comparison of non-PK columns to decide if the correct record is
10899     found.  I can see no scenario where it would be incorrect to
10900     chose the row to change only using a PK or an UNNI.
10901   */
10902   if (m_key_info->flags & HA_NOSAME || m_key_index == m_table->s->primary_key)
10903   {
10904     /* Unique does not have non nullable part */
10905     if (!(m_key_info->flags & (HA_NULL_PART_KEY)))
10906       goto end;  // record found
10907     else
10908     {
10909       /*
10910         Unique has nullable part. We need to check if there is any field in the
10911         BI image that is null and part of UNNI.
10912       */
10913       bool null_found= FALSE;
10914       for (uint i=0; i < m_key_info->user_defined_key_parts && !null_found; i++)
10915       {
10916         uint fieldnr= m_key_info->key_part[i].fieldnr - 1;
10917         Field **f= m_table->field+fieldnr;
10918         null_found= (*f)->is_null();
10919       }
10920 
10921       if (!null_found)
10922         goto end;           // record found
10923 
10924       /* else fall through to index scan */
10925     }
10926   }
10927 
10928   /*
10929     In case key is not unique, we still have to iterate over records found
10930     and find the one which is identical to the row given. A copy of the
10931     record we are looking for is stored in record[1].
10932    */
10933   DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10934 
10935   while (record_compare(m_table, &m_cols))
10936   {
10937     while((error= next_record_scan(false)))
10938     {
10939       /* We just skip records that has already been deleted */
10940       if (error == HA_ERR_RECORD_DELETED)
10941         continue;
10942       DBUG_PRINT("info",("no record matching the given row found"));
10943       goto end;
10944     }
10945   }
10946 
10947 end:
10948 
10949   DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10950 
10951   if (error && error != HA_ERR_RECORD_DELETED)
10952     m_table->file->print_error(error, MYF(0));
10953   else
10954     error= do_apply_row(rli);
10955 
10956   if (!error)
10957     error= close_record_scan();
10958   else
10959     /*
10960       we are already with errors. Keep the error code and
10961       try to close the scan anyway.
10962     */
10963     (void) close_record_scan();
10964 
10965   if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
10966       (saved_m_curr_row == m_curr_row))
10967   {
10968     /* we need to unpack the AI so that positions get updated */
10969     m_curr_row= m_curr_row_end;
10970     unpack_current_row(rli, &m_cols_ai);
10971   }
10972   m_table->default_column_bitmaps();
10973   DBUG_RETURN(error);
10974 
10975 }
10976 
do_hash_row(Relay_log_info const * rli)10977 int Rows_log_event::do_hash_row(Relay_log_info const *rli)
10978 {
10979   DBUG_ENTER("Rows_log_event::do_hash_row");
10980   DBUG_ASSERT(m_table && m_table->in_use != NULL);
10981   int error= 0;
10982 
10983   /* create an empty entry to add to the hash table */
10984   HASH_ROW_ENTRY* entry= m_hash.make_entry();
10985   if (entry == NULL)
10986   {
10987     error= 1;
10988     goto end;
10989   }
10990   /* Prepare the record, unpack and save positions. */
10991   entry->positions->bi_start= m_curr_row;        // save the bi start pos
10992   prepare_record(m_table, &m_cols, false);
10993   if ((error= unpack_current_row(rli, &m_cols)))
10994     goto end;
10995   entry->positions->bi_ends= m_curr_row_end;    // save the bi end pos
10996 
10997   /*
10998     Now that m_table->record[0] is filled in, we can add the entry
10999     to the hash table. Note that the put operation calculates the
11000     key based on record[0] contents (including BLOB fields).
11001    */
11002   m_hash.put(m_table, &m_cols, entry);
11003 
11004   if (m_key_index < MAX_KEY)
11005     add_key_to_distinct_keyset();
11006 
11007   /*
11008     We need to unpack the AI to advance the positions, so we
11009     know when we have reached m_rows_end and that we do not
11010     unpack the AI in the next iteration as if it was a BI.
11011   */
11012   if (get_general_type_code() == UPDATE_ROWS_EVENT)
11013   {
11014     /* Save a copy of the BI. */
11015     store_record(m_table, record[1]);
11016 
11017      /*
11018       This is the situation after hashing the BI:
11019 
11020       ===|=== before image ====|=== after image ===|===
11021          ^                     ^
11022          m_curr_row            m_curr_row_end
11023     */
11024 
11025     /* Set the position to the start of the record to be unpacked. */
11026     m_curr_row= m_curr_row_end;
11027 
11028     /* We shouldn't need this, but lets not leave loose ends */
11029     prepare_record(m_table, &m_cols, false);
11030     error= unpack_current_row(rli, &m_cols_ai);
11031 
11032     /*
11033       This is the situation after unpacking the AI:
11034 
11035       ===|=== before image ====|=== after image ===|===
11036                                ^                   ^
11037                                m_curr_row          m_curr_row_end
11038     */
11039 
11040     /* Restore back the copy of the BI. */
11041     restore_record(m_table, record[1]);
11042   }
11043 
11044 end:
11045   DBUG_RETURN(error);
11046 }
11047 
do_scan_and_update(Relay_log_info const * rli)11048 int Rows_log_event::do_scan_and_update(Relay_log_info const *rli)
11049 {
11050   DBUG_ENTER("Rows_log_event::do_scan_and_update");
11051   DBUG_ASSERT(m_table && m_table->in_use != NULL);
11052   DBUG_ASSERT(m_hash.is_empty() == false);
11053   TABLE *table= m_table;
11054   int error= 0;
11055   const uchar *saved_last_m_curr_row= NULL;
11056   const uchar *saved_last_m_curr_row_end= NULL;
11057   /* create an empty entry to add to the hash table */
11058   HASH_ROW_ENTRY* entry= NULL;
11059   int idempotent_errors= 0;
11060   int i= 0;
11061 
11062   saved_last_m_curr_row=m_curr_row;
11063   saved_last_m_curr_row_end=m_curr_row_end;
11064 
11065   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11066 
11067   /* open table or index depending on whether we have set m_key_index or not. */
11068   if ((error= open_record_scan()))
11069     goto err;
11070 
11071   /*
11072      Scan the table only once and compare against entries in hash.
11073      When a match is found, apply the changes.
11074    */
11075   do
11076   {
11077     /* get the next record from the table */
11078     error= next_record_scan(i == 0);
11079     i++;
11080 
11081     if(error)
11082       DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11083     switch (error) {
11084       case 0:
11085       {
11086         entry= m_hash.get(table, &m_cols);
11087         store_record(table, record[1]);
11088 
11089         /**
11090            If there are collisions we need to be sure that this is
11091            indeed the record we want.  Loop through all records for
11092            the given key and explicitly compare them against the
11093            record we got from the storage engine.
11094          */
11095         while(entry)
11096         {
11097           m_curr_row= entry->positions->bi_start;
11098           m_curr_row_end= entry->positions->bi_ends;
11099 
11100           prepare_record(table, &m_cols, false);
11101           if ((error= unpack_current_row(rli, &m_cols)))
11102             goto close_table;
11103 
11104           if (record_compare(table, &m_cols))
11105             m_hash.next(&entry);
11106           else
11107             break;   // we found a match
11108         }
11109 
11110         /**
11111            We found the entry we needed, just apply the changes.
11112          */
11113         if (entry)
11114         {
11115           // just to be safe, copy the record from the SE to table->record[0]
11116           restore_record(table, record[1]);
11117 
11118           /**
11119              At this point, both table->record[0] and
11120              table->record[1] have the SE row that matched the one
11121              in the hash table.
11122 
11123              Thence if this is a DELETE we wouldn't need to mess
11124              around with positions anymore, but since this can be an
11125              update, we need to provide positions so that AI is
11126              unpacked correctly to table->record[0] in UPDATE
11127              implementation of do_exec_row().
11128           */
11129           m_curr_row= entry->positions->bi_start;
11130           m_curr_row_end= entry->positions->bi_ends;
11131 
11132           /* we don't need this entry anymore, just delete it */
11133           if ((error= m_hash.del(entry)))
11134             goto err;
11135 
11136           if ((error= do_apply_row(rli)))
11137           {
11138             if (handle_idempotent_and_ignored_errors(rli, &error))
11139               goto close_table;
11140 
11141             do_post_row_operations(rli, error);
11142           }
11143         }
11144       }
11145       break;
11146 
11147       case HA_ERR_RECORD_DELETED:
11148         // get next
11149         continue;
11150 
11151       case HA_ERR_KEY_NOT_FOUND:
11152         /* If the slave exec mode is idempotent or the error is
11153             skipped error, then don't break */
11154         if (handle_idempotent_and_ignored_errors(rli, &error))
11155           goto close_table;
11156         idempotent_errors++;
11157         continue;
11158 
11159       case HA_ERR_END_OF_FILE:
11160       default:
11161         // exception (hash is not empty and we have reached EOF or
11162         // other error happened)
11163         goto close_table;
11164     }
11165   }
11166  /**
11167    if the slave_exec_mode is set to Idempotent, we cannot expect the hash to
11168    be empty. In such cases we count the number of idempotent errors and check
11169    if it is equal to or greater than the number of rows left in the hash.
11170   */
11171   while (((idempotent_errors < m_hash.size()) && !m_hash.is_empty()) &&
11172          (!error || (error == HA_ERR_RECORD_DELETED)));
11173 
11174 close_table:
11175   if (error == HA_ERR_RECORD_DELETED)
11176     error= 0;
11177 
11178   if (error)
11179   {
11180     table->file->print_error(error, MYF(0));
11181     DBUG_PRINT("info", ("Failed to get next record"
11182                         " (ha_rnd_next returns %d)",error));
11183     /*
11184       we are already with errors. Keep the error code and
11185       try to close the scan anyway.
11186     */
11187     (void) close_record_scan();
11188   }
11189   else
11190     error= close_record_scan();
11191 
11192   DBUG_ASSERT((m_hash.is_empty() && !error) ||
11193               (!m_hash.is_empty() &&
11194                ((error) || (idempotent_errors >= m_hash.size()))));
11195 
11196 err:
11197 
11198   if ((m_hash.is_empty() && !error) || (idempotent_errors >= m_hash.size()))
11199   {
11200     /**
11201        Reset the last positions, because the positions are lost while
11202        handling entries in the hash.
11203      */
11204     m_curr_row= saved_last_m_curr_row;
11205     m_curr_row_end= saved_last_m_curr_row_end;
11206   }
11207 
11208   DBUG_RETURN(error);
11209 }
11210 
do_hash_scan_and_update(Relay_log_info const * rli)11211 int Rows_log_event::do_hash_scan_and_update(Relay_log_info const *rli)
11212 {
11213   DBUG_ENTER("Rows_log_event::do_hash_scan_and_update");
11214   DBUG_ASSERT(m_table && m_table->in_use != NULL);
11215 
11216   // HASHING PART
11217 
11218   /* unpack the BI (and AI, if it exists) and add it to the hash map. */
11219   if (int error= this->do_hash_row(rli))
11220     DBUG_RETURN(error);
11221 
11222   /* We have not yet hashed all rows in the buffer. Do not proceed to the SCAN part. */
11223   if (m_curr_row_end < m_rows_end)
11224     DBUG_RETURN (0);
11225 
11226   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11227   DBUG_ASSERT(m_curr_row_end == m_rows_end);
11228 
11229   // SCANNING & UPDATE PART
11230 
11231   DBUG_RETURN(this->do_scan_and_update(rli));
11232 }
11233 
do_table_scan_and_update(Relay_log_info const * rli)11234 int Rows_log_event::do_table_scan_and_update(Relay_log_info const *rli)
11235 {
11236   int error= 0;
11237   const uchar* saved_m_curr_row= m_curr_row;
11238   TABLE* table= m_table;
11239 
11240   DBUG_ENTER("Rows_log_event::do_table_scan_and_update");
11241   DBUG_ASSERT(m_curr_row != m_rows_end);
11242   DBUG_PRINT("info",("locating record using table scan (ha_rnd_next)"));
11243 
11244   saved_m_curr_row= m_curr_row;
11245 
11246   /** unpack the before image */
11247   prepare_record(table, &m_cols, FALSE);
11248   if (!(error= unpack_current_row(rli, &m_cols)))
11249   {
11250     // Temporary fix to find out why it fails [/Matz]
11251     memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
11252 
11253     /** save a copy so that we can compare against it later */
11254     store_record(m_table, record[1]);
11255 
11256     int restart_count= 0; // Number of times scanning has restarted from top
11257 
11258     if ((error= m_table->file->ha_rnd_init(1)))
11259     {
11260       DBUG_PRINT("info",("error initializing table scan"
11261                          " (ha_rnd_init returns %d)",error));
11262       goto end;
11263     }
11264 
11265     /* Continue until we find the right record or have made a full loop */
11266     do
11267     {
11268   restart_ha_rnd_next:
11269       error= m_table->file->ha_rnd_next(m_table->record[0]);
11270       if (error)
11271         DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11272       switch (error) {
11273       case HA_ERR_END_OF_FILE:
11274         // restart scan from top
11275         if (++restart_count < 2)
11276         {
11277           if ((error= m_table->file->ha_rnd_init(1)))
11278             goto end;
11279           goto restart_ha_rnd_next;
11280         }
11281         break;
11282 
11283       case HA_ERR_RECORD_DELETED:
11284         // fetch next
11285         goto restart_ha_rnd_next;
11286       case 0:
11287         // we're good, check if record matches
11288         break;
11289 
11290       default:
11291         // exception
11292         goto end;
11293       }
11294     }
11295     while (restart_count < 2 && record_compare(m_table, &m_cols));
11296   }
11297 
11298 end:
11299 
11300   DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
11301 
11302   /* either we report error or apply the changes */
11303   if (error && error != HA_ERR_RECORD_DELETED)
11304   {
11305     DBUG_PRINT("info", ("Failed to get next record"
11306                         " (ha_rnd_next returns %d)",error));
11307     m_table->file->print_error(error, MYF(0));
11308   }
11309   else
11310     error= do_apply_row(rli);
11311 
11312 
11313   if (!error)
11314     error= close_record_scan();
11315   else
11316     /*
11317       we are already with errors. Keep the error code and
11318       try to close the scan anyway.
11319     */
11320     (void) close_record_scan();
11321 
11322   if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11323       (saved_m_curr_row == m_curr_row)) // we need to unpack the AI
11324   {
11325     m_curr_row= m_curr_row_end;
11326     unpack_current_row(rli, &m_cols);
11327   }
11328 
11329   table->default_column_bitmaps();
11330   DBUG_RETURN(error);
11331 }
11332 
do_apply_event(Relay_log_info const * rli)11333 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
11334 {
11335   DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
11336   TABLE *table= NULL;
11337   int error= 0;
11338 
11339   if (opt_bin_log)
11340   {
11341     enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
11342     if (state == GTID_STATEMENT_CANCEL)
11343       // error has already been printed; don't print anything more here
11344       DBUG_RETURN(-1);
11345     else if (state == GTID_STATEMENT_SKIP)
11346       DBUG_RETURN(0);
11347   }
11348 
11349   /*
11350     'thd' has been set by exec_relay_log_event(), just before calling
11351     do_apply_event(). We still check here to prevent future coding
11352     errors.
11353   */
11354   DBUG_ASSERT(rli->info_thd == thd);
11355 
11356   /*
11357     If there is no locks taken, this is the first binrow event seen
11358     after the table map events.  We should then lock all the tables
11359     used in the transaction and proceed with execution of the actual
11360     event.
11361   */
11362   if (!thd->lock)
11363   {
11364     /*
11365       Lock_tables() reads the contents of thd->lex, so they must be
11366       initialized.
11367 
11368       We also call the mysql_reset_thd_for_next_command(), since this
11369       is the logical start of the next "statement". Note that this
11370       call might reset the value of current_stmt_binlog_format, so
11371       we need to do any changes to that value after this function.
11372     */
11373     lex_start(thd);
11374     mysql_reset_thd_for_next_command(thd);
11375     /*
11376       The current statement is just about to begin and
11377       has not yet modified anything. Note, all.modified is reset
11378       by mysql_reset_thd_for_next_command.
11379     */
11380     thd->transaction.stmt.reset_unsafe_rollback_flags();
11381     /*
11382       This is a row injection, so we flag the "statement" as
11383       such. Note that this code is called both when the slave does row
11384       injections and when the BINLOG statement is used to do row
11385       injections.
11386     */
11387     thd->lex->set_stmt_row_injection();
11388 
11389     /*
11390       There are a few flags that are replicated with each row event.
11391       Make sure to set/clear them before executing the main body of
11392       the event.
11393     */
11394     if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
11395         thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
11396     else
11397         thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
11398 
11399     if (get_flags(RELAXED_UNIQUE_CHECKS_F))
11400         thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
11401     else
11402         thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
11403 
11404     thd->binlog_row_event_extra_data = m_extra_row_data;
11405 
11406     /* A small test to verify that objects have consistent types */
11407     DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
11408     DBUG_EXECUTE_IF("rows_log_event_before_open_table",
11409                     {
11410                       const char action[] = "now SIGNAL before_open_table WAIT_FOR go_ahead_sql";
11411                       DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(action)));
11412                     };);
11413     if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
11414     {
11415       if (thd->is_error())
11416       {
11417         uint actual_error= thd->get_stmt_da()->sql_errno();
11418         if (ignored_error_code(actual_error))
11419         {
11420           if (log_warnings > 1)
11421             rli->report(WARNING_LEVEL, actual_error,
11422                         "Error executing row event: '%s'",
11423                         thd->get_stmt_da()->message());
11424           thd->get_stmt_da()->clear_warning_info(thd->query_id);
11425           clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11426           error= 0;
11427           goto end;
11428         }
11429         else
11430         {
11431           rli->report(ERROR_LEVEL, actual_error,
11432                       "Error executing row event: '%s'",
11433                       thd->get_stmt_da()->message());
11434           thd->is_slave_error= 1;
11435         }
11436       }
11437       DBUG_RETURN(1);
11438     }
11439     /*
11440       When the open and locking succeeded, we check all tables to
11441       ensure that they still have the correct type.
11442     */
11443 
11444     {
11445       DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
11446                            rli->tables_to_lock));
11447 
11448       /**
11449         When using RBR and MyISAM MERGE tables the base tables that make
11450         up the MERGE table can be appended to the list of tables to lock.
11451 
11452         Thus, we just check compatibility for those that tables that have
11453         a correspondent table map event (ie, those that are actually going
11454         to be accessed while applying the event). That's why the loop stops
11455         at rli->tables_to_lock_count .
11456 
11457         NOTE: The base tables are added here are removed when
11458               close_thread_tables is called.
11459        */
11460       TABLE_LIST *table_list_ptr= rli->tables_to_lock;
11461       for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count);
11462            table_list_ptr= table_list_ptr->next_global, i++)
11463       {
11464         /*
11465           Below if condition takes care of skipping base tables that
11466           make up the MERGE table (which are added by open_tables()
11467           call). They are added next to the merge table in the list.
11468           For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
11469           are base tables for merge table 't3'), open_tables will modify
11470           the list by adding t1 and t2 again immediately after t3 in the
11471           list (*not at the end of the list*). New table_to_lock list will
11472           look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
11473           objects added by open_tables() call). There is no flag(or logic) in
11474           open_tables() that can skip adding these base tables to the list.
11475           So the logic here should take care of skipping them.
11476 
11477           tables_to_lock_count logic will take care of skipping base tables
11478           that are added at the end of the list.
11479           For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
11480           the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
11481           because tables_to_lock_count logic in this for loop.
11482         */
11483         if (table_list_ptr->parent_l)
11484           continue;
11485         /*
11486           We can use a down cast here since we know that every table added
11487           to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
11488           skipped above).
11489         */
11490         RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
11491         DBUG_ASSERT(ptr->m_tabledef_valid);
11492         TABLE *conv_table;
11493         if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
11494                                              ptr->table, &conv_table))
11495         {
11496           DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
11497                                ptr->table->s->db.str,
11498                                ptr->table->s->table_name.str));
11499           if (thd->is_slave_error)
11500           {
11501             const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
11502             DBUG_RETURN(ERR_BAD_TABLE_DEF);
11503           }
11504           else
11505           {
11506             thd->get_stmt_da()->clear_warning_info(thd->query_id);
11507             clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11508             error= 0;
11509             goto end;
11510           }
11511         }
11512         DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
11513                              " - conv_table: %p",
11514                              ptr->table->s->db.str,
11515                              ptr->table->s->table_name.str, conv_table));
11516         ptr->m_conv_table= conv_table;
11517       }
11518     }
11519 
11520     /*
11521       ... and then we add all the tables to the table map and but keep
11522       them in the tables to lock list.
11523 
11524       We also invalidate the query cache for all the tables, since
11525       they will now be changed.
11526 
11527       TODO [/Matz]: Maybe the query cache should not be invalidated
11528       here? It might be that a table is not changed, even though it
11529       was locked for the statement.  We do know that each
11530       Rows_log_event contain at least one row, so after processing one
11531       Rows_log_event, we can invalidate the query cache for the
11532       associated table.
11533      */
11534     TABLE_LIST *ptr= rli->tables_to_lock;
11535     for (uint i=0 ;  ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
11536     {
11537       /*
11538         Please see comment in above 'for' loop to know the reason
11539         for this if condition
11540       */
11541       if (ptr->parent_l)
11542         continue;
11543       const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
11544     }
11545 
11546 #ifdef HAVE_QUERY_CACHE
11547     query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11548 #endif
11549   }
11550 
11551   table=
11552     m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
11553 
11554   DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %llu", (ulong) m_table,
11555                        m_table_id.id()));
11556 
11557   /*
11558     A row event comprising of a P_S table
11559     - should not be replicated (i.e executed) by the slave SQL thread.
11560     - should not be executed by the client in the  form BINLOG '...' stmts.
11561   */
11562   if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
11563     table= NULL;
11564 
11565   if (table)
11566   {
11567     /*
11568       table == NULL means that this table should not be replicated
11569       (this was set up by Table_map_log_event::do_apply_event()
11570       which tested replicate-* rules).
11571     */
11572 
11573     /*
11574       It's not needed to set_time() but
11575       1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11576       much slave is behind
11577       2) it will be needed when we allow replication from a table with no
11578       TIMESTAMP column to a table with one.
11579       So we call set_time(), like in SBR. Presently it changes nothing.
11580     */
11581     thd->set_time(&when);
11582 
11583     thd->binlog_row_event_extra_data = m_extra_row_data;
11584 
11585     /*
11586       Now we are in a statement and will stay in a statement until we
11587       see a STMT_END_F.
11588 
11589       We set this flag here, before actually applying any rows, in
11590       case the SQL thread is stopped and we need to detect that we're
11591       inside a statement and halting abruptly might cause problems
11592       when restarting.
11593      */
11594     const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
11595 
11596      if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11597       set_flags(COMPLETE_ROWS_F);
11598 
11599     /*
11600       Set tables write and read sets.
11601 
11602       Read_set contains all slave columns (in case we are going to fetch
11603       a complete record from slave)
11604 
11605       Write_set equals the m_cols bitmap sent from master but it can be
11606       longer if slave has extra columns.
11607      */
11608 
11609     DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11610 
11611     bitmap_set_all(table->read_set);
11612     if (get_general_type_code() == DELETE_ROWS_EVENT ||
11613         get_general_type_code() == UPDATE_ROWS_EVENT)
11614         bitmap_intersect(table->read_set,&m_cols);
11615 
11616     bitmap_set_all(table->write_set);
11617 
11618     /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11619     MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
11620                              &m_cols_ai : &m_cols);
11621     bitmap_intersect(table->write_set, after_image);
11622 
11623     this->slave_exec_mode= slave_exec_mode_options; // fix the mode
11624 
11625     // Do event specific preparations
11626     error= do_before_row_operations(rli);
11627 
11628     /*
11629       Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11630       Don't allow generation of auto_increment value when processing
11631       rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
11632       to this rule happens when the auto_inc column exists on some
11633       extra columns on the slave. In that case, do not force
11634       MODE_NO_AUTO_VALUE_ON_ZERO.
11635     */
11636     ulong saved_sql_mode= thd->variables.sql_mode;
11637     if (!is_auto_inc_in_extra_columns())
11638       thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11639 
11640     // row processing loop
11641 
11642     /*
11643       set the initial time of this ROWS statement if it was not done
11644       before in some other ROWS event.
11645      */
11646     const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
11647 
11648     const uchar *saved_m_curr_row= m_curr_row;
11649 
11650     int (Rows_log_event::*do_apply_row_ptr)(Relay_log_info const *)= NULL;
11651 
11652     /**
11653        Skip update rows events that don't have data for this slave's
11654        table.
11655      */
11656     if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11657         !is_any_column_signaled_for_table(table, &m_cols_ai))
11658       goto AFTER_MAIN_EXEC_ROW_LOOP;
11659 
11660     /**
11661        If there are no columns marked in the read_set for this table,
11662        that means that we cannot lookup any row using the available BI
11663        in the binarr log. Thence, we immediatly raise an error:
11664        HA_ERR_END_OF_FILE.
11665      */
11666 
11667     if ((m_rows_lookup_algorithm != ROW_LOOKUP_NOT_NEEDED) &&
11668         !is_any_column_signaled_for_table(table, &m_cols))
11669     {
11670       error= HA_ERR_END_OF_FILE;
11671       goto AFTER_MAIN_EXEC_ROW_LOOP;
11672     }
11673     switch (m_rows_lookup_algorithm)
11674     {
11675       case ROW_LOOKUP_HASH_SCAN:
11676         do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11677         break;
11678 
11679       case ROW_LOOKUP_INDEX_SCAN:
11680         do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11681         break;
11682 
11683       case ROW_LOOKUP_TABLE_SCAN:
11684         do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11685         break;
11686 
11687       case ROW_LOOKUP_NOT_NEEDED:
11688         DBUG_ASSERT(get_general_type_code() == WRITE_ROWS_EVENT ||
11689                     get_general_type_code() == DELETE_ROWS_EVENT ||
11690                     get_general_type_code() == UPDATE_ROWS_EVENT);
11691 
11692         /* No need to scan for rows, just apply it */
11693         do_apply_row_ptr= &Rows_log_event::do_apply_row;
11694         break;
11695 
11696       default:
11697         DBUG_ASSERT(0);
11698         error= 1;
11699         goto AFTER_MAIN_EXEC_ROW_LOOP;
11700         break;
11701     }
11702 
11703     do {
11704 
11705       error= (this->*do_apply_row_ptr)(rli);
11706 
11707       if (!error)
11708         thd->updated_row_count++;
11709 
11710       if (handle_idempotent_and_ignored_errors(rli, &error))
11711         break;
11712 
11713       /* this advances m_curr_row */
11714       do_post_row_operations(rli, error);
11715 
11716     } while (!error && (m_curr_row != m_rows_end));
11717 
11718     if (unlikely(opt_userstat))
11719     {
11720       thd->update_stats(false);
11721 #ifndef EMBEDDED_LIBRARY
11722       update_global_user_stats(thd, true, time(NULL));
11723 #endif
11724     }
11725 
11726 AFTER_MAIN_EXEC_ROW_LOOP:
11727 
11728     if (saved_m_curr_row != m_curr_row && !table->file->has_transactions())
11729     {
11730       /*
11731         Usually, the trans_commit_stmt() propagates unsafe_rollback_flags
11732         from statement to transaction level. However, we cannot rely on
11733         this when row format is in use as several events can be processed
11734         before calling this function. This happens because it is called
11735         only when the latest event generated by a statement is processed.
11736 
11737         There are however upper level functions that execute per event
11738         and check transaction's status. So if the unsafe_rollback_flags
11739         are not propagated here, this can lead to errors.
11740 
11741         For example, a transaction that updates non-transactional tables
11742         may be stopped in the middle thus leading to inconsistencies
11743         after a restart.
11744       */
11745       thd->transaction.stmt.mark_modified_non_trans_table();
11746       thd->transaction.merge_unsafe_rollback_flags();
11747     }
11748 
11749     /*
11750       Restore the sql_mode after the rows event is processed.
11751     */
11752     thd->variables.sql_mode= saved_sql_mode;
11753 
11754     {/*
11755          The following failure injecion works in cooperation with tests
11756          setting @@global.debug= 'd,stop_slave_middle_group'.
11757          The sql thread receives the killed status and will proceed
11758          to shutdown trying to finish incomplete events group.
11759      */
11760       DBUG_EXECUTE_IF("stop_slave_middle_group",
11761                       if (thd->transaction.all.cannot_safely_rollback())
11762                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11763     }
11764 
11765     if ((error= do_after_row_operations(rli, error)) &&
11766         ignored_error_code(convert_handler_error(error, thd, table)))
11767     {
11768 
11769       if (log_warnings > 1)
11770         slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
11771                                 get_type_str(),
11772                                 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11773                                 (ulong) log_pos);
11774       thd->get_stmt_da()->clear_warning_info(thd->query_id);
11775       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11776       error= 0;
11777     }
11778   } // if (table)
11779 
11780   if (error)
11781   {
11782     slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
11783                              get_type_str(),
11784                              const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11785                              (ulong) log_pos);
11786     /*
11787       @todo We should probably not call
11788       reset_current_stmt_binlog_format_row() from here.
11789 
11790       Note: this applies to log_event_old.cc too.
11791       /Sven
11792     */
11793     thd->reset_current_stmt_binlog_format_row();
11794     thd->is_slave_error= 1;
11795     DBUG_RETURN(error);
11796   }
11797 end:
11798   if (get_flags(STMT_END_F))
11799   {
11800    if((error= rows_event_stmt_cleanup(rli, thd)))
11801    {
11802      if (table)
11803        slave_rows_error_report(ERROR_LEVEL,
11804                                thd->is_error() ? 0 : error,
11805                                rli, thd, table,
11806                                get_type_str(),
11807                                const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11808                                (ulong) log_pos);
11809      else
11810      {
11811        rli->report(ERROR_LEVEL,
11812                    thd->is_error() ? thd->get_stmt_da()->sql_errno() : error,
11813                    "Error in cleaning up after an event of type:%s; %s; the group"
11814                    " log file/position: %s %lu", get_type_str(),
11815                    thd->is_error() ? thd->get_stmt_da()->message() : "unexpected error",
11816                    const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11817                    (ulong) log_pos);
11818      }
11819    }
11820    /* We are at end of the statement (STMT_END_F flag), lets clean
11821      the memory which was used from thd's mem_root now.
11822      This needs to be done only if we are here in SQL thread context.
11823      In other flow ( in case of a regular thread which can happen
11824      when the thread is applying BINLOG'...' row event) we should
11825      *not* try to free the memory here. It will be done latter
11826      in dispatch_command() after command execution is completed.
11827     */
11828    if (thd->slave_thread)
11829      free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
11830   }
11831   DBUG_RETURN(error);
11832 }
11833 
11834 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)11835 Rows_log_event::do_shall_skip(Relay_log_info *rli)
11836 {
11837   /*
11838     If the slave skip counter is 1 and this event does not end a
11839     statement, then we should not start executing on the next event.
11840     Otherwise, we defer the decision to the normal skipping logic.
11841   */
11842   if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11843     return Log_event::EVENT_SKIP_IGNORE;
11844   else
11845     return Log_event::do_shall_skip(rli);
11846 }
11847 
11848 /**
11849    The function is called at Rows_log_event statement commit time,
11850    normally from Rows_log_event::do_update_pos() and possibly from
11851    Query_log_event::do_apply_event() of the COMMIT.
11852    The function commits the last statement for engines, binlog and
11853    releases resources have been allocated for the statement.
11854 
11855    @retval  0         Ok.
11856    @retval  non-zero  Error at the commit.
11857  */
11858 
rows_event_stmt_cleanup(Relay_log_info const * rli,THD * thd)11859 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
11860 {
11861   DBUG_EXECUTE_IF("simulate_rows_event_cleanup_failure",
11862                   {
11863                     my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
11864                     return (1);
11865                   });
11866   int error;
11867   {
11868     /*
11869       This is the end of a statement or transaction, so close (and
11870       unlock) the tables we opened when processing the
11871       Table_map_log_event starting the statement.
11872 
11873       OBSERVER.  This will clear *all* mappings, not only those that
11874       are open for the table. There is not good handle for on-close
11875       actions for tables.
11876 
11877       NOTE. Even if we have no table ('table' == 0) we still need to be
11878       here, so that we increase the group relay log position. If we didn't, we
11879       could have a group relay log position which lags behind "forever"
11880       (assume the last master's transaction is ignored by the slave because of
11881       replicate-ignore rules).
11882     */
11883     error= thd->binlog_flush_pending_rows_event(TRUE);
11884 
11885     /*
11886       If this event is not in a transaction, the call below will, if some
11887       transactional storage engines are involved, commit the statement into
11888       them and flush the pending event to binlog.
11889       If this event is in a transaction, the call will do nothing, but a
11890       Xid_log_event will come next which will, if some transactional engines
11891       are involved, commit the transaction and flush the pending event to the
11892       binlog.
11893       If there was a deadlock the transaction should have been rolled back
11894       already. So there should be no need to rollback the transaction.
11895     */
11896     DBUG_ASSERT(! thd->transaction_rollback_request);
11897     error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11898 
11899     /*
11900       Now what if this is not a transactional engine? we still need to
11901       flush the pending event to the binlog; we did it with
11902       thd->binlog_flush_pending_rows_event(). Note that we imitate
11903       what is done for real queries: a call to
11904       ha_autocommit_or_rollback() (sometimes only if involves a
11905       transactional engine), and a call to be sure to have the pending
11906       event flushed.
11907     */
11908 
11909     /*
11910       @todo We should probably not call
11911       reset_current_stmt_binlog_format_row() from here.
11912 
11913       Note: this applies to log_event_old.cc too
11914 
11915       Btw, the previous comment about transactional engines does not
11916       seem related to anything that happens here.
11917       /Sven
11918     */
11919     thd->reset_current_stmt_binlog_format_row();
11920 
11921     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
11922 
11923     /*
11924       Clean sql_command value
11925     */
11926     thd->lex->sql_command= SQLCOM_END;
11927 
11928   }
11929   return error;
11930 }
11931 
11932 /**
11933    The method either increments the relay log position or
11934    commits the current statement and increments the master group
11935    possition if the event is STMT_END_F flagged and
11936    the statement corresponds to the autocommit query (i.e replicated
11937    without wrapping in BEGIN/COMMIT)
11938 
11939    @retval 0         Success
11940    @retval non-zero  Error in the statement commit
11941  */
11942 int
do_update_pos(Relay_log_info * rli)11943 Rows_log_event::do_update_pos(Relay_log_info *rli)
11944 {
11945   DBUG_ENTER("Rows_log_event::do_update_pos");
11946   int error= 0;
11947 
11948   DBUG_PRINT("info", ("flags: %s",
11949                       get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11950 
11951   /* Worker does not execute binlog update position logics */
11952   DBUG_ASSERT(!is_mts_worker(rli->info_thd));
11953 
11954   if (get_flags(STMT_END_F))
11955   {
11956     /*
11957       Indicate that a statement is finished.
11958       Step the group log position if we are not in a transaction,
11959       otherwise increase the event log position.
11960     */
11961     error= rli->stmt_done(log_pos);
11962   }
11963   else
11964   {
11965     rli->inc_event_relay_log_pos();
11966   }
11967 
11968   DBUG_RETURN(error);
11969 }
11970 
11971 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11972 
11973 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)11974 bool Rows_log_event::write_data_header(IO_CACHE *file)
11975 {
11976   uchar buf[ROWS_HEADER_LEN_V2];	// No need to init the buffer
11977   DBUG_ASSERT(m_table_id.is_valid());
11978   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11979                   {
11980                     int4store(buf + 0, (ulong) m_table_id.id());
11981                     int2store(buf + 4, m_flags);
11982                     return (wrapper_my_b_safe_write(file, buf, 6));
11983                   });
11984   int6store(buf + RW_MAPID_OFFSET, m_table_id.id());
11985   int2store(buf + RW_FLAGS_OFFSET, m_flags);
11986   int rc = 0;
11987   if (likely(!log_bin_use_v1_row_events))
11988   {
11989     /*
11990        v2 event, with variable header portion.
11991        Determine length of variable header payload
11992     */
11993     uint16 vhlen= 2;
11994     uint16 vhpayloadlen= 0;
11995     uint16 extra_data_len= 0;
11996     if (m_extra_row_data)
11997     {
11998       extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
11999       vhpayloadlen= RW_V_TAG_LEN + extra_data_len;
12000     }
12001 
12002     /* Var-size header len includes len itself */
12003     int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);
12004     rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);
12005 
12006     /* Write var-sized payload, if any */
12007     if ((vhpayloadlen > 0) &&
12008         (rc == 0))
12009     {
12010       /* Add tag and extra row info */
12011       uchar type_code= RW_V_EXTRAINFO_TAG;
12012       rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);
12013       if (rc==0)
12014         rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
12015     }
12016   }
12017   else
12018   {
12019     rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);
12020   }
12021 
12022   return (rc != 0);
12023 }
12024 
write_data_body(IO_CACHE * file)12025 bool Rows_log_event::write_data_body(IO_CACHE*file)
12026 {
12027   /*
12028      Note that this should be the number of *bits*, not the number of
12029      bytes.
12030   */
12031   uchar sbuf[sizeof(m_width) + 1];
12032   my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
12033   bool res= false;
12034   uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
12035   DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
12036 
12037   DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
12038   res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
12039 
12040   DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
12041   res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
12042                               no_bytes_in_map(&m_cols));
12043   /*
12044     TODO[refactor write]: Remove the "down cast" here (and elsewhere).
12045    */
12046   if (get_general_type_code() == UPDATE_ROWS_EVENT)
12047   {
12048     DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
12049               no_bytes_in_map(&m_cols_ai));
12050     res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
12051                                 no_bytes_in_map(&m_cols_ai));
12052   }
12053   DBUG_DUMP("rows", m_rows_buf, data_size);
12054   res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
12055 
12056   return res;
12057 
12058 }
12059 #endif
12060 
12061 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12062 int Rows_log_event::pack_info(Protocol *protocol)
12063 {
12064   char buf[256];
12065   char const *const flagstr=
12066     get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
12067   size_t bytes= my_snprintf(buf, sizeof(buf),
12068                             "table_id: %llu%s", m_table_id.id(), flagstr);
12069   protocol->store(buf, bytes, &my_charset_bin);
12070   return 0;
12071 }
12072 #endif
12073 
12074 #ifdef MYSQL_CLIENT
print_helper(FILE * file,PRINT_EVENT_INFO * print_event_info,char const * const name)12075 void Rows_log_event::print_helper(FILE *file,
12076                                   PRINT_EVENT_INFO *print_event_info,
12077                                   char const *const name)
12078 {
12079   IO_CACHE *const head= &print_event_info->head_cache;
12080   IO_CACHE *const body= &print_event_info->body_cache;
12081   if (!print_event_info->short_form)
12082   {
12083     bool const last_stmt_event= get_flags(STMT_END_F);
12084     print_header(head, print_event_info, !last_stmt_event);
12085     my_b_printf(head, "\t%s: table id %llu%s\n",
12086                 name, m_table_id.id(),
12087                 last_stmt_event ? " flags: STMT_END_F" : "");
12088     print_base64(body, print_event_info, !last_stmt_event);
12089   }
12090 }
12091 #endif
12092 
12093 /**************************************************************************
12094 	Table_map_log_event member functions and support functions
12095 **************************************************************************/
12096 
12097 /**
12098   @page How replication of field metadata works.
12099 
12100   When a table map is created, the master first calls
12101   Table_map_log_event::save_field_metadata() which calculates how many
12102   values will be in the field metadata. Only those fields that require the
12103   extra data are added. The method also loops through all of the fields in
12104   the table calling the method Field::save_field_metadata() which returns the
12105   values for the field that will be saved in the metadata and replicated to
12106   the slave. Once all fields have been processed, the table map is written to
12107   the binlog adding the size of the field metadata and the field metadata to
12108   the end of the body of the table map.
12109 
12110   When a table map is read on the slave, the field metadata is read from the
12111   table map and passed to the table_def class constructor which saves the
12112   field metadata from the table map into an array based on the type of the
12113   field. Field metadata values not present (those fields that do not use extra
12114   data) in the table map are initialized as zero (0). The array size is the
12115   same as the columns for the table on the slave.
12116 
12117   Additionally, values saved for field metadata on the master are saved as a
12118   string of bytes (uchar) in the binlog. A field may require 1 or more bytes
12119   to store the information. In cases where values require multiple bytes
12120   (e.g. values > 255), the endian-safe methods are used to properly encode
12121   the values on the master and decode them on the slave. When the field
12122   metadata values are captured on the slave, they are stored in an array of
12123   type uint16. This allows the least number of casts to prevent casting bugs
12124   when the field metadata is used in comparisons of field attributes. When
12125   the field metadata is used for calculating addresses in pointer math, the
12126   type used is uint32.
12127 */
12128 
12129 #if !defined(MYSQL_CLIENT)
12130 /**
12131   Save the field metadata based on the real_type of the field.
12132   The metadata saved depends on the type of the field. Some fields
12133   store a single byte for pack_length() while others store two bytes
12134   for field_length (max length).
12135 
12136   @retval  0  Ok.
12137 
12138   @todo
12139   We may want to consider changing the encoding of the information.
12140   Currently, the code attempts to minimize the number of bytes written to
12141   the tablemap. There are at least two other alternatives; 1) using
12142   net_store_length() to store the data allowing it to choose the number of
12143   bytes that are appropriate thereby making the code much easier to
12144   maintain (only 1 place to change the encoding), or 2) use a fixed number
12145   of bytes for each field. The problem with option 1 is that net_store_length()
12146   will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
12147   for fields like CHAR which can be no larger than 255 characters, the method
12148   will use 3 bytes when the value is > 250. Further, every value that is
12149   encoded using 2 parts (e.g., pack_length, field_length) will be numerically
12150   > 250 therefore will use 3 bytes for eah value. The problem with option 2
12151   is less wasteful for space but does waste 1 byte for every field that does
12152   not encode 2 parts.
12153 */
save_field_metadata()12154 int Table_map_log_event::save_field_metadata()
12155 {
12156   DBUG_ENTER("Table_map_log_event::save_field_metadata");
12157   int index= 0;
12158   for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
12159   {
12160     DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
12161     index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
12162   }
12163   DBUG_RETURN(index);
12164 }
12165 #endif /* !defined(MYSQL_CLIENT) */
12166 
12167 /*
12168   Constructor used to build an event for writing to the binary log.
12169   Mats says tbl->s lives longer than this event so it's ok to copy pointers
12170   (tbl->s->db etc) and not pointer content.
12171  */
12172 #if !defined(MYSQL_CLIENT)
Table_map_log_event(THD * thd,TABLE * tbl,const Table_id & tid,bool using_trans)12173 Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl,
12174                                          const Table_id& tid,
12175                                          bool using_trans)
12176   : Log_event(thd, 0,
12177               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
12178                             Log_event::EVENT_STMT_CACHE,
12179               Log_event::EVENT_NORMAL_LOGGING),
12180     m_table(tbl),
12181     m_dbnam(tbl->s->db.str),
12182     m_dblen(m_dbnam ? tbl->s->db.length : 0),
12183     m_tblnam(tbl->s->table_name.str),
12184     m_tbllen(tbl->s->table_name.length),
12185     m_colcnt(tbl->s->fields),
12186     m_memory(NULL),
12187     m_table_id(tid),
12188     m_flags(TM_BIT_LEN_EXACT_F),
12189     m_data_size(0),
12190     m_field_metadata(0),
12191     m_field_metadata_size(0),
12192     m_null_bits(0),
12193     m_meta_memory(NULL)
12194 {
12195   uchar cbuf[sizeof(m_colcnt) + 1];
12196   uchar *cbuf_end;
12197   DBUG_ASSERT(m_table_id.is_valid());
12198   /*
12199     In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
12200     table.cc / alloc_table_share():
12201       Use the fact the key is db/0/table_name/0
12202     As we rely on this let's assert it.
12203   */
12204   DBUG_ASSERT((tbl->s->db.str == 0) ||
12205               (tbl->s->db.str[tbl->s->db.length] == 0));
12206   DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
12207 
12208 
12209   m_data_size=  TABLE_MAP_HEADER_LEN;
12210   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
12211   m_data_size+= m_dblen + 2;	// Include length and terminating \0
12212   m_data_size+= m_tbllen + 2;	// Include length and terminating \0
12213   cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12214   DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12215   m_data_size+= (cbuf_end - cbuf) + m_colcnt;	// COLCNT and column types
12216 
12217   /* If malloc fails, caught in is_valid() */
12218   if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
12219   {
12220     m_coltype= reinterpret_cast<uchar*>(m_memory);
12221     for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12222       m_coltype[i]= m_table->field[i]->binlog_type();
12223   }
12224 
12225   /*
12226     Calculate a bitmap for the results of maybe_null() for all columns.
12227     The bitmap is used to determine when there is a column from the master
12228     that is not on the slave and is null and thus not in the row data during
12229     replication.
12230   */
12231   uint num_null_bytes= (m_table->s->fields + 7) / 8;
12232   m_data_size+= num_null_bytes;
12233   m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12234                                  &m_null_bits, num_null_bytes,
12235                                  &m_field_metadata, (m_colcnt * 2),
12236                                  NULL);
12237 
12238   memset(m_field_metadata, 0, (m_colcnt * 2));
12239 
12240   /*
12241     Create an array for the field metadata and store it.
12242   */
12243   m_field_metadata_size= save_field_metadata();
12244   DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
12245 
12246   /*
12247     Now set the size of the data to the size of the field metadata array
12248     plus one or three bytes (see pack.c:net_store_length) for number of
12249     elements in the field metadata array.
12250   */
12251   if (m_field_metadata_size < 251)
12252     m_data_size+= m_field_metadata_size + 1;
12253   else
12254     m_data_size+= m_field_metadata_size + 3;
12255 
12256   memset(m_null_bits, 0, num_null_bytes);
12257   for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12258     if (m_table->field[i]->maybe_null())
12259       m_null_bits[(i / 8)]+= 1 << (i % 8);
12260   /*
12261     Marking event to require sequential execution in MTS
12262     if the query might have updated FK-referenced db.
12263     Unlike Query_log_event where this fact is encoded through
12264     the accessed db list in the Table_map case m_flags is exploited.
12265   */
12266   uchar dbs= thd->get_binlog_accessed_db_names() ?
12267     thd->get_binlog_accessed_db_names()->elements : 0;
12268   if (dbs == 1)
12269   {
12270     char *db_name= thd->get_binlog_accessed_db_names()->head();
12271     if (!strcmp(db_name, ""))
12272       m_flags |= TM_REFERRED_FK_DB_F;
12273   }
12274 }
12275 #endif /* !defined(MYSQL_CLIENT) */
12276 
12277 /*
12278   Constructor used by slave to read the event from the binary log.
12279  */
12280 #if defined(HAVE_REPLICATION)
Table_map_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12281 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
12282                                          const Format_description_log_event
12283                                          *description_event)
12284 
12285   : Log_event(buf, description_event),
12286 #ifndef MYSQL_CLIENT
12287     m_table(NULL),
12288 #endif
12289     m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
12290     m_colcnt(0), m_coltype(0),
12291     m_memory(NULL), m_table_id(ULONGLONG_MAX), m_flags(0),
12292     m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
12293     m_null_bits(0), m_meta_memory(NULL)
12294 {
12295   unsigned int bytes_read= 0;
12296   DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
12297 
12298   uint8 common_header_len= description_event->common_header_len;
12299   uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
12300   DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
12301                      event_len, common_header_len, post_header_len));
12302 
12303   /*
12304     Don't print debug messages when running valgrind since they can
12305     trigger false warnings.
12306    */
12307 #ifndef HAVE_purify
12308   DBUG_DUMP("event buffer", (uchar*) buf, event_len);
12309 #endif
12310 
12311   /* Read the post-header */
12312   const char *post_start= buf + common_header_len;
12313 
12314   post_start+= TM_MAPID_OFFSET;
12315   if (post_header_len == 6)
12316   {
12317     /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
12318     m_table_id= uint4korr(post_start);
12319     post_start+= 4;
12320   }
12321   else
12322   {
12323     DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
12324     m_table_id= uint6korr(post_start);
12325     post_start+= TM_FLAGS_OFFSET;
12326   }
12327 
12328   m_flags= uint2korr(post_start);
12329 
12330   /* Read the variable part of the event */
12331   const char *const vpart= buf + common_header_len + post_header_len;
12332 
12333   /* Extract the length of the various parts from the buffer */
12334   uchar const *const ptr_dblen= (uchar const*)vpart + 0;
12335   m_dblen= *(uchar*) ptr_dblen;
12336 
12337   /* Length of database name + counter + terminating null */
12338   uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
12339   m_tbllen= *(uchar*) ptr_tbllen;
12340 
12341   /* Length of table name + counter + terminating null */
12342   uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
12343   uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
12344   m_colcnt= net_field_length(&ptr_after_colcnt);
12345 
12346   DBUG_PRINT("info",("m_dblen: %lu  off: %ld  m_tbllen: %lu  off: %ld  m_colcnt: %lu  off: %ld",
12347                      (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
12348                      (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
12349                      m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
12350 
12351   bytes_read= (unsigned int) (ptr_after_colcnt - (unsigned char *)buf);
12352   /* Avoid reading out of buffer */
12353   if (event_len <= bytes_read || event_len - bytes_read < m_colcnt)
12354   {
12355     m_coltype= NULL;
12356     m_memory= NULL;
12357     DBUG_VOID_RETURN;
12358   }
12359 
12360   /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
12361   m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12362                                      &m_dbnam, (uint) m_dblen + 1,
12363                                      &m_tblnam, (uint) m_tbllen + 1,
12364                                      &m_coltype, (uint) m_colcnt,
12365                                      NullS);
12366 
12367   if (m_memory)
12368   {
12369     /* Copy the different parts into their memory */
12370     strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen  + 1, m_dblen + 1);
12371     strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
12372     memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
12373 
12374     ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
12375     bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
12376     DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
12377     if (bytes_read < event_len)
12378     {
12379       m_field_metadata_size= net_field_length(&ptr_after_colcnt);
12380       if (m_field_metadata_size <= (m_colcnt * 2))
12381       {
12382         uint num_null_bytes= (m_colcnt + 7) / 8;
12383         m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12384                                        &m_null_bits, num_null_bytes,
12385                                        &m_field_metadata, m_field_metadata_size,
12386                                        NULL);
12387         memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
12388         ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
12389         memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
12390       }
12391       else
12392       {
12393         m_coltype= NULL;
12394         my_free(m_memory);
12395         m_memory= NULL;
12396         DBUG_VOID_RETURN;
12397       }
12398     }
12399   }
12400 
12401   DBUG_VOID_RETURN;
12402 }
12403 #endif
12404 
~Table_map_log_event()12405 Table_map_log_event::~Table_map_log_event()
12406 {
12407   if (m_meta_memory != NULL)
12408     my_free(m_meta_memory);
12409   if (m_memory != NULL)
12410     my_free(m_memory);
12411 }
12412 
12413 #ifdef MYSQL_CLIENT
12414 
12415 /*
12416   Rewrite database name for the event to name specified by new_db
12417   SYNOPSIS
12418     new_db   Database name to change to
12419     new_len  Length
12420     desc     Event describing binlog that we're writing to.
12421 
12422   DESCRIPTION
12423     Reset db name. This function assumes that temp_buf member contains event
12424     representation taken from a binary log. It resets m_dbnam and m_dblen and
12425     rewrites temp_buf with new db name.
12426 
12427   RETURN
12428     0     - Success
12429     other - Error
12430 */
12431 
rewrite_db(const char * new_db,size_t new_len,const Format_description_log_event * desc)12432 int Table_map_log_event::rewrite_db(const char* new_db, size_t new_len,
12433                                     const Format_description_log_event* desc)
12434 {
12435   DBUG_ENTER("Table_map_log_event::rewrite_db");
12436   DBUG_ASSERT(temp_buf);
12437 
12438   uint header_len= min((unsigned)desc->common_header_len,
12439                        (unsigned)LOG_EVENT_MINIMAL_HEADER_LEN) + TABLE_MAP_HEADER_LEN;
12440   int len_diff;
12441 
12442   if (!(len_diff= new_len - m_dblen))
12443   {
12444     memcpy((void*) (temp_buf + header_len + 1), new_db, m_dblen + 1);
12445     memcpy((void*) m_dbnam, new_db, m_dblen + 1);
12446     DBUG_RETURN(0);
12447   }
12448 
12449   // Create new temp_buf
12450   ulong event_cur_len= uint4korr(temp_buf + EVENT_LEN_OFFSET);
12451   ulong event_new_len= event_cur_len + len_diff;
12452   char* new_temp_buf= (char*) my_malloc(event_new_len, MYF(MY_WME));
12453 
12454   if (!new_temp_buf)
12455   {
12456     sql_print_error("Table_map_log_event::rewrite_db: "
12457                     "failed to allocate new temp_buf (%d bytes required)",
12458                     event_new_len);
12459     DBUG_RETURN(-1);
12460   }
12461 
12462   // Rewrite temp_buf
12463   char* ptr= new_temp_buf;
12464   ulong cnt= 0;
12465 
12466   // Copy header and change event length
12467   memcpy(ptr, temp_buf, header_len);
12468   int4store(ptr + EVENT_LEN_OFFSET, event_new_len);
12469   ptr += header_len;
12470   cnt += header_len;
12471 
12472   // Write new db name length and new name
12473   *ptr++ = new_len;
12474   memcpy(ptr, new_db, new_len + 1);
12475   ptr += new_len + 1;
12476   cnt += m_dblen + 2;
12477 
12478   // Copy rest part
12479   memcpy(ptr, temp_buf + cnt, event_cur_len - cnt);
12480 
12481   // Reregister temp buf
12482   free_temp_buf();
12483   register_temp_buf(new_temp_buf);
12484 
12485   // Reset m_dbnam and m_dblen members
12486   m_dblen= new_len;
12487 
12488   // m_dbnam resides in m_memory together with m_tblnam and m_coltype
12489   uchar* memory= m_memory;
12490   char const* tblnam= m_tblnam;
12491   uchar* coltype= m_coltype;
12492 
12493   m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12494                                      &m_dbnam, (uint) m_dblen + 1,
12495                                      &m_tblnam, (uint) m_tbllen + 1,
12496                                      &m_coltype, (uint) m_colcnt,
12497                                      NullS);
12498 
12499   if (!m_memory)
12500   {
12501     sql_print_error("Table_map_log_event::rewrite_db: "
12502                     "failed to allocate new m_memory (%d + %d + %d bytes required)",
12503                     m_dblen + 1, m_tbllen + 1, m_colcnt);
12504     DBUG_RETURN(-1);
12505   }
12506 
12507   memcpy((void*)m_dbnam, new_db, m_dblen + 1);
12508   memcpy((void*)m_tblnam, tblnam, m_tbllen + 1);
12509   memcpy(m_coltype, coltype, m_colcnt);
12510 
12511   my_free(memory);
12512   DBUG_RETURN(0);
12513 }
12514 #endif /* MYSQL_CLIENT */
12515 /*
12516   Return value is an error code, one of:
12517 
12518       -1     Failure to open table   [from open_tables()]
12519        0     Success
12520        1     No room for more tables [from set_table()]
12521        2     Out of memory           [from set_table()]
12522        3     Wrong table definition
12523        4     Daisy-chaining RBR with SBR not possible
12524  */
12525 
12526 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12527 
12528 enum enum_tbl_map_status
12529 {
12530   /* no duplicate identifier found */
12531   OK_TO_PROCESS= 0,
12532 
12533   /* this table map must be filtered out */
12534   FILTERED_OUT= 1,
12535 
12536   /* identifier mapping table with different properties */
12537   SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
12538 
12539   /* a duplicate identifier was found mapping the same table */
12540   SAME_ID_MAPPING_SAME_TABLE= 3
12541 };
12542 
12543 /*
12544   Checks if this table map event should be processed or not. First
12545   it checks the filtering rules, and then looks for duplicate identifiers
12546   in the existing list of rli->tables_to_lock.
12547 
12548   It checks that there hasn't been any corruption by verifying that there
12549   are no duplicate entries with different properties.
12550 
12551   In some cases, some binary logs could get corrupted, showing several
12552   tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
12553   early sanity check for such cases and avoid that the server crashes
12554   later.
12555 
12556   In some corner cases, the master logs duplicate table map events, i.e.,
12557   same id, same database name, same table name (see: BUG#37137). This is
12558   different from the above as it's the same table that is mapped again
12559   to the same identifier. Thus we cannot just check for same ids and
12560   assume that the event is corrupted we need to check every property.
12561 
12562   NOTE: in the event that BUG#37137 ever gets fixed, this extra check
12563         will still be valid because we would need to support old binary
12564         logs anyway.
12565 
12566   @param rli The relay log info reference.
12567   @param table_list A list element containing the table to check against.
12568   @return OK_TO_PROCESS
12569             if there was no identifier already in rli->tables_to_lock
12570 
12571           FILTERED_OUT
12572             if the event is filtered according to the filtering rules
12573 
12574           SAME_ID_MAPPING_DIFFERENT_TABLE
12575             if the same identifier already maps a different table in
12576             rli->tables_to_lock
12577 
12578           SAME_ID_MAPPING_SAME_TABLE
12579             if the same identifier already maps the same table in
12580             rli->tables_to_lock.
12581 */
12582 static enum_tbl_map_status
check_table_map(Relay_log_info const * rli,RPL_TABLE_LIST * table_list)12583 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
12584 {
12585   DBUG_ENTER("check_table_map");
12586   enum_tbl_map_status res= OK_TO_PROCESS;
12587 
12588   if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
12589       (!rpl_filter->db_ok(table_list->db) ||
12590        (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
12591     res= FILTERED_OUT;
12592   else
12593   {
12594     RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
12595     for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
12596         ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
12597     {
12598       if (ptr->table_id == table_list->table_id)
12599       {
12600 
12601         if (strcmp(ptr->db, table_list->db) ||
12602             strcmp(ptr->alias, table_list->table_name) ||
12603             ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
12604           res= SAME_ID_MAPPING_DIFFERENT_TABLE;
12605         else
12606           res= SAME_ID_MAPPING_SAME_TABLE;
12607 
12608         break;
12609       }
12610     }
12611   }
12612 
12613   DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
12614 
12615   DBUG_RETURN(res);
12616 }
12617 
do_apply_event(Relay_log_info const * rli)12618 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
12619 {
12620   RPL_TABLE_LIST *table_list;
12621   char *db_mem, *tname_mem, *ptr;
12622   size_t dummy_len;
12623   void *memory;
12624   DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
12625   DBUG_ASSERT(rli->info_thd == thd);
12626 
12627   /* Step the query id to mark what columns that are actually used. */
12628   thd->set_query_id(next_query_id());
12629 
12630   if (!(memory= my_multi_malloc(MYF(MY_WME),
12631                                 &table_list, (uint) sizeof(RPL_TABLE_LIST),
12632                                 &db_mem, (uint) NAME_LEN + 1,
12633                                 &tname_mem, (uint) NAME_LEN + 1,
12634                                 NullS)))
12635     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
12636 
12637   strmov(db_mem, m_dbnam);
12638   strmov(tname_mem, m_tblnam);
12639 
12640   if (lower_case_table_names == 1)
12641   {
12642     my_casedn_str(system_charset_info, db_mem);
12643     my_casedn_str(system_charset_info, tname_mem);
12644   }
12645 
12646   /* rewrite rules changed the database */
12647   if (((ptr= (char*) rpl_filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem))
12648     strmov(db_mem, ptr);
12649 
12650   table_list->init_one_table(db_mem, strlen(db_mem),
12651                              tname_mem, strlen(tname_mem),
12652                              tname_mem, TL_WRITE);
12653 
12654   table_list->table_id=
12655     DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id.id());
12656   table_list->updating= 1;
12657   table_list->required_type= FRMTYPE_TABLE;
12658   DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name,
12659                        table_list->table_id.id()));
12660 
12661   enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
12662   if (tblmap_status == OK_TO_PROCESS)
12663   {
12664     DBUG_ASSERT(thd->lex->query_tables != table_list);
12665 
12666     /*
12667       Use placement new to construct the table_def instance in the
12668       memory allocated for it inside table_list.
12669 
12670       The memory allocated by the table_def structure (i.e., not the
12671       memory allocated *for* the table_def structure) is released
12672       inside Relay_log_info::clear_tables_to_lock() by calling the
12673       table_def destructor explicitly.
12674     */
12675     new (&table_list->m_tabledef)
12676       table_def(m_coltype, m_colcnt,
12677                 m_field_metadata, m_field_metadata_size,
12678                 m_null_bits, m_flags);
12679     table_list->m_tabledef_valid= TRUE;
12680     table_list->m_conv_table= NULL;
12681     table_list->open_type= OT_BASE_ONLY;
12682 
12683     /*
12684       We record in the slave's information that the table should be
12685       locked by linking the table into the list of tables to lock.
12686     */
12687     table_list->next_global= table_list->next_local= rli->tables_to_lock;
12688     const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
12689     const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
12690     /* 'memory' is freed in clear_tables_to_lock */
12691   }
12692   else  // FILTERED_OUT, SAME_ID_MAPPING_*
12693   {
12694     /*
12695       If mapped already but with different properties, we raise an
12696       error.
12697       If mapped already but with same properties we skip the event.
12698       If filtered out we skip the event.
12699 
12700       In all three cases, we need to free the memory previously
12701       allocated.
12702      */
12703     if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
12704     {
12705       /*
12706         Something bad has happened. We need to stop the slave as strange things
12707         could happen if we proceed: slave crash, wrong table being updated, ...
12708         As a consequence we push an error in this case.
12709        */
12710 
12711       char buf[256];
12712 
12713       my_snprintf(buf, sizeof(buf),
12714                   "Found table map event mapping table id %llu which "
12715                   "was already mapped but with different settings.",
12716                   table_list->table_id.id());
12717 
12718       if (thd->slave_thread)
12719         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
12720                     ER(ER_SLAVE_FATAL_ERROR), buf);
12721       else
12722         /*
12723           For the cases in which a 'BINLOG' statement is set to
12724           execute in a user session
12725          */
12726         my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
12727                         MYF(0), buf);
12728     }
12729 
12730     my_free(memory);
12731   }
12732 
12733   DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12734 }
12735 
12736 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)12737 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
12738 {
12739   /*
12740     If the slave skip counter is 1, then we should not start executing
12741     on the next event.
12742   */
12743   return continue_group(rli);
12744 }
12745 
do_update_pos(Relay_log_info * rli)12746 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
12747 {
12748   rli->inc_event_relay_log_pos();
12749   return 0;
12750 }
12751 
12752 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12753 
12754 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)12755 bool Table_map_log_event::write_data_header(IO_CACHE *file)
12756 {
12757   DBUG_ASSERT(m_table_id.is_valid());
12758   uchar buf[TABLE_MAP_HEADER_LEN];
12759   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12760                   {
12761                     int4store(buf + 0, m_table_id.id());
12762                     int2store(buf + 4, m_flags);
12763                     return (wrapper_my_b_safe_write(file, buf, 6));
12764                   });
12765   int6store(buf + TM_MAPID_OFFSET, m_table_id.id());
12766   int2store(buf + TM_FLAGS_OFFSET, m_flags);
12767   return (wrapper_my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
12768 }
12769 
write_data_body(IO_CACHE * file)12770 bool Table_map_log_event::write_data_body(IO_CACHE *file)
12771 {
12772   DBUG_ASSERT(m_dbnam != NULL);
12773   DBUG_ASSERT(m_tblnam != NULL);
12774   /* We use only one byte per length for storage in event: */
12775   DBUG_ASSERT(m_dblen < 128);
12776   DBUG_ASSERT(m_tbllen < 128);
12777 
12778   uchar const dbuf[]= { (uchar) m_dblen };
12779   uchar const tbuf[]= { (uchar) m_tbllen };
12780 
12781   uchar cbuf[sizeof(m_colcnt) + 1];
12782   uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12783   DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12784 
12785   /*
12786     Store the size of the field metadata.
12787   */
12788   uchar mbuf[sizeof(m_field_metadata_size)];
12789   uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12790 
12791   return (wrapper_my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
12792           wrapper_my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
12793           wrapper_my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
12794           wrapper_my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
12795           wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
12796           wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
12797           wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
12798           wrapper_my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
12799           wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
12800  }
12801 #endif
12802 
12803 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12804 
12805 /*
12806   Print some useful information for the SHOW BINARY LOG information
12807   field.
12808  */
12809 
12810 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12811 int Table_map_log_event::pack_info(Protocol *protocol)
12812 {
12813   char buf[256];
12814   size_t bytes= my_snprintf(buf, sizeof(buf),
12815                             "table_id: %llu (%s.%s)",
12816                             m_table_id.id(), m_dbnam, m_tblnam);
12817   protocol->store(buf, bytes, &my_charset_bin);
12818   return 0;
12819 }
12820 #endif
12821 
12822 
12823 #endif
12824 
12825 
12826 #ifdef MYSQL_CLIENT
print(FILE *,PRINT_EVENT_INFO * print_event_info)12827 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
12828 {
12829   if (!print_event_info->short_form)
12830   {
12831     print_header(&print_event_info->head_cache, print_event_info, TRUE);
12832     my_b_printf(&print_event_info->head_cache,
12833                 "\tTable_map: `%s`.`%s` mapped to number %llu\n",
12834                 m_dbnam, m_tblnam, m_table_id.id());
12835     print_base64(&print_event_info->body_cache, print_event_info, TRUE);
12836   }
12837 }
12838 #endif
12839 
12840 /**************************************************************************
12841 	Write_rows_log_event member functions
12842 **************************************************************************/
12843 
12844 /*
12845   Constructor used to build an event for writing to the binary log.
12846  */
12847 #if !defined(MYSQL_CLIENT)
Write_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid_arg,bool is_transactional,const uchar * extra_row_info)12848 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12849                                            const Table_id& tid_arg,
12850                                            bool is_transactional,
12851                                            const uchar* extra_row_info)
12852   : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
12853                    log_bin_use_v1_row_events?
12854                    WRITE_ROWS_EVENT_V1:
12855                    WRITE_ROWS_EVENT,
12856                    extra_row_info)
12857 {
12858 }
12859 #endif
12860 
12861 /*
12862   Constructor used by slave to read the event from the binary log.
12863  */
12864 #ifdef HAVE_REPLICATION
Write_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12865 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12866                                            const Format_description_log_event
12867                                            *description_event)
12868 : Rows_log_event(buf, event_len, description_event)
12869 {
12870 }
12871 #endif
12872 
12873 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12874 int
do_before_row_operations(const Slave_reporting_capability * const)12875 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12876 {
12877   int error= 0;
12878 
12879   m_table->file->rpl_before_write_rows();
12880 
12881   /*
12882     Increment the global status insert count variable
12883   */
12884   if (get_flags(STMT_END_F))
12885     status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
12886 
12887   /*
12888     Let storage engines treat this event as an INSERT command.
12889 
12890     Set 'sql_command' as SQLCOM_INSERT after the tables are locked.
12891     When locking the tables, it should be SQLCOM_END.
12892     THD::decide_binlog_format which is called from "lock tables"
12893     assumes that row_events will have 'sql_command' as SQLCOM_END.
12894   */
12895   thd->lex->sql_command= SQLCOM_INSERT;
12896 
12897   /**
12898      todo: to introduce a property for the event (handler?) which forces
12899      applying the event in the replace (idempotent) fashion.
12900   */
12901   if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12902       (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
12903   {
12904     /*
12905       We are using REPLACE semantics and not INSERT IGNORE semantics
12906       when writing rows, that is: new rows replace old rows.  We need to
12907       inform the storage engine that it should use this behaviour.
12908     */
12909 
12910     /* Tell the storage engine that we are using REPLACE semantics. */
12911     thd->lex->duplicates= DUP_REPLACE;
12912 
12913     /*
12914       Pretend we're executing a REPLACE command: this is needed for
12915       InnoDB and NDB Cluster since they are not (properly) checking the
12916       lex->duplicates flag.
12917     */
12918     thd->lex->sql_command= SQLCOM_REPLACE;
12919     /*
12920        Do not raise the error flag in case of hitting to an unique attribute
12921     */
12922     m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12923     /*
12924        NDB specific: update from ndb master wrapped as Write_rows
12925        so that the event should be applied to replace slave's row
12926     */
12927     m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12928     /*
12929        NDB specific: if update from ndb master wrapped as Write_rows
12930        does not find the row it's assumed idempotent binlog applying
12931        is taking place; don't raise the error.
12932     */
12933     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12934     /*
12935       TODO: the cluster team (Tomas?) says that it's better if the engine knows
12936       how many rows are going to be inserted, then it can allocate needed memory
12937       from the start.
12938     */
12939   }
12940 
12941 
12942   /* Honor next number column if present */
12943   m_table->next_number_field= m_table->found_next_number_field;
12944   /*
12945    * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12946    * sequence numbers for auto_increment fields if the values of them are 0.
12947    * If generateing a sequence number is decided by the values of
12948    * table->auto_increment_field_not_null and SQL_MODE(if includes
12949    * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12950    * SQL_MODE of slave sql thread is always consistency with master's.
12951    * In RBR, auto_increment fields never are NULL, except if the auto_inc
12952    * column exists only on the slave side (i.e., in an extra column
12953    * on the slave's table).
12954    */
12955   if (!is_auto_inc_in_extra_columns())
12956     m_table->auto_increment_field_not_null= TRUE;
12957   else
12958   {
12959     /*
12960       Here we have checked that there is an extra field
12961       on this server's table that has an auto_inc column.
12962 
12963       Mark that the auto_increment field is null and mark
12964       the read and write set bits.
12965 
12966       (There can only be one AUTO_INC column, it is always
12967        indexed and it cannot have a DEFAULT value).
12968     */
12969     m_table->auto_increment_field_not_null= FALSE;
12970     m_table->mark_auto_increment_column();
12971   }
12972 
12973   /**
12974      Sets it to ROW_LOOKUP_NOT_NEEDED.
12975    */
12976   decide_row_lookup_algorithm_and_key();
12977   DBUG_ASSERT(m_rows_lookup_algorithm==ROW_LOOKUP_NOT_NEEDED);
12978 
12979   return error;
12980 }
12981 
12982 int
do_after_row_operations(const Slave_reporting_capability * const,int error)12983 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12984                                               int error)
12985 {
12986   int local_error= 0;
12987 
12988   /**
12989     Clear the write_set bit for auto_inc field that only
12990     existed on the destination table as an extra column.
12991    */
12992   if (is_auto_inc_in_extra_columns())
12993   {
12994     bitmap_clear_bit(m_table->write_set, m_table->next_number_field->field_index);
12995     bitmap_clear_bit( m_table->read_set, m_table->next_number_field->field_index);
12996 
12997     if (get_flags(STMT_END_F))
12998       m_table->file->ha_release_auto_increment();
12999   }
13000   m_table->next_number_field=0;
13001   m_table->auto_increment_field_not_null= FALSE;
13002   if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
13003       m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
13004   {
13005     m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
13006     m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
13007     /*
13008       resetting the extra with
13009       table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
13010       fires bug#27077
13011       explanation: file->reset() performs this duty
13012       ultimately. Still todo: fix
13013     */
13014   }
13015   if ((local_error= m_table->file->ha_end_bulk_insert()))
13016   {
13017     m_table->file->print_error(local_error, MYF(0));
13018   }
13019 
13020   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
13021   m_table->file->rpl_after_write_rows();
13022 
13023   return error? error : local_error;
13024 }
13025 
13026 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13027 
13028 /*
13029   Check if there are more UNIQUE keys after the given key.
13030 */
13031 static int
last_uniq_key(TABLE * table,uint keyno)13032 last_uniq_key(TABLE *table, uint keyno)
13033 {
13034   while (++keyno < table->s->keys)
13035     if (table->key_info[keyno].flags & HA_NOSAME)
13036       return 0;
13037   return 1;
13038 }
13039 
13040 /**
13041    Check if an error is a duplicate key error.
13042 
13043    This function is used to check if an error code is one of the
13044    duplicate key error, i.e., and error code for which it is sensible
13045    to do a <code>get_dup_key()</code> to retrieve the duplicate key.
13046 
13047    @param errcode The error code to check.
13048 
13049    @return <code>true</code> if the error code is such that
13050    <code>get_dup_key()</code> will return true, <code>false</code>
13051    otherwise.
13052  */
13053 bool
is_duplicate_key_error(int errcode)13054 is_duplicate_key_error(int errcode)
13055 {
13056   switch (errcode)
13057   {
13058   case HA_ERR_FOUND_DUPP_KEY:
13059   case HA_ERR_FOUND_DUPP_UNIQUE:
13060     return true;
13061   }
13062   return false;
13063 }
13064 
13065 /**
13066   Write the current row into event's table.
13067 
13068   The row is located in the row buffer, pointed by @c m_curr_row member.
13069   Number of columns of the row is stored in @c m_width member (it can be
13070   different from the number of columns in the table to which we insert).
13071   Bitmap @c m_cols indicates which columns are present in the row. It is assumed
13072   that event's table is already open and pointed by @c m_table.
13073 
13074   If the same record already exists in the table it can be either overwritten
13075   or an error is reported depending on the value of @c overwrite flag
13076   (error reporting not yet implemented). Note that the matching record can be
13077   different from the row we insert if we use primary keys to identify records in
13078   the table.
13079 
13080   The row to be inserted can contain values only for selected columns. The
13081   missing columns are filled with default values using @c prepare_record()
13082   function. If a matching record is found in the table and @c overwritte is
13083   true, the missing columns are taken from it.
13084 
13085   @param  rli   Relay log info (needed for row unpacking).
13086   @param  overwrite
13087                 Shall we overwrite if the row already exists or signal
13088                 error (currently ignored).
13089 
13090   @returns Error code on failure, 0 on success.
13091 
13092   This method, if successful, sets @c m_curr_row_end pointer to point at the
13093   next row in the rows buffer. This is done when unpacking the row to be
13094   inserted.
13095 
13096   @note If a matching record is found, it is either updated using
13097   @c ha_update_row() or first deleted and then new record written.
13098 */
13099 
13100 int
write_row(const Relay_log_info * const rli,const bool overwrite)13101 Write_rows_log_event::write_row(const Relay_log_info *const rli,
13102                                 const bool overwrite)
13103 {
13104   DBUG_ENTER("write_row");
13105   DBUG_ASSERT(m_table != NULL && thd != NULL);
13106 
13107   TABLE *table= m_table;  // pointer to event's table
13108   int error;
13109   int UNINIT_VAR(keynum);
13110   auto_afree_ptr<char> key(NULL);
13111 
13112   prepare_record(table, &m_cols,
13113                  table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
13114 
13115   /* unpack row into table->record[0] */
13116   if ((error= unpack_current_row(rli, &m_cols)))
13117     DBUG_RETURN(error);
13118 
13119   /*
13120     When m_curr_row == m_curr_row_end, it means a row that contains nothing,
13121     so all the pointers shall be pointing to the same address, or else
13122     we have corrupt data and shall throw the error.
13123   */
13124   DBUG_PRINT("debug",("m_rows_buf= %p, m_rows_cur= %p, m_rows_end= %p",
13125                       m_rows_buf, m_rows_cur, m_rows_end));
13126   DBUG_PRINT("debug",("m_curr_row= %p, m_curr_row_end= %p",
13127                       m_curr_row, m_curr_row_end));
13128   if (m_curr_row == m_curr_row_end &&
13129       !((m_rows_buf == m_rows_cur) && (m_rows_cur == m_rows_end)))
13130   {
13131     my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
13132     DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
13133   }
13134 
13135   if (m_curr_row == m_rows_buf)
13136   {
13137     /* this is the first row to be inserted, we estimate the rows with
13138        the size of the first row and use that value to initialize
13139        storage engine for bulk insertion */
13140     DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
13141     ulong estimated_rows= 0;
13142     if (m_curr_row < m_curr_row_end)
13143       estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
13144     else if (m_curr_row == m_curr_row_end)
13145       estimated_rows= 1;
13146 
13147     m_table->file->ha_start_bulk_insert(estimated_rows);
13148   }
13149 
13150   /*
13151     Explicitly set the auto_inc to null to make sure that
13152     it gets an auto_generated value.
13153   */
13154   if (is_auto_inc_in_extra_columns())
13155     m_table->next_number_field->set_null();
13156 
13157 #ifndef DBUG_OFF
13158   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13159   DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
13160   DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
13161 #endif
13162 
13163   /*
13164     Try to write record. If a corresponding record already exists in the table,
13165     we try to change it using ha_update_row() if possible. Otherwise we delete
13166     it and repeat the whole process again.
13167 
13168     TODO: Add safety measures against infinite looping.
13169    */
13170 
13171   m_table->mark_columns_per_binlog_row_image();
13172 
13173   while ((error= table->file->ha_write_row(table->record[0])))
13174   {
13175     if (error == HA_ERR_LOCK_DEADLOCK ||
13176         error == HA_ERR_LOCK_WAIT_TIMEOUT ||
13177         (keynum= table->file->get_dup_key(error)) < 0 ||
13178         !overwrite)
13179     {
13180       DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
13181       /*
13182         Deadlock, waiting for lock or just an error from the handler
13183         such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
13184         Retrieval of the duplicate key number may fail
13185         - either because the error was not "duplicate key" error
13186         - or because the information which key is not available
13187       */
13188       table->file->print_error(error, MYF(0));
13189       goto error;
13190     }
13191     /*
13192        We need to retrieve the old row into record[1] to be able to
13193        either update or delete the offending record.  We either:
13194 
13195        - use ha_rnd_pos() with a row-id (available as dupp_row) to the
13196          offending row, if that is possible (MyISAM and Blackhole), or else
13197 
13198        - use ha_index_read_idx_map() with the key that is duplicated, to
13199          retrieve the offending row.
13200      */
13201     if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
13202     {
13203       DBUG_PRINT("info",("Locating offending record using ha_rnd_pos()"));
13204 
13205       if (table->file->inited && (error= table->file->ha_index_end()))
13206       {
13207         table->file->print_error(error, MYF(0));
13208         goto error;
13209       }
13210       if ((error= table->file->ha_rnd_init(FALSE)))
13211       {
13212         table->file->print_error(error, MYF(0));
13213         goto error;
13214       }
13215 
13216       error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
13217 
13218       table->file->ha_rnd_end();
13219       if (error)
13220       {
13221         DBUG_PRINT("info",("ha_rnd_pos() returns error %d",error));
13222         if (error == HA_ERR_RECORD_DELETED)
13223           error= HA_ERR_KEY_NOT_FOUND;
13224         table->file->print_error(error, MYF(0));
13225         goto error;
13226       }
13227     }
13228     else
13229     {
13230       DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
13231 
13232       if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
13233       {
13234         DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
13235         error= my_errno;
13236         goto error;
13237       }
13238 
13239       if (key.get() == NULL)
13240       {
13241         key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
13242         if (key.get() == NULL)
13243         {
13244           DBUG_PRINT("info",("Can't allocate key buffer"));
13245           error= ENOMEM;
13246           goto error;
13247         }
13248       }
13249 
13250       key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
13251                0);
13252       error= table->file->ha_index_read_idx_map(table->record[1], keynum,
13253                                                 (const uchar*)key.get(),
13254                                                 HA_WHOLE_KEY,
13255                                                 HA_READ_KEY_EXACT);
13256       if (error)
13257       {
13258         DBUG_PRINT("info",("ha_index_read_idx_map() returns %s", HA_ERR(error)));
13259         if (error == HA_ERR_RECORD_DELETED)
13260           error= HA_ERR_KEY_NOT_FOUND;
13261         table->file->print_error(error, MYF(0));
13262         goto error;
13263       }
13264     }
13265 
13266     /*
13267        Now, record[1] should contain the offending row.  That
13268        will enable us to update it or, alternatively, delete it (so
13269        that we can insert the new row afterwards).
13270      */
13271 
13272     /*
13273       If row is incomplete we will use the record found to fill
13274       missing columns.
13275     */
13276     if (!get_flags(COMPLETE_ROWS_F))
13277     {
13278       restore_record(table,record[1]);
13279       error= unpack_current_row(rli, &m_cols);
13280     }
13281 
13282 #ifndef DBUG_OFF
13283     DBUG_PRINT("debug",("preparing for update: before and after image"));
13284     DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
13285     DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
13286 #endif
13287 
13288     /*
13289        REPLACE is defined as either INSERT or DELETE + INSERT.  If
13290        possible, we can replace it with an UPDATE, but that will not
13291        work on InnoDB if FOREIGN KEY checks are necessary.
13292 
13293        I (Matz) am not sure of the reason for the last_uniq_key()
13294        check as, but I'm guessing that it's something along the
13295        following lines.
13296 
13297        Suppose that we got the duplicate key to be a key that is not
13298        the last unique key for the table and we perform an update:
13299        then there might be another key for which the unique check will
13300        fail, so we're better off just deleting the row and inserting
13301        the correct row.
13302      */
13303     if (last_uniq_key(table, keynum) &&
13304         !table->file->referenced_by_foreign_key())
13305     {
13306       DBUG_PRINT("info",("Updating row using ha_update_row()"));
13307       error=table->file->ha_update_row(table->record[1],
13308                                        table->record[0]);
13309       switch (error) {
13310 
13311       case HA_ERR_RECORD_IS_THE_SAME:
13312         DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
13313                            " ha_update_row()"));
13314         error= 0;
13315 
13316       case 0:
13317         break;
13318 
13319       default:
13320         DBUG_PRINT("info",("ha_update_row() returns error %d",error));
13321         table->file->print_error(error, MYF(0));
13322       }
13323 
13324       goto error;
13325     }
13326     else
13327     {
13328       DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
13329       if ((error= table->file->ha_delete_row(table->record[1])))
13330       {
13331         DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
13332         table->file->print_error(error, MYF(0));
13333         goto error;
13334       }
13335       /* Will retry ha_write_row() with the offending row removed. */
13336     }
13337   }
13338 
13339 error:
13340   m_table->default_column_bitmaps();
13341   DBUG_RETURN(error);
13342 }
13343 
13344 #endif
13345 
13346 int
do_exec_row(const Relay_log_info * const rli)13347 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13348 {
13349   DBUG_ASSERT(m_table != NULL);
13350   int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
13351 
13352   if (error && !thd->is_error())
13353   {
13354     DBUG_ASSERT(0);
13355     my_error(ER_UNKNOWN_ERROR, MYF(0));
13356   }
13357 
13358   return error;
13359 }
13360 
13361 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13362 
13363 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13364 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
13365 {
13366   DBUG_EXECUTE_IF("simulate_cache_read_error",
13367                   {DBUG_SET("+d,simulate_my_b_fill_error");});
13368   Rows_log_event::print_helper(file, print_event_info, "Write_rows");
13369 }
13370 #endif
13371 
13372 /**************************************************************************
13373 	Delete_rows_log_event member functions
13374 **************************************************************************/
13375 
13376 /*
13377   Constructor used to build an event for writing to the binary log.
13378  */
13379 
13380 #ifndef MYSQL_CLIENT
Delete_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13381 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13382                                              const Table_id& tid,
13383                                              bool is_transactional,
13384                                              const uchar* extra_row_info)
13385   : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13386                    log_bin_use_v1_row_events?
13387                    DELETE_ROWS_EVENT_V1:
13388                    DELETE_ROWS_EVENT,
13389                    extra_row_info)
13390 {
13391 }
13392 #endif /* #if !defined(MYSQL_CLIENT) */
13393 
13394 /*
13395   Constructor used by slave to read the event from the binary log.
13396  */
13397 #ifdef HAVE_REPLICATION
Delete_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13398 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
13399                                              const Format_description_log_event
13400                                              *description_event)
13401   : Rows_log_event(buf, event_len, description_event)
13402 {
13403 }
13404 #endif
13405 
13406 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13407 
13408 int
do_before_row_operations(const Slave_reporting_capability * const)13409 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13410 {
13411   int error= 0;
13412   DBUG_ENTER("Delete_rows_log_event::do_before_row_operations");
13413   m_table->file->rpl_before_delete_rows();
13414   /*
13415     Increment the global status delete count variable
13416    */
13417   if (get_flags(STMT_END_F))
13418     status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
13419 
13420   /*
13421     Let storage engines treat this event as a DELETE command.
13422 
13423     Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13424     When locking the tables, it should be SQLCOM_END.
13425     THD::decide_binlog_format which is called from "lock tables"
13426     assumes that row_events will have 'sql_command' as SQLCOM_END.
13427   */
13428   thd->lex->sql_command= SQLCOM_DELETE;
13429 
13430   error= row_operations_scan_and_key_setup();
13431   DBUG_RETURN(error);
13432 
13433 }
13434 
13435 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13436 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13437                                                int error)
13438 {
13439   DBUG_ENTER("Delete_rows_log_event::do_after_row_operations");
13440   error= row_operations_scan_and_key_teardown(error);
13441   m_table->file->rpl_after_delete_rows();
13442   DBUG_RETURN(error);
13443 }
13444 
do_exec_row(const Relay_log_info * const rli)13445 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13446 {
13447   int error;
13448   DBUG_ASSERT(m_table != NULL);
13449   if (m_rows_lookup_algorithm == ROW_LOOKUP_NOT_NEEDED) {
13450     error= unpack_current_row(rli, &m_cols);
13451     if (error)
13452       return error;
13453   }
13454   /* m_table->record[0] contains the BI */
13455   m_table->mark_columns_per_binlog_row_image();
13456   error= m_table->file->ha_delete_row(m_table->record[0]);
13457   m_table->default_column_bitmaps();
13458   return error;
13459 }
13460 
13461 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13462 
13463 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13464 void Delete_rows_log_event::print(FILE *file,
13465                                   PRINT_EVENT_INFO* print_event_info)
13466 {
13467   Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
13468 }
13469 #endif
13470 
13471 
13472 /**************************************************************************
13473 	Update_rows_log_event member functions
13474 **************************************************************************/
13475 
13476 /*
13477   Constructor used to build an event for writing to the binary log.
13478  */
13479 #if !defined(MYSQL_CLIENT)
Update_rows_log_event(THD * thd_arg,TABLE * tbl_arg,const Table_id & tid,bool is_transactional,const uchar * extra_row_info)13480 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13481                                              const Table_id& tid,
13482                                              bool is_transactional,
13483                                              const uchar* extra_row_info)
13484 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13485                  log_bin_use_v1_row_events?
13486                  UPDATE_ROWS_EVENT_V1:
13487                  UPDATE_ROWS_EVENT,
13488                  extra_row_info)
13489 {
13490   init(tbl_arg->write_set);
13491 }
13492 
init(MY_BITMAP const * cols)13493 void Update_rows_log_event::init(MY_BITMAP const *cols)
13494 {
13495   /* if bitmap_init fails, caught in is_valid() */
13496   if (likely(!bitmap_init(&m_cols_ai,
13497                           m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
13498                           m_width,
13499                           false)))
13500   {
13501     /* Cols can be zero if this is a dummy binrows event */
13502     if (likely(cols != NULL))
13503     {
13504       memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
13505       create_last_word_mask(&m_cols_ai);
13506     }
13507   }
13508 }
13509 #endif /* !defined(MYSQL_CLIENT) */
13510 
13511 
~Update_rows_log_event()13512 Update_rows_log_event::~Update_rows_log_event()
13513 {
13514   if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
13515     m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
13516   bitmap_free(&m_cols_ai); // To pair with bitmap_init().
13517 }
13518 
13519 
13520 /*
13521   Constructor used by slave to read the event from the binary log.
13522  */
13523 #ifdef HAVE_REPLICATION
Update_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13524 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
13525                                              const
13526                                              Format_description_log_event
13527                                              *description_event)
13528   : Rows_log_event(buf, event_len, description_event)
13529 {
13530 }
13531 #endif
13532 
13533 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13534 
13535 int
do_before_row_operations(const Slave_reporting_capability * const)13536 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13537 {
13538   int error= 0;
13539   DBUG_ENTER("Update_rows_log_event::do_before_row_operations");
13540   m_table->file->rpl_before_update_rows();
13541   /*
13542     Increment the global status update count variable
13543   */
13544   if (get_flags(STMT_END_F))
13545     status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
13546 
13547   /*
13548     Let storage engines treat this event as an UPDATE command.
13549 
13550     Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13551     When locking the tables, it should be SQLCOM_END.
13552     THD::decide_binlog_format which is called from "lock tables"
13553     assumes that row_events will have 'sql_command' as SQLCOM_END.
13554    */
13555   thd->lex->sql_command= SQLCOM_UPDATE;
13556 
13557   error= row_operations_scan_and_key_setup();
13558   DBUG_RETURN(error);
13559 
13560 }
13561 
13562 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13563 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13564                                                int error)
13565 {
13566   DBUG_ENTER("Update_rows_log_event::do_after_row_operations");
13567   error= row_operations_scan_and_key_teardown(error);
13568   m_table->file->rpl_after_update_rows();
13569   DBUG_RETURN(error);
13570 }
13571 
13572 int
do_exec_row(const Relay_log_info * const rli)13573 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13574 {
13575   DBUG_ASSERT(m_table != NULL);
13576   int error= 0;
13577 
13578   if (m_rows_lookup_algorithm == ROW_LOOKUP_NOT_NEEDED) {
13579     error= unpack_current_row(rli, &m_cols);
13580     if (error)
13581       return error;
13582   }
13583 
13584   /*
13585     This is the situation after locating BI:
13586 
13587     ===|=== before image ====|=== after image ===|===
13588        ^                     ^
13589        m_curr_row            m_curr_row_end
13590 
13591     BI found in the table is stored in record[0]. We copy it to record[1]
13592     and unpack AI to record[0].
13593    */
13594 
13595   store_record(m_table,record[1]);
13596 
13597   m_curr_row= m_curr_row_end;
13598   /* this also updates m_curr_row_end */
13599   if ((error= unpack_current_row(rli, &m_cols_ai)))
13600     return error;
13601 
13602   /*
13603     Now we have the right row to update.  The old row (the one we're
13604     looking for) is in record[1] and the new row is in record[0].
13605   */
13606 #ifndef HAVE_purify
13607   /*
13608     Don't print debug messages when running valgrind since they can
13609     trigger false warnings.
13610    */
13611   DBUG_PRINT("info",("Updating row in table"));
13612   DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
13613   DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
13614 #endif
13615 
13616   // Temporary fix to find out why it fails [/Matz]
13617   memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
13618   memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
13619 
13620   m_table->mark_columns_per_binlog_row_image();
13621   error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
13622   if (error == HA_ERR_RECORD_IS_THE_SAME)
13623     error= 0;
13624   m_table->default_column_bitmaps();
13625 
13626   return error;
13627 }
13628 
13629 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13630 
13631 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13632 void Update_rows_log_event::print(FILE *file,
13633 				  PRINT_EVENT_INFO* print_event_info)
13634 {
13635   Rows_log_event::print_helper(file, print_event_info, "Update_rows");
13636 }
13637 #endif
13638 
13639 
Incident_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13640 Incident_log_event::Incident_log_event(const char *buf, uint event_len,
13641                                        const Format_description_log_event *descr_event)
13642   : Log_event(buf, descr_event)
13643 {
13644   DBUG_ENTER("Incident_log_event::Incident_log_event");
13645   uint8 const common_header_len=
13646     descr_event->common_header_len;
13647   uint8 const post_header_len=
13648     descr_event->post_header_len[INCIDENT_EVENT-1];
13649 
13650   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13651                      event_len, common_header_len, post_header_len));
13652 
13653   m_message.str= NULL;
13654   m_message.length= 0;
13655   int incident_number= uint2korr(buf + common_header_len);
13656   if (incident_number >= INCIDENT_COUNT ||
13657       incident_number <= INCIDENT_NONE)
13658   {
13659     // If the incident is not recognized, this binlog event is
13660     // invalid.  If we set incident_number to INCIDENT_NONE, the
13661     // invalidity will be detected by is_valid().
13662     m_incident= INCIDENT_NONE;
13663     DBUG_VOID_RETURN;
13664   }
13665   m_incident= static_cast<Incident>(incident_number);
13666   char const *ptr= buf + common_header_len + post_header_len;
13667   char const *const str_end= buf + event_len;
13668   uint8 len= 0;                   // Assignment to keep compiler happy
13669   const char *str= NULL;          // Assignment to keep compiler happy
13670   read_str_at_most_255_bytes(&ptr, str_end, &str, &len);
13671   if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
13672   {
13673     /* Mark this event invalid */
13674     m_incident= INCIDENT_NONE;
13675     DBUG_VOID_RETURN;
13676   }
13677   strmake(m_message.str, str, len);
13678   m_message.length= len;
13679   DBUG_PRINT("info", ("m_incident: %d", m_incident));
13680   DBUG_VOID_RETURN;
13681 }
13682 
13683 
~Incident_log_event()13684 Incident_log_event::~Incident_log_event()
13685 {
13686   if (m_message.str)
13687     my_free(m_message.str);
13688 }
13689 
13690 
13691 const char *
description() const13692 Incident_log_event::description() const
13693 {
13694   static const char *const description[]= {
13695     "NOTHING",                                  // Not used
13696     "LOST_EVENTS"
13697   };
13698 
13699   DBUG_PRINT("info", ("m_incident: %d", m_incident));
13700 
13701   return description[m_incident];
13702 }
13703 
13704 
13705 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13706 int Incident_log_event::pack_info(Protocol *protocol)
13707 {
13708   char buf[256];
13709   size_t bytes;
13710   if (m_message.length > 0)
13711     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
13712                        m_incident, description());
13713   else
13714     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
13715                        m_incident, description(), m_message.str);
13716   protocol->store(buf, bytes, &my_charset_bin);
13717   return 0;
13718 }
13719 #endif
13720 
13721 
13722 #ifdef MYSQL_CLIENT
13723 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13724 Incident_log_event::print(FILE *file,
13725                           PRINT_EVENT_INFO *print_event_info)
13726 {
13727   if (print_event_info->short_form)
13728     return;
13729 
13730   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13731   my_b_printf(&print_event_info->head_cache,
13732               "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n",
13733               description());
13734 }
13735 #endif
13736 
13737 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
13738 int
do_apply_event(Relay_log_info const * rli)13739 Incident_log_event::do_apply_event(Relay_log_info const *rli)
13740 {
13741   DBUG_ENTER("Incident_log_event::do_apply_event");
13742 
13743   if (ignored_error_code(ER_SLAVE_INCIDENT))
13744   {
13745     DBUG_PRINT("info", ("Ignoring Incident"));
13746     DBUG_RETURN(0);
13747   }
13748 
13749   rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
13750               ER(ER_SLAVE_INCIDENT),
13751               description(),
13752               m_message.length > 0 ? m_message.str : "<none>");
13753   DBUG_RETURN(1);
13754 }
13755 #endif
13756 
13757 bool
write_data_header(IO_CACHE * file)13758 Incident_log_event::write_data_header(IO_CACHE *file)
13759 {
13760   DBUG_ENTER("Incident_log_event::write_data_header");
13761   DBUG_PRINT("enter", ("m_incident: %d", m_incident));
13762   uchar buf[sizeof(int16)];
13763   int2store(buf, (int16) m_incident);
13764 #ifndef MYSQL_CLIENT
13765   DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
13766 #else
13767    DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
13768 #endif
13769 }
13770 
13771 bool
write_data_body(IO_CACHE * file)13772 Incident_log_event::write_data_body(IO_CACHE *file)
13773 {
13774   uchar tmp[1];
13775   DBUG_ENTER("Incident_log_event::write_data_body");
13776   tmp[0]= (uchar) m_message.length;
13777   crc= my_checksum(crc, (uchar*) tmp, 1);
13778   if (m_message.length > 0)
13779   {
13780     crc= my_checksum(crc, (uchar*) m_message.str, m_message.length);
13781     // todo: report a bug on write_str accepts uint but treats it as uchar
13782   }
13783   DBUG_RETURN(write_str_at_most_255_bytes(file, m_message.str, (uint) m_message.length));
13784 }
13785 
13786 
Ignorable_log_event(const char * buf,const Format_description_log_event * descr_event)13787 Ignorable_log_event::Ignorable_log_event(const char *buf,
13788                                          const Format_description_log_event *descr_event)
13789   : Log_event(buf, descr_event)
13790 {
13791   DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
13792   DBUG_VOID_RETURN;
13793 }
13794 
~Ignorable_log_event()13795 Ignorable_log_event::~Ignorable_log_event()
13796 {
13797 }
13798 
13799 #ifndef MYSQL_CLIENT
13800 /* Pack info for its unrecognized ignorable event */
pack_info(Protocol * protocol)13801 int Ignorable_log_event::pack_info(Protocol *protocol)
13802 {
13803   char buf[256];
13804   size_t bytes;
13805   bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized ignorable event");
13806   protocol->store(buf, bytes, &my_charset_bin);
13807   return 0;
13808 }
13809 #endif
13810 
13811 #ifdef MYSQL_CLIENT
13812 /* Print for its unrecognized ignorable event */
13813 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13814 Ignorable_log_event::print(FILE *file,
13815                            PRINT_EVENT_INFO *print_event_info)
13816 {
13817   if (print_event_info->short_form)
13818     return;
13819 
13820   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13821   my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
13822   my_b_printf(&print_event_info->head_cache,
13823               "# Unrecognized ignorable event\n");
13824 }
13825 #endif
13826 
13827 
Rows_query_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13828 Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
13829                                            const Format_description_log_event *descr_event)
13830   : Ignorable_log_event(buf, descr_event)
13831 {
13832   DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
13833   uint8 const common_header_len=
13834     descr_event->common_header_len;
13835   uint8 const post_header_len=
13836     descr_event->post_header_len[ROWS_QUERY_LOG_EVENT-1];
13837 
13838   m_rows_query= NULL;
13839 
13840   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13841                      event_len, common_header_len, post_header_len));
13842 
13843   /*
13844    m_rows_query length is stored using only one byte, but that length is
13845    ignored and the complete query is read.
13846   */
13847   unsigned int offset= common_header_len + post_header_len + 1;
13848   /* Avoid reading out of buffer */
13849   if (offset > event_len)
13850     DBUG_VOID_RETURN;
13851 
13852   unsigned int len= event_len - offset;
13853   if (!(m_rows_query= (char*) my_malloc(len+1, MYF(MY_WME))))
13854     return;
13855   strmake(m_rows_query, buf + offset, len);
13856   DBUG_PRINT("info", ("m_rows_query: %s", m_rows_query));
13857   DBUG_VOID_RETURN;
13858 }
13859 
~Rows_query_log_event()13860 Rows_query_log_event::~Rows_query_log_event()
13861 {
13862   my_free(m_rows_query);
13863 }
13864 
13865 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13866 int Rows_query_log_event::pack_info(Protocol *protocol)
13867 {
13868   char *buf;
13869   size_t bytes;
13870   ulong len= sizeof("# ") + (ulong) strlen(m_rows_query);
13871   if (!(buf= (char*) my_malloc(len, MYF(MY_WME))))
13872     return 1;
13873   bytes= my_snprintf(buf, len, "# %s", m_rows_query);
13874   protocol->store(buf, bytes, &my_charset_bin);
13875   my_free(buf);
13876   return 0;
13877 }
13878 #endif
13879 
13880 #ifdef MYSQL_CLIENT
13881 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13882 Rows_query_log_event::print(FILE *file,
13883                             PRINT_EVENT_INFO *print_event_info)
13884 {
13885   if (!print_event_info->short_form && print_event_info->verbose > 1)
13886   {
13887     IO_CACHE *const head= &print_event_info->head_cache;
13888     IO_CACHE *const body= &print_event_info->body_cache;
13889     char *token= NULL, *saveptr= NULL;
13890     char *rows_query_copy= NULL;
13891     if (!(rows_query_copy= my_strdup(m_rows_query, MYF(MY_WME))))
13892       return;
13893 
13894     print_header(head, print_event_info, FALSE);
13895     my_b_printf(head, "\tRows_query\n");
13896     /*
13897       Prefix every line of a multi-line query with '#' to prevent the
13898       statement from being executed when binary log will be processed
13899       using 'mysqlbinlog --verbose --verbose'.
13900     */
13901     for (token= strtok_r(rows_query_copy, "\n", &saveptr); token;
13902          token= strtok_r(NULL, "\n", &saveptr))
13903       my_b_printf(head, "# %s\n", token);
13904     my_free(rows_query_copy);
13905     print_base64(body, print_event_info, true);
13906   }
13907 }
13908 #endif
13909 
13910 bool
write_data_body(IO_CACHE * file)13911 Rows_query_log_event::write_data_body(IO_CACHE *file)
13912 {
13913   DBUG_ENTER("Rows_query_log_event::write_data_body");
13914   /*
13915    m_rows_query length will be stored using only one byte, but on read
13916    that length will be ignored and the complete query will be read.
13917   */
13918   DBUG_RETURN(write_str_at_most_255_bytes(file, m_rows_query,
13919               (uint) strlen(m_rows_query)));
13920 }
13921 
13922 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13923 int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
13924 {
13925   DBUG_ENTER("Rows_query_log_event::do_apply_event");
13926   DBUG_ASSERT(rli->info_thd == thd);
13927   /* Set query for writing Rows_query log event into binlog later.*/
13928   thd->set_query(m_rows_query, (uint32) strlen(m_rows_query));
13929   thd->set_query_for_display(m_rows_query, strlen(m_rows_query));
13930 
13931   DBUG_ASSERT(rli->rows_query_ev == NULL);
13932 
13933   const_cast<Relay_log_info*>(rli)->rows_query_ev= this;
13934 
13935   DBUG_RETURN(0);
13936 }
13937 #endif
13938 
13939 
13940 const char *Gtid_log_event::SET_STRING_PREFIX= "SET @@SESSION.GTID_NEXT= '";
13941 
13942 
Gtid_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)13943 Gtid_log_event::Gtid_log_event(const char *buffer, uint event_len,
13944                                const Format_description_log_event *descr_event)
13945   : Log_event(buffer, descr_event)
13946 {
13947   DBUG_ENTER("Gtid_log_event::Gtid_log_event(const char *, uint, const Format_description_log_event *");
13948   uint8 const common_header_len=
13949     descr_event->common_header_len;
13950 
13951 #ifndef DBUG_OFF
13952   uint8 const post_header_len=
13953     buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13954     descr_event->post_header_len[ANONYMOUS_GTID_LOG_EVENT - 1] :
13955     descr_event->post_header_len[GTID_LOG_EVENT - 1];
13956   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13957                      event_len, common_header_len, post_header_len));
13958 #endif
13959 
13960   char const *ptr_buffer= buffer + common_header_len;
13961 
13962   spec.type= buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13963     ANONYMOUS_GROUP : GTID_GROUP;
13964 
13965   commit_flag= *ptr_buffer != 0;
13966   ptr_buffer+= ENCODED_FLAG_LENGTH;
13967 
13968   sid.copy_from((uchar *)ptr_buffer);
13969   ptr_buffer+= ENCODED_SID_LENGTH;
13970 
13971   // SIDNO is only generated if needed, in get_sidno().
13972   spec.gtid.sidno= -1;
13973 
13974   spec.gtid.gno= uint8korr(ptr_buffer);
13975   ptr_buffer+= ENCODED_GNO_LENGTH;
13976 
13977   DBUG_VOID_RETURN;
13978 }
13979 
13980 #ifndef MYSQL_CLIENT
Gtid_log_event(THD * thd_arg,bool using_trans,const Gtid_specification * spec_arg)13981 Gtid_log_event::Gtid_log_event(THD* thd_arg, bool using_trans,
13982                                const Gtid_specification *spec_arg)
13983 : Log_event(thd_arg, thd_arg->variables.gtid_next.type == ANONYMOUS_GROUP ?
13984             LOG_EVENT_IGNORABLE_F : 0,
13985             using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13986             Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING),
13987   commit_flag(true)
13988 {
13989   DBUG_ENTER("Gtid_log_event::Gtid_log_event(THD *)");
13990   spec= spec_arg ? *spec_arg : thd_arg->variables.gtid_next;
13991   if (spec.type == GTID_GROUP)
13992   {
13993     global_sid_lock->rdlock();
13994     sid= global_sid_map->sidno_to_sid(spec.gtid.sidno);
13995     global_sid_lock->unlock();
13996   }
13997   else
13998     sid.clear();
13999 #ifndef DBUG_OFF
14000   char buf[MAX_SET_STRING_LENGTH + 1];
14001   to_string(buf);
14002   DBUG_PRINT("info", ("%s", buf));
14003 #endif
14004   DBUG_VOID_RETURN;
14005 }
14006 #endif
14007 
14008 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14009 int Gtid_log_event::pack_info(Protocol *protocol)
14010 {
14011   char buffer[MAX_SET_STRING_LENGTH + 1];
14012   size_t len= to_string(buffer);
14013   protocol->store(buffer, len, &my_charset_bin);
14014   return 0;
14015 }
14016 #endif
14017 
to_string(char * buf) const14018 size_t Gtid_log_event::to_string(char *buf) const
14019 {
14020   char *p= buf;
14021   DBUG_ASSERT(strlen(SET_STRING_PREFIX) == SET_STRING_PREFIX_LENGTH);
14022   strcpy(p, SET_STRING_PREFIX);
14023   p+= SET_STRING_PREFIX_LENGTH;
14024   p+= spec.to_string(&sid, p);
14025   *p++= '\'';
14026   *p= '\0';
14027   return p - buf;
14028 }
14029 
14030 #ifdef MYSQL_CLIENT
14031 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14032 Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
14033 {
14034   char buffer[MAX_SET_STRING_LENGTH + 1];
14035   IO_CACHE *const head= &print_event_info->head_cache;
14036   if (!print_event_info->short_form)
14037   {
14038     print_header(head, print_event_info, FALSE);
14039     my_b_printf(head, "\tGTID [commit=%s]\n", commit_flag ? "yes" : "no");
14040   }
14041   to_string(buffer);
14042   my_b_printf(head, "%s%s\n", buffer, print_event_info->delimiter);
14043 }
14044 #endif
14045 
14046 #ifdef MYSQL_SERVER
write_data_header(IO_CACHE * file)14047 bool Gtid_log_event::write_data_header(IO_CACHE *file)
14048 {
14049   DBUG_ENTER("Gtid_log_event::write_data_header");
14050   char buffer[POST_HEADER_LENGTH];
14051   char* ptr_buffer= buffer;
14052 
14053   *ptr_buffer= commit_flag ? 1 : 0;
14054   ptr_buffer+= ENCODED_FLAG_LENGTH;
14055 
14056 #ifndef DBUG_OFF
14057   char buf[rpl_sid::TEXT_LENGTH + 1];
14058   sid.to_string(buf);
14059   DBUG_PRINT("info", ("sid=%s sidno=%d gno=%lld",
14060                       buf, spec.gtid.sidno, spec.gtid.gno));
14061 #endif
14062 
14063   sid.copy_to((uchar *)ptr_buffer);
14064   ptr_buffer+= ENCODED_SID_LENGTH;
14065 
14066   int8store(ptr_buffer, spec.gtid.gno);
14067   ptr_buffer+= ENCODED_GNO_LENGTH;
14068 
14069   DBUG_ASSERT(ptr_buffer == (buffer + sizeof(buffer)));
14070   DBUG_RETURN(wrapper_my_b_safe_write(file, (uchar *) buffer, sizeof(buffer)));
14071 }
14072 #endif // MYSQL_SERVER
14073 
14074 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)14075 int Gtid_log_event::do_apply_event(Relay_log_info const *rli)
14076 {
14077   DBUG_ENTER("Gtid_log_event::do_apply_event");
14078   DBUG_ASSERT(rli->info_thd == thd);
14079 
14080   if (get_type_code() == ANONYMOUS_GTID_LOG_EVENT)
14081   {
14082     if (gtid_mode == GTID_MODE_ON)
14083     {
14084       my_error(ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON, MYF(0));
14085       DBUG_RETURN(1);
14086     }
14087     thd->variables.gtid_next.set_anonymous();
14088     /*
14089       We do not need to write the anonymous gtid log event into binary log,
14090       since we should not add new fields to include logical timestamps used
14091       for applying transactions in parallel in the GA version.
14092     */
14093     DBUG_RETURN(0);
14094   }
14095 
14096   /* Applying Gtid_log_event should report an error when GTID_MODE is OFF */
14097   if (gtid_mode == GTID_MODE_OFF)
14098   {
14099     my_error(ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF, MYF(0));
14100     DBUG_RETURN(1);
14101   }
14102 
14103   rpl_sidno sidno= get_sidno(true);
14104   if (sidno < 0)
14105     DBUG_RETURN(1); // out of memory
14106   if (thd->owned_gtid.sidno)
14107   {
14108     /*
14109       Slave will execute this code if a previous Gtid_log_event was applied
14110       but the GTID wasn't consumed yet (the transaction was not committed
14111       nor rolled back).
14112       On a client session we cannot do consecutive SET GTID_NEXT without
14113       a COMMIT or a ROLLBACK in the middle.
14114       Applying this event without rolling back the current transaction may
14115       lead to problems, as a "BEGIN" event following this GTID will
14116       implicitly commit the "partial transaction" and will consume the
14117       GTID. If this "partial transaction" was left in the relay log by the
14118       IO thread restarting in the middle of a transaction, you could have
14119       the partial transaction being logged with the GTID on the slave,
14120       causing data corruption on replication.
14121     */
14122     if (thd->transaction.all.ha_list)
14123     {
14124       /* This is not an error (XA is safe), just an information */
14125       rli->report(INFORMATION_LEVEL, 0,
14126                   "Rolling back unfinished transaction (no COMMIT "
14127                   "or ROLLBACK in relay log). A probable cause is partial "
14128                   "transaction left on relay log because of restarting IO "
14129                   "thread with auto-positioning protocol.");
14130       const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
14131     }
14132     gtid_rollback(thd);
14133   }
14134   thd->variables.gtid_next.set(sidno, spec.gtid.gno);
14135   DBUG_PRINT("info", ("setting gtid_next=%d:%lld",
14136                       sidno, spec.gtid.gno));
14137 
14138   if (gtid_acquire_ownership_single(thd))
14139     DBUG_RETURN(1);
14140 
14141   DBUG_RETURN(0);
14142 }
14143 
do_update_pos(Relay_log_info * rli)14144 int Gtid_log_event::do_update_pos(Relay_log_info *rli)
14145 {
14146   /*
14147     This event does not increment group positions. This means
14148     that if there is a failure after it has been processed,
14149     it will be automatically re-executed.
14150   */
14151   rli->inc_event_relay_log_pos();
14152   DBUG_EXECUTE_IF("crash_after_update_pos_gtid",
14153                   sql_print_information("Crashing crash_after_update_pos_gtid.");
14154                   DBUG_SUICIDE(););
14155   return 0;
14156 }
14157 #endif
14158 
Previous_gtids_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)14159 Previous_gtids_log_event::Previous_gtids_log_event(
14160   const char *buffer, uint event_len,
14161   const Format_description_log_event *descr_event)
14162   : Log_event(buffer, descr_event)
14163 {
14164   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event");
14165   uint8 const common_header_len=
14166     descr_event->common_header_len;
14167   uint8 const post_header_len=
14168     descr_event->post_header_len[PREVIOUS_GTIDS_LOG_EVENT - 1];
14169 
14170   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
14171                      event_len, common_header_len, post_header_len));
14172 
14173   buf= (const uchar *)buffer + common_header_len + post_header_len;
14174   buf_size= (const uchar *)buffer + event_len - buf;
14175   DBUG_PRINT("info", ("data size of the event: %d", buf_size));
14176   DBUG_VOID_RETURN;
14177 }
14178 
14179 #ifndef MYSQL_CLIENT
Previous_gtids_log_event(const Gtid_set * set)14180 Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set)
14181 : Log_event(Log_event::EVENT_NO_CACHE,
14182             Log_event::EVENT_IMMEDIATE_LOGGING)
14183 {
14184   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event(THD *, const Gtid_set *)");
14185   global_sid_lock->assert_some_lock();
14186   buf_size= set->get_encoded_length();
14187   uchar *buffer= (uchar *) my_malloc(buf_size, MYF(MY_WME));
14188   if (buffer != NULL)
14189   {
14190     set->encode(buffer);
14191     register_temp_buf((char *)buffer);
14192   }
14193   this->buf= buffer;
14194   // if buf == NULL, is_valid will return false
14195   DBUG_VOID_RETURN;
14196 }
14197 #endif
14198 
14199 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14200 int Previous_gtids_log_event::pack_info(Protocol *protocol)
14201 {
14202   size_t length= 0;
14203   global_sid_lock->rdlock();
14204   char *str= get_str(&length, &Gtid_set::default_string_format);
14205   global_sid_lock->unlock();
14206   if (str == NULL)
14207     return 1;
14208   protocol->store(str, length, &my_charset_bin);
14209   my_free(str);
14210   return 0;
14211 }
14212 #endif
14213 
14214 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14215 void Previous_gtids_log_event::print(FILE *file,
14216                                      PRINT_EVENT_INFO *print_event_info)
14217 {
14218   IO_CACHE *const head= &print_event_info->head_cache;
14219 
14220   global_sid_lock->rdlock();
14221   char *str= get_str(NULL, &Gtid_set::commented_string_format);
14222   global_sid_lock->unlock();
14223   if (str != NULL)
14224   {
14225     if (!print_event_info->short_form)
14226     {
14227       print_header(head, print_event_info, FALSE);
14228       my_b_printf(head, "\tPrevious-GTIDs\n");
14229     }
14230     my_b_printf(head, "%s\n", str);
14231     my_free(str);
14232   }
14233 }
14234 #endif
14235 
add_to_set(Gtid_set * target) const14236 int Previous_gtids_log_event::add_to_set(Gtid_set *target) const
14237 {
14238   DBUG_ENTER("Previous_gtids_log_event::add_to_set(Gtid_set *)");
14239   size_t end_pos= 0;
14240   size_t add_size= DBUG_EVALUATE_IF("gtid_has_extra_data", 10, 0);
14241   /* Silently ignore additional unknown data at the end of the encoding */
14242   PROPAGATE_REPORTED_ERROR_INT(target->add_gtid_encoding(buf,
14243                                                          buf_size + add_size,
14244                                                          &end_pos));
14245   DBUG_ASSERT(end_pos <= (size_t) buf_size);
14246   DBUG_RETURN(0);
14247 }
14248 
get_str(size_t * length_p,const Gtid_set::String_format * string_format) const14249 char *Previous_gtids_log_event::get_str(
14250   size_t *length_p, const Gtid_set::String_format *string_format) const
14251 {
14252   DBUG_ENTER("Previous_gtids_log_event::get_str(size_t *)");
14253   Sid_map sid_map(NULL);
14254   Gtid_set set(&sid_map, NULL);
14255   DBUG_PRINT("info", ("temp_buf=%p buf=%p", temp_buf, buf));
14256   if (set.add_gtid_encoding(buf, buf_size) != RETURN_STATUS_OK)
14257     DBUG_RETURN(NULL);
14258   set.dbug_print("set");
14259   size_t length= set.get_string_length(string_format);
14260   DBUG_PRINT("info", ("string length= %lu", (ulong) length));
14261   char* str= (char *)my_malloc(length + 1, MYF(MY_WME));
14262   if (str != NULL)
14263   {
14264     set.to_string(str, string_format);
14265     if (length_p != NULL)
14266       *length_p= length;
14267   }
14268   DBUG_RETURN(str);
14269 }
14270 
14271 #ifndef MYSQL_CLIENT
write_data_body(IO_CACHE * file)14272 bool Previous_gtids_log_event::write_data_body(IO_CACHE *file)
14273 {
14274   DBUG_ENTER("Previous_gtids_log_event::write_data_body");
14275   DBUG_PRINT("info", ("size=%d", buf_size));
14276   bool ret= wrapper_my_b_safe_write(file, buf, buf_size);
14277   DBUG_RETURN(ret);
14278 }
14279 #endif
14280 
14281 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_update_pos(Relay_log_info * rli)14282 int Previous_gtids_log_event::do_update_pos(Relay_log_info *rli)
14283 {
14284   rli->inc_event_relay_log_pos();
14285   return 0;
14286 }
14287 #endif
14288 
14289 
14290 #ifdef MYSQL_CLIENT
14291 /**
14292   The default values for these variables should be values that are
14293   *incorrect*, i.e., values that cannot occur in an event.  This way,
14294   they will always be printed for the first event.
14295 */
st_print_event_info()14296 st_print_event_info::st_print_event_info()
14297   :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
14298    auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
14299    lc_time_names_number(~0),
14300    charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
14301    thread_id(0), thread_id_printed(false),server_id_from_fd_event(0),
14302    base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE),
14303    have_unflushed_events(false), skipped_event_in_transaction(false),
14304    is_gtid_next_set(false), is_gtid_next_valid(true)
14305 {
14306   /*
14307     Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
14308     program's startup, but these explicit memset() is for the day someone
14309     creates dynamic instances.
14310   */
14311   memset(db, 0, sizeof(db));
14312   memset(charset, 0, sizeof(charset));
14313   memset(time_zone_str, 0, sizeof(time_zone_str));
14314   delimiter[0]= ';';
14315   delimiter[1]= 0;
14316   myf const flags = MYF(MY_WME | MY_NABP);
14317   open_cached_file(&head_cache, NULL, NULL, 0, flags);
14318   open_cached_file(&body_cache, NULL, NULL, 0, flags);
14319 }
14320 #endif
14321 
14322 
14323 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)14324 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
14325                     const Format_description_log_event* description_event)
14326   :Log_event(buf, description_event)
14327 {
14328   uint8 header_size= description_event->common_header_len;
14329   ident_len = event_len - header_size;
14330   set_if_smaller(ident_len,FN_REFLEN-1);
14331   log_ident= buf + header_size;
14332 }
14333 #endif
14334 
14335 #ifdef MYSQL_SERVER
14336 /*
14337   This is a utility function that adds a quoted identifier into the a buffer.
14338   This also escapes any existance of the quote string inside the identifier.
14339 
14340   SYNOPSIS
14341     my_strmov_quoted_identifier
14342     thd                   thread handler
14343     buffer                target buffer
14344     identifier            the identifier to be quoted
14345     length                length of the identifier
14346 */
my_strmov_quoted_identifier(THD * thd,char * buffer,const char * identifier,uint length)14347 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
14348                                    const char* identifier,
14349                                    uint length)
14350 {
14351   int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
14352   return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
14353 }
14354 #else
my_strmov_quoted_identifier(char * buffer,const char * identifier)14355 size_t my_strmov_quoted_identifier(char *buffer,  const char* identifier)
14356 {
14357   int q= '`';
14358   return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
14359 }
14360 
14361 #endif
14362 
my_strmov_quoted_identifier_helper(int q,char * buffer,const char * identifier,uint length)14363 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
14364                                           const char* identifier,
14365                                           uint length)
14366 {
14367   size_t written= 0;
14368   char quote_char;
14369   uint id_length= (length) ? length : strlen(identifier);
14370 
14371   if (q == EOF)
14372   {
14373     (void) strncpy(buffer, identifier, id_length);
14374     return id_length;
14375   }
14376   quote_char= (char) q;
14377   *buffer++= quote_char;
14378   written++;
14379   while (id_length--)
14380   {
14381     if (*identifier == quote_char)
14382     {
14383       *buffer++= quote_char;
14384       written++;
14385     }
14386     *buffer++= *identifier++;
14387     written++;
14388   }
14389   *buffer++= quote_char;
14390   return ++written;
14391 }
14392 
14393