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 #if WITH_WSREP
57 #include "wsrep_mysqld.h"
58 #endif
59 #define window_size Log_throttle::LOG_THROTTLE_WINDOW_SIZE
60 Error_log_throttle
61 slave_ignored_err_throttle(window_size,
62                            sql_print_warning,
63                            "Error log throttle: %lu time(s) Error_code: 1237"
64                            " \"Slave SQL thread ignored the query because of"
65                            " replicate-*-table rules\" got suppressed.");
66 #endif /* MYSQL_CLIENT */
67 
68 #include <base64.h>
69 #include <my_bitmap.h>
70 #include "rpl_utility.h"
71 
72 #include "sql_digest.h"
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   uint max_allowed_packet= thd ? slave_max_allowed_packet : ~0U;
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     sql_print_error("Error in Log_event::read_log_event(): "
1427                     "'%s', data_len: %lu, event_type: %d",
1428 		    error,data_len,head[EVENT_TYPE_OFFSET]);
1429     my_free(buf);
1430     /*
1431       The SQL slave thread will check if file->error<0 to know
1432       if there was an I/O error. Even if there is no "low-level" I/O errors
1433       with 'file', any of the high-level above errors is worrying
1434       enough to stop the SQL thread now ; as we are skipping the current event,
1435       going on with reading and successfully executing other events can
1436       only corrupt the slave's databases. So stop.
1437       The file->error is also checked to record the position of
1438       the last valid event when master server recovers.
1439     */
1440     file->error= -1;
1441   }
1442   DBUG_RETURN(res);
1443 }
1444 
1445 
1446 /**
1447   Binlog format tolerance is in (buf, event_len, description_event)
1448   constructors.
1449 */
1450 
read_log_event(const char * buf,uint event_len,const char ** error,const Format_description_log_event * description_event,my_bool crc_check)1451 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1452 				     const char **error,
1453                                      const Format_description_log_event *description_event,
1454                                      my_bool crc_check)
1455 {
1456   Log_event* ev;
1457   uint8 alg;
1458   DBUG_ENTER("Log_event::read_log_event(char *, uint, char **, Format_description_log_event *, my_bool)");
1459   DBUG_ASSERT(description_event != 0);
1460   DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1461   DBUG_DUMP("data", (unsigned char*) buf, event_len);
1462 
1463   /* Check the integrity */
1464   if (event_len < EVENT_LEN_OFFSET ||
1465       (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1466   {
1467     DBUG_PRINT("error", ("event_len=%u EVENT_LEN_OFFSET=%d "
1468                          "buf[EVENT_TYPE_OFFSET]=%d ENUM_END_EVENT=%d "
1469                          "uint4korr(buf+EVENT_LEN_OFFSET)=%d",
1470                          event_len, EVENT_LEN_OFFSET,
1471                          buf[EVENT_TYPE_OFFSET], ENUM_END_EVENT,
1472                          uint4korr(buf+EVENT_LEN_OFFSET)));
1473     *error="Sanity check failed";		// Needed to free buffer
1474     DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1475   }
1476 
1477   uint event_type= buf[EVENT_TYPE_OFFSET];
1478   // all following START events in the current file are without checksum
1479   if (event_type == START_EVENT_V3)
1480     (const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
1481   // Sanity check for Format description event
1482   if (event_type == FORMAT_DESCRIPTION_EVENT)
1483   {
1484     if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN +
1485         ST_COMMON_HEADER_LEN_OFFSET)
1486     {
1487       *error= "Found invalid Format description event in binary log";
1488       DBUG_RETURN(0);
1489     }
1490     uint tmp_header_len= buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET];
1491     if (event_len < tmp_header_len + ST_SERVER_VER_OFFSET + ST_SERVER_VER_LEN)
1492     {
1493       *error= "Found invalid Format description event in binary log";
1494       DBUG_RETURN(0);
1495     }
1496   }
1497   /*
1498     CRC verification by SQL and Show-Binlog-Events master side.
1499     The caller has to provide @description_event->checksum_alg to
1500     be the last seen FD's (A) descriptor.
1501     If event is FD the descriptor is in it.
1502     Notice, FD of the binlog can be only in one instance and therefore
1503     Show-Binlog-Events executing master side thread needs just to know
1504     the only FD's (A) value -  whereas RL can contain more.
1505     In the RL case, the alg is kept in FD_e (@description_event) which is reset
1506     to the newer read-out event after its execution with possibly new alg descriptor.
1507     Therefore in a typical sequence of RL:
1508     {FD_s^0, FD_m, E_m^1} E_m^1
1509     will be verified with (A) of FD_m.
1510 
1511     See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
1512     lines (log.h).
1513 
1514     Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
1515   */
1516   alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
1517     description_event->checksum_alg : get_checksum_alg(buf, event_len);
1518   // Emulate the corruption during reading an event
1519   DBUG_EXECUTE_IF("corrupt_read_log_event_char",
1520     if (event_type != FORMAT_DESCRIPTION_EVENT)
1521     {
1522       char *debug_event_buf_c = (char *)buf;
1523       int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
1524       debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1525       DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
1526       DBUG_SET("");
1527     }
1528   );
1529   if (crc_check &&
1530       event_checksum_test((uchar *) buf, event_len, alg) &&
1531       /* Skip the crc check when simulating an unknown ignorable log event. */
1532       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1533   {
1534     *error= "Event crc check failed! Most likely there is event corruption.";
1535 #ifdef MYSQL_CLIENT
1536     if (force_opt)
1537     {
1538       ev= new Unknown_log_event(buf, description_event);
1539       DBUG_RETURN(ev);
1540     }
1541 #endif
1542     DBUG_RETURN(NULL);
1543   }
1544 
1545   if (event_type > description_event->number_of_event_types &&
1546       event_type != FORMAT_DESCRIPTION_EVENT &&
1547       /*
1548         Skip the event type check when simulating an
1549         unknown ignorable log event.
1550       */
1551       !DBUG_EVALUATE_IF("simulate_unknown_ignorable_log_event", 1, 0))
1552   {
1553     /*
1554       It is unsafe to use the description_event if its post_header_len
1555       array does not include the event type.
1556     */
1557     DBUG_PRINT("error", ("event type %d found, but the current "
1558                          "Format_description_log_event supports only %d event "
1559                          "types", event_type,
1560                          description_event->number_of_event_types));
1561     ev= NULL;
1562   }
1563   else
1564   {
1565     /*
1566       In some previuos versions (see comment in
1567       Format_description_log_event::Format_description_log_event(char*,...)),
1568       event types were assigned different id numbers than in the
1569       present version. In order to replicate from such versions to the
1570       present version, we must map those event type id's to our event
1571       type id's.  The mapping is done with the event_type_permutation
1572       array, which was set up when the Format_description_log_event
1573       was read.
1574     */
1575     if (description_event->event_type_permutation)
1576     {
1577       uint new_event_type;
1578       if (event_type >= EVENT_TYPE_PERMUTATION_NUM)
1579         /* Safe guard for read out of bounds of event_type_permutation. */
1580         new_event_type= UNKNOWN_EVENT;
1581       else
1582         new_event_type= description_event->event_type_permutation[event_type];
1583 
1584       DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1585                  event_type, new_event_type,
1586                  get_type_str((Log_event_type)new_event_type)));
1587       event_type= new_event_type;
1588     }
1589 
1590     if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
1591         (event_type == FORMAT_DESCRIPTION_EVENT ||
1592          alg != BINLOG_CHECKSUM_ALG_OFF))
1593       event_len= event_len - BINLOG_CHECKSUM_LEN;
1594 
1595     switch(event_type) {
1596     case QUERY_EVENT:
1597       ev  = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1598       break;
1599     case LOAD_EVENT:
1600       ev = new Load_log_event(buf, event_len, description_event);
1601       break;
1602     case NEW_LOAD_EVENT:
1603       ev = new Load_log_event(buf, event_len, description_event);
1604       break;
1605     case ROTATE_EVENT:
1606       ev = new Rotate_log_event(buf, event_len, description_event);
1607       break;
1608     case CREATE_FILE_EVENT:
1609       ev = new Create_file_log_event(buf, event_len, description_event);
1610       break;
1611     case APPEND_BLOCK_EVENT:
1612       ev = new Append_block_log_event(buf, event_len, description_event);
1613       break;
1614     case DELETE_FILE_EVENT:
1615       ev = new Delete_file_log_event(buf, event_len, description_event);
1616       break;
1617     case EXEC_LOAD_EVENT:
1618       ev = new Execute_load_log_event(buf, event_len, description_event);
1619       break;
1620     case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1621       ev = new Start_log_event_v3(buf, event_len, description_event);
1622       break;
1623     case STOP_EVENT:
1624       ev = new Stop_log_event(buf, description_event);
1625       break;
1626     case INTVAR_EVENT:
1627       ev = new Intvar_log_event(buf, description_event);
1628       break;
1629     case XID_EVENT:
1630       ev = new Xid_log_event(buf, description_event);
1631       break;
1632     case RAND_EVENT:
1633       ev = new Rand_log_event(buf, description_event);
1634       break;
1635     case USER_VAR_EVENT:
1636       ev = new User_var_log_event(buf, event_len, description_event);
1637       break;
1638     case FORMAT_DESCRIPTION_EVENT:
1639       ev = new Format_description_log_event(buf, event_len, description_event);
1640       break;
1641 #if defined(HAVE_REPLICATION)
1642     case PRE_GA_WRITE_ROWS_EVENT:
1643       ev = new Write_rows_log_event_old(buf, event_len, description_event);
1644       break;
1645     case PRE_GA_UPDATE_ROWS_EVENT:
1646       ev = new Update_rows_log_event_old(buf, event_len, description_event);
1647       break;
1648     case PRE_GA_DELETE_ROWS_EVENT:
1649       ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1650       break;
1651     case WRITE_ROWS_EVENT_V1:
1652       ev = new Write_rows_log_event(buf, event_len, description_event);
1653       break;
1654     case UPDATE_ROWS_EVENT_V1:
1655       ev = new Update_rows_log_event(buf, event_len, description_event);
1656       break;
1657     case DELETE_ROWS_EVENT_V1:
1658       ev = new Delete_rows_log_event(buf, event_len, description_event);
1659       break;
1660     case TABLE_MAP_EVENT:
1661       ev = new Table_map_log_event(buf, event_len, description_event);
1662       break;
1663 #endif
1664     case BEGIN_LOAD_QUERY_EVENT:
1665       ev = new Begin_load_query_log_event(buf, event_len, description_event);
1666       break;
1667     case EXECUTE_LOAD_QUERY_EVENT:
1668       ev= new Execute_load_query_log_event(buf, event_len, description_event);
1669       break;
1670     case INCIDENT_EVENT:
1671       ev = new Incident_log_event(buf, event_len, description_event);
1672       break;
1673     case ROWS_QUERY_LOG_EVENT:
1674       ev= new Rows_query_log_event(buf, event_len, description_event);
1675       break;
1676     case GTID_LOG_EVENT:
1677     case ANONYMOUS_GTID_LOG_EVENT:
1678       ev= new Gtid_log_event(buf, event_len, description_event);
1679       break;
1680     case PREVIOUS_GTIDS_LOG_EVENT:
1681       ev= new Previous_gtids_log_event(buf, event_len, description_event);
1682       break;
1683 #if defined(HAVE_REPLICATION)
1684     case WRITE_ROWS_EVENT:
1685       ev = new Write_rows_log_event(buf, event_len, description_event);
1686       break;
1687     case UPDATE_ROWS_EVENT:
1688       ev = new Update_rows_log_event(buf, event_len, description_event);
1689       break;
1690     case DELETE_ROWS_EVENT:
1691       ev = new Delete_rows_log_event(buf, event_len, description_event);
1692       break;
1693 #endif
1694     default:
1695       /*
1696         Create an object of Ignorable_log_event for unrecognized sub-class.
1697         So that SLAVE SQL THREAD will only update the position and continue.
1698       */
1699       if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1700       {
1701         ev= new Ignorable_log_event(buf, description_event);
1702       }
1703       else
1704       {
1705         DBUG_PRINT("error",("Unknown event code: %d",
1706                             (int) buf[EVENT_TYPE_OFFSET]));
1707         ev= NULL;
1708       }
1709       break;
1710     }
1711   }
1712 
1713   if (ev)
1714   {
1715     ev->checksum_alg= alg;
1716     if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1717         ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1718       ev->crc= uint4korr(buf + (event_len));
1719   }
1720 
1721   DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1722                             ev ? ev->get_type_str() : "<unknown>",
1723                             buf[EVENT_TYPE_OFFSET],
1724                             event_len));
1725   /*
1726     is_valid() are small event-specific sanity tests which are
1727     important; for example there are some my_malloc() in constructors
1728     (e.g. Query_log_event::Query_log_event(char*...)); when these
1729     my_malloc() fail we can't return an error out of the constructor
1730     (because constructor is "void") ; so instead we leave the pointer we
1731     wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1732     Same for Format_description_log_event, member 'post_header_len'.
1733 
1734     SLAVE_EVENT is never used, so it should not be read ever.
1735   */
1736   if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
1737   {
1738     DBUG_PRINT("error",("Found invalid event in binary log"));
1739 
1740     delete ev;
1741 #ifdef MYSQL_CLIENT
1742     if (!force_opt) /* then mysqlbinlog dies */
1743     {
1744       *error= "Found invalid event in binary log";
1745       DBUG_RETURN(0);
1746     }
1747     ev= new Unknown_log_event(buf, description_event);
1748 #else
1749     *error= "Found invalid event in binary log";
1750     DBUG_RETURN(0);
1751 #endif
1752   }
1753   DBUG_RETURN(ev);
1754 }
1755 
1756 #ifdef MYSQL_CLIENT
1757 
1758 /*
1759   Log_event::print_header()
1760 */
1761 
print_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool is_more MY_ATTRIBUTE ((unused)))1762 void Log_event::print_header(IO_CACHE* file,
1763                              PRINT_EVENT_INFO* print_event_info,
1764                              bool is_more MY_ATTRIBUTE((unused)))
1765 {
1766   char llbuff[22];
1767   my_off_t hexdump_from= print_event_info->hexdump_from;
1768   DBUG_ENTER("Log_event::print_header");
1769 
1770   my_b_printf(file, "#");
1771   print_timestamp(file, NULL);
1772   my_b_printf(file, " server id %lu  end_log_pos %s ", (ulong) server_id,
1773               llstr(log_pos,llbuff));
1774 
1775   /* print the checksum */
1776 
1777   if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1778       checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1779   {
1780     char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
1781     size_t const bytes_written=
1782       my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
1783     my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
1784     my_b_printf(file, checksum_buf, bytes_written);
1785   }
1786 
1787   /* mysqlbinlog --hexdump */
1788   if (print_event_info->hexdump_from)
1789   {
1790     my_b_printf(file, "\n");
1791     uchar *ptr= (uchar*)temp_buf;
1792     my_off_t size=
1793       uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1794     my_off_t i;
1795 
1796     /* Header len * 4 >= header len * (2 chars + space + extra space) */
1797     char *h, hex_string[49]= {0};
1798     char *c, char_string[16+1]= {0};
1799 
1800     /* Pretty-print event common header if header is exactly 19 bytes */
1801     if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1802     {
1803       char emit_buf[256];               // Enough for storing one line
1804       my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
1805                   "Size      Master Pos    Flags \n");
1806       size_t const bytes_written=
1807         my_snprintf(emit_buf, sizeof(emit_buf),
1808                     "# %8.8lx %02x %02x %02x %02x   %02x   "
1809                     "%02x %02x %02x %02x   %02x %02x %02x %02x   "
1810                     "%02x %02x %02x %02x   %02x %02x\n",
1811                     (unsigned long) hexdump_from,
1812                     ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1813                     ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1814                     ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1815       DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1816       my_b_write(file, (uchar*) emit_buf, bytes_written);
1817       ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1818       hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1819     }
1820 
1821     /* Rest of event (without common header) */
1822     for (i= 0, c= char_string, h=hex_string;
1823 	 i < size;
1824 	 i++, ptr++)
1825     {
1826       my_snprintf(h, 4, (i % 16 <= 7) ? "%02x " : " %02x", *ptr);
1827       h += 3;
1828 
1829       *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1830 
1831       if (i % 16 == 15)
1832       {
1833         /*
1834           my_b_printf() does not support full printf() formats, so we
1835           have to do it this way.
1836 
1837           TODO: Rewrite my_b_printf() to support full printf() syntax.
1838          */
1839         char emit_buf[256];
1840         size_t const bytes_written=
1841           my_snprintf(emit_buf, sizeof(emit_buf),
1842                       "# %8.8lx %-48.48s |%16s|\n",
1843                       (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1844                       hex_string, char_string);
1845         DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1846 	my_b_write(file, (uchar*) emit_buf, bytes_written);
1847 	hex_string[0]= 0;
1848 	char_string[0]= 0;
1849 	c= char_string;
1850 	h= hex_string;
1851       }
1852     }
1853     *c= '\0';
1854     DBUG_ASSERT(hex_string[48] == 0);
1855 
1856     if (hex_string[0])
1857     {
1858       char emit_buf[256];
1859       // Right-pad hex_string with spaces, up to 48 characters.
1860       memset(h, ' ', (sizeof(hex_string) -1) - (h - hex_string));
1861       size_t const bytes_written=
1862         my_snprintf(emit_buf, sizeof(emit_buf),
1863                     "# %8.8lx %-48.48s |%s|\n",
1864                     (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1865                     hex_string, char_string);
1866       DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1867       my_b_write(file, (uchar*) emit_buf, bytes_written);
1868     }
1869     /*
1870       need a # to prefix the rest of printouts for example those of
1871       Rows_log_event::print_helper().
1872     */
1873     my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1874   }
1875   DBUG_VOID_RETURN;
1876 }
1877 
1878 
1879 /**
1880   Prints a quoted string to io cache.
1881   Control characters are displayed as hex sequence, e.g. \x00
1882 
1883   @param[in] file              IO cache
1884   @param[in] prt               Pointer to string
1885   @param[in] length            String length
1886 */
1887 
1888 static void
my_b_write_quoted(IO_CACHE * file,const uchar * ptr,uint length)1889 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
1890 {
1891   const uchar *s;
1892   my_b_printf(file, "'");
1893   for (s= ptr; length > 0 ; s++, length--)
1894   {
1895     if (*s > 0x1F && *s != '\'' && *s != '\\')
1896       my_b_write(file, s, 1);
1897     else
1898     {
1899       uchar hex[10];
1900       size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
1901       my_b_write(file, hex, len);
1902     }
1903   }
1904   my_b_printf(file, "'");
1905 }
1906 
1907 /**
1908   Prints a bit string to io cache in format  b'1010'.
1909 
1910   @param[in] file              IO cache
1911   @param[in] ptr               Pointer to string
1912   @param[in] nbits             Number of bits
1913 */
1914 static void
my_b_write_bit(IO_CACHE * file,const uchar * ptr,uint nbits)1915 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
1916 {
1917   uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
1918   my_b_printf(file, "b'");
1919   for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
1920   {
1921     int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8))  & 0x01;
1922     my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
1923   }
1924   my_b_printf(file, "'");
1925 }
1926 
1927 
1928 /**
1929   Prints a packed string to io cache.
1930   The string consists of length packed to 1 or 2 bytes,
1931   followed by string data itself.
1932 
1933   @param[in] file              IO cache
1934   @param[in] ptr               Pointer to string
1935   @param[in] length            String size
1936 
1937   @retval   - number of bytes scanned.
1938 */
1939 static size_t
my_b_write_quoted_with_length(IO_CACHE * file,const uchar * ptr,uint length)1940 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
1941 {
1942   if (length < 256)
1943   {
1944     length= *ptr;
1945     my_b_write_quoted(file, ptr + 1, length);
1946     return length + 1;
1947   }
1948   else
1949   {
1950     length= uint2korr(ptr);
1951     my_b_write_quoted(file, ptr + 2, length);
1952     return length + 2;
1953   }
1954 }
1955 
1956 
1957 /**
1958   Prints a 32-bit number in both signed and unsigned representation
1959 
1960   @param[in] file              IO cache
1961   @param[in] sl                Signed number
1962   @param[in] ul                Unsigned number
1963 */
1964 static void
my_b_write_sint32_and_uint32(IO_CACHE * file,int32 si,uint32 ui)1965 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
1966 {
1967   my_b_printf(file, "%d", si);
1968   if (si < 0)
1969     my_b_printf(file, " (%u)", ui);
1970 }
1971 
1972 
1973 /**
1974   Print a packed value of the given SQL type into IO cache
1975 
1976   @param[in] file              IO cache
1977   @param[in] ptr               Pointer to string
1978   @param[in] type              Column type
1979   @param[in] meta              Column meta information
1980   @param[out] typestr          SQL type string buffer (for verbose output)
1981   @param[out] typestr_length   Size of typestr
1982 
1983   @retval   - number of bytes scanned from ptr.
1984 */
1985 static size_t
log_event_print_value(IO_CACHE * file,const uchar * ptr,uint type,uint meta,char * typestr,size_t typestr_length)1986 log_event_print_value(IO_CACHE *file, const uchar *ptr,
1987                       uint type, uint meta,
1988                       char *typestr, size_t typestr_length)
1989 {
1990   uint32 length= 0;
1991 
1992   if (type == MYSQL_TYPE_STRING)
1993   {
1994     if (meta >= 256)
1995     {
1996       uint byte0= meta >> 8;
1997       uint byte1= meta & 0xFF;
1998 
1999       if ((byte0 & 0x30) != 0x30)
2000       {
2001         /* a long CHAR() field: see #37426 */
2002         length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
2003         type= byte0 | 0x30;
2004       }
2005       else
2006         length = meta & 0xFF;
2007     }
2008     else
2009       length= meta;
2010   }
2011 
2012   switch (type) {
2013   case MYSQL_TYPE_LONG:
2014     {
2015       int32 si= sint4korr(ptr);
2016       uint32 ui= uint4korr(ptr);
2017       my_b_write_sint32_and_uint32(file, si, ui);
2018       my_snprintf(typestr, typestr_length, "INT");
2019       return 4;
2020     }
2021 
2022   case MYSQL_TYPE_TINY:
2023     {
2024       my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
2025                                   (uint) (unsigned char) *ptr);
2026       my_snprintf(typestr, typestr_length, "TINYINT");
2027       return 1;
2028     }
2029 
2030   case MYSQL_TYPE_SHORT:
2031     {
2032       int32 si= (int32) sint2korr(ptr);
2033       uint32 ui= (uint32) uint2korr(ptr);
2034       my_b_write_sint32_and_uint32(file, si, ui);
2035       my_snprintf(typestr, typestr_length, "SHORTINT");
2036       return 2;
2037     }
2038 
2039   case MYSQL_TYPE_INT24:
2040     {
2041       int32 si= sint3korr(ptr);
2042       uint32 ui= uint3korr(ptr);
2043       my_b_write_sint32_and_uint32(file, si, ui);
2044       my_snprintf(typestr, typestr_length, "MEDIUMINT");
2045       return 3;
2046     }
2047 
2048   case MYSQL_TYPE_LONGLONG:
2049     {
2050       char tmp[64];
2051       longlong si= sint8korr(ptr);
2052       longlong10_to_str(si, tmp, -10);
2053       my_b_printf(file, "%s", tmp);
2054       if (si < 0)
2055       {
2056         ulonglong ui= uint8korr(ptr);
2057         longlong10_to_str((longlong) ui, tmp, 10);
2058         my_b_printf(file, " (%s)", tmp);
2059       }
2060       my_snprintf(typestr, typestr_length, "LONGINT");
2061       return 8;
2062     }
2063 
2064   case MYSQL_TYPE_NEWDECIMAL:
2065     {
2066       uint precision= meta >> 8;
2067       uint decimals= meta & 0xFF;
2068       uint bin_size= my_decimal_get_binary_size(precision, decimals);
2069       my_decimal dec;
2070       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2071                         precision, decimals);
2072       int len= DECIMAL_MAX_STR_LENGTH;
2073       char buff[DECIMAL_MAX_STR_LENGTH + 1];
2074       decimal2string(&dec,buff,&len, 0, 0, 0);
2075       my_b_printf(file, "%s", buff);
2076       my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2077                   precision, decimals);
2078       return bin_size;
2079     }
2080 
2081   case MYSQL_TYPE_FLOAT:
2082     {
2083       float fl;
2084       float4get(fl, ptr);
2085       char tmp[320];
2086       sprintf(tmp, "%-20g", (double) fl);
2087       my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2088       my_snprintf(typestr, typestr_length, "FLOAT");
2089       return 4;
2090     }
2091 
2092   case MYSQL_TYPE_DOUBLE:
2093     {
2094       double dbl;
2095       float8get(dbl, ptr);
2096       char tmp[320];
2097       sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
2098       my_b_printf(file, "%s", tmp);
2099       strcpy(typestr, "DOUBLE");
2100       return 8;
2101     }
2102 
2103   case MYSQL_TYPE_BIT:
2104     {
2105       /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2106       uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2107       length= (nbits + 7) / 8;
2108       my_b_write_bit(file, ptr, nbits);
2109       my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2110       return length;
2111     }
2112 
2113   case MYSQL_TYPE_TIMESTAMP:
2114     {
2115       uint32 i32= uint4korr(ptr);
2116       my_b_printf(file, "%d", i32);
2117       my_snprintf(typestr, typestr_length, "TIMESTAMP");
2118       return 4;
2119     }
2120 
2121   case MYSQL_TYPE_TIMESTAMP2:
2122     {
2123       char buf[MAX_DATE_STRING_REP_LENGTH];
2124       struct timeval tm;
2125       my_timestamp_from_binary(&tm, ptr, meta);
2126       int buflen= my_timeval_to_str(&tm, buf, meta);
2127       my_b_write(file, buf, buflen);
2128       my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2129       return my_timestamp_binary_length(meta);
2130     }
2131 
2132   case MYSQL_TYPE_DATETIME:
2133     {
2134       size_t d, t;
2135       uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2136       d= i64 / 1000000;
2137       t= i64 % 1000000;
2138       my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
2139                   static_cast<int>(d / 10000),
2140                   static_cast<int>(d % 10000) / 100,
2141                   static_cast<int>(d % 100),
2142                   static_cast<int>(t / 10000),
2143                   static_cast<int>(t % 10000) / 100,
2144                   static_cast<int>(t % 100));
2145       my_snprintf(typestr, typestr_length, "DATETIME");
2146       return 8;
2147     }
2148 
2149   case MYSQL_TYPE_DATETIME2:
2150     {
2151       char buf[MAX_DATE_STRING_REP_LENGTH];
2152       MYSQL_TIME ltime;
2153       longlong packed= my_datetime_packed_from_binary(ptr, meta);
2154       TIME_from_longlong_datetime_packed(&ltime, packed);
2155       int buflen= my_datetime_to_str(&ltime, buf, meta);
2156       my_b_write_quoted(file, (uchar *) buf, buflen);
2157       my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2158       return my_datetime_binary_length(meta);
2159     }
2160 
2161   case MYSQL_TYPE_TIME:
2162     {
2163       uint32 i32= uint3korr(ptr);
2164       my_b_printf(file, "'%02d:%02d:%02d'",
2165                   i32 / 10000, (i32 % 10000) / 100, i32 % 100);
2166       my_snprintf(typestr, typestr_length, "TIME");
2167       return 3;
2168     }
2169 
2170   case MYSQL_TYPE_TIME2:
2171     {
2172       char buf[MAX_DATE_STRING_REP_LENGTH];
2173       MYSQL_TIME ltime;
2174       longlong packed= my_time_packed_from_binary(ptr, meta);
2175       TIME_from_longlong_time_packed(&ltime, packed);
2176       int buflen= my_time_to_str(&ltime, buf, meta);
2177       my_b_write_quoted(file, (uchar *) buf, buflen);
2178       my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2179       return my_time_binary_length(meta);
2180     }
2181 
2182   case MYSQL_TYPE_NEWDATE:
2183     {
2184       uint32 tmp= uint3korr(ptr);
2185       int part;
2186       char buf[11];
2187       char *pos= &buf[10];  // start from '\0' to the beginning
2188 
2189       /* Copied from field.cc */
2190       *pos--=0;					// End NULL
2191       part=(int) (tmp & 31);
2192       *pos--= (char) ('0'+part%10);
2193       *pos--= (char) ('0'+part/10);
2194       *pos--= ':';
2195       part=(int) (tmp >> 5 & 15);
2196       *pos--= (char) ('0'+part%10);
2197       *pos--= (char) ('0'+part/10);
2198       *pos--= ':';
2199       part=(int) (tmp >> 9);
2200       *pos--= (char) ('0'+part%10); part/=10;
2201       *pos--= (char) ('0'+part%10); part/=10;
2202       *pos--= (char) ('0'+part%10); part/=10;
2203       *pos=   (char) ('0'+part);
2204       my_b_printf(file , "'%s'", buf);
2205       my_snprintf(typestr, typestr_length, "DATE");
2206       return 3;
2207     }
2208 
2209   case MYSQL_TYPE_YEAR:
2210     {
2211       uint32 i32= *ptr;
2212       my_b_printf(file, "%04d", i32+ 1900);
2213       my_snprintf(typestr, typestr_length, "YEAR");
2214       return 1;
2215     }
2216 
2217   case MYSQL_TYPE_ENUM:
2218     switch (meta & 0xFF) {
2219     case 1:
2220       my_b_printf(file, "%d", (int) *ptr);
2221       my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
2222       return 1;
2223     case 2:
2224       {
2225         int32 i32= uint2korr(ptr);
2226         my_b_printf(file, "%d", i32);
2227         my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
2228         return 2;
2229       }
2230     default:
2231       my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2232       return 0;
2233     }
2234     break;
2235 
2236   case MYSQL_TYPE_SET:
2237     my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2238     my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2239     return meta & 0xFF;
2240 
2241   case MYSQL_TYPE_BLOB:
2242     switch (meta) {
2243     case 1:
2244       length= *ptr;
2245       my_b_write_quoted(file, ptr + 1, length);
2246       my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
2247       return length + 1;
2248     case 2:
2249       length= uint2korr(ptr);
2250       my_b_write_quoted(file, ptr + 2, length);
2251       my_snprintf(typestr, typestr_length, "BLOB/TEXT");
2252       return length + 2;
2253     case 3:
2254       length= uint3korr(ptr);
2255       my_b_write_quoted(file, ptr + 3, length);
2256       my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
2257       return length + 3;
2258     case 4:
2259       length= uint4korr(ptr);
2260       my_b_write_quoted(file, ptr + 4, length);
2261       my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
2262       return length + 4;
2263     default:
2264       my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2265       return 0;
2266     }
2267 
2268   case MYSQL_TYPE_VARCHAR:
2269   case MYSQL_TYPE_VAR_STRING:
2270     length= meta;
2271     my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
2272     return my_b_write_quoted_with_length(file, ptr, length);
2273 
2274   case MYSQL_TYPE_STRING:
2275     my_snprintf(typestr, typestr_length, "STRING(%d)", length);
2276     return my_b_write_quoted_with_length(file, ptr, length);
2277 
2278   default:
2279     {
2280       char tmp[5];
2281       my_snprintf(tmp, sizeof(tmp), "%04x", meta);
2282       my_b_printf(file,
2283                   "!! Don't know how to handle column type=%d meta=%d (%s)",
2284                   type, meta, tmp);
2285     }
2286     break;
2287   }
2288   *typestr= 0;
2289   return 0;
2290 }
2291 
2292 
2293 /**
2294   Print a packed row into IO cache
2295 
2296   @param[in] file              IO cache
2297   @param[in] td                Table definition
2298   @param[in] print_event_into  Print parameters
2299   @param[in] cols_bitmap       Column bitmaps.
2300   @param[in] value             Pointer to packed row
2301   @param[in] prefix            Row's SQL clause ("SET", "WHERE", etc)
2302 
2303   @retval   - number of bytes scanned.
2304 */
2305 
2306 
2307 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)2308 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
2309                                       PRINT_EVENT_INFO *print_event_info,
2310                                       MY_BITMAP *cols_bitmap,
2311                                       const uchar *value, const uchar *prefix)
2312 {
2313   const uchar *value0= value;
2314   const uchar *null_bits= value;
2315   uint null_bit_index= 0;
2316   char typestr[64]= "";
2317 
2318   /*
2319     Skip metadata bytes which gives the information about nullabity of master
2320     columns. Master writes one bit for each affected column.
2321    */
2322   value+= (bitmap_bits_set(cols_bitmap) + 7) / 8;
2323 
2324   my_b_printf(file, "%s", prefix);
2325 
2326   for (size_t i= 0; i < td->size(); i ++)
2327   {
2328     int is_null= (null_bits[null_bit_index / 8]
2329                   >> (null_bit_index % 8))  & 0x01;
2330 
2331     if (bitmap_is_set(cols_bitmap, i) == 0)
2332       continue;
2333 
2334     if (is_null)
2335     {
2336       my_b_printf(file, "###   @%d=NULL", static_cast<int>(i + 1));
2337     }
2338     else
2339     {
2340       my_b_printf(file, "###   @%d=", static_cast<int>(i + 1));
2341       size_t fsize= td->calc_field_size((uint)i, (uchar*) value);
2342       if (value + fsize > m_rows_end)
2343       {
2344         my_b_printf(file, "***Corrupted replication event was detected."
2345                     " Not printing the value***\n");
2346         value+= fsize;
2347         return 0;
2348       }
2349       size_t size= log_event_print_value(file, value,
2350                                          td->type(i), td->field_metadata(i),
2351                                          typestr, sizeof(typestr));
2352       if (!size)
2353         return 0;
2354 
2355       value+= size;
2356     }
2357 
2358     if (print_event_info->verbose > 1)
2359     {
2360       my_b_printf(file, " /* ");
2361 
2362       if (typestr[0])
2363         my_b_printf(file, "%s ", typestr);
2364       else
2365         my_b_printf(file, "type=%d ", td->type(i));
2366 
2367       my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
2368                   td->field_metadata(i),
2369                   td->maybe_null(i), is_null);
2370       my_b_printf(file, "*/");
2371     }
2372 
2373     my_b_printf(file, "\n");
2374 
2375     null_bit_index++;
2376   }
2377   return value - value0;
2378 }
2379 
2380 
2381 /**
2382   Print a row event into IO cache in human readable form (in SQL format)
2383 
2384   @param[in] file              IO cache
2385   @param[in] print_event_into  Print parameters
2386 */
print_verbose(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)2387 void Rows_log_event::print_verbose(IO_CACHE *file,
2388                                    PRINT_EVENT_INFO *print_event_info)
2389 {
2390   // Quoted length of the identifier can be twice the original length
2391   char quoted_db[1 + NAME_LEN * 2 + 2];
2392   char quoted_table[1 + NAME_LEN * 2 + 2];
2393   int quoted_db_len, quoted_table_len;
2394   Table_map_log_event *map;
2395   table_def *td;
2396   const char *sql_command, *sql_clause1, *sql_clause2;
2397   Log_event_type general_type_code= get_general_type_code();
2398 
2399   if (m_extra_row_data)
2400   {
2401     uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
2402     uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
2403     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
2404 
2405     my_b_printf(file, "### Extra row data format: %u, len: %u :",
2406                 m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
2407                 extra_payload_len);
2408     if (extra_payload_len)
2409     {
2410       /*
2411          Buffer for hex view of string, including '0x' prefix,
2412          2 hex chars / byte and trailing 0
2413       */
2414       const int buff_len= 2 + (256 * 2) + 1;
2415       char buff[buff_len];
2416       str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
2417                  extra_payload_len);
2418       my_b_printf(file, "%s", buff);
2419     }
2420     my_b_printf(file, "\n");
2421   }
2422 
2423   switch (general_type_code) {
2424   case WRITE_ROWS_EVENT:
2425     sql_command= "INSERT INTO";
2426     sql_clause1= "### SET\n";
2427     sql_clause2= NULL;
2428     break;
2429   case DELETE_ROWS_EVENT:
2430     sql_command= "DELETE FROM";
2431     sql_clause1= "### WHERE\n";
2432     sql_clause2= NULL;
2433     break;
2434   case UPDATE_ROWS_EVENT:
2435     sql_command= "UPDATE";
2436     sql_clause1= "### WHERE\n";
2437     sql_clause2= "### SET\n";
2438     break;
2439   default:
2440     sql_command= sql_clause1= sql_clause2= NULL;
2441     DBUG_ASSERT(0); /* Not possible */
2442   }
2443 
2444   if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2445       !(td= map->create_table_def()))
2446   {
2447     char llbuff[22];
2448     my_b_printf(file, "### Row event for unknown table #%s",
2449                 llstr(m_table_id, llbuff));
2450     return;
2451   }
2452 
2453   /* If the write rows event contained no values for the AI */
2454   if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
2455   {
2456     my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
2457                       map->get_db_name(), map->get_table_name());
2458     goto end;
2459   }
2460 
2461   for (const uchar *value= m_rows_buf; value < m_rows_end; )
2462   {
2463     size_t length;
2464 #ifdef MYSQL_SERVER
2465     quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2466                                         map->get_db_name(), 0);
2467     quoted_table_len= my_strmov_quoted_identifier(this->thd,
2468                                                   (char *) quoted_table,
2469                                                   map->get_table_name(), 0);
2470 #else
2471     quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2472                                                map->get_db_name());
2473     quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2474                                           map->get_table_name());
2475 #endif
2476     quoted_db[quoted_db_len]= '\0';
2477     quoted_table[quoted_table_len]= '\0';
2478     my_b_printf(file, "### %s %s.%s\n",
2479                       sql_command,
2480                       quoted_db, quoted_table);
2481     /* Print the first image */
2482     if (!(length= print_verbose_one_row(file, td, print_event_info,
2483                                   &m_cols, value,
2484                                   (const uchar*) sql_clause1)))
2485       goto end;
2486     value+= length;
2487 
2488     /* Print the second image (for UPDATE only) */
2489     if (sql_clause2)
2490     {
2491       if (!(length= print_verbose_one_row(file, td, print_event_info,
2492                                       &m_cols_ai, value,
2493                                       (const uchar*) sql_clause2)))
2494         goto end;
2495       value+= length;
2496     }
2497   }
2498 
2499 end:
2500   delete td;
2501 }
2502 
2503 #ifdef MYSQL_CLIENT
free_table_map_log_event(Table_map_log_event * event)2504 void free_table_map_log_event(Table_map_log_event *event)
2505 {
2506   delete event;
2507 }
2508 #endif
2509 
print_base64(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info,bool more)2510 void Log_event::print_base64(IO_CACHE* file,
2511                              PRINT_EVENT_INFO* print_event_info,
2512                              bool more)
2513 {
2514   const uchar *ptr= (const uchar *)temp_buf;
2515   uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2516   DBUG_ENTER("Log_event::print_base64");
2517 
2518   uint64 const tmp_str_sz= base64_needed_encoded_length((uint64) size);
2519   char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
2520   if (!tmp_str) {
2521     fprintf(stderr, "\nError: Out of memory. "
2522             "Could not print correct binlog event.\n");
2523     DBUG_VOID_RETURN;
2524   }
2525 
2526   if (base64_encode(ptr, (size_t) size, tmp_str))
2527   {
2528     DBUG_ASSERT(0);
2529   }
2530 
2531   if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2532   {
2533     if (my_b_tell(file) == 0)
2534       my_b_printf(file, "\nBINLOG '\n");
2535 
2536     my_b_printf(file, "%s\n", tmp_str);
2537 
2538     if (!more)
2539       my_b_printf(file, "'%s\n", print_event_info->delimiter);
2540   }
2541 
2542   if (print_event_info->verbose)
2543   {
2544     Rows_log_event *ev= NULL;
2545     Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
2546 
2547     if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
2548         checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
2549       size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
2550 
2551     switch(et)
2552     {
2553     case TABLE_MAP_EVENT:
2554     {
2555       Table_map_log_event *map;
2556       map= new Table_map_log_event((const char*) ptr, size,
2557                                    glob_description_event);
2558       print_event_info->m_table_map.set_table(map->get_table_id(), map);
2559       break;
2560     }
2561     case WRITE_ROWS_EVENT:
2562     case WRITE_ROWS_EVENT_V1:
2563     {
2564       ev= new Write_rows_log_event((const char*) ptr, size,
2565                                    glob_description_event);
2566       break;
2567     }
2568     case DELETE_ROWS_EVENT:
2569     case DELETE_ROWS_EVENT_V1:
2570     {
2571       ev= new Delete_rows_log_event((const char*) ptr, size,
2572                                     glob_description_event);
2573       break;
2574     }
2575     case UPDATE_ROWS_EVENT:
2576     case UPDATE_ROWS_EVENT_V1:
2577     {
2578       ev= new Update_rows_log_event((const char*) ptr, size,
2579                                     glob_description_event);
2580       break;
2581     }
2582     default:
2583       break;
2584     }
2585 
2586     if (ev)
2587     {
2588       ev->print_verbose(file, print_event_info);
2589       delete ev;
2590     }
2591   }
2592 
2593   my_free(tmp_str);
2594   DBUG_VOID_RETURN;
2595 }
2596 
2597 
2598 /*
2599   Log_event::print_timestamp()
2600 */
2601 
print_timestamp(IO_CACHE * file,time_t * ts)2602 void Log_event::print_timestamp(IO_CACHE* file, time_t *ts)
2603 {
2604   struct tm *res;
2605   /*
2606     In some Windows versions timeval.tv_sec is defined as "long",
2607     not as "time_t" and can be of a different size.
2608     Let's use a temporary time_t variable to execute localtime()
2609     with a correct argument type.
2610   */
2611   time_t ts_tmp= ts ? *ts : (ulong)when.tv_sec;
2612   DBUG_ENTER("Log_event::print_timestamp");
2613   struct tm tm_tmp;
2614   localtime_r(&ts_tmp, (res= &tm_tmp));
2615   my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2616               res->tm_year % 100,
2617               res->tm_mon+1,
2618               res->tm_mday,
2619               res->tm_hour,
2620               res->tm_min,
2621               res->tm_sec);
2622   DBUG_VOID_RETURN;
2623 }
2624 
2625 #endif /* MYSQL_CLIENT */
2626 
2627 
2628 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2629 inline Log_event::enum_skip_reason
continue_group(Relay_log_info * rli)2630 Log_event::continue_group(Relay_log_info *rli)
2631 {
2632   if (rli->slave_skip_counter == 1)
2633     return Log_event::EVENT_SKIP_IGNORE;
2634   return Log_event::do_shall_skip(rli);
2635 }
2636 
2637 /**
2638    @param end_group_sets_max_dbs  when true the group terminal event
2639                           can carry partition info, see a note below.
2640    @return true  in cases the current event
2641                  carries partition data,
2642            false otherwise
2643 
2644    @note Some events combination may force to adjust partition info.
2645          In particular BEGIN, BEGIN_LOAD_QUERY_EVENT, COMMIT
2646          where none of the events holds partitioning data
2647          causes the sequential applying of the group through
2648          assigning OVER_MAX_DBS_IN_EVENT_MTS to mts_accessed_dbs
2649          of COMMIT query event.
2650 */
contains_partition_info(bool end_group_sets_max_dbs)2651 bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2652 {
2653   bool res;
2654 
2655   switch (get_type_code()) {
2656   case TABLE_MAP_EVENT:
2657   case EXECUTE_LOAD_QUERY_EVENT:
2658     res= true;
2659 
2660     break;
2661 
2662   case QUERY_EVENT:
2663     if (ends_group() && end_group_sets_max_dbs)
2664     {
2665       res= true;
2666       static_cast<Query_log_event*>(this)->mts_accessed_dbs=
2667         OVER_MAX_DBS_IN_EVENT_MTS;
2668     }
2669     else
2670       res= (!ends_group() && !starts_group()) ? true : false;
2671 
2672     break;
2673 
2674   default:
2675     res= false;
2676   }
2677 
2678   return res;
2679 }
2680 
2681 /**
2682    The method maps the event to a Worker and return a pointer to it.
2683    As a part of the group, an event belongs to one of the following types:
2684 
2685    B - beginning of a group of events (BEGIN query_log_event)
2686    g - mini-group representative event containing the partition info
2687       (any Table_map, a Query_log_event)
2688    p - a mini-group internal event that *p*receeding its g-parent
2689       (int_, rand_, user_ var:s)
2690    r - a mini-group internal "regular" event that follows its g-parent
2691       (Delete, Update, Write -rows)
2692    T - terminator of the group (XID, COMMIT, ROLLBACK, auto-commit query)
2693 
2694    Only the first g-event computes the assigned Worker which once
2695    is determined remains to be for the rest of the group.
2696    That is the g-event solely carries partitioning info.
2697    For B-event the assigned Worker is NULL to indicate Coordinator
2698    has not yet decided. The same applies to p-event.
2699 
2700    Notice, these is a special group consisting of optionally multiple p-events
2701    terminating with a g-event.
2702    Such case is caused by old master binlog and a few corner-cases of
2703    the current master version (todo: to fix).
2704 
2705    In case of the event accesses more than OVER_MAX_DBS the method
2706    has to ensure sure previously assigned groups to all other workers are
2707    done.
2708 
2709 
2710    @note The function updates GAQ queue directly, updates APH hash
2711          plus relocates some temporary tables from Coordinator's list into
2712          involved entries of APH through @c map_db_to_worker.
2713          There's few memory allocations commented where to be freed.
2714 
2715    @return a pointer to the Worker struct or NULL.
2716 */
2717 
get_slave_worker(Relay_log_info * rli)2718 Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
2719 {
2720   Slave_job_group group, *ptr_group= NULL;
2721   bool is_s_event;
2722   Slave_worker *ret_worker= NULL;
2723   char llbuff[22];
2724 #ifndef DBUG_OFF
2725   THD *thd= rli->info_thd;
2726 #endif
2727   Slave_committed_queue *gaq= rli->gaq;
2728 
2729   /* checking partioning properties and perform corresponding actions */
2730 
2731   // Beginning of a group designated explicitly with BEGIN or GTID
2732   if ((is_s_event= starts_group()) || is_gtid_event(this) ||
2733       // or DDL:s or autocommit queries possibly associated with own p-events
2734       (!rli->curr_group_seen_begin && !rli->curr_group_seen_gtid &&
2735        /*
2736          the following is a special case of B-free still multi-event group like
2737          { p_1,p_2,...,p_k, g }.
2738          In that case either GAQ is empty (the very first group is being
2739          assigned) or the last assigned group index points at one of
2740          mapped-to-a-worker.
2741        */
2742        (gaq->empty() ||
2743         gaq->get_job_group(rli->gaq->assigned_group_index)->
2744         worker_id != MTS_WORKER_UNDEF)))
2745   {
2746     if (!rli->curr_group_seen_gtid && !rli->curr_group_seen_begin)
2747     {
2748       ulong gaq_idx MY_ATTRIBUTE((unused));
2749       rli->mts_groups_assigned++;
2750 
2751       rli->curr_group_isolated= FALSE;
2752       group.reset(log_pos, rli->mts_groups_assigned);
2753       // the last occupied GAQ's array index
2754       gaq_idx= gaq->assigned_group_index= gaq->en_queue((void *) &group);
2755 
2756       DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF && gaq_idx < gaq->size);
2757       DBUG_ASSERT(gaq->get_job_group(rli->gaq->assigned_group_index)->
2758                   group_relay_log_name == NULL);
2759       DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF);  // gaq must have room
2760       DBUG_ASSERT(rli->last_assigned_worker == NULL);
2761 
2762       if (is_s_event || is_gtid_event(this))
2763       {
2764         Log_event *ptr_curr_ev= this;
2765         // B-event is appended to the Deferred Array associated with GCAP
2766         insert_dynamic(&rli->curr_group_da,
2767                        (uchar*) &ptr_curr_ev);
2768 
2769         DBUG_ASSERT(rli->curr_group_da.elements == 1);
2770 
2771         if (starts_group())
2772         {
2773           // mark the current group as started with explicit B-event
2774           rli->mts_end_group_sets_max_dbs= true;
2775           rli->curr_group_seen_begin= true;
2776         }
2777 
2778         if (is_gtid_event(this))
2779           // mark the current group as started with explicit Gtid-event
2780           rli->curr_group_seen_gtid= true;
2781 
2782         return ret_worker;
2783       }
2784     }
2785     else
2786     {
2787       Log_event *ptr_curr_ev= this;
2788       // B-event is appended to the Deferred Array associated with GCAP
2789       insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2790       rli->curr_group_seen_begin= true;
2791       rli->mts_end_group_sets_max_dbs= true;
2792       DBUG_ASSERT(rli->curr_group_da.elements == 2);
2793       DBUG_ASSERT(starts_group());
2794       return ret_worker;
2795     }
2796   }
2797 
2798   // mini-group representative
2799 
2800   if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
2801   {
2802     int i= 0;
2803     Mts_db_names mts_dbs;
2804 
2805     get_mts_dbs(&mts_dbs);
2806     /*
2807       Bug 12982188 - MTS: SBR ABORTS WITH ERROR 1742 ON LOAD DATA
2808       Logging on master can create a group with no events holding
2809       the partition info.
2810       The following assert proves there's the only reason
2811       for such group.
2812     */
2813     DBUG_ASSERT(!ends_group() ||
2814                 /*
2815                   This is an empty group being processed due to gtids.
2816                 */
2817                 (rli->curr_group_seen_begin && rli->curr_group_seen_gtid &&
2818                  ends_group()) ||
2819                 (rli->mts_end_group_sets_max_dbs &&
2820                  ((rli->curr_group_da.elements == 3 && rli->curr_group_seen_gtid) ||
2821                  (rli->curr_group_da.elements == 2 && !rli->curr_group_seen_gtid)) &&
2822                  ((*(Log_event **)
2823                    dynamic_array_ptr(&rli->curr_group_da,
2824                                      rli->curr_group_da.elements - 1))->
2825                   get_type_code() == BEGIN_LOAD_QUERY_EVENT)));
2826 
2827     // partioning info is found which drops the flag
2828     rli->mts_end_group_sets_max_dbs= false;
2829     ret_worker= rli->last_assigned_worker;
2830     if (mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS)
2831     {
2832       // Worker with id 0 to handle serial execution
2833       if (!ret_worker)
2834         ret_worker= *(Slave_worker**) dynamic_array_ptr(&rli->workers, 0);
2835       // No need to know a possible error out of synchronization call.
2836       (void) wait_for_workers_to_finish(rli, ret_worker);
2837       /*
2838         this marking is transferred further into T-event of the current group.
2839       */
2840       rli->curr_group_isolated= TRUE;
2841     }
2842 
2843     /* One run of the loop in the case of over-max-db:s */
2844     for (i= 0; i < ((mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS) ? mts_dbs.num : 1);
2845          i++)
2846     {
2847       /*
2848         The over max db:s case handled through passing to map_db_to_worker
2849         such "all" db as encoded as  the "" empty string.
2850         Note, the empty string is allocated in a large buffer
2851         to satisfy hashcmp() implementation.
2852       */
2853       const char all_db[NAME_LEN]= {0};
2854       if (!(ret_worker=
2855             map_db_to_worker(mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS ?
2856                              all_db : mts_dbs.name[i], rli,
2857                              &mts_assigned_partitions[i],
2858                              /*
2859                                todo: optimize it. Although pure
2860                                rows- event load in insensetive to the flag value
2861                              */
2862                              TRUE,
2863                              ret_worker)))
2864       {
2865         llstr(rli->get_event_relay_log_pos(), llbuff);
2866         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2867                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2868                  "could not distribute the event to a Worker");
2869         return ret_worker;
2870       }
2871       // all temporary tables are transferred from Coordinator in over-max case
2872       DBUG_ASSERT(mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
2873       DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db,
2874                           mts_dbs.num != OVER_MAX_DBS_IN_EVENT_MTS ?
2875                           mts_dbs.name[i] : all_db));
2876       DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
2877       DBUG_ASSERT(mts_assigned_partitions[i]->usage >= 0);
2878     }
2879 
2880     if ((ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index))->
2881         worker_id == MTS_WORKER_UNDEF)
2882     {
2883       ptr_group->worker_id= ret_worker->id;
2884 
2885       DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2886     }
2887 
2888     DBUG_ASSERT(i == mts_dbs.num || mts_dbs.num == OVER_MAX_DBS_IN_EVENT_MTS);
2889   }
2890   else
2891   {
2892     // a mini-group internal "regular" event
2893     if (rli->last_assigned_worker)
2894     {
2895       ret_worker= rli->last_assigned_worker;
2896 
2897       DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0 ||
2898                   ret_worker->id == 0);
2899     }
2900     else // int_, rand_, user_ var:s, load-data events
2901     {
2902       Log_event *ptr_curr_ev= this;
2903 
2904       if (!(get_type_code() == INTVAR_EVENT ||
2905             get_type_code() == RAND_EVENT ||
2906             get_type_code() == USER_VAR_EVENT ||
2907             get_type_code() == BEGIN_LOAD_QUERY_EVENT ||
2908             get_type_code() == APPEND_BLOCK_EVENT ||
2909             is_ignorable_event()))
2910       {
2911         DBUG_ASSERT(!ret_worker);
2912 
2913         llstr(rli->get_event_relay_log_pos(), llbuff);
2914         my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2915                  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2916                  "the event is a part of a group that is unsupported in "
2917                  "the parallel execution mode");
2918 
2919         return ret_worker;
2920       }
2921 
2922       insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2923 
2924       DBUG_ASSERT(!ret_worker);
2925       return ret_worker;
2926     }
2927   }
2928 
2929   DBUG_ASSERT(ret_worker);
2930 
2931   /*
2932     Preparing event physical coordinates info for Worker before any
2933     event got scheduled so when Worker error-stopped at the first
2934     event it would be aware of where exactly in the event stream.
2935   */
2936   if (!ret_worker->master_log_change_notified)
2937   {
2938     if (!ptr_group)
2939       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2940     ptr_group->group_master_log_name=
2941       my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2942     ret_worker->master_log_change_notified= true;
2943 
2944     DBUG_ASSERT(!ptr_group->notified);
2945 #ifndef DBUG_OFF
2946     ptr_group->notified= true;
2947 #endif
2948   }
2949 
2950   // T-event: Commit, Xid, a DDL query or dml query of B-less group.
2951   if (ends_group() || !rli->curr_group_seen_begin)
2952   {
2953     rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
2954     if (rli->curr_group_isolated)
2955       set_mts_isolate_group();
2956     if (!ptr_group)
2957       ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2958 
2959     DBUG_ASSERT(ret_worker != NULL);
2960 
2961     /*
2962       The following two blocks are executed if the worker has not been
2963       notified about new relay-log or a new checkpoints.
2964       Relay-log string is freed by Coordinator, Worker deallocates
2965       strings in the checkpoint block.
2966       However if the worker exits earlier reclaiming for both happens anyway at
2967       GAQ delete.
2968     */
2969     if (!ret_worker->relay_log_change_notified)
2970     {
2971       /*
2972         Prior this event, C rotated the relay log to drop each
2973         Worker's notified flag. Now group terminating event initiates
2974         the new relay-log (where the current event is from) name
2975         delivery to Worker that will receive it in commit_positions().
2976       */
2977       DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2978 
2979       ptr_group->group_relay_log_name= (char *)
2980         my_malloc(strlen(rli->
2981                          get_group_relay_log_name()) + 1, MYF(MY_WME));
2982       strcpy(ptr_group->group_relay_log_name,
2983              rli->get_event_relay_log_name());
2984 
2985       DBUG_ASSERT(ptr_group->group_relay_log_name != NULL);
2986 
2987       ret_worker->relay_log_change_notified= TRUE;
2988     }
2989 
2990     if (!ret_worker->checkpoint_notified)
2991     {
2992       if (!ptr_group)
2993         ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2994       ptr_group->checkpoint_log_name=
2995         my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2996       ptr_group->checkpoint_log_pos= rli->get_group_master_log_pos();
2997       ptr_group->checkpoint_relay_log_name=
2998         my_strdup(rli->get_group_relay_log_name(), MYF(MY_WME));
2999       ptr_group->checkpoint_relay_log_pos= rli->get_group_relay_log_pos();
3000       ptr_group->shifted= ret_worker->bitmap_shifted;
3001       ret_worker->bitmap_shifted= 0;
3002       ret_worker->checkpoint_notified= TRUE;
3003     }
3004     ptr_group->checkpoint_seqno= rli->checkpoint_seqno;
3005     ptr_group->ts= when.tv_sec + (time_t) exec_time; // Seconds_behind_master related
3006     rli->checkpoint_seqno++;
3007     /*
3008       Coordinator should not use the main memroot however its not
3009       reset elsewhere either, so let's do it safe way.
3010       The main mem root is also reset by the SQL thread in at the end
3011       of applying which Coordinator does not do in this case.
3012       That concludes the memroot reset can't harm anything in SQL thread roles
3013       after Coordinator has finished its current scheduling.
3014     */
3015     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3016 
3017 #ifndef DBUG_OFF
3018     w_rr++;
3019 #endif
3020 
3021   }
3022 
3023   return ret_worker;
3024 }
3025 
3026 /**
3027    Scheduling event to execute in parallel or execute it directly.
3028    In MTS case the event gets associated with either Coordinator or a
3029    Worker.  A special case of the association is NULL when the Worker
3030    can't be decided yet.  In the single threaded sequential mode the
3031    event maps to SQL thread rli.
3032 
3033    @note in case of MTS failure Coordinator destroys all gathered
3034          deferred events.
3035 
3036    @return 0 as success, otherwise a failure.
3037 */
apply_event(Relay_log_info * rli)3038 int Log_event::apply_event(Relay_log_info *rli)
3039 {
3040   DBUG_ENTER("LOG_EVENT:apply_event");
3041   bool parallel= FALSE;
3042   enum enum_mts_event_exec_mode actual_exec_mode= EVENT_EXEC_PARALLEL;
3043   THD *thd= rli->info_thd;
3044 
3045   worker= rli;
3046 
3047   if (rli->is_mts_recovery())
3048   {
3049     bool skip=
3050       bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index) &&
3051       (get_mts_execution_mode(::server_id,
3052        rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
3053        == EVENT_EXEC_PARALLEL);
3054     if (skip)
3055     {
3056       DBUG_RETURN(0);
3057     }
3058     else
3059     {
3060       DBUG_RETURN(do_apply_event(rli));
3061     }
3062   }
3063 
3064   if (!(parallel= rli->is_parallel_exec()) ||
3065       ((actual_exec_mode=
3066         get_mts_execution_mode(::server_id,
3067                            rli->mts_group_status == Relay_log_info::MTS_IN_GROUP))
3068        != EVENT_EXEC_PARALLEL))
3069   {
3070     if (parallel)
3071     {
3072       /*
3073          There are two classes of events that Coordinator executes
3074          itself. One e.g the master Rotate requires all Workers to finish up
3075          their assignments. The other async class, e.g the slave Rotate,
3076          can't have this such synchronization because Worker might be waiting
3077          for terminal events to finish.
3078       */
3079 
3080       if (actual_exec_mode != EVENT_EXEC_ASYNC)
3081       {
3082         /*
3083           this  event does not split the current group but is indeed
3084           a separator beetwen two master's binlog therefore requiring
3085           Workers to sync.
3086         */
3087         if (rli->curr_group_da.elements > 0)
3088         {
3089           char llbuff[22];
3090           /*
3091              Possible reason is a old version binlog sequential event
3092              wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var.
3093              MTS has to stop to suggest restart in the permanent sequential mode.
3094           */
3095           llstr(rli->get_event_relay_log_pos(), llbuff);
3096           my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3097                    get_type_str(), rli->get_event_relay_log_name(), llbuff,
3098                    "possible malformed group of events from an old master");
3099 
3100           /* Coordinator cant continue, it marks MTS group status accordingly */
3101           rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
3102 
3103           goto err;
3104         }
3105         /*
3106           Marking sure the event will be executed in sequential mode.
3107         */
3108         if (wait_for_workers_to_finish(rli) == -1)
3109         {
3110           // handle synchronization error
3111           rli->report(WARNING_LEVEL, 0,
3112                       "Slave worker thread has failed to apply an event. As a "
3113                       "consequence, the coordinator thread is stopping "
3114                       "execution.");
3115           DBUG_RETURN(-1);
3116         }
3117         /*
3118           Given not in-group mark the event handler can invoke checkpoint
3119           update routine in the following course.
3120         */
3121         DBUG_ASSERT(rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP);
3122 
3123 #ifndef DBUG_OFF
3124         /* all Workers are idle as done through wait_for_workers_to_finish */
3125         for (uint k= 0; k < rli->curr_group_da.elements; k++)
3126         {
3127           DBUG_ASSERT(!(*(Slave_worker **)
3128                         dynamic_array_ptr(&rli->workers, k))->usage_partition);
3129           DBUG_ASSERT(!(*(Slave_worker **)
3130                         dynamic_array_ptr(&rli->workers, k))->jobs.len);
3131         }
3132 #endif
3133       }
3134       else
3135       {
3136         DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_ASYNC);
3137       }
3138     }
3139     DBUG_RETURN(do_apply_event(rli));
3140   }
3141 
3142   DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_PARALLEL);
3143   DBUG_ASSERT(!(rli->curr_group_seen_begin && ends_group()) ||
3144               /*
3145                 This is an empty group being processed due to gtids.
3146               */
3147               (rli->curr_group_seen_begin && rli->curr_group_seen_gtid
3148                && ends_group()) ||
3149               rli->last_assigned_worker ||
3150               /*
3151                 Begin_load_query can be logged w/o db info and within
3152                 Begin/Commit. That's a pattern forcing sequential
3153                 applying of LOAD-DATA.
3154               */
3155               (*(Log_event **)
3156                dynamic_array_ptr(&rli->curr_group_da,
3157                                  rli->curr_group_da.elements - 1))->
3158               get_type_code() == BEGIN_LOAD_QUERY_EVENT);
3159 
3160   worker= NULL;
3161   rli->mts_group_status= Relay_log_info::MTS_IN_GROUP;
3162 
3163   worker= (Relay_log_info*)
3164     (rli->last_assigned_worker= get_slave_worker(rli));
3165 
3166 #ifndef DBUG_OFF
3167   if (rli->last_assigned_worker)
3168     DBUG_PRINT("mts", ("Assigning job to worker %lu",
3169                rli->last_assigned_worker->id));
3170 #endif
3171 
3172 err:
3173   if (thd->is_error())
3174   {
3175     DBUG_ASSERT(!worker);
3176 
3177     /*
3178       Destroy all deferred buffered events but the current prior to exit.
3179       The current one will be deleted as an event never destined/assigned
3180       to any Worker in Coordinator's regular execution path.
3181     */
3182     for (uint k= 0; k < rli->curr_group_da.elements; k++)
3183     {
3184       Log_event *ev_buf=
3185         *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k);
3186       if (this != ev_buf)
3187         delete ev_buf;
3188     }
3189     rli->curr_group_da.elements= 0;
3190   }
3191   else
3192   {
3193     DBUG_ASSERT(worker || rli->curr_group_assigned_parts.elements == 0);
3194   }
3195 
3196   DBUG_RETURN((!thd->is_error() ||
3197                DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ?
3198               0 : -1);
3199 }
3200 
3201 #endif
3202 
3203 /**************************************************************************
3204 	Query_log_event methods
3205 **************************************************************************/
3206 
3207 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3208 
3209 /**
3210   This (which is used only for SHOW BINLOG EVENTS) could be updated to
3211   print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
3212   only an information, it does not produce suitable queries to replay (for
3213   example it does not print LOAD DATA INFILE).
3214   @todo
3215     show the catalog ??
3216 */
3217 
pack_info(Protocol * protocol)3218 int Query_log_event::pack_info(Protocol *protocol)
3219 {
3220   // TODO: show the catalog ??
3221   String temp_buf;
3222   // Add use `DB` to the string if required
3223   if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
3224       && db && db_len)
3225   {
3226     temp_buf.append("use ");
3227     append_identifier(this->thd, &temp_buf, db, db_len);
3228     temp_buf.append("; ");
3229   }
3230   // Add the query to the string
3231   if (query && q_len)
3232     temp_buf.append(query);
3233  // persist the buffer in protocol
3234   protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
3235   return 0;
3236 }
3237 #endif
3238 
3239 #ifndef MYSQL_CLIENT
3240 
3241 /**
3242   Utility function for the next method (Query_log_event::write()) .
3243 */
write_str_with_code_and_len(uchar ** dst,const char * src,uint len,uint code)3244 static void write_str_with_code_and_len(uchar **dst, const char *src,
3245                                         uint len, uint code)
3246 {
3247   /*
3248     only 1 byte to store the length of catalog, so it should not
3249     surpass 255
3250   */
3251   DBUG_ASSERT(len <= 255);
3252   DBUG_ASSERT(src);
3253   *((*dst)++)= code;
3254   *((*dst)++)= (uchar) len;
3255   bmove(*dst, src, len);
3256   (*dst)+= len;
3257 }
3258 
3259 
3260 /**
3261   Query_log_event::write().
3262 
3263   @note
3264     In this event we have to modify the header to have the correct
3265     EVENT_LEN_OFFSET as we don't yet know how many status variables we
3266     will print!
3267 */
3268 
write(IO_CACHE * file)3269 bool Query_log_event::write(IO_CACHE* file)
3270 {
3271   uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3272   uchar *start, *start_of_status;
3273   ulong event_length;
3274 
3275   if (!query)
3276     return 1;                                   // Something wrong with event
3277 
3278   /*
3279     We want to store the thread id:
3280     (- as an information for the user when he reads the binlog)
3281     - if the query uses temporary table: for the slave SQL thread to know to
3282     which master connection the temp table belongs.
3283     Now imagine we (write()) are called by the slave SQL thread (we are
3284     logging a query executed by this thread; the slave runs with
3285     --log-slave-updates). Then this query will be logged with
3286     thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
3287     the same name were created simultaneously on the master (in the master
3288     binlog you have
3289     CREATE TEMPORARY TABLE t; (thread 1)
3290     CREATE TEMPORARY TABLE t; (thread 2)
3291     ...)
3292     then in the slave's binlog there will be
3293     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3294     CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3295     which is bad (same thread id!).
3296 
3297     To avoid this, we log the thread's thread id EXCEPT for the SQL
3298     slave thread for which we log the original (master's) thread id.
3299     Now this moves the bug: what happens if the thread id on the
3300     master was 10 and when the slave replicates the query, a
3301     connection number 10 is opened by a normal client on the slave,
3302     and updates a temp table of the same name? We get a problem
3303     again. To avoid this, in the handling of temp tables (sql_base.cc)
3304     we use thread_id AND server_id.  TODO when this is merged into
3305     4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
3306     and is a session variable: that's to make mysqlbinlog work with
3307     temp tables. We probably need to introduce
3308 
3309     SET PSEUDO_SERVER_ID
3310     for mysqlbinlog in 4.1. mysqlbinlog would print:
3311     SET PSEUDO_SERVER_ID=
3312     SET PSEUDO_THREAD_ID=
3313     for each query using temp tables.
3314   */
3315   int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
3316   int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
3317   buf[Q_DB_LEN_OFFSET] = (char) db_len;
3318   int2store(buf + Q_ERR_CODE_OFFSET, error_code);
3319 
3320   /*
3321     You MUST always write status vars in increasing order of code. This
3322     guarantees that a slightly older slave will be able to parse those he
3323     knows.
3324   */
3325   start_of_status= start= buf+QUERY_HEADER_LEN;
3326   if (flags2_inited)
3327   {
3328     *start++= Q_FLAGS2_CODE;
3329     int4store(start, flags2);
3330     start+= 4;
3331   }
3332   if (sql_mode_inited)
3333   {
3334     *start++= Q_SQL_MODE_CODE;
3335     int8store(start, sql_mode);
3336     start+= 8;
3337   }
3338   if (catalog_len) // i.e. this var is inited (false for 4.0 events)
3339   {
3340     write_str_with_code_and_len(&start,
3341                                 catalog, catalog_len, Q_CATALOG_NZ_CODE);
3342     /*
3343       In 5.0.x where x<4 masters we used to store the end zero here. This was
3344       a waste of one byte so we don't do it in x>=4 masters. We change code to
3345       Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
3346       of this x>=4 master segfault (expecting a zero when there is
3347       none). Remaining compatibility problems are: the older slave will not
3348       find the catalog; but it is will not crash, and it's not an issue
3349       that it does not find the catalog as catalogs were not used in these
3350       older MySQL versions (we store it in binlog and read it from relay log
3351       but do nothing useful with it). What is an issue is that the older slave
3352       will stop processing the Q_* blocks (and jumps to the db/query) as soon
3353       as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
3354       Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
3355       various ways. Documented that you should not mix alpha/beta versions if
3356       they are not exactly the same version, with example of 5.0.3->5.0.2 and
3357       5.0.4->5.0.3. If replication is from older to new, the new will
3358       recognize Q_CATALOG_CODE and have no problem.
3359     */
3360   }
3361   if (auto_increment_increment != 1 || auto_increment_offset != 1)
3362   {
3363     *start++= Q_AUTO_INCREMENT;
3364     int2store(start, auto_increment_increment);
3365     int2store(start+2, auto_increment_offset);
3366     start+= 4;
3367   }
3368   if (charset_inited)
3369   {
3370     *start++= Q_CHARSET_CODE;
3371     memcpy(start, charset, 6);
3372     start+= 6;
3373   }
3374   if (time_zone_len)
3375   {
3376     /* In the TZ sys table, column Name is of length 64 so this should be ok */
3377     DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
3378     write_str_with_code_and_len(&start,
3379                                 time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
3380   }
3381   if (lc_time_names_number)
3382   {
3383     DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
3384     *start++= Q_LC_TIME_NAMES_CODE;
3385     int2store(start, lc_time_names_number);
3386     start+= 2;
3387   }
3388   if (charset_database_number)
3389   {
3390     DBUG_ASSERT(charset_database_number <= 0xFFFF);
3391     *start++= Q_CHARSET_DATABASE_CODE;
3392     int2store(start, charset_database_number);
3393     start+= 2;
3394   }
3395   if (table_map_for_update)
3396   {
3397     *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
3398     int8store(start, table_map_for_update);
3399     start+= 8;
3400   }
3401   if (master_data_written != 0)
3402   {
3403     /*
3404       Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
3405       has binlog_version<4 and the slave has binlog_version=4. See comment
3406       for master_data_written in log_event.h for details.
3407     */
3408     *start++= Q_MASTER_DATA_WRITTEN_CODE;
3409     int4store(start, master_data_written);
3410     start+= 4;
3411   }
3412 
3413   if (thd && thd->need_binlog_invoker())
3414   {
3415     LEX_STRING user;
3416     LEX_STRING host;
3417     memset(&user, 0, sizeof(user));
3418     memset(&host, 0, sizeof(host));
3419 
3420     if (thd->slave_thread && thd->has_invoker())
3421     {
3422       /* user will be null, if master is older than this patch */
3423       user= thd->get_invoker_user();
3424       host= thd->get_invoker_host();
3425     }
3426     else
3427     {
3428       Security_context *ctx= thd->security_ctx;
3429 
3430       user.length= strlen(ctx->priv_user);
3431       user.str= ctx->priv_user;
3432       if (ctx->priv_host[0] != '\0')
3433       {
3434         host.str= ctx->priv_host;
3435         host.length= strlen(ctx->priv_host);
3436       }
3437     }
3438 
3439     *start++= Q_INVOKER;
3440 
3441     /*
3442       Store user length and user. The max length of use is 16, so 1 byte is
3443       enough to store the user's length.
3444      */
3445     *start++= (uchar)user.length;
3446     memcpy(start, user.str, user.length);
3447     start+= user.length;
3448 
3449     /*
3450       Store host length and host. The max length of host is 60, so 1 byte is
3451       enough to store the host's length.
3452      */
3453     *start++= (uchar)host.length;
3454     memcpy(start, host.str, host.length);
3455     start+= host.length;
3456   }
3457 
3458   if (thd && thd->get_binlog_accessed_db_names() != NULL)
3459   {
3460     uchar dbs;
3461     *start++= Q_UPDATED_DB_NAMES;
3462 
3463     compile_time_assert(MAX_DBS_IN_EVENT_MTS <= OVER_MAX_DBS_IN_EVENT_MTS);
3464 
3465     /*
3466        In case of the number of db:s exceeds MAX_DBS_IN_EVENT_MTS
3467        no db:s is written and event will require the sequential applying on slave.
3468     */
3469     dbs=
3470       (thd->get_binlog_accessed_db_names()->elements <= MAX_DBS_IN_EVENT_MTS) ?
3471       thd->get_binlog_accessed_db_names()->elements : OVER_MAX_DBS_IN_EVENT_MTS;
3472 
3473     DBUG_ASSERT(dbs != 0);
3474 
3475     if (dbs <= MAX_DBS_IN_EVENT_MTS)
3476     {
3477       List_iterator_fast<char> it(*thd->get_binlog_accessed_db_names());
3478       char *db_name= it++;
3479       /*
3480          the single "" db in the acccessed db list corresponds to the same as
3481          exceeds MAX_DBS_IN_EVENT_MTS case, so dbs is set to the over-max.
3482       */
3483       if (dbs == 1 && !strcmp(db_name, ""))
3484         dbs= OVER_MAX_DBS_IN_EVENT_MTS;
3485       *start++= dbs;
3486       if (dbs != OVER_MAX_DBS_IN_EVENT_MTS)
3487         do
3488         {
3489           strcpy((char*) start, db_name);
3490           start += strlen(db_name) + 1;
3491         } while ((db_name= it++));
3492     }
3493     else
3494     {
3495       *start++= dbs;
3496     }
3497   }
3498 
3499   if (thd && thd->query_start_usec_used)
3500   {
3501     *start++= Q_MICROSECONDS;
3502     get_time();
3503     int3store(start, when.tv_usec);
3504     start+= 3;
3505   }
3506 
3507   /*
3508     NOTE: When adding new status vars, please don't forget to update
3509     the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
3510     code_name() in this file.
3511 
3512     Here there could be code like
3513     if (command-line-option-which-says-"log_this_variable" && inited)
3514     {
3515     *start++= Q_THIS_VARIABLE_CODE;
3516     int4store(start, this_variable);
3517     start+= 4;
3518     }
3519   */
3520 
3521   /* Store length of status variables */
3522   status_vars_len= (uint) (start-start_of_status);
3523   DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
3524   int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
3525 
3526   /*
3527     Calculate length of whole event
3528     The "1" below is the \0 in the db's length
3529   */
3530   event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
3531 
3532   return (write_header(file, event_length) ||
3533           wrapper_my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
3534           write_post_header_for_derived(file) ||
3535           wrapper_my_b_safe_write(file, (uchar*) start_of_status,
3536                           (uint) (start-start_of_status)) ||
3537           wrapper_my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
3538           wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
3539 	  write_footer(file)) ? 1 : 0;
3540 }
3541 
3542 /**
3543   The simplest constructor that could possibly work.  This is used for
3544   creating static objects that have a special meaning and are invisible
3545   to the log.
3546 */
Query_log_event()3547 Query_log_event::Query_log_event()
3548   :Log_event(), data_buf(0)
3549 {
3550   memset(&user, 0, sizeof(user));
3551   memset(&host, 0, sizeof(host));
3552 }
3553 
3554 
3555 /**
3556   Creates a Query Log Event.
3557 
3558   @param thd_arg      Thread handle
3559   @param query_arg    Array of char representing the query
3560   @param query_length Size of the 'query_arg' array
3561   @param using_trans  Indicates that there are transactional changes.
3562   @param immediate    After being written to the binary log, the event
3563                       must be flushed immediately. This indirectly implies
3564                       the stmt-cache.
3565   @param suppress_use Suppress the generation of 'USE' statements
3566   @param errcode      The error code of the query
3567   @param ignore       Ignore user's statement, i.e. lex information, while
3568                       deciding which cache must be used.
3569 */
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)3570 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
3571 				 ulong query_length, bool using_trans,
3572 				 bool immediate, bool suppress_use,
3573                                  int errcode, bool ignore_cmd_internals)
3574 
3575   :Log_event(thd_arg,
3576              (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
3577               0) |
3578              (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
3579 	     using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
3580                           Log_event::EVENT_STMT_CACHE,
3581              Log_event::EVENT_NORMAL_LOGGING),
3582    data_buf(0), query(query_arg), catalog(thd_arg->catalog),
3583    db(thd_arg->db), q_len((uint32) query_length),
3584    thread_id(thd_arg->thread_id),
3585    /* save the original thread id; we already know the server id */
3586    slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3587    flags2_inited(1), sql_mode_inited(1), charset_inited(1),
3588    sql_mode(thd_arg->variables.sql_mode),
3589    auto_increment_increment(thd_arg->variables.auto_increment_increment),
3590    auto_increment_offset(thd_arg->variables.auto_increment_offset),
3591    lc_time_names_number(thd_arg->variables.lc_time_names->number),
3592    charset_database_number(0),
3593    table_map_for_update((ulonglong)thd_arg->table_map_for_update),
3594    master_data_written(0), mts_accessed_dbs(0)
3595 {
3596 
3597 #ifdef WITH_WSREP
3598   /*
3599     If Query_log_event will contain non trans keyword (not BEGIN, COMMIT,
3600     SAVEPOINT or ROLLBACK) we disable PA for this transaction.
3601    */
3602   if (!is_trans_keyword())
3603     thd->wsrep_PA_safe= false;
3604 #endif /* WITH_WSREP */
3605   memset(&user, 0, sizeof(user));
3606   memset(&host, 0, sizeof(host));
3607 
3608   error_code= errcode;
3609 
3610   /*
3611   exec_time calculation has changed to use the same method that is used
3612   to fill out "thd_arg->start_time"
3613   */
3614 
3615   struct timeval end_time;
3616   ulonglong micro_end_time= my_micro_time();
3617   my_micro_time_to_timeval(micro_end_time, &end_time);
3618 
3619   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
3620 
3621   /**
3622     @todo this means that if we have no catalog, then it is replicated
3623     as an existing catalog of length zero. is that safe? /sven
3624   */
3625   catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
3626   /* status_vars_len is set just before writing the event */
3627   db_len = (db) ? (uint32) strlen(db) : 0;
3628   if (thd_arg->variables.collation_database != thd_arg->db_charset)
3629     charset_database_number= thd_arg->variables.collation_database->number;
3630 
3631   /*
3632     We only replicate over the bits of flags2 that we need: the rest
3633     are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
3634 
3635     We also force AUTOCOMMIT=1.  Rationale (cf. BUG#29288): After
3636     fixing BUG#26395, we always write BEGIN and COMMIT around all
3637     transactions (even single statements in autocommit mode).  This is
3638     so that replication from non-transactional to transactional table
3639     and error recovery from XA to non-XA table should work as
3640     expected.  The BEGIN/COMMIT are added in log.cc. However, there is
3641     one exception: MyISAM bypasses log.cc and writes directly to the
3642     binlog.  So if autocommit is off, master has MyISAM, and slave has
3643     a transactional engine, then the slave will just see one long
3644     never-ending transaction.  The only way to bypass explicit
3645     BEGIN/COMMIT in the binlog is by using a non-transactional table.
3646     So setting AUTOCOMMIT=1 will make this work as expected.
3647 
3648     Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
3649     assume AUTOCOMMIT=1 on slave; the slave still reads the state of
3650     the autocommit flag as written by the master to the binlog. This
3651     behavior may change after WL#4162 has been implemented.
3652   */
3653   flags2= (uint32) (thd_arg->variables.option_bits &
3654                     (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
3655   DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
3656   DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
3657   DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
3658   DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
3659   int2store(charset, thd_arg->variables.character_set_client->number);
3660   int2store(charset+2, thd_arg->variables.collation_connection->number);
3661   int2store(charset+4, thd_arg->variables.collation_server->number);
3662   if (thd_arg->time_zone_used)
3663   {
3664     /*
3665       Note that our event becomes dependent on the Time_zone object
3666       representing the time zone. Fortunately such objects are never deleted
3667       or changed during mysqld's lifetime.
3668     */
3669     time_zone_len= thd_arg->variables.time_zone->get_name()->length();
3670     time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
3671   }
3672   else
3673     time_zone_len= 0;
3674 
3675   /*
3676     In what follows, we define in which cache, trx-cache or stmt-cache,
3677     this Query Log Event will be written to.
3678 
3679     If ignore_cmd_internals is defined, we rely on the is_trans flag to
3680     choose the cache and this is done in the base class Log_event. False
3681     means that the stmt-cache will be used and upon statement commit/rollback
3682     the cache will be flushed to disk. True means that the trx-cache will
3683     be used and upon transaction commit/rollback the cache will be flushed
3684     to disk.
3685 
3686     If set immediate cache is defined, for convenience, we automatically
3687     use the stmt-cache. This mean that the statement will be written
3688     to the stmt-cache and immediately flushed to disk without waiting
3689     for a commit/rollback notification.
3690 
3691     For example, the cluster/ndb captures a request to execute a DDL
3692     statement and synchronously propagate it to all available MySQL
3693     servers. Unfortunately, the current protocol assumes that the
3694     generated events are immediately written to diks and does not check
3695     for commit/rollback.
3696 
3697     Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are
3698     generated and in this case the statements have the immediate flag
3699     set because there is no commit/rollback.
3700 
3701     If the immediate flag is not set, the decision on the cache is based
3702     on the current statement and the flag is_trans, which indicates if
3703     a transactional engine was updated.
3704 
3705     Statements are classifed as row producers (i.e. can_generate_row_events())
3706     or non-row producers. Non-row producers, DDL in general, are treated
3707     as the immediate flag was set and for convenience are written to the
3708     stmt-cache and immediately flushed to disk.
3709 
3710     Row producers are handled in general according to the is_trans flag.
3711     False means that the stmt-cache will be used and upon statement
3712     commit/rollback the cache will be flushed to disk. True means that the
3713     trx-cache will be used and upon transaction commit/rollback the cache
3714     will be flushed to disk.
3715 
3716     Unfortunately, there are exceptions to this non-row and row producer
3717     rules:
3718 
3719       . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not
3720         have the flag is_trans set because there is no updated engine but
3721         must be written to the trx-cache.
3722 
3723       . SET If auto-commit is on, it must not go through a cache.
3724 
3725       . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY
3726         must be handled as row producer.
3727 
3728       . DROP TABLE is classfied as non-row producer but DROP TEMPORARY
3729         must be handled as row producer.
3730 
3731     Finally, some statements that does not have the flag is_trans set may
3732     be written to the trx-cache based on the following criteria:
3733 
3734       . updated both a transactional and a non-transactional engine (i.e.
3735         stmt_has_updated_trans_table()).
3736 
3737       . accessed both a transactional and a non-transactional engine and
3738         is classified as unsafe (i.e. is_mixed_stmt_unsafe()).
3739 
3740       . is executed within a transaction and previously a transactional
3741         engine was updated and the flag binlog_direct_non_trans_update
3742         is set.
3743   */
3744   if (ignore_cmd_internals)
3745     return;
3746 
3747   /*
3748     TRUE defines that the trx-cache must be used.
3749   */
3750   bool cmd_can_generate_row_events= FALSE;
3751   /*
3752     TRUE defines that the trx-cache must be used.
3753   */
3754   bool cmd_must_go_to_trx_cache= FALSE;
3755 
3756   LEX *lex= thd->lex;
3757   if (!immediate)
3758   {
3759     switch (lex->sql_command)
3760     {
3761       case SQLCOM_DROP_TABLE:
3762         cmd_can_generate_row_events= lex->drop_temporary &&
3763                                      thd->in_multi_stmt_transaction_mode();
3764       break;
3765       case SQLCOM_CREATE_TABLE:
3766         cmd_must_go_to_trx_cache= lex->select_lex.item_list.elements &&
3767                                   thd->is_current_stmt_binlog_format_row();
3768         cmd_can_generate_row_events=
3769           ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
3770             thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache;
3771         break;
3772       case SQLCOM_SET_OPTION:
3773         if (lex->autocommit)
3774           cmd_can_generate_row_events= cmd_must_go_to_trx_cache= FALSE;
3775         else
3776           cmd_can_generate_row_events= TRUE;
3777         break;
3778       case SQLCOM_RELEASE_SAVEPOINT:
3779       case SQLCOM_ROLLBACK_TO_SAVEPOINT:
3780       case SQLCOM_SAVEPOINT:
3781         cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE;
3782         break;
3783       default:
3784         cmd_can_generate_row_events=
3785           sqlcom_can_generate_row_events(thd->lex->sql_command);
3786         break;
3787     }
3788   }
3789 
3790   if (cmd_can_generate_row_events)
3791   {
3792     cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
3793     if (cmd_must_go_to_trx_cache ||
3794         stmt_has_updated_trans_table(thd->transaction.stmt.ha_list) ||
3795         thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
3796                                        thd->variables.binlog_direct_non_trans_update,
3797                                        trans_has_updated_trans_table(thd),
3798                                        thd->tx_isolation) ||
3799         (!thd->variables.binlog_direct_non_trans_update && trans_has_updated_trans_table(thd)))
3800     {
3801       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3802       event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
3803     }
3804     else
3805     {
3806       event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3807       event_cache_type= Log_event::EVENT_STMT_CACHE;
3808     }
3809   }
3810   else
3811   {
3812     event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
3813     event_cache_type= Log_event::EVENT_STMT_CACHE;
3814   }
3815 
3816   DBUG_ASSERT(event_cache_type != Log_event::EVENT_INVALID_CACHE);
3817   DBUG_ASSERT(event_logging_type != Log_event::EVENT_INVALID_LOGGING);
3818   DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %llu",
3819                      (ulong) flags2, sql_mode));
3820 }
3821 #endif /* MYSQL_CLIENT */
3822 
3823 
3824 /* 2 utility functions for the next method */
3825 
3826 /**
3827    Read a string with length from memory.
3828 
3829    This function reads the string-with-length stored at
3830    <code>src</code> and extract the length into <code>*len</code> and
3831    a pointer to the start of the string into <code>*dst</code>. The
3832    string can then be copied using <code>memcpy()</code> with the
3833    number of bytes given in <code>*len</code>.
3834 
3835    @param src Pointer to variable holding a pointer to the memory to
3836               read the string from.
3837    @param dst Pointer to variable holding a pointer where the actual
3838               string starts. Starting from this position, the string
3839               can be copied using @c memcpy().
3840    @param len Pointer to variable where the length will be stored.
3841    @param end One-past-the-end of the memory where the string is
3842               stored.
3843 
3844    @return    Zero if the entire string can be copied successfully,
3845               @c UINT_MAX if the length could not be read from memory
3846               (that is, if <code>*src >= end</code>), otherwise the
3847               number of bytes that are missing to read the full
3848               string, which happends <code>*dst + *len >= end</code>.
3849 */
3850 static int
get_str_len_and_pointer(const Log_event::Byte ** src,const char ** dst,uint * len,const Log_event::Byte * end)3851 get_str_len_and_pointer(const Log_event::Byte **src,
3852                         const char **dst,
3853                         uint *len,
3854                         const Log_event::Byte *end)
3855 {
3856   if (*src >= end)
3857     return -1;       // Will be UINT_MAX in two-complement arithmetics
3858   uint length= **src;
3859   if (length > 0)
3860   {
3861     if (*src + length >= end)
3862       return *src + length - end + 1;       // Number of bytes missing
3863     *dst= (char *)*src + 1;                    // Will be copied later
3864   }
3865   *len= length;
3866   *src+= length + 1;
3867   return 0;
3868 }
3869 
copy_str_and_move(const char ** src,Log_event::Byte ** dst,uint len)3870 static void copy_str_and_move(const char **src,
3871                               Log_event::Byte **dst,
3872                               uint len)
3873 {
3874   memcpy(*dst, *src, len);
3875   *src= (const char *)*dst;
3876   (*dst)+= len;
3877   *(*dst)++= 0;
3878 }
3879 
3880 
3881 #ifndef DBUG_OFF
3882 static char const *
code_name(int code)3883 code_name(int code)
3884 {
3885   static char buf[255];
3886   switch (code) {
3887   case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
3888   case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
3889   case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
3890   case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
3891   case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
3892   case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
3893   case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
3894   case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
3895   case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
3896   case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
3897   case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
3898   case Q_UPDATED_DB_NAMES: return "Q_UPDATED_DB_NAMES";
3899   case Q_MICROSECONDS: return "Q_MICROSECONDS";
3900   }
3901   sprintf(buf, "CODE#%d", code);
3902   return buf;
3903 }
3904 #endif
3905 
3906 /**
3907    Macro to check that there is enough space to read from memory.
3908 
3909    @param PTR Pointer to memory
3910    @param END End of memory
3911    @param CNT Number of bytes that should be read.
3912  */
3913 #define CHECK_SPACE(PTR,END,CNT)                      \
3914   do {                                                \
3915     DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
3916     DBUG_ASSERT((PTR) + (CNT) <= (END));              \
3917     if ((PTR) + (CNT) > (END)) {                      \
3918       DBUG_PRINT("info", ("query= 0"));               \
3919       query= 0;                                       \
3920       DBUG_VOID_RETURN;                               \
3921     }                                                 \
3922   } while (0)
3923 
3924 
3925 /**
3926   This is used by the SQL slave thread to prepare the event before execution.
3927 */
Query_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event,Log_event_type event_type)3928 Query_log_event::Query_log_event(const char* buf, uint event_len,
3929                                  const Format_description_log_event
3930                                  *description_event,
3931                                  Log_event_type event_type)
3932   :Log_event(buf, description_event), data_buf(0), query(NullS),
3933    db(NullS), catalog_len(0), status_vars_len(0),
3934    flags2_inited(0), sql_mode_inited(0), charset_inited(0),
3935    auto_increment_increment(1), auto_increment_offset(1),
3936    time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
3937    table_map_for_update(0), master_data_written(0),
3938    mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS)
3939 {
3940   ulong data_len;
3941   uint32 tmp;
3942   uint8 common_header_len, post_header_len;
3943   Log_event::Byte *start;
3944   const Log_event::Byte *end;
3945   bool catalog_nz= 1;
3946   DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
3947 
3948   memset(&user, 0, sizeof(user));
3949   memset(&host, 0, sizeof(host));
3950   common_header_len= description_event->common_header_len;
3951   post_header_len= description_event->post_header_len[event_type-1];
3952   DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
3953                      event_len, common_header_len, post_header_len));
3954 
3955   /*
3956     We test if the event's length is sensible, and if so we compute data_len.
3957     We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
3958     We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
3959   */
3960   if (event_len < (uint)(common_header_len + post_header_len))
3961     DBUG_VOID_RETURN;
3962   data_len = event_len - (common_header_len + post_header_len);
3963   buf+= common_header_len;
3964 
3965   slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
3966   exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
3967   db_len = (uchar)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
3968   error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
3969 
3970   /*
3971     5.0 format starts here.
3972     Depending on the format, we may or not have affected/warnings etc
3973     The remnent post-header to be parsed has length:
3974   */
3975   tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
3976   if (tmp)
3977   {
3978     status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
3979     /*
3980       Check if status variable length is corrupt and will lead to very
3981       wrong data. We could be even more strict and require data_len to
3982       be even bigger, but this will suffice to catch most corruption
3983       errors that can lead to a crash.
3984     */
3985     if (status_vars_len > min<ulong>(data_len, MAX_SIZE_LOG_EVENT_STATUS))
3986     {
3987       DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
3988                           status_vars_len, data_len));
3989       query= 0;
3990       DBUG_VOID_RETURN;
3991     }
3992     data_len-= status_vars_len;
3993     DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
3994                         (uint) status_vars_len));
3995     tmp-= 2;
3996   }
3997   else
3998   {
3999     /*
4000       server version < 5.0 / binlog_version < 4 master's event is
4001       relay-logged with storing the original size of the event in
4002       Q_MASTER_DATA_WRITTEN_CODE status variable.
4003       The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
4004       event from the relay log.
4005     */
4006     DBUG_ASSERT(description_event->binlog_version < 4);
4007     master_data_written= data_written;
4008   }
4009   /*
4010     We have parsed everything we know in the post header for QUERY_EVENT,
4011     the rest of post header is either comes from older version MySQL or
4012     dedicated to derived events (e.g. Execute_load_query...)
4013   */
4014 
4015   /* variable-part: the status vars; only in MySQL 5.0  */
4016 
4017   start= (Log_event::Byte*) (buf+post_header_len);
4018   end= (const Log_event::Byte*) (start+status_vars_len);
4019   for (const Log_event::Byte* pos= start; pos < end;)
4020   {
4021     switch (*pos++) {
4022     case Q_FLAGS2_CODE:
4023       CHECK_SPACE(pos, end, 4);
4024       flags2_inited= 1;
4025       flags2= uint4korr(pos);
4026       DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
4027       pos+= 4;
4028       break;
4029     case Q_SQL_MODE_CODE:
4030     {
4031 #ifndef DBUG_OFF
4032       char buff[22];
4033 #endif
4034       CHECK_SPACE(pos, end, 8);
4035       sql_mode_inited= 1;
4036       sql_mode= uint8korr(pos);
4037       DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
4038 			 llstr(sql_mode, buff)));
4039       pos+= 8;
4040       break;
4041     }
4042     case Q_CATALOG_NZ_CODE:
4043       DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
4044                           (ulong) pos, (ulong) end));
4045       if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
4046       {
4047         DBUG_PRINT("info", ("query= 0"));
4048         query= 0;
4049         DBUG_VOID_RETURN;
4050       }
4051       break;
4052     case Q_AUTO_INCREMENT:
4053       CHECK_SPACE(pos, end, 4);
4054       auto_increment_increment= uint2korr(pos);
4055       auto_increment_offset=    uint2korr(pos+2);
4056       pos+= 4;
4057       break;
4058     case Q_CHARSET_CODE:
4059     {
4060       CHECK_SPACE(pos, end, 6);
4061       charset_inited= 1;
4062       memcpy(charset, pos, 6);
4063       pos+= 6;
4064       break;
4065     }
4066     case Q_TIME_ZONE_CODE:
4067     {
4068       if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
4069       {
4070         DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
4071         query= 0;
4072         DBUG_VOID_RETURN;
4073       }
4074       break;
4075     }
4076     case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
4077       CHECK_SPACE(pos, end, 1);
4078       if ((catalog_len= *pos))
4079         catalog= (char*) pos+1;                           // Will be copied later
4080       CHECK_SPACE(pos, end, catalog_len + 2);
4081       pos+= catalog_len+2; // leap over end 0
4082       catalog_nz= 0; // catalog has end 0 in event
4083       break;
4084     case Q_LC_TIME_NAMES_CODE:
4085       CHECK_SPACE(pos, end, 2);
4086       lc_time_names_number= uint2korr(pos);
4087       pos+= 2;
4088       break;
4089     case Q_CHARSET_DATABASE_CODE:
4090       CHECK_SPACE(pos, end, 2);
4091       charset_database_number= uint2korr(pos);
4092       pos+= 2;
4093       break;
4094     case Q_TABLE_MAP_FOR_UPDATE_CODE:
4095       CHECK_SPACE(pos, end, 8);
4096       table_map_for_update= uint8korr(pos);
4097       pos+= 8;
4098       break;
4099     case Q_MASTER_DATA_WRITTEN_CODE:
4100       CHECK_SPACE(pos, end, 4);
4101       data_written= master_data_written= uint4korr(pos);
4102       pos+= 4;
4103       break;
4104     case Q_MICROSECONDS:
4105     {
4106       CHECK_SPACE(pos, end, 3);
4107       when.tv_usec= uint3korr(pos);
4108       pos+= 3;
4109       break;
4110     }
4111     case Q_INVOKER:
4112     {
4113       CHECK_SPACE(pos, end, 1);
4114       user.length= *pos++;
4115       CHECK_SPACE(pos, end, user.length);
4116       user.str= (char *)pos;
4117       if (user.length == 0)
4118         user.str= (char *)"";
4119       pos+= user.length;
4120 
4121       CHECK_SPACE(pos, end, 1);
4122       host.length= *pos++;
4123       CHECK_SPACE(pos, end, host.length);
4124       host.str= (char *)pos;
4125       if (host.length == 0)
4126         host.str= (char *)"";
4127       pos+= host.length;
4128       break;
4129     }
4130     case Q_UPDATED_DB_NAMES:
4131     {
4132       uchar i= 0;
4133       CHECK_SPACE(pos, end, 1);
4134       mts_accessed_dbs= *pos++;
4135       /*
4136          Notice, the following check is positive also in case of
4137          the master's MAX_DBS_IN_EVENT_MTS > the slave's one and the event
4138          contains e.g the master's MAX_DBS_IN_EVENT_MTS db:s.
4139       */
4140       if (mts_accessed_dbs > MAX_DBS_IN_EVENT_MTS)
4141       {
4142         mts_accessed_dbs= OVER_MAX_DBS_IN_EVENT_MTS;
4143         break;
4144       }
4145 
4146       DBUG_ASSERT(mts_accessed_dbs != 0);
4147 
4148       for (i= 0; i < mts_accessed_dbs && pos < start + status_vars_len; i++)
4149       {
4150         DBUG_EXECUTE_IF("query_log_event_mts_corrupt_db_names",
4151                         {
4152                           if (mts_accessed_dbs == 2)
4153                           {
4154                             DBUG_ASSERT(pos[sizeof("d?") - 1] == 0);
4155                             ((char*) pos)[sizeof("d?") - 1]= 'a';
4156                           }});
4157         strncpy(mts_accessed_db_names[i], (char*) pos,
4158                 min<ulong>(NAME_LEN, start + status_vars_len - pos));
4159         mts_accessed_db_names[i][NAME_LEN - 1]= 0;
4160         pos+= 1 + strlen((const char*) pos);
4161       }
4162       if (i != mts_accessed_dbs || pos > start + status_vars_len)
4163         DBUG_VOID_RETURN;
4164       break;
4165     }
4166     default:
4167       /* That's why you must write status vars in growing order of code */
4168       DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
4169  code: %u), skipping the rest of them", (uint) *(pos-1)));
4170       pos= (const uchar*) end;                         // Break loop
4171     }
4172   }
4173 
4174   /**
4175     Layout for the data buffer is as follows
4176     +--------+-----------+------+------+---------+----+-------+
4177     | catlog | time_zone | user | host | db name | \0 | Query |
4178     +--------+-----------+------+------+---------+----+-------+
4179 
4180     To support the query cache we append the following buffer to the above
4181     +-------+----------------------------------------+-------+
4182     |db len | uninitiatlized space of size of db len | FLAGS |
4183     +-------+----------------------------------------+-------+
4184 
4185     The area of buffer starting from Query field all the way to the end belongs
4186     to the Query buffer and its structure is described in alloc_query() in
4187     sql_parse.cc
4188     */
4189 
4190 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4191   if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4192                                                     +  time_zone_len + 1
4193                                                     +  user.length + 1
4194                                                     +  host.length + 1
4195                                                     +  data_len + 1
4196                                                     +  sizeof(size_t)//for db_len
4197                                                     +  db_len + 1
4198                                                     +  QUERY_CACHE_FLAGS_SIZE,
4199                                                        MYF(MY_WME))))
4200 #else
4201   if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4202                                                     +  time_zone_len + 1
4203                                                     +  user.length + 1
4204                                                     +  host.length + 1
4205                                                     +  data_len + 1,
4206                                                        MYF(MY_WME))))
4207 #endif
4208       DBUG_VOID_RETURN;
4209   if (catalog_len)                                  // If catalog is given
4210   {
4211     /**
4212       @todo we should clean up and do only copy_str_and_move; it
4213       works for both cases.  Then we can remove the catalog_nz
4214       flag. /sven
4215     */
4216     if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
4217       copy_str_and_move(&catalog, &start, catalog_len);
4218     else
4219     {
4220       memcpy(start, catalog, catalog_len+1); // copy end 0
4221       catalog= (const char *)start;
4222       start+= catalog_len+1;
4223     }
4224   }
4225   if (time_zone_len)
4226     copy_str_and_move(&time_zone_str, &start, time_zone_len);
4227 
4228   if (user.length > 0)
4229     copy_str_and_move((const char **)&(user.str), &start, user.length);
4230   if (host.length > 0)
4231     copy_str_and_move((const char **)&(host.str), &start, host.length);
4232 
4233   /**
4234     if time_zone_len or catalog_len are 0, then time_zone and catalog
4235     are uninitialized at this point.  shouldn't they point to the
4236     zero-length null-terminated strings we allocated space for in the
4237     my_alloc call above? /sven
4238   */
4239 
4240   /* A 2nd variable part; this is common to all versions */
4241   memcpy((char*) start, end, data_len);          // Copy db and query
4242   start[data_len]= '\0';              // End query with \0 (For safetly)
4243   db= (char *)start;
4244   query= (char *)(start + db_len + 1);
4245   q_len= data_len - db_len -1;
4246 
4247   if (data_len && (data_len < db_len ||
4248                    data_len < q_len ||
4249                    data_len != (db_len + q_len + 1)))
4250   {
4251     q_len= 0;
4252     query= NULL;
4253     DBUG_VOID_RETURN;
4254   }
4255 
4256   unsigned int max_length;
4257   max_length= (event_len - ((const char*)(end + db_len + 1) -
4258                             (buf - common_header_len)));
4259   if (q_len != max_length)
4260   {
4261     q_len= 0;
4262     query= NULL;
4263     DBUG_VOID_RETURN;
4264   }
4265   /**
4266     Append the db length at the end of the buffer. This will be used by
4267     Query_cache::send_result_to_client() in case the query cache is On.
4268    */
4269 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4270   size_t db_length= (size_t)db_len;
4271   memcpy(start + data_len + 1, &db_length, sizeof(size_t));
4272 #endif
4273   DBUG_VOID_RETURN;
4274 }
4275 
4276 
4277 #ifdef MYSQL_CLIENT
4278 /**
4279   Query_log_event::print().
4280 
4281   @todo
4282     print the catalog ??
4283 */
print_query_header(IO_CACHE * file,PRINT_EVENT_INFO * print_event_info)4284 void Query_log_event::print_query_header(IO_CACHE* file,
4285 					 PRINT_EVENT_INFO* print_event_info)
4286 {
4287   // TODO: print the catalog ??
4288   char buff[48], *end;  // Enough for "SET TIMESTAMP=1305535348.123456"
4289   char quoted_id[1+ 2*FN_REFLEN+ 2];
4290   int quoted_len= 0;
4291   bool different_db= 1;
4292   uint32 tmp;
4293 
4294   if (!print_event_info->short_form)
4295   {
4296     print_header(file, print_event_info, FALSE);
4297     my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
4298                 get_type_str(), (ulong) thread_id, (ulong) exec_time,
4299                 error_code);
4300   }
4301 
4302   if ((flags & LOG_EVENT_SUPPRESS_USE_F))
4303   {
4304     if (!is_trans_keyword())
4305       print_event_info->db[0]= '\0';
4306   }
4307   else if (db)
4308   {
4309 #ifdef MYSQL_SERVER
4310     quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
4311 #else
4312     quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
4313 #endif
4314     quoted_id[quoted_len]= '\0';
4315     different_db= memcmp(print_event_info->db, db, db_len + 1);
4316     if (different_db)
4317       memcpy(print_event_info->db, db, db_len + 1);
4318     if (db[0] && different_db)
4319       my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
4320   }
4321 
4322   end=int10_to_str((long) when.tv_sec, strmov(buff,"SET TIMESTAMP="),10);
4323   if (when.tv_usec)
4324     end+= sprintf(end, ".%06d", (int) when.tv_usec);
4325   end= strmov(end, print_event_info->delimiter);
4326   *end++='\n';
4327   DBUG_ASSERT(end < buff + sizeof(buff));
4328   my_b_write(file, (uchar*) buff, (uint) (end-buff));
4329   if ((!print_event_info->thread_id_printed ||
4330        ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
4331         thread_id != print_event_info->thread_id)))
4332   {
4333     // If --short-form, print deterministic value instead of pseudo_thread_id.
4334     my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
4335                 short_form ? 999999999 : (ulong)thread_id,
4336                 print_event_info->delimiter);
4337     print_event_info->thread_id= thread_id;
4338     print_event_info->thread_id_printed= 1;
4339   }
4340 
4341   /*
4342     If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
4343     print (remember we don't produce mixed relay logs so there cannot be
4344     5.0 events before that one so there is nothing to reset).
4345   */
4346   if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
4347   {
4348     /* tmp is a bitmask of bits which have changed. */
4349     if (likely(print_event_info->flags2_inited))
4350       /* All bits which have changed */
4351       tmp= (print_event_info->flags2) ^ flags2;
4352     else /* that's the first Query event we read */
4353     {
4354       print_event_info->flags2_inited= 1;
4355       tmp= ~((uint32)0); /* all bits have changed */
4356     }
4357 
4358     if (unlikely(tmp)) /* some bits have changed */
4359     {
4360       bool need_comma= 0;
4361       my_b_printf(file, "SET ");
4362       print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
4363                        "@@session.foreign_key_checks", &need_comma);
4364       print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
4365                        "@@session.sql_auto_is_null", &need_comma);
4366       print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
4367                        "@@session.unique_checks", &need_comma);
4368       print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
4369                        "@@session.autocommit", &need_comma);
4370       my_b_printf(file,"%s\n", print_event_info->delimiter);
4371       print_event_info->flags2= flags2;
4372     }
4373   }
4374 
4375   /*
4376     Now the session variables;
4377     it's more efficient to pass SQL_MODE as a number instead of a
4378     comma-separated list.
4379     FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
4380     variables (they have no global version; they're not listed in
4381     sql_class.h), The tests below work for pure binlogs or pure relay
4382     logs. Won't work for mixed relay logs but we don't create mixed
4383     relay logs (that is, there is no relay log with a format change
4384     except within the 3 first events, which mysqlbinlog handles
4385     gracefully). So this code should always be good.
4386   */
4387 
4388   if (likely(sql_mode_inited) &&
4389       (unlikely(print_event_info->sql_mode != sql_mode ||
4390                 !print_event_info->sql_mode_inited)))
4391   {
4392     my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
4393                 (ulong)sql_mode, print_event_info->delimiter);
4394     print_event_info->sql_mode= sql_mode;
4395     print_event_info->sql_mode_inited= 1;
4396   }
4397   if (print_event_info->auto_increment_increment != auto_increment_increment ||
4398       print_event_info->auto_increment_offset != auto_increment_offset)
4399   {
4400     my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
4401                 auto_increment_increment,auto_increment_offset,
4402                 print_event_info->delimiter);
4403     print_event_info->auto_increment_increment= auto_increment_increment;
4404     print_event_info->auto_increment_offset=    auto_increment_offset;
4405   }
4406 
4407   /* TODO: print the catalog when we feature SET CATALOG */
4408 
4409   if (likely(charset_inited) &&
4410       (unlikely(!print_event_info->charset_inited ||
4411                 memcmp(print_event_info->charset, charset, 6))))
4412   {
4413     char *charset_p= charset; // Avoid type-punning warning.
4414     CHARSET_INFO *cs_info= get_charset(uint2korr(charset_p), MYF(MY_WME));
4415     if (cs_info)
4416     {
4417       /* for mysql client */
4418       my_b_printf(file, "/*!\\C %s */%s\n",
4419                   cs_info->csname, print_event_info->delimiter);
4420     }
4421     my_b_printf(file,"SET "
4422                 "@@session.character_set_client=%d,"
4423                 "@@session.collation_connection=%d,"
4424                 "@@session.collation_server=%d"
4425                 "%s\n",
4426                 uint2korr(charset_p),
4427                 uint2korr(charset+2),
4428                 uint2korr(charset+4),
4429                 print_event_info->delimiter);
4430     memcpy(print_event_info->charset, charset, 6);
4431     print_event_info->charset_inited= 1;
4432   }
4433   if (time_zone_len)
4434   {
4435     if (memcmp(print_event_info->time_zone_str,
4436                time_zone_str, time_zone_len+1))
4437     {
4438       my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
4439                   time_zone_str, print_event_info->delimiter);
4440       memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
4441     }
4442   }
4443   if (lc_time_names_number != print_event_info->lc_time_names_number)
4444   {
4445     my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
4446                 lc_time_names_number, print_event_info->delimiter);
4447     print_event_info->lc_time_names_number= lc_time_names_number;
4448   }
4449   if (charset_database_number != print_event_info->charset_database_number)
4450   {
4451     if (charset_database_number)
4452       my_b_printf(file, "SET @@session.collation_database=%d%s\n",
4453                   charset_database_number, print_event_info->delimiter);
4454     else
4455       my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
4456                   print_event_info->delimiter);
4457     print_event_info->charset_database_number= charset_database_number;
4458   }
4459 }
4460 
4461 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)4462 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4463 {
4464   IO_CACHE *const head= &print_event_info->head_cache;
4465 
4466   /**
4467     reduce the size of io cache so that the write function is called
4468     for every call to my_b_write().
4469    */
4470   DBUG_EXECUTE_IF ("simulate_file_write_error",
4471                    {head->write_pos= head->write_end- 500;});
4472   print_query_header(head, print_event_info);
4473   my_b_write(head, (uchar*) query, q_len);
4474   my_b_printf(head, "\n%s\n", print_event_info->delimiter);
4475 }
4476 #endif /* MYSQL_CLIENT */
4477 
4478 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4479 
4480 /**
4481    Associating slave Worker thread to a subset of temporary tables
4482    belonging to db-partitions the event accesses.
4483    The pointer if all entries is cleaned.
4484 
4485    @param thd   THD instance pointer
4486 */
attach_temp_tables_worker(THD * thd)4487 void Query_log_event::attach_temp_tables_worker(THD *thd)
4488 {
4489   if (!is_mts_worker(thd) || (ends_group() || starts_group()))
4490     return;
4491 
4492   // in over max-db:s case just one special partition is locked
4493   int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4494               1 : mts_accessed_dbs);
4495 
4496   DBUG_ASSERT(!thd->temporary_tables);
4497 
4498   for (int i= 0; i < parts; i++)
4499   {
4500     mts_move_temp_tables_to_thd(thd,
4501                                 mts_assigned_partitions[i]->temporary_tables);
4502     mts_assigned_partitions[i]->temporary_tables= NULL;
4503   }
4504 }
4505 
4506 /**
4507    Dissociating slave Worker thread from its thd->temporary_tables
4508    to possibly update the involved entries of db-to-worker hash
4509    with new values of temporary_tables.
4510 
4511    @param thd   THD instance pointer
4512 */
detach_temp_tables_worker(THD * thd)4513 void Query_log_event::detach_temp_tables_worker(THD *thd)
4514 {
4515   if (!is_mts_worker(thd))
4516     return;
4517 
4518   int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4519               1 : mts_accessed_dbs);
4520   /*
4521     todo: optimize for a case of
4522 
4523     a. one db
4524        Only detaching temporary_tables from thd to entry would require
4525        instead of the double-loop below.
4526 
4527     b. unchanged thd->temporary_tables.
4528        In such case the involved entries would continue to hold the
4529        unmodified lists provided that the attach_ method does not
4530        destroy references to them.
4531   */
4532   for (int i= 0; i < parts; i++)
4533   {
4534     mts_assigned_partitions[i]->temporary_tables= NULL;
4535   }
4536 
4537   for (TABLE *table= thd->temporary_tables; table;)
4538   {
4539     int i;
4540     char *db_name= NULL;
4541 
4542     // find which entry to go
4543     for (i= 0; i < parts; i++)
4544     {
4545       db_name= mts_accessed_db_names[i];
4546 
4547       if (!strlen(db_name))
4548         break;
4549 
4550       // Only default database is rewritten.
4551       if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
4552       {
4553         size_t dummy_len;
4554         const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
4555         // db_name != db_filtered means that db_name is rewritten.
4556         if (strcmp(db_name, db_filtered))
4557           db_name= (char*)db_filtered;
4558       }
4559 
4560       if (strcmp(table->s->db.str, db_name) < 0)
4561         continue;
4562       else
4563       {
4564         // When rewrite db rules are used we can not rely on
4565         // mts_accessed_db_names elements order.
4566         if (!rpl_filter->is_rewrite_empty() &&
4567             strcmp(table->s->db.str, db_name))
4568           continue;
4569         else
4570           break;
4571       }
4572     }
4573 
4574     DBUG_ASSERT(db_name && (
4575                 !strcmp(table->s->db.str, db_name) ||
4576                 !strlen(db_name))
4577                 );
4578     DBUG_ASSERT(i < mts_accessed_dbs);
4579 
4580     // table pointer is shifted inside the function
4581     table= mts_move_temp_table_to_entry(table, thd, mts_assigned_partitions[i]);
4582   }
4583 
4584   DBUG_ASSERT(!thd->temporary_tables);
4585 #ifndef DBUG_OFF
4586   for (int i= 0; i < parts; i++)
4587   {
4588     DBUG_ASSERT(!mts_assigned_partitions[i]->temporary_tables ||
4589                 !mts_assigned_partitions[i]->temporary_tables->prev);
4590   }
4591 #endif
4592 }
4593 
4594 /*
4595   Query_log_event::do_apply_event()
4596 */
do_apply_event(Relay_log_info const * rli)4597 int Query_log_event::do_apply_event(Relay_log_info const *rli)
4598 {
4599   return do_apply_event(rli, query, q_len);
4600 }
4601 
4602 /*
4603   is_silent_error
4604 
4605   Return true if the thread has an error which should be
4606   handled silently
4607 */
4608 
is_silent_error(THD * thd)4609 static bool is_silent_error(THD* thd)
4610 {
4611   DBUG_ENTER("is_silent_error");
4612   Diagnostics_area::Sql_condition_iterator it=
4613     thd->get_stmt_da()->sql_conditions();
4614   const Sql_condition *err;
4615   while ((err= it++))
4616   {
4617     DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
4618                         err->get_message_text()));
4619     switch (err->get_sql_errno())
4620     {
4621     case ER_SLAVE_SILENT_RETRY_TRANSACTION:
4622     {
4623       DBUG_RETURN(true);
4624     }
4625     default:
4626       break;
4627     }
4628   }
4629   DBUG_RETURN(false);
4630 }
4631 
4632 /**
4633   @todo
4634   Compare the values of "affected rows" around here. Something
4635   like:
4636   @code
4637      if ((uint32) affected_in_event != (uint32) affected_on_slave)
4638      {
4639      sql_print_error("Slave: did not get the expected number of affected \
4640      rows running query from master - expected %d, got %d (this numbers \
4641      should have matched modulo 4294967296).", 0, ...);
4642      thd->query_error = 1;
4643      }
4644   @endcode
4645   We may also want an option to tell the slave to ignore "affected"
4646   mismatch. This mismatch could be implemented with a new ER_ code, and
4647   to ignore it you would use --slave-skip-errors...
4648 */
do_apply_event(Relay_log_info const * rli,const char * query_arg,uint32 q_len_arg)4649 int Query_log_event::do_apply_event(Relay_log_info const *rli,
4650                                       const char *query_arg, uint32 q_len_arg)
4651 {
4652   DBUG_ENTER("Query_log_event::do_apply_event");
4653   int expected_error,actual_error= 0;
4654   HA_CREATE_INFO db_options;
4655 
4656   /*
4657     Colleagues: please never free(thd->catalog) in MySQL. This would
4658     lead to bugs as here thd->catalog is a part of an alloced block,
4659     not an entire alloced block (see
4660     Query_log_event::do_apply_event()). Same for thd->db.  Thank
4661     you.
4662   */
4663   thd->catalog= catalog_len ? (char *) catalog : (char *)"";
4664 
4665   size_t valid_len;
4666   bool len_error;
4667   bool is_invalid_db_name= validate_string(system_charset_info, db, db_len,
4668                                            &valid_len, &len_error);
4669 
4670   DBUG_PRINT("debug",("is_invalid_db_name= %s, valid_len=%zu, len_error=%s",
4671                       is_invalid_db_name ? "true" : "false",
4672                       valid_len,
4673                       len_error ? "true" : "false"));
4674 
4675   if (is_invalid_db_name || len_error)
4676   {
4677     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4678                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4679                 "Invalid database name in Query event.");
4680     thd->is_slave_error= true;
4681     goto end;
4682   }
4683 
4684   set_thd_db(thd, db, db_len);
4685 
4686   /*
4687     Setting the character set and collation of the current database thd->db.
4688    */
4689   load_db_opt_by_name(thd, thd->db, &db_options);
4690   if (db_options.default_table_charset)
4691     thd->db_charset= db_options.default_table_charset;
4692   thd->variables.auto_increment_increment= auto_increment_increment;
4693   thd->variables.auto_increment_offset=    auto_increment_offset;
4694 
4695   /*
4696     InnoDB internally stores the master log position it has executed so far,
4697     i.e. the position just after the COMMIT event.
4698     When InnoDB will want to store, the positions in rli won't have
4699     been updated yet, so group_master_log_* will point to old BEGIN
4700     and event_master_log* will point to the beginning of current COMMIT.
4701     But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
4702     END of the current log event (COMMIT). We save it in rli so that InnoDB can
4703     access it.
4704   */
4705   const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
4706   DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
4707 
4708   /*
4709     todo: such cleanup should not be specific to Query event and therefore
4710           is preferable at a common with other event pre-execution point
4711   */
4712   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4713   if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock != NULL)
4714   {
4715     /*
4716       Cleaning-up the last statement context:
4717       the terminal event of the current statement flagged with
4718       STMT_END_F got filtered out in ndb circular replication.
4719     */
4720     int error;
4721     char llbuff[22];
4722     if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
4723     {
4724       const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
4725                   "Error in cleaning up after an event preceeding the commit; "
4726                   "the group log file/position: %s %s",
4727                   const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
4728                   llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
4729                         llbuff));
4730     }
4731     /*
4732       Executing a part of rli->stmt_done() logics that does not deal
4733       with group position change. The part is redundant now but is
4734       future-change-proof addon, e.g if COMMIT handling will start checking
4735       invariants like IN_STMT flag must be off at committing the transaction.
4736     */
4737     const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
4738     const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
4739   }
4740   else
4741   {
4742     const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
4743   }
4744 
4745   /*
4746     Note:   We do not need to execute reset_one_shot_variables() if this
4747             db_ok() test fails.
4748     Reason: The db stored in binlog events is the same for SET and for
4749             its companion query.  If the SET is ignored because of
4750             db_ok(), the companion query will also be ignored, and if
4751             the companion query is ignored in the db_ok() test of
4752             ::do_apply_event(), then the companion SET also have so
4753             we don't need to reset_one_shot_variables().
4754   */
4755   {
4756     thd->set_time(&when);
4757     thd->set_query_and_id((char*)query_arg, q_len_arg,
4758                           thd->charset(), next_query_id());
4759     thd->set_query_for_display(query_arg, q_len_arg);
4760     thd->variables.pseudo_thread_id= thread_id;		// for temp tables
4761     attach_temp_tables_worker(thd);
4762     DBUG_PRINT("query",("%s", thd->query()));
4763 
4764     if (ignored_error_code((expected_error= error_code)) ||
4765 	!unexpected_error_code(expected_error))
4766     {
4767       if (flags2_inited)
4768         /*
4769           all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
4770           must take their value from flags2.
4771         */
4772         thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
4773       /*
4774         else, we are in a 3.23/4.0 binlog; we previously received a
4775         Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
4776         nothing to do.
4777       */
4778       /*
4779         We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
4780         slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
4781         force us to ignore the dir too. Imagine you are a ring of machines, and
4782         one has a disk problem so that you temporarily need
4783         MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
4784         elsewhere (you don't want all slaves to start ignoring the dirs).
4785       */
4786       if (sql_mode_inited)
4787         thd->variables.sql_mode=
4788           (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
4789                        (sql_mode & ~(ulonglong) MODE_NO_DIR_IN_CREATE));
4790       if (charset_inited)
4791       {
4792         if (rli->cached_charset_compare(charset))
4793         {
4794           char *charset_p= charset; // Avoid type-punning warning.
4795           /* Verify that we support the charsets found in the event. */
4796           if (!(thd->variables.character_set_client=
4797                 get_charset(uint2korr(charset_p), MYF(MY_WME))) ||
4798               !(thd->variables.collation_connection=
4799                 get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
4800               !(thd->variables.collation_server=
4801                 get_charset(uint2korr(charset+4), MYF(MY_WME))))
4802           {
4803             /*
4804               We updated the thd->variables with nonsensical values (0). Let's
4805               set them to something safe (i.e. which avoids crash), and we'll
4806               stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
4807               ignore this error).
4808             */
4809             set_slave_thread_default_charset(thd, rli);
4810             goto compare_errors;
4811           }
4812           thd->update_charset(); // for the charset change to take effect
4813           /*
4814             Reset thd->query_string.cs to the newly set value.
4815             Note, there is a small flaw here. For a very short time frame
4816             if the new charset is different from the old charset and
4817             if another thread executes "SHOW PROCESSLIST" after
4818             the above thd->set_query_and_id() and before this thd->set_query(),
4819             and if the current query has some non-ASCII characters,
4820             the another thread may see some '?' marks in the PROCESSLIST
4821             result. This should be acceptable now. This is a reminder
4822             to fix this if any refactoring happens here sometime.
4823           */
4824           thd->set_query((char*) query_arg, q_len_arg, thd->charset());
4825           thd->reset_query_for_display();
4826         }
4827       }
4828       if (time_zone_len)
4829       {
4830         String tmp(time_zone_str, time_zone_len, &my_charset_bin);
4831         if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
4832         {
4833           my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
4834           thd->variables.time_zone= global_system_variables.time_zone;
4835           goto compare_errors;
4836         }
4837       }
4838       if (lc_time_names_number)
4839       {
4840         if (!(thd->variables.lc_time_names=
4841               my_locale_by_number(lc_time_names_number)))
4842         {
4843           my_printf_error(ER_UNKNOWN_ERROR,
4844                       "Unknown locale: '%d'", MYF(0), lc_time_names_number);
4845           thd->variables.lc_time_names= &my_locale_en_US;
4846           goto compare_errors;
4847         }
4848       }
4849       else
4850         thd->variables.lc_time_names= &my_locale_en_US;
4851       if (charset_database_number)
4852       {
4853         CHARSET_INFO *cs;
4854         if (!(cs= get_charset(charset_database_number, MYF(0))))
4855         {
4856           char buf[20];
4857           int10_to_str((int) charset_database_number, buf, -10);
4858           my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
4859           goto compare_errors;
4860         }
4861         thd->variables.collation_database= cs;
4862       }
4863       else
4864         thd->variables.collation_database= thd->db_charset;
4865 
4866       {
4867         const CHARSET_INFO *cs= thd->charset();
4868         /*
4869           We cannot ask for parsing a statement using a character set
4870           without state_maps (parser internal data).
4871         */
4872         if (!cs->state_map)
4873         {
4874           rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4875                       ER_THD(thd, ER_SLAVE_FATAL_ERROR),
4876                       "character_set cannot be parsed");
4877           thd->is_slave_error= true;
4878           goto end;
4879         }
4880       }
4881 
4882       thd->table_map_for_update= (table_map)table_map_for_update;
4883       thd->set_invoker(&user, &host);
4884       /*
4885         Flag if we need to rollback the statement transaction on
4886         slave if it by chance succeeds.
4887         If we expected a non-zero error code and get nothing and,
4888         it is a concurrency issue or ignorable issue, effects
4889         of the statement should be rolled back.
4890       */
4891       if (expected_error &&
4892           (ignored_error_code(expected_error) ||
4893            concurrency_error_code(expected_error)))
4894       {
4895         thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
4896       }
4897       /* Execute the query (note that we bypass dispatch_command()) */
4898       Parser_state parser_state;
4899       if (!parser_state.init(thd, thd->query(), thd->query_length()))
4900       {
4901         DBUG_ASSERT(thd->m_digest == NULL);
4902         thd->m_digest= & thd->m_digest_state;
4903         DBUG_ASSERT(thd->m_statement_psi == NULL);
4904         thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
4905                                                     stmt_info_rpl.m_key,
4906                                                     thd->db, thd->db_length,
4907                                                     thd->charset());
4908         THD_STAGE_INFO(thd, stage_init);
4909         if (thd->m_digest != NULL)
4910           thd->m_digest->reset(thd->m_token_array, max_digest_length);
4911 
4912         mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
4913         /* Finalize server status flags after executing a statement. */
4914         thd->update_server_status();
4915         log_slow_statement(thd);
4916       }
4917 
4918       thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
4919 
4920       /*
4921         Resetting the enable_slow_log thd variable.
4922 
4923         We need to reset it back to the opt_log_slow_slave_statements
4924         value after the statement execution (and slow logging
4925         is done). It might have changed if the statement was an
4926         admin statement (in which case, down in mysql_parse execution
4927         thd->enable_slow_log is set to the value of
4928         opt_log_slow_admin_statements).
4929       */
4930       thd->enable_slow_log= opt_log_slow_slave_statements;
4931     }
4932     else
4933     {
4934       /*
4935         The query got a really bad error on the master (thread killed etc),
4936         which could be inconsistent. Parse it to test the table names: if the
4937         replicate-*-do|ignore-table rules say "this query must be ignored" then
4938         we exit gracefully; otherwise we warn about the bad error and tell DBA
4939         to check/fix it.
4940       */
4941       if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
4942         clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
4943       else
4944       {
4945         rli->report(ERROR_LEVEL, expected_error,
4946 #ifdef WITH_WSREP
4947                           "\
4948 Query partially completed on the master (error on master: %d) \
4949 and was aborted. There is a chance that your master is inconsistent at this \
4950 point. If you are sure that your master is ok, run this query manually on the \
4951 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4952 START SLAVE; . Query: '%s'", expected_error,
4953         (!opt_log_raw) && thd->rewritten_query.length()
4954           ? thd->rewritten_query.c_ptr_safe() : thd->query());
4955 #else
4956                           "\
4957 Query partially completed on the master (error on master: %d) \
4958 and was aborted. There is a chance that your master is inconsistent at this \
4959 point. If you are sure that your master is ok, run this query manually on the \
4960 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4961 START SLAVE; . Query: '%s'", expected_error, thd->query());
4962 #endif /* WITH_WSREP */
4963         thd->is_slave_error= 1;
4964       }
4965       goto end;
4966     }
4967 
4968     /* If the query was not ignored, it is printed to the general log */
4969     if (!thd->is_error() || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
4970     {
4971       /* log the rewritten query if the query was rewritten
4972          and the option to log raw was not set.
4973 
4974          There is an assumption here. We assume that query log
4975          events can never have multi-statement queries, thus the
4976          parsed statement is the same as the raw one.
4977        */
4978       if (opt_log_raw || thd->rewritten_query.length() == 0)
4979         general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
4980       else
4981         general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
4982                                           thd->rewritten_query.length());
4983     }
4984 
4985 compare_errors:
4986     /*
4987       In the slave thread, we may sometimes execute some DROP / * 40005
4988       TEMPORARY * / TABLE that come from parts of binlogs (likely if we
4989       use RESET SLAVE or CHANGE MASTER TO), while the temporary table
4990       has already been dropped. To ignore such irrelevant "table does
4991       not exist errors", we silently clear the error if TEMPORARY was used.
4992     */
4993     if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
4994         thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
4995         !expected_error)
4996       thd->get_stmt_da()->reset_diagnostics_area();
4997     /*
4998       If we expected a non-zero error code, and we don't get the same error
4999       code, and it should be ignored or is related to a concurrency issue.
5000     */
5001     actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
5002     DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
5003                        expected_error, actual_error));
5004 
5005     /*
5006       If a statement with expected error is received on slave and if the
5007       statement is not filtered on the slave, only then compare the expected
5008       error with the actual error that happened on slave.
5009     */
5010     if ((expected_error && rpl_filter->db_ok(thd->db) &&
5011          expected_error != actual_error &&
5012          !concurrency_error_code(expected_error)) &&
5013         !ignored_error_code(actual_error) &&
5014         !ignored_error_code(expected_error))
5015     {
5016       rli->report(ERROR_LEVEL, 0,
5017                       "\
5018 Query caused different errors on master and slave.     \
5019 Error on master: message (format)='%s' error code=%d ; \
5020 Error on slave: actual message='%s', error code=%d. \
5021 Default database: '%s'. Query: '%s'",
5022                       ER_SAFE(expected_error),
5023                       expected_error,
5024                       actual_error ? thd->get_stmt_da()->message() : "no error",
5025                       actual_error,
5026 #ifdef WITH_WSREP
5027                       print_slave_db_safe(db),
5028                   (!opt_log_raw) && thd->rewritten_query.length()
5029                   ? thd->rewritten_query.c_ptr_safe() : query_arg);
5030 #else
5031                       print_slave_db_safe(db), query_arg);
5032 #endif /* WITH_WSREP */
5033       thd->is_slave_error= 1;
5034     }
5035     /*
5036       If we get the same error code as expected and it is not a concurrency
5037       issue, or should be ignored.
5038     */
5039     else if ((expected_error == actual_error &&
5040               !concurrency_error_code(expected_error)) ||
5041              ignored_error_code(actual_error))
5042     {
5043       DBUG_PRINT("info",("error ignored"));
5044       if (actual_error && log_warnings > 1 && ignored_error_code(actual_error))
5045       {
5046         if (actual_error == ER_SLAVE_IGNORED_TABLE)
5047         {
5048           if (!slave_ignored_err_throttle.log(thd))
5049             rli->report(WARNING_LEVEL, actual_error,
5050                         "Could not execute %s event. Detailed error: %s;"
5051                         " Error log throttle is enabled. This error will not be"
5052                         " displayed for next %lu secs. It will be suppressed",
5053                         get_type_str(), thd->get_stmt_da()->message(),
5054                         (window_size / 1000000));
5055         }
5056         else
5057           rli->report(WARNING_LEVEL, actual_error,
5058                       "Could not execute %s event. Detailed error: %s;",
5059                       get_type_str(), thd->get_stmt_da()->message());
5060       }
5061       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
5062       thd->killed= THD::NOT_KILLED;
5063     }
5064     /*
5065       Other cases: mostly we expected no error and get one.
5066     */
5067     else if (thd->is_slave_error || thd->is_fatal_error)
5068     {
5069       if (!is_silent_error(thd))
5070       {
5071         rli->report(ERROR_LEVEL, actual_error,
5072                     "Error '%s' on query. Default database: '%s'. Query: '%s'",
5073                     (actual_error ? thd->get_stmt_da()->message() :
5074                      "unexpected success or fatal error"),
5075 #ifdef WITH_WSREP
5076                       print_slave_db_safe(thd->db),
5077                   (!opt_log_raw) && thd->rewritten_query.length()
5078                   ? thd->rewritten_query.c_ptr_safe() : query_arg);
5079 #else
5080                     print_slave_db_safe(thd->db), query_arg);
5081 #endif /* WITH_WSREP */
5082       }
5083       thd->is_slave_error= 1;
5084     }
5085 
5086     /*
5087       TODO: compare the values of "affected rows" around here. Something
5088       like:
5089       if ((uint32) affected_in_event != (uint32) affected_on_slave)
5090       {
5091       sql_print_error("Slave: did not get the expected number of affected \
5092       rows running query from master - expected %d, got %d (this numbers \
5093       should have matched modulo 4294967296).", 0, ...);
5094       thd->is_slave_error = 1;
5095       }
5096       We may also want an option to tell the slave to ignore "affected"
5097       mismatch. This mismatch could be implemented with a new ER_ code, and
5098       to ignore it you would use --slave-skip-errors...
5099 
5100       To do the comparison we need to know the value of "affected" which the
5101       above mysql_parse() computed. And we need to know the value of
5102       "affected" in the master's binlog. Both will be implemented later. The
5103       important thing is that we now have the format ready to log the values
5104       of "affected" in the binlog. So we can release 5.0.0 before effectively
5105       logging "affected" and effectively comparing it.
5106     */
5107   } /* End of if (db_ok(... */
5108 
5109   {
5110     /**
5111       The following failure injecion works in cooperation with tests
5112       setting @@global.debug= 'd,stop_slave_middle_group'.
5113       The sql thread receives the killed status and will proceed
5114       to shutdown trying to finish incomplete events group.
5115     */
5116 
5117     // TODO: address the middle-group killing in MTS case
5118 
5119     DBUG_EXECUTE_IF("stop_slave_middle_group",
5120                     if (strcmp("COMMIT", query) != 0 &&
5121                         strcmp("BEGIN", query) != 0)
5122                     {
5123                       if (thd->transaction.all.cannot_safely_rollback())
5124                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;
5125                     };);
5126   }
5127 
5128 end:
5129 
5130   if (thd->temporary_tables)
5131     detach_temp_tables_worker(thd);
5132   /*
5133     Probably we have set thd->query, thd->db, thd->catalog to point to places
5134     in the data_buf of this event. Now the event is going to be deleted
5135     probably, so data_buf will be freed, so the thd->... listed above will be
5136     pointers to freed memory.
5137     So we must set them to 0, so that those bad pointers values are not later
5138     used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
5139     don't suffer from these assignments to 0 as DROP TEMPORARY
5140     TABLE uses the db.table syntax.
5141   */
5142   thd->catalog= 0;
5143   thd->set_db(NULL, 0);                 /* will free the current database */
5144   thd->reset_query();
5145   thd->lex->sql_command= SQLCOM_END;
5146   DBUG_PRINT("info", ("end: query= 0"));
5147 
5148   /* Mark the statement completed. */
5149   MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
5150   thd->m_statement_psi= NULL;
5151   thd->m_digest= NULL;
5152 
5153   /*
5154     As a disk space optimization, future masters will not log an event for
5155     LAST_INSERT_ID() if that function returned 0 (and thus they will be able
5156     to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
5157     variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
5158     resetting below we are ready to support that.
5159   */
5160   thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
5161   thd->first_successful_insert_id_in_prev_stmt= 0;
5162   thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
5163   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
5164   DBUG_RETURN(thd->is_slave_error);
5165 }
5166 
do_update_pos(Relay_log_info * rli)5167 int Query_log_event::do_update_pos(Relay_log_info *rli)
5168 {
5169   /*
5170     Note that we will not increment group* positions if we are just
5171     after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
5172     from its following updating query.
5173   */
5174   int ret= 0;
5175   if (thd->one_shot_set)
5176   {
5177     rli->inc_event_relay_log_pos();
5178   }
5179   else
5180     ret= Log_event::do_update_pos(rli);
5181 
5182   DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
5183        if (!strcmp("COMMIT", query))
5184        {
5185          sql_print_information("Crashing crash_after_commit_and_update_pos.");
5186          rli->flush_info(true);
5187          ha_flush_logs(0);
5188          DBUG_SUICIDE();
5189        }
5190   );
5191 
5192   return ret;
5193 }
5194 
5195 
5196 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5197 Query_log_event::do_shall_skip(Relay_log_info *rli)
5198 {
5199   DBUG_ENTER("Query_log_event::do_shall_skip");
5200   DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
5201   DBUG_ASSERT(query && q_len > 0);
5202 
5203   if (rli->slave_skip_counter > 0)
5204   {
5205     if (strcmp("BEGIN", query) == 0)
5206     {
5207       thd->variables.option_bits|= OPTION_BEGIN;
5208       DBUG_RETURN(Log_event::continue_group(rli));
5209     }
5210 
5211     if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
5212     {
5213       thd->variables.option_bits&= ~OPTION_BEGIN;
5214       DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5215     }
5216   }
5217   DBUG_RETURN(Log_event::do_shall_skip(rli));
5218 }
5219 
5220 #endif
5221 
5222 
5223 /**************************************************************************
5224 	Start_log_event_v3 methods
5225 **************************************************************************/
5226 
5227 #ifndef MYSQL_CLIENT
Start_log_event_v3()5228 Start_log_event_v3::Start_log_event_v3()
5229   :Log_event(), created(0), binlog_version(BINLOG_VERSION),
5230    dont_set_created(0)
5231 {
5232   memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5233 }
5234 #endif
5235 
5236 /*
5237   Start_log_event_v3::pack_info()
5238 */
5239 
5240 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)5241 int Start_log_event_v3::pack_info(Protocol *protocol)
5242 {
5243   char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5244   pos= strmov(buf, "Server ver: ");
5245   pos= strmov(pos, server_version);
5246   pos= strmov(pos, ", Binlog ver: ");
5247   pos= int10_to_str(binlog_version, pos, 10);
5248   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5249   return 0;
5250 }
5251 #endif
5252 
5253 
5254 /*
5255   Start_log_event_v3::print()
5256 */
5257 
5258 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)5259 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5260 {
5261   DBUG_ENTER("Start_log_event_v3::print");
5262 
5263   IO_CACHE *const head= &print_event_info->head_cache;
5264 
5265   if (!print_event_info->short_form)
5266   {
5267     print_header(head, print_event_info, FALSE);
5268     my_b_printf(head, "\tStart: binlog v %d, server v %s created ",
5269                 binlog_version, server_version);
5270     print_timestamp(head, NULL);
5271     if (created)
5272       my_b_printf(head," at startup");
5273     my_b_printf(head, "\n");
5274     if (flags & LOG_EVENT_BINLOG_IN_USE_F)
5275       my_b_printf(head, "# Warning: this binlog is either in use or was not "
5276                   "closed properly.\n");
5277   }
5278   if (!is_artificial_event() && created)
5279   {
5280 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5281     /*
5282       This is for mysqlbinlog: like in replication, we want to delete the stale
5283       tmp files left by an unclean shutdown of mysqld (temporary tables)
5284       and rollback unfinished transaction.
5285       Probably this can be done with RESET CONNECTION (syntax to be defined).
5286     */
5287     my_b_printf(head,"RESET CONNECTION%s\n", print_event_info->delimiter);
5288 #else
5289     my_b_printf(head,"ROLLBACK%s\n", print_event_info->delimiter);
5290     if (print_event_info->is_gtid_next_set)
5291       print_event_info->is_gtid_next_valid= false;
5292 #endif
5293   }
5294   // set gtid_next=automatic if we have previously set it to uuid:number
5295   if (!print_event_info->is_gtid_next_valid)
5296   {
5297     my_b_printf(head, "%sAUTOMATIC'%s\n",
5298                 Gtid_log_event::SET_STRING_PREFIX,
5299                 print_event_info->delimiter);
5300     print_event_info->is_gtid_next_set= false;
5301     print_event_info->is_gtid_next_valid= true;
5302   }
5303   if (temp_buf &&
5304       print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5305       !print_event_info->short_form)
5306   {
5307     if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
5308       my_b_printf(head, "BINLOG '\n");
5309     print_base64(head, print_event_info, FALSE);
5310     print_event_info->printed_fd_event= TRUE;
5311   }
5312   DBUG_VOID_RETURN;
5313 }
5314 #endif /* MYSQL_CLIENT */
5315 
5316 /*
5317   Start_log_event_v3::Start_log_event_v3()
5318 */
5319 
Start_log_event_v3(const char * buf,uint event_len,const Format_description_log_event * description_event)5320 Start_log_event_v3::Start_log_event_v3(const char* buf, uint event_len,
5321                                        const Format_description_log_event
5322                                        *description_event)
5323   :Log_event(buf, description_event), binlog_version(BINLOG_VERSION)
5324 {
5325   if (event_len < (uint)description_event->common_header_len +
5326       ST_COMMON_HEADER_LEN_OFFSET)
5327   {
5328     server_version[0]= 0;
5329     return;
5330   }
5331   buf+= description_event->common_header_len;
5332   binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
5333   memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
5334 	 ST_SERVER_VER_LEN);
5335   // prevent overrun if log is corrupted on disk
5336   server_version[ST_SERVER_VER_LEN-1]= 0;
5337   created= uint4korr(buf+ST_CREATED_OFFSET);
5338   dont_set_created= 1;
5339 }
5340 
5341 
5342 /*
5343   Start_log_event_v3::write()
5344 */
5345 
5346 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5347 bool Start_log_event_v3::write(IO_CACHE* file)
5348 {
5349   char buff[START_V3_HEADER_LEN];
5350   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5351   memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5352   if (!dont_set_created)
5353     created= get_time();
5354   int4store(buff + ST_CREATED_OFFSET,created);
5355   return (write_header(file, sizeof(buff)) ||
5356           wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
5357 	  write_footer(file));
5358 }
5359 #endif
5360 
5361 
5362 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5363 
5364 /**
5365   Start_log_event_v3::do_apply_event() .
5366   The master started
5367 
5368     IMPLEMENTATION
5369     - To handle the case where the master died without having time to write
5370     DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
5371     TODO), we clean up all temporary tables that we got, if we are sure we
5372     can (see below).
5373 
5374   @todo
5375     - Remove all active user locks.
5376     Guilhem 2003-06: this is true but not urgent: the worst it can cause is
5377     the use of a bit of memory for a user lock which will not be used
5378     anymore. If the user lock is later used, the old one will be released. In
5379     other words, no deadlock problem.
5380 */
5381 
do_apply_event(Relay_log_info const * rli)5382 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
5383 {
5384   DBUG_ENTER("Start_log_event_v3::do_apply_event");
5385   int error= 0;
5386   switch (binlog_version)
5387   {
5388   case 3:
5389   case 4:
5390     /*
5391       This can either be 4.x (then a Start_log_event_v3 is only at master
5392       startup so we are sure the master has restarted and cleared his temp
5393       tables; the event always has 'created'>0) or 5.0 (then we have to test
5394       'created').
5395     */
5396     if (created)
5397     {
5398       error= close_temporary_tables(thd);
5399       cleanup_load_tmpdir();
5400     }
5401     else
5402     {
5403       /*
5404         Set all temporary tables thread references to the current thread
5405         as they may point to the "old" SQL slave thread in case of its
5406         restart.
5407       */
5408       TABLE *table;
5409       for (table= thd->temporary_tables; table; table= table->next)
5410         table->in_use= thd;
5411     }
5412     break;
5413 
5414     /*
5415        Now the older formats; in that case load_tmpdir is cleaned up by the I/O
5416        thread.
5417     */
5418   case 1:
5419     if (strncmp(rli->get_rli_description_event()->server_version,
5420                 "3.23.57",7) >= 0 && created)
5421     {
5422       /*
5423         Can distinguish, based on the value of 'created': this event was
5424         generated at master startup.
5425       */
5426       error= close_temporary_tables(thd);
5427     }
5428     /*
5429       Otherwise, can't distinguish a Start_log_event generated at
5430       master startup and one generated by master FLUSH LOGS, so cannot
5431       be sure temp tables have to be dropped. So do nothing.
5432     */
5433     break;
5434   default:
5435     /*
5436       This case is not expected. It can be either an event corruption or an
5437       unsupported binary log version.
5438     */
5439     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5440                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
5441                 "Binlog version not supported");
5442     DBUG_RETURN(1);
5443   }
5444   DBUG_RETURN(error);
5445 }
5446 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5447 
5448 /***************************************************************************
5449        Format_description_log_event methods
5450 ****************************************************************************/
5451 
5452 /**
5453   Format_description_log_event 1st ctor.
5454 
5455     Ctor. Can be used to create the event to write to the binary log (when the
5456     server starts or when FLUSH LOGS), or to create artificial events to parse
5457     binlogs from MySQL 3.23 or 4.x.
5458     When in a client, only the 2nd use is possible.
5459 
5460   @param binlog_version         the binlog version for which we want to build
5461                                 an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
5462                                 x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
5463                                 old 4.0 (binlog version 2) is not supported;
5464                                 it should not be used for replication with
5465                                 5.0.
5466   @param server_ver             a string containing the server version.
5467 */
5468 
5469 Format_description_log_event::
Format_description_log_event(uint8 binlog_ver,const char * server_ver)5470 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
5471   :Start_log_event_v3(), event_type_permutation(0)
5472 {
5473   binlog_version= binlog_ver;
5474   switch (binlog_ver) {
5475   case 4: /* MySQL 5.0 */
5476     memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5477     DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
5478                     strmov(server_version, "5.0.34"););
5479     common_header_len= LOG_EVENT_HEADER_LEN;
5480     number_of_event_types= LOG_EVENT_TYPES;
5481     /* we'll catch my_malloc() error in is_valid() */
5482     post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
5483                                        + BINLOG_CHECKSUM_ALG_DESC_LEN,
5484                                        MYF(0));
5485     /*
5486       This long list of assignments is not beautiful, but I see no way to
5487       make it nicer, as the right members are #defines, not array members, so
5488       it's impossible to write a loop.
5489     */
5490     if (post_header_len)
5491     {
5492 #ifndef DBUG_OFF
5493       // Allows us to sanity-check that all events initialized their
5494       // events (see the end of this 'if' block).
5495       memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
5496 #endif
5497 
5498       /* Note: all event types must explicitly fill in their lengths here. */
5499       post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5500       post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
5501       post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
5502       post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
5503       post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
5504       post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5505       post_header_len[SLAVE_EVENT-1]= 0;   /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5506       post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5507       post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5508       post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5509       post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5510       post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
5511       post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
5512       post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
5513       post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
5514       post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
5515       post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
5516       post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
5517       /*
5518         The PRE_GA events are never be written to any binlog, but
5519         their lengths are included in Format_description_log_event.
5520         Hence, we need to be assign some value here, to avoid reading
5521         uninitialized memory when the array is written to disk.
5522       */
5523       post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
5524       post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
5525       post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
5526 
5527       post_header_len[TABLE_MAP_EVENT-1]=       TABLE_MAP_HEADER_LEN;
5528       post_header_len[WRITE_ROWS_EVENT_V1-1]=   ROWS_HEADER_LEN_V1;
5529       post_header_len[UPDATE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
5530       post_header_len[DELETE_ROWS_EVENT_V1-1]=  ROWS_HEADER_LEN_V1;
5531       /*
5532         We here have the possibility to simulate a master of before we changed
5533         the table map id to be stored in 6 bytes: when it was stored in 4
5534         bytes (=> post_header_len was 6). This is used to test backward
5535         compatibility.
5536         This code can be removed after a few months (today is Dec 21st 2005),
5537         when we know that the 4-byte masters are not deployed anymore (check
5538         with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
5539         too.
5540       */
5541       DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5542                       post_header_len[TABLE_MAP_EVENT-1]=
5543                       post_header_len[WRITE_ROWS_EVENT_V1-1]=
5544                       post_header_len[UPDATE_ROWS_EVENT_V1-1]=
5545                       post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
5546       post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
5547       post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
5548       post_header_len[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5549       post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5550       post_header_len[WRITE_ROWS_EVENT-1]=  ROWS_HEADER_LEN_V2;
5551       post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5552       post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5553       post_header_len[GTID_LOG_EVENT-1]=
5554         post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]=
5555         Gtid_log_event::POST_HEADER_LENGTH;
5556       post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5557 
5558       // Sanity-check that all post header lengths are initialized.
5559       int i;
5560       for (i=0; i<number_of_event_types; i++)
5561         DBUG_ASSERT(post_header_len[i] != 255);
5562     }
5563     break;
5564 
5565   case 1: /* 3.23 */
5566   case 3: /* 4.0.x x>=2 */
5567     /*
5568       We build an artificial (i.e. not sent by the master) event, which
5569       describes what those old master versions send.
5570     */
5571     if (binlog_ver==1)
5572       strmov(server_version, server_ver ? server_ver : "3.23");
5573     else
5574       strmov(server_version, server_ver ? server_ver : "4.0");
5575     common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
5576       LOG_EVENT_MINIMAL_HEADER_LEN;
5577     /*
5578       The first new event in binlog version 4 is Format_desc. So any event type
5579       after that does not exist in older versions. We use the events known by
5580       version 3, even if version 1 had only a subset of them (this is not a
5581       problem: it uses a few bytes for nothing but unifies code; it does not
5582       make the slave detect less corruptions).
5583     */
5584     number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
5585     post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
5586                                        MYF(0));
5587     if (post_header_len)
5588     {
5589       post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5590       post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
5591       post_header_len[STOP_EVENT-1]= 0;
5592       post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
5593       post_header_len[INTVAR_EVENT-1]= 0;
5594       post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5595       post_header_len[SLAVE_EVENT-1]= 0;  /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5596       post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5597       post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5598       post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5599       post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5600       post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
5601       post_header_len[RAND_EVENT-1]= 0;
5602       post_header_len[USER_VAR_EVENT-1]= 0;
5603     }
5604     break;
5605   default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
5606     post_header_len= 0; /* will make is_valid() fail */
5607     break;
5608   }
5609   calc_server_version_split();
5610   checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5611 }
5612 
5613 
5614 /**
5615   The problem with this constructor is that the fixed header may have a
5616   length different from this version, but we don't know this length as we
5617   have not read the Format_description_log_event which says it, yet. This
5618   length is in the post-header of the event, but we don't know where the
5619   post-header starts.
5620 
5621   So this type of event HAS to:
5622   - either have the header's length at the beginning (in the header, at a
5623   fixed position which will never be changed), not in the post-header. That
5624   would make the header be "shifted" compared to other events.
5625   - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
5626   versions, so that we know for sure.
5627 
5628   I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
5629   it is sent before Format_description_log_event).
5630 */
5631 
5632 Format_description_log_event::
Format_description_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)5633 Format_description_log_event(const char* buf,
5634                              uint event_len,
5635                              const
5636                              Format_description_log_event*
5637                              description_event)
5638   :Start_log_event_v3(buf, event_len, description_event),
5639    common_header_len(0), post_header_len(NULL), event_type_permutation(0)
5640 {
5641   ulong ver_calc;
5642   DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
5643   if (!Start_log_event_v3::is_valid())
5644     DBUG_VOID_RETURN; /* sanity check */
5645   buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
5646   if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
5647     DBUG_VOID_RETURN; /* sanity check */
5648   number_of_event_types=
5649     event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
5650   DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
5651                       common_header_len, number_of_event_types));
5652   /* If alloc fails, we'll detect it in is_valid() */
5653 
5654   post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
5655                                       number_of_event_types*
5656                                       sizeof(*post_header_len),
5657                                       MYF(0));
5658   calc_server_version_split();
5659   if ((ver_calc= get_version_product()) >= checksum_version_product)
5660   {
5661     /* the last bytes are the checksum alg desc and value (or value's room) */
5662     number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
5663     /*
5664       FD from the checksum-home version server (ver_calc ==
5665       checksum_version_product) must have
5666       number_of_event_types == LOG_EVENT_TYPES.
5667     */
5668     DBUG_ASSERT(ver_calc != checksum_version_product ||
5669                 number_of_event_types == LOG_EVENT_TYPES);
5670     checksum_alg= post_header_len[number_of_event_types];
5671   }
5672   else
5673   {
5674     checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5675   }
5676 
5677   /*
5678     In some previous versions, the events were given other event type
5679     id numbers than in the present version. When replicating from such
5680     a version, we therefore set up an array that maps those id numbers
5681     to the id numbers of the present server.
5682 
5683     If post_header_len is null, it means malloc failed, and is_valid
5684     will fail, so there is no need to do anything.
5685 
5686     The trees in which events have wrong id's are:
5687 
5688     mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
5689     mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
5690     mysql-5.1-wl2325-no-dd
5691 
5692     (this was found by grepping for two lines in sequence where the
5693     first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
5694     "TABLE_MAP_EVENT," in log_event.h in all trees)
5695 
5696     In these trees, the following server_versions existed since
5697     TABLE_MAP_EVENT was introduced:
5698 
5699     5.1.1-a_drop5p3   5.1.1-a_drop5p4        5.1.1-alpha
5700     5.1.2-a_drop5p10  5.1.2-a_drop5p11       5.1.2-a_drop5p12
5701     5.1.2-a_drop5p13  5.1.2-a_drop5p14       5.1.2-a_drop5p15
5702     5.1.2-a_drop5p16  5.1.2-a_drop5p16b      5.1.2-a_drop5p16c
5703     5.1.2-a_drop5p17  5.1.2-a_drop5p4        5.1.2-a_drop5p5
5704     5.1.2-a_drop5p6   5.1.2-a_drop5p7        5.1.2-a_drop5p8
5705     5.1.2-a_drop5p9   5.1.3-a_drop5p17       5.1.3-a_drop5p17b
5706     5.1.3-a_drop5p17c 5.1.4-a_drop5p18       5.1.4-a_drop5p19
5707     5.1.4-a_drop5p20  5.1.4-a_drop6p0        5.1.4-a_drop6p1
5708     5.1.4-a_drop6p2   5.1.5-a_drop5p20       5.2.0-a_drop6p3
5709     5.2.0-a_drop6p4   5.2.0-a_drop6p5        5.2.0-a_drop6p6
5710     5.2.1-a_drop6p10  5.2.1-a_drop6p11       5.2.1-a_drop6p12
5711     5.2.1-a_drop6p6   5.2.1-a_drop6p7        5.2.1-a_drop6p8
5712     5.2.2-a_drop6p13  5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
5713     5.2.2-a_drop6p13c
5714 
5715     (this was found by grepping for "mysql," in all historical
5716     versions of configure.in in the trees listed above).
5717 
5718     There are 5.1.1-alpha versions that use the new event id's, so we
5719     do not test that version string.  So replication from 5.1.1-alpha
5720     with the other event id's to a new version does not work.
5721     Moreover, we can safely ignore the part after drop[56].  This
5722     allows us to simplify the big list above to the following regexes:
5723 
5724     5\.1\.[1-5]-a_drop5.*
5725     5\.1\.4-a_drop6.*
5726     5\.2\.[0-2]-a_drop6.*
5727 
5728     This is what we test for in the 'if' below.
5729   */
5730   if (post_header_len &&
5731       server_version[0] == '5' && server_version[1] == '.' &&
5732       server_version[3] == '.' &&
5733       strncmp(server_version + 5, "-a_drop", 7) == 0 &&
5734       ((server_version[2] == '1' &&
5735         server_version[4] >= '1' && server_version[4] <= '5' &&
5736         server_version[12] == '5') ||
5737        (server_version[2] == '1' &&
5738         server_version[4] == '4' &&
5739         server_version[12] == '6') ||
5740        (server_version[2] == '2' &&
5741         server_version[4] >= '0' && server_version[4] <= '2' &&
5742         server_version[12] == '6')))
5743   {
5744     if (number_of_event_types != 22)
5745     {
5746       DBUG_PRINT("info", (" number_of_event_types=%d",
5747                           number_of_event_types));
5748       /* this makes is_valid() return false. */
5749       my_free(post_header_len);
5750       post_header_len= NULL;
5751       DBUG_VOID_RETURN;
5752     }
5753     static const uint8 perm[EVENT_TYPE_PERMUTATION_NUM]=
5754       {
5755         UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
5756         INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
5757         APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
5758         NEW_LOAD_EVENT,
5759         RAND_EVENT, USER_VAR_EVENT,
5760         FORMAT_DESCRIPTION_EVENT,
5761         TABLE_MAP_EVENT,
5762         PRE_GA_WRITE_ROWS_EVENT,
5763         PRE_GA_UPDATE_ROWS_EVENT,
5764         PRE_GA_DELETE_ROWS_EVENT,
5765         XID_EVENT,
5766         BEGIN_LOAD_QUERY_EVENT,
5767         EXECUTE_LOAD_QUERY_EVENT,
5768       };
5769     event_type_permutation= perm;
5770     /*
5771       Since we use (permuted) event id's to index the post_header_len
5772       array, we need to permute the post_header_len array too.
5773     */
5774     uint8 post_header_len_temp[EVENT_TYPE_PERMUTATION_NUM];
5775     for (uint i= 1; i < EVENT_TYPE_PERMUTATION_NUM; i++)
5776       post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
5777     for (uint i= 0; i < EVENT_TYPE_PERMUTATION_NUM - 1; i++)
5778       post_header_len[i] = post_header_len_temp[i];
5779   }
5780   DBUG_VOID_RETURN;
5781 }
5782 
5783 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)5784 bool Format_description_log_event::write(IO_CACHE* file)
5785 {
5786   bool ret;
5787   bool no_checksum;
5788   /*
5789     We don't call Start_log_event_v3::write() because this would make 2
5790     my_b_safe_write().
5791   */
5792   uchar buff[FORMAT_DESCRIPTION_HEADER_LEN + BINLOG_CHECKSUM_ALG_DESC_LEN];
5793   size_t rec_size= sizeof(buff);
5794   int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5795   memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5796   if (!dont_set_created)
5797     created= get_time();
5798   int4store(buff + ST_CREATED_OFFSET,created);
5799   buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
5800   memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
5801          LOG_EVENT_TYPES);
5802   /*
5803     if checksum is requested
5804     record the checksum-algorithm descriptor next to
5805     post_header_len vector which will be followed by the checksum value.
5806     Master is supposed to trigger checksum computing by binlog_checksum_options,
5807     slave does it via marking the event according to
5808     FD_queue checksum_alg value.
5809   */
5810   compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
5811 #ifndef DBUG_OFF
5812   data_written= 0; // to prepare for need_checksum assert
5813 #endif
5814   buff[FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
5815     checksum_alg : (uint8) BINLOG_CHECKSUM_ALG_OFF;
5816   /*
5817      FD of checksum-aware server is always checksum-equipped, (V) is in,
5818      regardless of @@global.binlog_checksum policy.
5819      Thereby a combination of (A) == 0, (V) != 0 means
5820      it's the checksum-aware server's FD event that heads checksum-free binlog
5821      file.
5822      Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
5823      A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
5824      heading the checksummed binlog.
5825      (A), (V) presence in FD of the checksum-aware server makes the event
5826      1 + 4 bytes bigger comparing to the former FD.
5827   */
5828 
5829   if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
5830   {
5831     checksum_alg= BINLOG_CHECKSUM_ALG_CRC32;  // Forcing (V) room to fill anyway
5832   }
5833   ret= (write_header(file, rec_size) ||
5834         wrapper_my_b_safe_write(file, buff, rec_size) ||
5835         write_footer(file));
5836   if (no_checksum)
5837     checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
5838   return ret;
5839 }
5840 #endif
5841 
5842 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)5843 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
5844 {
5845   int ret= 0;
5846   DBUG_ENTER("Format_description_log_event::do_apply_event");
5847 
5848   /*
5849     As a transaction NEVER spans on 2 or more binlogs:
5850     if we have an active transaction at this point, the master died
5851     while writing the transaction to the binary log, i.e. while
5852     flushing the binlog cache to the binlog. XA guarantees that master has
5853     rolled back. So we roll back.
5854     Note: this event could be sent by the master to inform us of the
5855     format of its binlog; in other words maybe it is not at its
5856     original place when it comes to us; we'll know this by checking
5857     log_pos ("artificial" events have log_pos == 0).
5858   */
5859   if (!thd->rli_fake && !is_artificial_event() && created
5860       && thd->transaction.all.ha_list)
5861   {
5862     /* This is not an error (XA is safe), just an information */
5863     rli->report(INFORMATION_LEVEL, 0,
5864                 "Rolling back unfinished transaction (no COMMIT "
5865                 "or ROLLBACK in relay log). A probable cause is that "
5866                 "the master died while writing the transaction to "
5867                 "its binary log, thus rolled back too.");
5868     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
5869   }
5870 
5871   /*
5872     If this event comes from ourselves, there is no cleaning task to
5873     perform, we don't call Start_log_event_v3::do_apply_event()
5874     (this was just to update the log's description event).
5875   */
5876   if (server_id != (uint32) ::server_id)
5877   {
5878     /*
5879       If the event was not requested by the slave i.e. the master sent
5880       it while the slave asked for a position >4, the event will make
5881       rli->group_master_log_pos advance. Say that the slave asked for
5882       position 1000, and the Format_desc event's end is 96. Then in
5883       the beginning of replication rli->group_master_log_pos will be
5884       0, then 96, then jump to first really asked event (which is
5885       >96). So this is ok.
5886     */
5887     ret= Start_log_event_v3::do_apply_event(rli);
5888   }
5889 
5890   if (!ret)
5891   {
5892     /* Save the information describing this binlog */
5893     const_cast<Relay_log_info *>(rli)->set_rli_description_event(this);
5894   }
5895 
5896   DBUG_RETURN(ret);
5897 }
5898 
do_update_pos(Relay_log_info * rli)5899 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
5900 {
5901   if (server_id == (uint32) ::server_id)
5902   {
5903     /*
5904       We only increase the relay log position if we are skipping
5905       events and do not touch any group_* variables, nor flush the
5906       relay log info.  If there is a crash, we will have to re-skip
5907       the events again, but that is a minor issue.
5908 
5909       If we do not skip stepping the group log position (and the
5910       server id was changed when restarting the server), it might well
5911       be that we start executing at a position that is invalid, e.g.,
5912       at a Rows_log_event or a Query_log_event preceeded by a
5913       Intvar_log_event instead of starting at a Table_map_log_event or
5914       the Intvar_log_event respectively.
5915      */
5916     rli->inc_event_relay_log_pos();
5917     return 0;
5918   }
5919   else
5920   {
5921     return Log_event::do_update_pos(rli);
5922   }
5923 }
5924 
5925 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)5926 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
5927 {
5928   return Log_event::EVENT_SKIP_NOT;
5929 }
5930 
5931 #endif
5932 
5933 
5934 /**
5935    'server_version_split' is used for lookups to find if the server which
5936    created this event has some known bug.
5937 */
calc_server_version_split()5938 void Format_description_log_event::calc_server_version_split()
5939 {
5940   do_server_version_split(server_version, server_version_split);
5941 
5942   DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
5943                      " '%s' %d %d %d", server_version,
5944                      server_version_split[0],
5945                      server_version_split[1], server_version_split[2]));
5946 }
5947 
5948 /**
5949    @return integer representing the version of server that originated
5950    the current FD instance.
5951 */
get_version_product() const5952 ulong Format_description_log_event::get_version_product() const
5953 {
5954   return version_product(server_version_split);
5955 }
5956 
5957 /**
5958    @return TRUE is the event's version is earlier than one that introduced
5959    the replication event checksum. FALSE otherwise.
5960 */
is_version_before_checksum() const5961 bool Format_description_log_event::is_version_before_checksum() const
5962 {
5963   return get_version_product() < checksum_version_product;
5964 }
5965 
5966 /**
5967    @param buf buffer holding serialized FD event
5968    @param len netto (possible checksum is stripped off) length of the event buf
5969 
5970    @return  the version-safe checksum alg descriptor where zero
5971             designates no checksum, 255 - the orginator is
5972             checksum-unaware (effectively no checksum) and the actuall
5973             [1-254] range alg descriptor.
5974 */
get_checksum_alg(const char * buf,ulong len)5975 uint8 get_checksum_alg(const char* buf, ulong len)
5976 {
5977   uint8 ret;
5978   char version[ST_SERVER_VER_LEN];
5979   uchar version_split[3];
5980 
5981   DBUG_ENTER("get_checksum_alg");
5982   DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
5983 
5984   memcpy(version, buf +
5985          buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
5986          + ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
5987   version[ST_SERVER_VER_LEN - 1]= 0;
5988 
5989   do_server_version_split(version, version_split);
5990   ret= (version_product(version_split) < checksum_version_product) ?
5991     (uint8) BINLOG_CHECKSUM_ALG_UNDEF :
5992     * (uint8*) (buf + len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN);
5993   DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
5994               ret == BINLOG_CHECKSUM_ALG_UNDEF ||
5995               ret == BINLOG_CHECKSUM_ALG_CRC32);
5996   DBUG_RETURN(ret);
5997 }
5998 
5999 
6000   /**************************************************************************
6001         Load_log_event methods
6002    General note about Load_log_event: the binlogging of LOAD DATA INFILE is
6003    going to be changed in 5.0 (or maybe in 5.1; not decided yet).
6004    However, the 5.0 slave could still have to read such events (from a 4.x
6005    master), convert them (which just means maybe expand the header, when 5.0
6006    servers have a UID in events) (remember that whatever is after the header
6007    will be like in 4.x, as this event's format is not modified in 5.0 as we
6008    will use new types of events to log the new LOAD DATA INFILE features).
6009    To be able to read/convert, we just need to not assume that the common
6010    header is of length LOG_EVENT_HEADER_LEN (we must use the description
6011    event).
6012    Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
6013    between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
6014    positions displayed in SHOW SLAVE STATUS then are fine too).
6015   **************************************************************************/
6016 
6017 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_query_buffer_length()6018 uint Load_log_event::get_query_buffer_length()
6019 {
6020   return
6021     //the DB name may double if we escape the quote character
6022     5 + 2*db_len + 3 +
6023     18 + fname_len*4 + 2 +                    // "LOAD DATA INFILE 'file''"
6024     11 +                                    // "CONCURRENT "
6025     7 +					    // LOCAL
6026     9 +                                     // " REPLACE or IGNORE "
6027     13 + table_name_len*2 +                 // "INTO TABLE `table`"
6028     21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
6029     23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
6030     12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
6031     21 + sql_ex.line_term_len*4 + 2 +       // " LINES TERMINATED BY 'str'"
6032     19 + sql_ex.line_start_len*4 + 2 +      // " LINES STARTING BY 'str'"
6033     15 + 22 +                               // " IGNORE xxx  LINES"
6034     3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
6035 }
6036 
6037 
print_query(bool need_db,const char * cs,char * buf,char ** end,char ** fn_start,char ** fn_end)6038 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
6039                                  char **end, char **fn_start, char **fn_end)
6040 {
6041   char quoted_id[1 + NAME_LEN * 2 + 2];//quoted  length
6042   int  quoted_id_len= 0;
6043   char *pos= buf;
6044 
6045   if (need_db && db && db_len)
6046   {
6047     pos= strmov(pos, "use ");
6048 #ifdef MYSQL_SERVER
6049     quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
6050                                                db, 0);
6051 #else
6052     quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
6053 #endif
6054     quoted_id[quoted_id_len]= '\0';
6055     pos= strmov(pos, quoted_id);
6056     pos= strmov(pos, "; ");
6057   }
6058 
6059   pos= strmov(pos, "LOAD DATA ");
6060 
6061   if (is_concurrent)
6062     pos= strmov(pos, "CONCURRENT ");
6063 
6064   if (fn_start)
6065     *fn_start= pos;
6066 
6067   if (check_fname_outside_temp_buf())
6068     pos= strmov(pos, "LOCAL ");
6069   pos= strmov(pos, "INFILE ");
6070   pos= pretty_print_str(pos, fname, fname_len);
6071   pos= strmov(pos, " ");
6072 
6073   if (sql_ex.opt_flags & REPLACE_FLAG)
6074     pos= strmov(pos, "REPLACE ");
6075   else if (sql_ex.opt_flags & IGNORE_FLAG)
6076     pos= strmov(pos, "IGNORE ");
6077 
6078   pos= strmov(pos ,"INTO");
6079 
6080   if (fn_end)
6081     *fn_end= pos;
6082 
6083   pos= strmov(pos ," TABLE ");
6084   memcpy(pos, table_name, table_name_len);
6085   pos+= table_name_len;
6086 
6087   if (cs != NULL)
6088   {
6089     pos= strmov(pos ," CHARACTER SET ");
6090     pos= strmov(pos ,  cs);
6091   }
6092 
6093   /* We have to create all optional fields as the default is not empty */
6094   pos= strmov(pos, " FIELDS TERMINATED BY ");
6095   pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
6096   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6097     pos= strmov(pos, " OPTIONALLY ");
6098   pos= strmov(pos, " ENCLOSED BY ");
6099   pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
6100 
6101   pos= strmov(pos, " ESCAPED BY ");
6102   pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
6103 
6104   pos= strmov(pos, " LINES TERMINATED BY ");
6105   pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
6106   if (sql_ex.line_start_len)
6107   {
6108     pos= strmov(pos, " STARTING BY ");
6109     pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
6110   }
6111 
6112   if ((long) skip_lines > 0)
6113   {
6114     pos= strmov(pos, " IGNORE ");
6115     pos= longlong10_to_str((longlong) skip_lines, pos, 10);
6116     pos= strmov(pos," LINES ");
6117   }
6118 
6119   if (num_fields)
6120   {
6121     uint i;
6122     const char *field= fields;
6123     pos= strmov(pos, " (");
6124     for (i = 0; i < num_fields; i++)
6125     {
6126       if (i)
6127       {
6128         *pos++= ' ';
6129         *pos++= ',';
6130       }
6131       quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
6132                                                  0);
6133       memcpy(pos, quoted_id, quoted_id_len-1);
6134     }
6135     *pos++= ')';
6136   }
6137 
6138   *end= pos;
6139 }
6140 
6141 
pack_info(Protocol * protocol)6142 int Load_log_event::pack_info(Protocol *protocol)
6143 {
6144   char *buf, *end;
6145 
6146   if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
6147     return 1;
6148   print_query(TRUE, NULL, buf, &end, 0, 0);
6149   protocol->store(buf, end-buf, &my_charset_bin);
6150   my_free(buf);
6151   return 0;
6152 }
6153 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
6154 
6155 
6156 #ifndef MYSQL_CLIENT
6157 
6158 /*
6159   Load_log_event::write_data_header()
6160 */
6161 
write_data_header(IO_CACHE * file)6162 bool Load_log_event::write_data_header(IO_CACHE* file)
6163 {
6164   char buf[LOAD_HEADER_LEN];
6165   int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
6166   int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
6167   int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
6168   buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
6169   buf[L_DB_LEN_OFFSET] = (char)db_len;
6170   int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
6171   return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
6172 }
6173 
6174 
6175 /*
6176   Load_log_event::write_data_body()
6177 */
6178 
write_data_body(IO_CACHE * file)6179 bool Load_log_event::write_data_body(IO_CACHE* file)
6180 {
6181   if (sql_ex.write_data(file))
6182     return 1;
6183   if (num_fields && fields && field_lens)
6184   {
6185     if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
6186 	my_b_safe_write(file, (uchar*)fields, field_block_len))
6187       return 1;
6188   }
6189   return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
6190 	  my_b_safe_write(file, (uchar*)db, db_len + 1) ||
6191 	  my_b_safe_write(file, (uchar*)fname, fname_len));
6192 }
6193 
6194 
6195 /*
6196   Load_log_event::Load_log_event()
6197 */
6198 
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)6199 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
6200 			       const char *db_arg, const char *table_name_arg,
6201 			       List<Item> &fields_arg,
6202                                bool is_concurrent_arg,
6203 			       enum enum_duplicates handle_dup,
6204 			       bool ignore, bool using_trans)
6205   :Log_event(thd_arg,
6206              thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
6207              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
6208                            Log_event::EVENT_STMT_CACHE,
6209              Log_event::EVENT_NORMAL_LOGGING),
6210    thread_id(thd_arg->thread_id),
6211    slave_proxy_id(thd_arg->variables.pseudo_thread_id),
6212    num_fields(0),fields(0),
6213    field_lens(0),field_block_len(0),
6214    table_name(table_name_arg ? table_name_arg : ""),
6215    db(db_arg), fname(ex->file_name), local_fname(FALSE),
6216    is_concurrent(is_concurrent_arg)
6217 {
6218 
6219   /*
6220   exec_time calculation has changed to use the same method that is used
6221   to fill out "thd_arg->start_time"
6222   */
6223 
6224   struct timeval end_time;
6225   ulonglong micro_end_time= my_micro_time();
6226   my_micro_time_to_timeval(micro_end_time, &end_time);
6227 
6228   exec_time= end_time.tv_sec - thd_arg->start_time.tv_sec;
6229 
6230   /* db can never be a zero pointer in 4.0 */
6231   db_len = (uint32) strlen(db);
6232   table_name_len = (uint32) strlen(table_name);
6233   fname_len = (fname) ? (uint) strlen(fname) : 0;
6234   sql_ex.field_term = (char*) ex->field_term->ptr();
6235   sql_ex.field_term_len = (uint8) ex->field_term->length();
6236   sql_ex.enclosed = (char*) ex->enclosed->ptr();
6237   sql_ex.enclosed_len = (uint8) ex->enclosed->length();
6238   sql_ex.line_term = (char*) ex->line_term->ptr();
6239   sql_ex.line_term_len = (uint8) ex->line_term->length();
6240   sql_ex.line_start = (char*) ex->line_start->ptr();
6241   sql_ex.line_start_len = (uint8) ex->line_start->length();
6242   sql_ex.escaped = (char*) ex->escaped->ptr();
6243   sql_ex.escaped_len = (uint8) ex->escaped->length();
6244   sql_ex.opt_flags = 0;
6245   sql_ex.cached_new_format = -1;
6246 
6247   if (ex->dumpfile)
6248     sql_ex.opt_flags|= DUMPFILE_FLAG;
6249   if (ex->opt_enclosed)
6250     sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
6251 
6252   sql_ex.empty_flags= 0;
6253 
6254   switch (handle_dup) {
6255   case DUP_REPLACE:
6256     sql_ex.opt_flags|= REPLACE_FLAG;
6257     break;
6258   case DUP_UPDATE:				// Impossible here
6259   case DUP_ERROR:
6260     break;
6261   }
6262   if (ignore)
6263     sql_ex.opt_flags|= IGNORE_FLAG;
6264 
6265   if (!ex->field_term->length())
6266     sql_ex.empty_flags |= FIELD_TERM_EMPTY;
6267   if (!ex->enclosed->length())
6268     sql_ex.empty_flags |= ENCLOSED_EMPTY;
6269   if (!ex->line_term->length())
6270     sql_ex.empty_flags |= LINE_TERM_EMPTY;
6271   if (!ex->line_start->length())
6272     sql_ex.empty_flags |= LINE_START_EMPTY;
6273   if (!ex->escaped->length())
6274     sql_ex.empty_flags |= ESCAPED_EMPTY;
6275 
6276   skip_lines = ex->skip_lines;
6277 
6278   List_iterator<Item> li(fields_arg);
6279   field_lens_buf.length(0);
6280   fields_buf.length(0);
6281   Item* item;
6282   while ((item = li++))
6283   {
6284     num_fields++;
6285     uchar len= (uchar) item->item_name.length();
6286     field_block_len += len + 1;
6287     fields_buf.append(item->item_name.ptr(), len + 1);
6288     field_lens_buf.append((char*)&len, 1);
6289   }
6290 
6291   field_lens = (const uchar*)field_lens_buf.ptr();
6292   fields = fields_buf.ptr();
6293 }
6294 #endif /* !MYSQL_CLIENT */
6295 
6296 
6297 /**
6298   @note
6299     The caller must do buf[event_len] = 0 before he starts using the
6300     constructed event.
6301 */
Load_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6302 Load_log_event::Load_log_event(const char *buf, uint event_len,
6303                                const Format_description_log_event *description_event)
6304   :Log_event(buf, description_event), num_fields(0), fields(0),
6305    field_lens(0),field_block_len(0),
6306    table_name(0), db(0), fname(0), local_fname(FALSE),
6307    /*
6308      Load_log_event which comes from the binary log does not contain
6309      information about the type of insert which was used on the master.
6310      Assume that it was an ordinary, non-concurrent LOAD DATA.
6311     */
6312    is_concurrent(FALSE)
6313 {
6314   DBUG_ENTER("Load_log_event");
6315   /*
6316     I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6317     4.0->5.0 and 5.0->5.0 and it works.
6318   */
6319   if (event_len)
6320     copy_log_event(buf, event_len,
6321                    ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
6322                     LOAD_HEADER_LEN +
6323                     description_event->common_header_len :
6324                     LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
6325                    description_event);
6326   /* otherwise it's a derived class, will call copy_log_event() itself */
6327   DBUG_VOID_RETURN;
6328 }
6329 
6330 
6331 /*
6332   Load_log_event::copy_log_event()
6333 */
6334 
copy_log_event(const char * buf,ulong event_len,int body_offset,const Format_description_log_event * description_event)6335 int Load_log_event::copy_log_event(const char *buf, ulong event_len,
6336                                    int body_offset,
6337                                    const Format_description_log_event *description_event)
6338 {
6339   DBUG_ENTER("Load_log_event::copy_log_event");
6340   uint data_len;
6341   char* buf_end = (char*)buf + event_len;
6342   /* this is the beginning of the post-header */
6343   const char* data_head = buf + description_event->common_header_len;
6344   slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
6345   exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
6346   skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
6347   table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
6348   db_len = (uint)data_head[L_DB_LEN_OFFSET];
6349   num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
6350 
6351   if ((int) event_len < body_offset)
6352     DBUG_RETURN(1);
6353   /*
6354     Sql_ex.init() on success returns the pointer to the first byte after
6355     the sql_ex structure, which is the start of field lengths array.
6356   */
6357   if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
6358                                         buf_end,
6359                                         buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
6360     DBUG_RETURN(1);
6361 
6362   data_len = event_len - body_offset;
6363   if (num_fields > data_len) // simple sanity check against corruption
6364     DBUG_RETURN(1);
6365   for (uint i = 0; i < num_fields; i++)
6366     field_block_len += (uint)field_lens[i] + 1;
6367 
6368   fields = (char*)field_lens + num_fields;
6369   table_name  = fields + field_block_len;
6370   if (strlen(table_name) > NAME_LEN)
6371     goto err;
6372 
6373   db = table_name + table_name_len + 1;
6374   DBUG_EXECUTE_IF ("simulate_invalid_address",
6375                    db_len = data_len;);
6376   fname = db + db_len + 1;
6377   if ((db_len > data_len) || (fname > buf_end))
6378     goto err;
6379   fname_len = (uint) strlen(fname);
6380   if ((fname_len > data_len) || (fname + fname_len > buf_end))
6381     goto err;
6382   // null termination is accomplished by the caller doing buf[event_len]=0
6383 
6384   DBUG_RETURN(0);
6385 
6386 err:
6387   // Invalid event.
6388   table_name = 0;
6389   DBUG_RETURN(1);
6390 }
6391 
6392 
6393 /*
6394   Load_log_event::print()
6395 */
6396 
6397 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6398 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6399 {
6400   print(file, print_event_info, 0);
6401 }
6402 
6403 
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info,bool commented)6404 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
6405 			   bool commented)
6406 {
6407   IO_CACHE *const head= &print_event_info->head_cache;
6408   size_t id_len= 0;
6409   char temp_buf[1 + 2*FN_REFLEN + 2];
6410 
6411   DBUG_ENTER("Load_log_event::print");
6412   if (!print_event_info->short_form)
6413   {
6414     print_header(head, print_event_info, FALSE);
6415     my_b_printf(head, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
6416                 thread_id, exec_time);
6417   }
6418 
6419   bool different_db= 1;
6420   if (db)
6421   {
6422     /*
6423       If the database is different from the one of the previous statement, we
6424       need to print the "use" command, and we update the last_db.
6425       But if commented, the "use" is going to be commented so we should not
6426       update the last_db.
6427     */
6428     if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
6429         !commented)
6430       memcpy(print_event_info->db, db, db_len + 1);
6431   }
6432 
6433   if (db && db[0] && different_db)
6434   {
6435 #ifdef MYSQL_SERVER
6436     id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
6437 #else
6438     id_len= my_strmov_quoted_identifier(temp_buf, db);
6439 #endif
6440     temp_buf[id_len]= '\0';
6441     my_b_printf(head, "%suse %s%s\n",
6442                 commented ? "# " : "", temp_buf, print_event_info->delimiter);
6443   }
6444   if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
6445     my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
6446             commented ? "# " : "", (ulong)thread_id,
6447             print_event_info->delimiter);
6448   my_b_printf(head, "%sLOAD DATA ",
6449               commented ? "# " : "");
6450   if (check_fname_outside_temp_buf())
6451     my_b_printf(head, "LOCAL ");
6452   my_b_printf(head, "INFILE '%-*s' ", fname_len, fname);
6453 
6454   if (sql_ex.opt_flags & REPLACE_FLAG)
6455     my_b_printf(head,"REPLACE ");
6456   else if (sql_ex.opt_flags & IGNORE_FLAG)
6457     my_b_printf(head,"IGNORE ");
6458 
6459 #ifdef MYSQL_SERVER
6460     id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
6461 #else
6462     id_len= my_strmov_quoted_identifier(temp_buf, table_name);
6463 #endif
6464   temp_buf[id_len]= '\0';
6465   my_b_printf(head, "INTO TABLE %s", temp_buf);
6466 
6467   my_b_printf(head, " FIELDS TERMINATED BY ");
6468   pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len);
6469 
6470   if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6471     my_b_printf(head," OPTIONALLY ");
6472   my_b_printf(head, " ENCLOSED BY ");
6473   pretty_print_str(head, sql_ex.enclosed, sql_ex.enclosed_len);
6474 
6475   my_b_printf(head, " ESCAPED BY ");
6476   pretty_print_str(head, sql_ex.escaped, sql_ex.escaped_len);
6477 
6478   my_b_printf(head," LINES TERMINATED BY ");
6479   pretty_print_str(head, sql_ex.line_term, sql_ex.line_term_len);
6480 
6481 
6482   if (sql_ex.line_start)
6483   {
6484     my_b_printf(head," STARTING BY ");
6485     pretty_print_str(head, sql_ex.line_start, sql_ex.line_start_len);
6486   }
6487   if ((long) skip_lines > 0)
6488     my_b_printf(head, " IGNORE %ld LINES", (long) skip_lines);
6489 
6490   if (num_fields)
6491   {
6492     uint i;
6493     const char* field = fields;
6494     my_b_printf(head, " (");
6495     for (i = 0; i < num_fields; i++)
6496     {
6497       if (i)
6498         my_b_printf(head, ",");
6499       id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
6500       temp_buf[id_len]= '\0';
6501       my_b_printf(head, "%s", temp_buf);
6502 
6503       field += field_lens[i]  + 1;
6504     }
6505     my_b_printf(head, ")");
6506   }
6507 
6508   my_b_printf(head, "%s\n", print_event_info->delimiter);
6509   DBUG_VOID_RETURN;
6510 }
6511 #endif /* MYSQL_CLIENT */
6512 
6513 #ifndef MYSQL_CLIENT
6514 
6515 /**
6516   Load_log_event::set_fields()
6517 
6518   @note
6519     This function can not use the member variable
6520     for the database, since LOAD DATA INFILE on the slave
6521     can be for a different database than the current one.
6522     This is the reason for the affected_db argument to this method.
6523 */
6524 
set_fields(const char * affected_db,List<Item> & field_list,Name_resolution_context * context)6525 void Load_log_event::set_fields(const char* affected_db,
6526 				List<Item> &field_list,
6527                                 Name_resolution_context *context)
6528 {
6529   uint i;
6530   const char* field = fields;
6531   for (i= 0; i < num_fields; i++)
6532   {
6533     field_list.push_back(new Item_field(context,
6534                                         affected_db, table_name, field));
6535     field+= field_lens[i]  + 1;
6536   }
6537 }
6538 #endif /* !MYSQL_CLIENT */
6539 
6540 
6541 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6542 /**
6543   Does the data loading job when executing a LOAD DATA on the slave.
6544 
6545   @param net
6546   @param rli
6547   @param use_rli_only_for_errors     If set to 1, rli is provided to
6548                                      Load_log_event::exec_event only for this
6549                                      function to have rli->get_rpl_log_name and
6550                                      rli->last_slave_error, both being used by
6551                                      error reports. rli's position advancing
6552                                      is skipped (done by the caller which is
6553                                      Execute_load_log_event::exec_event).
6554                                      If set to 0, rli is provided for full use,
6555                                      i.e. for error reports and position
6556                                      advancing.
6557 
6558   @todo
6559     fix this; this can be done by testing rules in
6560     Create_file_log_event::exec_event() and then discarding Append_block and
6561     al.
6562   @todo
6563     this is a bug - this needs to be moved to the I/O thread
6564 
6565   @retval
6566     0           Success
6567   @retval
6568     1           Failure
6569 */
6570 
do_apply_event(NET * net,Relay_log_info const * rli,bool use_rli_only_for_errors)6571 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
6572                                    bool use_rli_only_for_errors)
6573 {
6574   DBUG_ASSERT(thd->query() == 0);
6575   thd->reset_query_inner();                    // Should not be needed
6576   set_thd_db(thd, db, db_len);
6577   thd->is_slave_error= 0;
6578   clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
6579 
6580   /* see Query_log_event::do_apply_event() and BUG#13360 */
6581   DBUG_ASSERT(!rli->m_table_map.count());
6582   /*
6583     Usually lex_start() is called by mysql_parse(), but we need it here
6584     as the present method does not call mysql_parse().
6585   */
6586   lex_start(thd);
6587   thd->lex->local_file= local_fname;
6588   mysql_reset_thd_for_next_command(thd);
6589 
6590   if (!use_rli_only_for_errors)
6591   {
6592     /*
6593       Saved for InnoDB, see comment in
6594       Query_log_event::do_apply_event()
6595     */
6596     const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
6597     DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
6598   }
6599 
6600    /*
6601     We test replicate_*_db rules. Note that we have already prepared
6602     the file to load, even if we are going to ignore and delete it
6603     now. So it is possible that we did a lot of disk writes for
6604     nothing. In other words, a big LOAD DATA INFILE on the master will
6605     still consume a lot of space on the slave (space in the relay log
6606     + space of temp files: twice the space of the file to load...)
6607     even if it will finally be ignored.  TODO: fix this; this can be
6608     done by testing rules in Create_file_log_event::do_apply_event()
6609     and then discarding Append_block and al. Another way is do the
6610     filtering in the I/O thread (more efficient: no disk writes at
6611     all).
6612 
6613 
6614     Note:   We do not need to execute reset_one_shot_variables() if this
6615             db_ok() test fails.
6616     Reason: The db stored in binlog events is the same for SET and for
6617             its companion query.  If the SET is ignored because of
6618             db_ok(), the companion query will also be ignored, and if
6619             the companion query is ignored in the db_ok() test of
6620             ::do_apply_event(), then the companion SET also have so
6621             we don't need to reset_one_shot_variables().
6622   */
6623   if (rpl_filter->db_ok(thd->db))
6624   {
6625     thd->set_time(&when);
6626     thd->set_query_id(next_query_id());
6627     thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
6628 
6629     TABLE_LIST tables;
6630     char table_buf[NAME_LEN + 1];
6631     strmov(table_buf, table_name);
6632     if (lower_case_table_names == 1)
6633       my_casedn_str(system_charset_info, table_buf);
6634     tables.init_one_table(thd->strmake(thd->db, thd->db_length),
6635                           thd->db_length,
6636                           table_buf, strlen(table_buf),
6637                           table_buf, TL_WRITE);
6638     tables.updating= 1;
6639 
6640     // the table will be opened in mysql_load
6641     if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
6642     {
6643       // TODO: this is a bug - this needs to be moved to the I/O thread
6644       if (net)
6645         skip_load_data_infile(net);
6646     }
6647     else
6648     {
6649       char llbuff[22];
6650       char *end;
6651       enum enum_duplicates handle_dup;
6652       bool ignore= 0;
6653       char *load_data_query;
6654 
6655       /*
6656         Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
6657         and written to slave's binlog if binlogging is on.
6658       */
6659       if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
6660       {
6661         /*
6662           This will set thd->fatal_error in case of OOM. So we surely will notice
6663           that something is wrong.
6664         */
6665         goto error;
6666       }
6667 
6668       print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
6669       *end= 0;
6670       thd->set_query(load_data_query, (uint) (end - load_data_query));
6671 
6672       if (sql_ex.opt_flags & REPLACE_FLAG)
6673         handle_dup= DUP_REPLACE;
6674       else if (sql_ex.opt_flags & IGNORE_FLAG)
6675       {
6676         ignore= 1;
6677         handle_dup= DUP_ERROR;
6678       }
6679       else
6680       {
6681         /*
6682           When replication is running fine, if it was DUP_ERROR on the
6683           master then we could choose IGNORE here, because if DUP_ERROR
6684           suceeded on master, and data is identical on the master and slave,
6685           then there should be no uniqueness errors on slave, so IGNORE is
6686           the same as DUP_ERROR. But in the unlikely case of uniqueness errors
6687           (because the data on the master and slave happen to be different
6688           (user error or bug), we want LOAD DATA to print an error message on
6689           the slave to discover the problem.
6690 
6691           If reading from net (a 3.23 master), mysql_load() will change this
6692           to IGNORE.
6693         */
6694         handle_dup= DUP_ERROR;
6695       }
6696       /*
6697         We need to set thd->lex->sql_command and thd->lex->duplicates
6698         since InnoDB tests these variables to decide if this is a LOAD
6699         DATA ... REPLACE INTO ... statement even though mysql_parse()
6700         is not called.  This is not needed in 5.0 since there the LOAD
6701         DATA ... statement is replicated using mysql_parse(), which
6702         sets the thd->lex fields correctly.
6703       */
6704       thd->lex->sql_command= SQLCOM_LOAD;
6705       thd->lex->duplicates= handle_dup;
6706 
6707       sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
6708       String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
6709       String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
6710       String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
6711       String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
6712       String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
6713       const String empty_str("", 0, log_cs);
6714       ex.field_term= &field_term;
6715       ex.enclosed= &enclosed;
6716       ex.line_term= &line_term;
6717       ex.line_start= &line_start;
6718       ex.escaped= &escaped;
6719 
6720       ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
6721       if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
6722         ex.field_term= &empty_str;
6723 
6724       ex.skip_lines = skip_lines;
6725       List<Item> field_list;
6726       thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
6727       set_fields(tables.db, field_list, &thd->lex->select_lex.context);
6728       thd->variables.pseudo_thread_id= thread_id;
6729       if (net)
6730       {
6731         // mysql_load will use thd->net to read the file
6732         thd->net.vio = net->vio;
6733         // Make sure the client does not get confused about the packet sequence
6734         thd->net.pkt_nr = net->pkt_nr;
6735       }
6736       /*
6737         It is safe to use tmp_list twice because we are not going to
6738         update it inside mysql_load().
6739       */
6740       List<Item> tmp_list;
6741       if (open_temporary_tables(thd, &tables) ||
6742           mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
6743                      handle_dup, ignore, net != 0))
6744         thd->is_slave_error= 1;
6745       if (thd->cuted_fields)
6746       {
6747         /* log_pos is the position of the LOAD event in the master log */
6748         sql_print_warning("Slave: load data infile on table '%s' at "
6749                           "log position %s in log '%s' produced %ld "
6750                           "warning(s). Default database: '%s'",
6751                           (char*) table_name,
6752                           llstr(log_pos,llbuff),
6753                           const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
6754                           (ulong) thd->cuted_fields,
6755                           print_slave_db_safe(thd->db));
6756       }
6757       if (net)
6758         net->pkt_nr= thd->net.pkt_nr;
6759     }
6760   }
6761   else
6762   {
6763     /*
6764       We will just ask the master to send us /dev/null if we do not
6765       want to load the data.
6766       TODO: this a bug - needs to be done in I/O thread
6767     */
6768     if (net)
6769       skip_load_data_infile(net);
6770   }
6771 
6772 error:
6773   thd->net.vio = 0;
6774   const char *remember_db= thd->db;
6775   thd->catalog= 0;
6776   thd->set_db(NULL, 0);                   /* will free the current database */
6777   thd->reset_query();
6778   thd->get_stmt_da()->set_overwrite_status(true);
6779   thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
6780   thd->get_stmt_da()->set_overwrite_status(false);
6781   close_thread_tables(thd);
6782   /*
6783     - If transaction rollback was requested due to deadlock
6784       perform it and release metadata locks.
6785     - If inside a multi-statement transaction,
6786     defer the release of metadata locks until the current
6787     transaction is either committed or rolled back. This prevents
6788     other statements from modifying the table for the entire
6789     duration of this transaction.  This provides commit ordering
6790     and guarantees serializability across multiple transactions.
6791     - If in autocommit mode, or outside a transactional context,
6792     automatically release metadata locks of the current statement.
6793   */
6794   if (thd->transaction_rollback_request)
6795   {
6796     trans_rollback_implicit(thd);
6797     thd->mdl_context.release_transactional_locks();
6798   }
6799   else if (! thd->in_multi_stmt_transaction_mode())
6800     thd->mdl_context.release_transactional_locks();
6801   else
6802     thd->mdl_context.release_statement_locks();
6803 
6804   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
6805                   thd->is_slave_error= 0; thd->is_fatal_error= 1;);
6806 
6807   if (thd->is_slave_error)
6808   {
6809     /* this err/sql_errno code is copy-paste from net_send_error() */
6810     const char *err;
6811     int sql_errno;
6812     if (thd->is_error())
6813     {
6814       err= thd->get_stmt_da()->message();
6815       sql_errno= thd->get_stmt_da()->sql_errno();
6816     }
6817     else
6818     {
6819       sql_errno=ER_UNKNOWN_ERROR;
6820       err=ER(sql_errno);
6821     }
6822     rli->report(ERROR_LEVEL, sql_errno,"\
6823 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
6824                     err, (char*)table_name, print_slave_db_safe(remember_db));
6825     free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6826     return 1;
6827   }
6828   free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6829 
6830   if (thd->is_fatal_error)
6831   {
6832     char buf[256];
6833     my_snprintf(buf, sizeof(buf),
6834                 "Running LOAD DATA INFILE on table '%-.64s'."
6835                 " Default database: '%-.64s'",
6836                 (char*)table_name,
6837                 print_slave_db_safe(remember_db));
6838 
6839     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6840                 ER(ER_SLAVE_FATAL_ERROR), buf);
6841     return 1;
6842   }
6843 
6844   return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
6845 }
6846 #endif
6847 
6848 
6849 /**************************************************************************
6850   Rotate_log_event methods
6851 **************************************************************************/
6852 
6853 /*
6854   Rotate_log_event::pack_info()
6855 */
6856 
6857 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)6858 int Rotate_log_event::pack_info(Protocol *protocol)
6859 {
6860   char buf1[256], buf[22];
6861   String tmp(buf1, sizeof(buf1), log_cs);
6862   tmp.length(0);
6863   tmp.append(new_log_ident, ident_len);
6864   tmp.append(STRING_WITH_LEN(";pos="));
6865   tmp.append(llstr(pos,buf));
6866   protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
6867   return 0;
6868 }
6869 #endif
6870 
6871 
6872 /*
6873   Rotate_log_event::print()
6874 */
6875 
6876 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)6877 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6878 {
6879   char buf[22];
6880   IO_CACHE *const head= &print_event_info->head_cache;
6881 
6882   if (print_event_info->short_form)
6883     return;
6884   print_header(head, print_event_info, FALSE);
6885   my_b_printf(head, "\tRotate to ");
6886   if (new_log_ident)
6887     my_b_write(head, (uchar*) new_log_ident, (uint)ident_len);
6888   my_b_printf(head, "  pos: %s\n", llstr(pos, buf));
6889 }
6890 #endif /* MYSQL_CLIENT */
6891 
6892 
6893 
6894 /*
6895   Rotate_log_event::Rotate_log_event() (2 constructors)
6896 */
6897 
6898 
6899 #ifndef MYSQL_CLIENT
Rotate_log_event(const char * new_log_ident_arg,uint ident_len_arg,ulonglong pos_arg,uint flags_arg)6900 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
6901                                    uint ident_len_arg, ulonglong pos_arg,
6902                                    uint flags_arg)
6903   :Log_event(Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING),
6904    new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ?
6905    ident_len_arg : (uint) strlen(new_log_ident_arg)), flags(flags_arg)
6906 {
6907 #ifndef DBUG_OFF
6908   char buff[22];
6909   DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
6910   DBUG_PRINT("enter",("new_log_ident: %s  pos: %s  flags: %lu", new_log_ident_arg,
6911                       llstr(pos_arg, buff), (ulong) flags));
6912 #endif
6913   if (flags & DUP_NAME)
6914     new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
6915   if (flags & RELAY_LOG)
6916     set_relay_log_event();
6917   DBUG_VOID_RETURN;
6918 }
6919 #endif
6920 
6921 
Rotate_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)6922 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
6923                                    const Format_description_log_event* description_event)
6924   :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
6925 {
6926   DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
6927   // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
6928   uint8 header_size= description_event->common_header_len;
6929   uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
6930   uint ident_offset;
6931   if (event_len < header_size)
6932     DBUG_VOID_RETURN;
6933   buf += header_size;
6934   pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
6935   ident_len = (uint)(event_len -
6936                      (header_size+post_header_len));
6937   ident_offset = post_header_len;
6938   set_if_smaller(ident_len,FN_REFLEN-1);
6939   new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
6940   DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
6941   DBUG_VOID_RETURN;
6942 }
6943 
6944 
6945 /*
6946   Rotate_log_event::write()
6947 */
6948 
6949 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)6950 bool Rotate_log_event::write(IO_CACHE* file)
6951 {
6952   char buf[ROTATE_HEADER_LEN];
6953   int8store(buf + R_POS_OFFSET, pos);
6954   return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
6955           wrapper_my_b_safe_write(file, (uchar*) buf, ROTATE_HEADER_LEN) ||
6956           wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
6957                                      (uint) ident_len) ||
6958           write_footer(file));
6959 }
6960 #endif
6961 
6962 
6963 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6964 
6965 /*
6966   Got a rotate log event from the master.
6967 
6968   This is mainly used so that we can later figure out the logname and
6969   position for the master.
6970 
6971   We can't rotate the slave's BINlog as this will cause infinitive rotations
6972   in a A -> B -> A setup.
6973   The NOTES below is a wrong comment which will disappear when 4.1 is merged.
6974 
6975   This must only be called from the Slave SQL thread, since it calls
6976   flush_relay_log_info().
6977 
6978   @retval
6979     0	ok
6980 */
do_update_pos(Relay_log_info * rli)6981 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
6982 {
6983   int error= 0;
6984   DBUG_ENTER("Rotate_log_event::do_update_pos");
6985 #ifndef DBUG_OFF
6986   char buf[32];
6987 #endif
6988 
6989   DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
6990                       (ulong) this->server_id, (ulong) ::server_id));
6991   DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
6992   DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
6993 
6994   /*
6995     If we are in a transaction or in a group: the only normal case is
6996     when the I/O thread was copying a big transaction, then it was
6997     stopped and restarted: we have this in the relay log:
6998 
6999     BEGIN
7000     ...
7001     ROTATE (a fake one)
7002     ...
7003     COMMIT or ROLLBACK
7004 
7005     In that case, we don't want to touch the coordinates which
7006     correspond to the beginning of the transaction.  Starting from
7007     5.0.0, there also are some rotates from the slave itself, in the
7008     relay log, which shall not change the group positions.
7009   */
7010 
7011   /*
7012     The way we check if SQL thread is currently in a group is different
7013     for STS and MTS.
7014   */
7015   bool in_group = rli->is_parallel_exec() ?
7016     (rli->mts_group_status == Relay_log_info::MTS_IN_GROUP) :
7017     rli->is_in_group();
7018 
7019   if ((server_id != ::server_id || rli->replicate_same_server_id) &&
7020       !is_relay_log_event() &&
7021       !in_group)
7022   {
7023     if (rli->is_parallel_exec())
7024     {
7025       /*
7026         Rotate events are special events that are handled as a
7027         synchronization point. For that reason, the checkpoint
7028         routine is being called here.
7029       */
7030       if ((error= mts_checkpoint_routine(rli, 0, false,
7031                                          true/*need_data_lock=true*/)))
7032         goto err;
7033     }
7034 
7035     mysql_mutex_lock(&rli->data_lock);
7036     DBUG_PRINT("info", ("old group_master_log_name: '%s'  "
7037                         "old group_master_log_pos: %lu",
7038                         rli->get_group_master_log_name(),
7039                         (ulong) rli->get_group_master_log_pos()));
7040 
7041     memcpy((void *)rli->get_group_master_log_name(),
7042            new_log_ident, ident_len + 1);
7043     rli->notify_group_master_log_name_update();
7044     if ((error= rli->inc_group_relay_log_pos(pos,
7045                                              false/*need_data_lock=false*/)))
7046     {
7047       mysql_mutex_unlock(&rli->data_lock);
7048       goto err;
7049     }
7050 
7051     DBUG_PRINT("info", ("new group_master_log_name: '%s'  "
7052                         "new group_master_log_pos: %lu",
7053                         rli->get_group_master_log_name(),
7054                         (ulong) rli->get_group_master_log_pos()));
7055     mysql_mutex_unlock(&rli->data_lock);
7056     if (rli->is_parallel_exec())
7057     {
7058       bool real_event= server_id && !is_artificial_event();
7059       rli->reset_notified_checkpoint(0,
7060                                      real_event ? when.tv_sec + (time_t) exec_time : 0,
7061                                      true/*need_data_lock=true*/);
7062     }
7063 
7064     /*
7065       Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
7066       a master's downgrade from 5.0 to 4.0.
7067       However, no need to reset rli_description_event: indeed, if the next
7068       master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
7069       master is 4.0 then the events are in the slave's format (conversion).
7070     */
7071     set_slave_thread_options(thd);
7072     set_slave_thread_default_charset(thd, rli);
7073     thd->variables.sql_mode= global_system_variables.sql_mode;
7074     thd->variables.auto_increment_increment=
7075       thd->variables.auto_increment_offset= 1;
7076   }
7077   else
7078     rli->inc_event_relay_log_pos();
7079 
7080 err:
7081   DBUG_RETURN(error);
7082 }
7083 
7084 
7085 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7086 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
7087 {
7088   enum_skip_reason reason= Log_event::do_shall_skip(rli);
7089 
7090   switch (reason) {
7091   case Log_event::EVENT_SKIP_NOT:
7092   case Log_event::EVENT_SKIP_COUNT:
7093     return Log_event::EVENT_SKIP_NOT;
7094 
7095   case Log_event::EVENT_SKIP_IGNORE:
7096     return Log_event::EVENT_SKIP_IGNORE;
7097   }
7098   DBUG_ASSERT(0);
7099   return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
7100 }
7101 
7102 #endif
7103 
7104 
7105 /**************************************************************************
7106 	Intvar_log_event methods
7107 **************************************************************************/
7108 
7109 /*
7110   Intvar_log_event::pack_info()
7111 */
7112 
7113 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7114 int Intvar_log_event::pack_info(Protocol *protocol)
7115 {
7116   char buf[256], *pos;
7117   pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
7118   *pos++= '=';
7119   pos= longlong10_to_str(val, pos, -10);
7120   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7121   return 0;
7122 }
7123 #endif
7124 
7125 
7126 /*
7127   Intvar_log_event::Intvar_log_event()
7128 */
7129 
Intvar_log_event(const char * buf,const Format_description_log_event * description_event)7130 Intvar_log_event::Intvar_log_event(const char* buf,
7131                                    const Format_description_log_event* description_event)
7132   :Log_event(buf, description_event)
7133 {
7134   /* The Post-Header is empty. The Varible Data part begins immediately. */
7135   buf+= description_event->common_header_len +
7136     description_event->post_header_len[INTVAR_EVENT-1];
7137   type= buf[I_TYPE_OFFSET];
7138   val= uint8korr(buf+I_VAL_OFFSET);
7139 }
7140 
7141 
7142 /*
7143   Intvar_log_event::get_var_type_name()
7144 */
7145 
get_var_type_name()7146 const char* Intvar_log_event::get_var_type_name()
7147 {
7148   switch(type) {
7149   case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
7150   case INSERT_ID_EVENT: return "INSERT_ID";
7151   default: /* impossible */ return "UNKNOWN";
7152   }
7153 }
7154 
7155 
7156 /*
7157   Intvar_log_event::write()
7158 */
7159 
7160 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7161 bool Intvar_log_event::write(IO_CACHE* file)
7162 {
7163   uchar buf[9];
7164   buf[I_TYPE_OFFSET]= (uchar) type;
7165   int8store(buf + I_VAL_OFFSET, val);
7166   return (write_header(file, sizeof(buf)) ||
7167           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7168 	  write_footer(file));
7169 }
7170 #endif
7171 
7172 
7173 /*
7174   Intvar_log_event::print()
7175 */
7176 
7177 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7178 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7179 {
7180   char llbuff[22];
7181   const char *msg;
7182   LINT_INIT(msg);
7183   IO_CACHE *const head= &print_event_info->head_cache;
7184 
7185   if (!print_event_info->short_form)
7186   {
7187     print_header(head, print_event_info, FALSE);
7188     my_b_printf(head, "\tIntvar\n");
7189   }
7190 
7191   my_b_printf(head, "SET ");
7192   switch (type) {
7193   case LAST_INSERT_ID_EVENT:
7194     msg="LAST_INSERT_ID";
7195     break;
7196   case INSERT_ID_EVENT:
7197     msg="INSERT_ID";
7198     break;
7199   case INVALID_INT_EVENT:
7200   default: // cannot happen
7201     msg="INVALID_INT";
7202     break;
7203   }
7204   my_b_printf(head, "%s=%s%s\n",
7205               msg, llstr(val,llbuff), print_event_info->delimiter);
7206 }
7207 #endif
7208 
7209 
7210 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
7211 
7212 /*
7213   Intvar_log_event::do_apply_event()
7214 */
7215 
do_apply_event(Relay_log_info const * rli)7216 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
7217 {
7218   /*
7219     We are now in a statement until the associated query log event has
7220     been processed.
7221    */
7222   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7223 
7224   if (rli->deferred_events_collecting)
7225     return rli->deferred_events->add(this);
7226 
7227   switch (type) {
7228   case LAST_INSERT_ID_EVENT:
7229     thd->first_successful_insert_id_in_prev_stmt= val;
7230     break;
7231   case INSERT_ID_EVENT:
7232     thd->force_one_auto_inc_interval(val);
7233     break;
7234   }
7235   return 0;
7236 }
7237 
do_update_pos(Relay_log_info * rli)7238 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
7239 {
7240   rli->inc_event_relay_log_pos();
7241   return 0;
7242 }
7243 
7244 
7245 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7246 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
7247 {
7248   /*
7249     It is a common error to set the slave skip counter to 1 instead of
7250     2 when recovering from an insert which used a auto increment,
7251     rand, or user var.  Therefore, if the slave skip counter is 1, we
7252     just say that this event should be skipped by ignoring it, meaning
7253     that we do not change the value of the slave skip counter since it
7254     will be decreased by the following insert event.
7255   */
7256   return continue_group(rli);
7257 }
7258 
7259 #endif
7260 
7261 
7262 /**************************************************************************
7263   Rand_log_event methods
7264 **************************************************************************/
7265 
7266 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7267 int Rand_log_event::pack_info(Protocol *protocol)
7268 {
7269   char buf1[256], *pos;
7270   pos= strmov(buf1,"rand_seed1=");
7271   pos= int10_to_str((long) seed1, pos, 10);
7272   pos= strmov(pos, ",rand_seed2=");
7273   pos= int10_to_str((long) seed2, pos, 10);
7274   protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
7275   return 0;
7276 }
7277 #endif
7278 
7279 
Rand_log_event(const char * buf,const Format_description_log_event * description_event)7280 Rand_log_event::Rand_log_event(const char* buf,
7281                                const Format_description_log_event* description_event)
7282   :Log_event(buf, description_event)
7283 {
7284   /* The Post-Header is empty. The Variable Data part begins immediately. */
7285   buf+= description_event->common_header_len +
7286     description_event->post_header_len[RAND_EVENT-1];
7287   seed1= uint8korr(buf+RAND_SEED1_OFFSET);
7288   seed2= uint8korr(buf+RAND_SEED2_OFFSET);
7289 }
7290 
7291 
7292 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7293 bool Rand_log_event::write(IO_CACHE* file)
7294 {
7295   uchar buf[16];
7296   int8store(buf + RAND_SEED1_OFFSET, seed1);
7297   int8store(buf + RAND_SEED2_OFFSET, seed2);
7298   return (write_header(file, sizeof(buf)) ||
7299           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7300 	  write_footer(file));
7301 }
7302 #endif
7303 
7304 
7305 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7306 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7307 {
7308   IO_CACHE *const head= &print_event_info->head_cache;
7309 
7310   char llbuff[22],llbuff2[22];
7311   if (!print_event_info->short_form)
7312   {
7313     print_header(head, print_event_info, FALSE);
7314     my_b_printf(head, "\tRand\n");
7315   }
7316   my_b_printf(head, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
7317               llstr(seed1, llbuff),llstr(seed2, llbuff2),
7318               print_event_info->delimiter);
7319 }
7320 #endif /* MYSQL_CLIENT */
7321 
7322 
7323 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)7324 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
7325 {
7326   /*
7327     We are now in a statement until the associated query log event has
7328     been processed.
7329    */
7330   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7331 
7332   if (rli->deferred_events_collecting)
7333     return rli->deferred_events->add(this);
7334 
7335   thd->rand.seed1= (ulong) seed1;
7336   thd->rand.seed2= (ulong) seed2;
7337   return 0;
7338 }
7339 
do_update_pos(Relay_log_info * rli)7340 int Rand_log_event::do_update_pos(Relay_log_info *rli)
7341 {
7342   rli->inc_event_relay_log_pos();
7343   return 0;
7344 }
7345 
7346 
7347 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7348 Rand_log_event::do_shall_skip(Relay_log_info *rli)
7349 {
7350   /*
7351     It is a common error to set the slave skip counter to 1 instead of
7352     2 when recovering from an insert which used a auto increment,
7353     rand, or user var.  Therefore, if the slave skip counter is 1, we
7354     just say that this event should be skipped by ignoring it, meaning
7355     that we do not change the value of the slave skip counter since it
7356     will be decreased by the following insert event.
7357   */
7358   return continue_group(rli);
7359 }
7360 
7361 /**
7362    Exec deferred Int-, Rand- and User- var events prefixing
7363    a Query-log-event event.
7364 
7365    @param thd THD handle
7366 
7367    @return false on success, true if a failure in an event applying occurred.
7368 */
slave_execute_deferred_events(THD * thd)7369 bool slave_execute_deferred_events(THD *thd)
7370 {
7371   bool res= false;
7372   Relay_log_info *rli= thd->rli_slave;
7373 
7374   DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
7375 
7376   if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
7377     return res;
7378 
7379   res= rli->deferred_events->execute(rli);
7380 
7381   return res;
7382 }
7383 
7384 #endif /* !MYSQL_CLIENT */
7385 
7386 
7387 /**************************************************************************
7388   Xid_log_event methods
7389 **************************************************************************/
7390 
7391 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7392 int Xid_log_event::pack_info(Protocol *protocol)
7393 {
7394   char buf[128], *pos;
7395   pos= strmov(buf, "COMMIT /* xid=");
7396   pos= longlong10_to_str(xid, pos, 10);
7397   pos= strmov(pos, " */");
7398   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7399   return 0;
7400 }
7401 #endif
7402 
7403 /**
7404   @note
7405   It's ok not to use int8store here,
7406   as long as xid_t::set(ulonglong) and
7407   xid_t::get_my_xid doesn't do it either.
7408   We don't care about actual values of xids as long as
7409   identical numbers compare identically
7410 */
7411 
7412 Xid_log_event::
Xid_log_event(const char * buf,const Format_description_log_event * description_event)7413 Xid_log_event(const char* buf,
7414               const Format_description_log_event *description_event)
7415   :Log_event(buf, description_event)
7416 {
7417   /* The Post-Header is empty. The Variable Data part begins immediately. */
7418   buf+= description_event->common_header_len +
7419     description_event->post_header_len[XID_EVENT-1];
7420   memcpy((char*) &xid, buf, sizeof(xid));
7421 }
7422 
7423 
7424 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7425 bool Xid_log_event::write(IO_CACHE* file)
7426 {
7427   DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
7428   return (write_header(file, sizeof(xid)) ||
7429 	  wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
7430 	  write_footer(file));
7431 }
7432 #endif
7433 
7434 
7435 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)7436 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7437 {
7438   IO_CACHE *const head= &print_event_info->head_cache;
7439 
7440   if (!print_event_info->short_form)
7441   {
7442     char buf[64];
7443     longlong10_to_str(xid, buf, 10);
7444 
7445     print_header(head, print_event_info, FALSE);
7446     my_b_printf(head, "\tXid = %s\n", buf);
7447   }
7448   my_b_printf(head, "COMMIT%s\n", print_event_info->delimiter);
7449 }
7450 #endif /* MYSQL_CLIENT */
7451 
7452 
7453 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7454 /**
7455    The methods combines few commit actions to make it useable
7456    as in the single- so multi- threaded case.
7457 
7458    @param  thd    a pointer to THD handle
7459    @return false  as success and
7460            true   as an error
7461 */
7462 
do_commit(THD * thd)7463 bool Xid_log_event::do_commit(THD *thd)
7464 {
7465   DBUG_EXECUTE_IF("dbug.reached_commit",
7466                   {DBUG_SET("+d,dbug.enabled_commit");});
7467   bool error= trans_commit(thd); /* Automatically rolls back on error. */
7468   DBUG_EXECUTE_IF("crash_after_apply",
7469                   sql_print_information("Crashing crash_after_apply.");
7470                   DBUG_SUICIDE(););
7471   thd->mdl_context.release_transactional_locks();
7472 
7473   if (thd->variables.gtid_next.type == GTID_GROUP &&
7474       thd->owned_gtid.sidno != 0)
7475   {
7476     // GTID logging and cleanup runs regardless of the current res
7477     error |= gtid_empty_group_log_and_cleanup(thd);
7478   }
7479 
7480   /*
7481     Increment the global status commit count variable
7482   */
7483   if (!error)
7484     status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
7485 
7486   return error;
7487 }
7488 
7489 /**
7490    Worker commits Xid transaction and in case of its transactional
7491    info table marks the current group as done in the Coordnator's
7492    Group Assigned Queue.
7493 
7494    @return zero as success or non-zero as an error
7495 */
do_apply_event_worker(Slave_worker * w)7496 int Xid_log_event::do_apply_event_worker(Slave_worker *w)
7497 {
7498   int error= 0;
7499   lex_start(thd);
7500   mysql_reset_thd_for_next_command(thd);
7501   Slave_committed_queue *coordinator_gaq= w->c_rli->gaq;
7502 
7503   /* For a slave Xid_log_event is COMMIT */
7504   general_log_print(thd, COM_QUERY,
7505                     "COMMIT /* implicit, from Xid_log_event */");
7506 
7507   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7508                      w->get_group_master_log_name(),
7509                      w->get_group_master_log_pos(),
7510                      w->get_group_relay_log_name(),
7511                      w->get_group_relay_log_pos(),
7512                      w->get_event_relay_log_name(),
7513                      w->get_event_relay_log_pos()));
7514 
7515   DBUG_EXECUTE_IF("crash_before_update_pos",
7516                   sql_print_information("Crashing crash_before_update_pos.");
7517                   DBUG_SUICIDE(););
7518 
7519   ulong gaq_idx= mts_group_idx;
7520   Slave_job_group *ptr_group= coordinator_gaq->get_job_group(gaq_idx);
7521 
7522   if ((error= w->commit_positions(this, ptr_group,
7523                                   w->c_rli->is_transactional())))
7524     goto err;
7525 
7526   DBUG_PRINT("mts", ("do_apply group master %s %llu  group relay %s %llu event %s %llu.",
7527                      w->get_group_master_log_name(),
7528                      w->get_group_master_log_pos(),
7529                      w->get_group_relay_log_name(),
7530                      w->get_group_relay_log_pos(),
7531                      w->get_event_relay_log_name(),
7532                      w->get_event_relay_log_pos()));
7533 
7534   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7535                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7536                   DBUG_SUICIDE(););
7537 
7538   error= do_commit(thd);
7539   if (error)
7540     w->rollback_positions(ptr_group);
7541 err:
7542   return error;
7543 }
7544 
do_apply_event(Relay_log_info const * rli)7545 int Xid_log_event::do_apply_event(Relay_log_info const *rli)
7546 {
7547   DBUG_ENTER("Xid_log_event::do_apply_event");
7548   int error= 0;
7549   char saved_group_master_log_name[FN_REFLEN];
7550   char saved_group_relay_log_name[FN_REFLEN];
7551   volatile my_off_t saved_group_master_log_pos;
7552   volatile my_off_t saved_group_relay_log_pos;
7553 
7554   char new_group_master_log_name[FN_REFLEN];
7555   char new_group_relay_log_name[FN_REFLEN];
7556   volatile my_off_t new_group_master_log_pos;
7557   volatile my_off_t new_group_relay_log_pos;
7558 
7559   lex_start(thd);
7560   mysql_reset_thd_for_next_command(thd);
7561   Relay_log_info *rli_ptr= const_cast<Relay_log_info *>(rli);
7562 
7563   /* For a slave Xid_log_event is COMMIT */
7564   general_log_print(thd, COM_QUERY,
7565                     "COMMIT /* implicit, from Xid_log_event */");
7566 
7567   mysql_mutex_lock(&rli_ptr->data_lock);
7568 
7569   /*
7570     Save the rli positions. We need them to temporarily reset the positions
7571     just before the commit.
7572    */
7573   strmake(saved_group_master_log_name, rli_ptr->get_group_master_log_name(),
7574           FN_REFLEN - 1);
7575   saved_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7576   strmake(saved_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7577           FN_REFLEN - 1);
7578   saved_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7579 
7580   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7581     rli_ptr->get_group_master_log_name(),
7582     rli_ptr->get_group_master_log_pos(),
7583     rli_ptr->get_group_relay_log_name(),
7584     rli_ptr->get_group_relay_log_pos(),
7585     rli_ptr->get_event_relay_log_name(),
7586     rli_ptr->get_event_relay_log_pos()));
7587 
7588   DBUG_EXECUTE_IF("crash_before_update_pos",
7589                   sql_print_information("Crashing crash_before_update_pos.");
7590                   DBUG_SUICIDE(););
7591 
7592   /*
7593     We need to update the positions in here to make it transactional.
7594   */
7595   rli_ptr->inc_event_relay_log_pos();
7596   rli_ptr->set_group_relay_log_pos(rli_ptr->get_event_relay_log_pos());
7597   rli_ptr->set_group_relay_log_name(rli_ptr->get_event_relay_log_name());
7598 
7599   rli_ptr->notify_group_relay_log_name_update();
7600 
7601   if (log_pos) // 3.23 binlogs don't have log_posx
7602     rli_ptr->set_group_master_log_pos(log_pos);
7603 
7604   /*
7605     rli repository being transactional means replication is crash safe.
7606     Positions are written into transactional tables ahead of commit and the
7607     changes are made permanent during commit.
7608    */
7609   if (rli_ptr->is_transactional())
7610   {
7611     if ((error= rli_ptr->flush_info(true)))
7612       goto err;
7613   }
7614 
7615   DBUG_PRINT("info", ("do_apply group master %s %llu  group relay %s %llu event %s %llu\n",
7616                       rli_ptr->get_group_master_log_name(),
7617                       rli_ptr->get_group_master_log_pos(),
7618                       rli_ptr->get_group_relay_log_name(),
7619                       rli_ptr->get_group_relay_log_pos(),
7620                       rli_ptr->get_event_relay_log_name(),
7621                       rli_ptr->get_event_relay_log_pos()));
7622 
7623   DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7624                   sql_print_information("Crashing crash_after_update_pos_before_apply.");
7625                   DBUG_SUICIDE(););
7626 
7627   /**
7628     Commit operation expects the global transaction state variable 'xa_state'to
7629     be set to 'XA_NOTR'. In order to simulate commit failure we set
7630     the 'xa_state' to 'XA_IDLE' so that the commit reports 'ER_XAER_RMFAIL'
7631     error.
7632    */
7633   DBUG_EXECUTE_IF("simulate_commit_failure",
7634                   {
7635                   thd->transaction.xid_state.xa_state = XA_IDLE;
7636                   });
7637 
7638   /*
7639     Save the new rli positions. These positions will be set back to group*
7640     positions on successful completion of the commit operation.
7641    */
7642   strmake(new_group_master_log_name, rli_ptr->get_group_master_log_name(),
7643           FN_REFLEN - 1);
7644   new_group_master_log_pos= rli_ptr->get_group_master_log_pos();
7645   strmake(new_group_relay_log_name, rli_ptr->get_group_relay_log_name(),
7646           FN_REFLEN - 1);
7647   new_group_relay_log_pos= rli_ptr->get_group_relay_log_pos();
7648   /*
7649     Rollback positions in memory just before commit. Position values will be
7650     reset to their new values only on successful commit operation.
7651    */
7652   rli_ptr->set_group_master_log_name(saved_group_master_log_name);
7653   rli_ptr->notify_group_master_log_name_update();
7654   rli_ptr->set_group_master_log_pos(saved_group_master_log_pos);
7655   rli_ptr->set_group_relay_log_name(saved_group_relay_log_name);
7656   rli_ptr->notify_group_relay_log_name_update();
7657   rli_ptr->set_group_relay_log_pos(saved_group_relay_log_pos);
7658 
7659   DBUG_PRINT("info", ("Rolling back to group master %s %llu  group relay %s"
7660                       " %llu\n", rli_ptr->get_group_master_log_name(),
7661                       rli_ptr->get_group_master_log_pos(),
7662                       rli_ptr->get_group_relay_log_name(),
7663                       rli_ptr->get_group_relay_log_pos()));
7664   mysql_mutex_unlock(&rli_ptr->data_lock);
7665   error= do_commit(thd);
7666   mysql_mutex_lock(&rli_ptr->data_lock);
7667   if (error)
7668   {
7669 #ifdef WITH_WSREP
7670     /* if slave transaction has to be replayed, do not report error message */
7671     if ((!WSREP(thd) || thd->wsrep_conflict_state != MUST_REPLAY))
7672 #endif /* WITH_WSREP */
7673     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
7674                 "Error in Xid_log_event: Commit could not be completed, '%s'",
7675                 thd->get_stmt_da()->message());
7676   }
7677   else
7678   {
7679     DBUG_EXECUTE_IF("crash_after_commit_before_update_pos",
7680                     sql_print_information("Crashing "
7681                                           "crash_after_commit_before_update_pos.");
7682                     DBUG_SUICIDE(););
7683     /* Update positions on successful commit */
7684     rli_ptr->set_group_master_log_name(new_group_master_log_name);
7685     rli_ptr->notify_group_master_log_name_update();
7686     rli_ptr->set_group_master_log_pos(new_group_master_log_pos);
7687     rli_ptr->set_group_relay_log_name(new_group_relay_log_name);
7688     rli_ptr->notify_group_relay_log_name_update();
7689     rli_ptr->set_group_relay_log_pos(new_group_relay_log_pos);
7690 
7691     DBUG_PRINT("info", ("Updating positions on succesful commit to group master"
7692                         " %s %llu  group relay %s %llu\n",
7693                         rli_ptr->get_group_master_log_name(),
7694                         rli_ptr->get_group_master_log_pos(),
7695                         rli_ptr->get_group_relay_log_name(),
7696                         rli_ptr->get_group_relay_log_pos()));
7697 
7698     /*
7699       For transactional repository the positions are flushed ahead of commit.
7700       Where as for non transactional rli repository the positions are flushed
7701       only on succesful commit.
7702      */
7703     if (!rli_ptr->is_transactional())
7704       rli_ptr->flush_info(false);
7705   }
7706 err:
7707   mysql_cond_broadcast(&rli_ptr->data_cond);
7708   mysql_mutex_unlock(&rli_ptr->data_lock);
7709 
7710   DBUG_RETURN(error);
7711 }
7712 
7713 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)7714 Xid_log_event::do_shall_skip(Relay_log_info *rli)
7715 {
7716   DBUG_ENTER("Xid_log_event::do_shall_skip");
7717   if (rli->slave_skip_counter > 0) {
7718     thd->variables.option_bits&= ~OPTION_BEGIN;
7719     DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
7720   }
7721   DBUG_RETURN(Log_event::do_shall_skip(rli));
7722 }
7723 #endif /* !MYSQL_CLIENT */
7724 
7725 
7726 /**************************************************************************
7727   User_var_log_event methods
7728 **************************************************************************/
7729 
7730 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)7731 int User_var_log_event::pack_info(Protocol* protocol)
7732 {
7733   char *buf= 0;
7734   char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
7735   int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len);
7736   quoted_id[id_len]= '\0';
7737   uint val_offset= 2 + id_len;
7738   uint event_len= val_offset;
7739 
7740   if (is_null)
7741   {
7742     if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
7743       return 1;
7744     strmov(buf + val_offset, "NULL");
7745     event_len= val_offset + 4;
7746   }
7747   else
7748   {
7749     switch (type) {
7750     case REAL_RESULT:
7751       double real_val;
7752       float8get(real_val, val);
7753       if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
7754                                    MYF(MY_WME))))
7755         return 1;
7756       event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
7757                           buf + val_offset, NULL);
7758       break;
7759     case INT_RESULT:
7760       if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
7761         return 1;
7762       event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
7763                                    ((flags & User_var_log_event::UNSIGNED_F) ?
7764                                     10 : -10))-buf;
7765       break;
7766     case DECIMAL_RESULT:
7767     {
7768       if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH + 1,
7769                                    MYF(MY_WME))))
7770         return 1;
7771       String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin);
7772       my_decimal dec;
7773       binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
7774                         val[1]);
7775       my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
7776       event_len= str.length() + val_offset;
7777       break;
7778     }
7779     case STRING_RESULT:
7780       /* 15 is for 'COLLATE' and other chars */
7781       buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
7782                              MYF(MY_WME));
7783       CHARSET_INFO *cs;
7784       if (!buf)
7785         return 1;
7786       if (!(cs= get_charset(charset_number, MYF(0))))
7787       {
7788         strmov(buf+val_offset, "???");
7789         event_len+= 3;
7790       }
7791       else
7792       {
7793         char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
7794         p= str_to_hex(p, val, val_len);
7795         p= strxmov(p, " COLLATE ", cs->name, NullS);
7796         event_len= p-buf;
7797       }
7798       break;
7799     case ROW_RESULT:
7800     default:
7801       DBUG_ASSERT(1);
7802       return 1;
7803     }
7804   }
7805   buf[0]= '@';
7806   memcpy(buf + 1, quoted_id, id_len);
7807   buf[1 + id_len]= '=';
7808   protocol->store(buf, event_len, &my_charset_bin);
7809   my_free(buf);
7810   return 0;
7811 }
7812 #endif /* !MYSQL_CLIENT */
7813 
7814 
7815 User_var_log_event::
User_var_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)7816 User_var_log_event(const char* buf, uint event_len,
7817                    const Format_description_log_event* description_event)
7818   :Log_event(buf, description_event)
7819 #ifndef MYSQL_CLIENT
7820   , deferred(false), query_id(0)
7821 #endif
7822 {
7823   bool error= false;
7824   const char* buf_start= buf;
7825   /* The Post-Header is empty. The Variable Data part begins immediately. */
7826   const char *start= buf;
7827   buf+= description_event->common_header_len +
7828     description_event->post_header_len[USER_VAR_EVENT-1];
7829   name_len= uint4korr(buf);
7830   /* Avoid reading out of buffer */
7831   if ((buf - buf_start) + UV_NAME_LEN_SIZE + name_len > event_len)
7832   {
7833     error= true;
7834     goto err;
7835   }
7836 
7837   name= (char *) buf + UV_NAME_LEN_SIZE;
7838 
7839   /*
7840     We don't know yet is_null value, so we must assume that name_len
7841     may have the bigger value possible, is_null= True and there is no
7842     payload for val, or even that name_len is 0.
7843   */
7844   if (!valid_buffer_range<uint>(name_len, buf_start, name,
7845                                 event_len - UV_VAL_IS_NULL))
7846   {
7847     error= true;
7848     goto err;
7849   }
7850 
7851   buf+= UV_NAME_LEN_SIZE + name_len;
7852   is_null= (bool) *buf;
7853   flags= User_var_log_event::UNDEF_F;    // defaults to UNDEF_F
7854   if (is_null)
7855   {
7856     type= STRING_RESULT;
7857     charset_number= my_charset_bin.number;
7858     val_len= 0;
7859     val= 0;
7860   }
7861   else
7862   {
7863     if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
7864                                   + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
7865                                   buf_start, buf, event_len))
7866     {
7867       error= true;
7868       goto err;
7869     }
7870 
7871     type= (Item_result) buf[UV_VAL_IS_NULL];
7872     charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
7873     val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7874                        UV_CHARSET_NUMBER_SIZE);
7875     val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7876                    UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
7877 
7878     if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
7879     {
7880       error= true;
7881       goto err;
7882     }
7883 
7884     /**
7885       We need to check if this is from an old server
7886       that did not pack information for flags.
7887       We do this by checking if there are extra bytes
7888       after the packed value. If there are we take the
7889       extra byte and it's value is assumed to contain
7890       the flags value.
7891 
7892       Old events will not have this extra byte, thence,
7893       we keep the flags set to UNDEF_F.
7894     */
7895     uint bytes_read= ((val + val_len) - start);
7896     if (bytes_read > event_len)
7897     {
7898       error= true;
7899       goto err;
7900     }
7901 #ifndef DBUG_OFF
7902     bool old_pre_checksum_fd= description_event->is_version_before_checksum();
7903 #endif
7904     DBUG_ASSERT((bytes_read == data_written -
7905                  (old_pre_checksum_fd ||
7906                   (description_event->checksum_alg ==
7907                    BINLOG_CHECKSUM_ALG_OFF)) ?
7908                  0 : BINLOG_CHECKSUM_LEN)
7909                 ||
7910                 (bytes_read == data_written -1 -
7911                  (old_pre_checksum_fd ||
7912                   (description_event->checksum_alg ==
7913                    BINLOG_CHECKSUM_ALG_OFF)) ?
7914                  0 : BINLOG_CHECKSUM_LEN));
7915     if ((data_written - bytes_read) > 0)
7916     {
7917       flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7918                     UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
7919                     val_len);
7920     }
7921   }
7922 
7923 err:
7924   if (error)
7925     name= 0;
7926 }
7927 
7928 
7929 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)7930 bool User_var_log_event::write(IO_CACHE* file)
7931 {
7932   char buf[UV_NAME_LEN_SIZE];
7933   char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7934 	    UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
7935   uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
7936   uint unsigned_len= 0;
7937   uint buf1_length;
7938   ulong event_length;
7939 
7940   int4store(buf, name_len);
7941 
7942   if ((buf1[0]= is_null))
7943   {
7944     buf1_length= 1;
7945     val_len= 0;                                 // Length of 'pos'
7946   }
7947   else
7948   {
7949     buf1[1]= type;
7950     int4store(buf1 + 2, charset_number);
7951 
7952     switch (type) {
7953     case REAL_RESULT:
7954       float8store(buf2, *(double*) val);
7955       break;
7956     case INT_RESULT:
7957       int8store(buf2, *(longlong*) val);
7958       unsigned_len= 1;
7959       break;
7960     case DECIMAL_RESULT:
7961     {
7962       my_decimal *dec= (my_decimal *)val;
7963       dec->fix_buffer_pointer();
7964       buf2[0]= (char)(dec->intg + dec->frac);
7965       buf2[1]= (char)dec->frac;
7966       decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
7967       val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
7968       break;
7969     }
7970     case STRING_RESULT:
7971       pos= (uchar*) val;
7972       break;
7973     case ROW_RESULT:
7974     default:
7975       DBUG_ASSERT(1);
7976       return 0;
7977     }
7978     int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
7979     buf1_length= 10;
7980   }
7981 
7982   /* Length of the whole event */
7983   event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
7984 
7985   return (write_header(file, event_length) ||
7986           wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
7987 	  wrapper_my_b_safe_write(file, (uchar*) name, name_len)     ||
7988 	  wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
7989 	  wrapper_my_b_safe_write(file, pos, val_len) ||
7990           wrapper_my_b_safe_write(file, &flags, unsigned_len) ||
7991 	  write_footer(file));
7992 }
7993 #endif
7994 
7995 
7996 /*
7997   User_var_log_event::print()
7998 */
7999 
8000 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8001 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8002 {
8003   IO_CACHE *const head= &print_event_info->head_cache;
8004   char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
8005   char name_id[NAME_LEN];
8006   int quoted_len= 0;
8007 
8008   if (!print_event_info->short_form)
8009   {
8010     print_header(head, print_event_info, FALSE);
8011     my_b_printf(head, "\tUser_var\n");
8012   }
8013   strmov(name_id, name);
8014   name_id[name_len]= '\0';
8015   my_b_printf(head, "SET @");
8016   quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
8017                                           (const char *) name_id);
8018   quoted_id[quoted_len]= '\0';
8019   my_b_write(head, (uchar*) quoted_id, quoted_len);
8020 
8021   if (is_null)
8022   {
8023     my_b_printf(head, ":=NULL%s\n", print_event_info->delimiter);
8024   }
8025   else
8026   {
8027     switch (type) {
8028     case REAL_RESULT:
8029       double real_val;
8030       char real_buf[FMT_G_BUFSIZE(14)];
8031       float8get(real_val, val);
8032       sprintf(real_buf, "%.14g", real_val);
8033       my_b_printf(head, ":=%s%s\n", real_buf, print_event_info->delimiter);
8034       break;
8035     case INT_RESULT:
8036       char int_buf[22];
8037       longlong10_to_str(uint8korr(val), int_buf,
8038                         ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
8039       my_b_printf(head, ":=%s%s\n", int_buf, print_event_info->delimiter);
8040       break;
8041     case DECIMAL_RESULT:
8042     {
8043       char str_buf[200];
8044       int str_len= sizeof(str_buf) - 1;
8045       int precision= (int)val[0];
8046       int scale= (int)val[1];
8047       decimal_digit_t dec_buf[10];
8048       decimal_t dec;
8049       dec.len= 10;
8050       dec.buf= dec_buf;
8051 
8052       bin2decimal((uchar*) val+2, &dec, precision, scale);
8053       decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
8054       str_buf[str_len]= 0;
8055       my_b_printf(head, ":=%s%s\n", str_buf, print_event_info->delimiter);
8056       break;
8057     }
8058     case STRING_RESULT:
8059     {
8060       /*
8061         Let's express the string in hex. That's the most robust way. If we
8062         print it in character form instead, we need to escape it with
8063         character_set_client which we don't know (we will know it in 5.0, but
8064         in 4.1 we don't know it easily when we are printing
8065         User_var_log_event). Explanation why we would need to bother with
8066         character_set_client (quoting Bar):
8067         > Note, the parser doesn't switch to another unescaping mode after
8068         > it has met a character set introducer.
8069         > For example, if an SJIS client says something like:
8070         > SET @a= _ucs2 \0a\0b'
8071         > the string constant is still unescaped according to SJIS, not
8072         > according to UCS2.
8073       */
8074       char *hex_str;
8075       CHARSET_INFO *cs;
8076 
8077       hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
8078       if (!hex_str)
8079         return;
8080       str_to_hex(hex_str, val, val_len);
8081       /*
8082         For proper behaviour when mysqlbinlog|mysql, we need to explicitely
8083         specify the variable's collation. It will however cause problems when
8084         people want to mysqlbinlog|mysql into another server not supporting the
8085         character set. But there's not much to do about this and it's unlikely.
8086       */
8087       if (!(cs= get_charset(charset_number, MYF(0))))
8088         /*
8089           Generate an unusable command (=> syntax error) is probably the best
8090           thing we can do here.
8091         */
8092         my_b_printf(head, ":=???%s\n", print_event_info->delimiter);
8093       else
8094         my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n",
8095                     cs->csname, hex_str, cs->name,
8096                     print_event_info->delimiter);
8097       my_free(hex_str);
8098     }
8099       break;
8100     case ROW_RESULT:
8101     default:
8102       DBUG_ASSERT(1);
8103       return;
8104     }
8105   }
8106 }
8107 #endif
8108 
8109 
8110 /*
8111   User_var_log_event::do_apply_event()
8112 */
8113 
8114 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8115 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
8116 {
8117   Item *it= 0;
8118   CHARSET_INFO *charset;
8119   query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
8120 
8121   if (rli->deferred_events_collecting)
8122   {
8123     set_deferred(current_thd->query_id);
8124     return rli->deferred_events->add(this);
8125   } else if (is_deferred())
8126   {
8127     sav_query_id= current_thd->query_id;
8128     current_thd->query_id= query_id; /* recreating original time context */
8129   }
8130 
8131   if (!(charset= get_charset(charset_number, MYF(MY_WME))))
8132   {
8133     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8134                 ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8135                 "Invalid character set for User var event");
8136     return 1;
8137   }
8138   double real_val;
8139   longlong int_val;
8140 
8141   /*
8142     We are now in a statement until the associated query log event has
8143     been processed.
8144    */
8145   const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
8146 
8147   if (is_null)
8148   {
8149     it= new Item_null();
8150   }
8151   else
8152   {
8153     switch (type) {
8154     case REAL_RESULT:
8155       if (val_len != 8)
8156       {
8157         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8158                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8159                     "Invalid variable length at User var event");
8160         return 1;
8161       }
8162       float8get(real_val, val);
8163       it= new Item_float(real_val, 0);
8164       val= (char*) &real_val;		// Pointer to value in native format
8165       val_len= 8;
8166       break;
8167     case INT_RESULT:
8168       if (val_len != 8)
8169       {
8170         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8171                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8172                     "Invalid variable length at User var event");
8173         return 1;
8174       }
8175       int_val= (longlong) uint8korr(val);
8176       it= new Item_int(int_val);
8177       val= (char*) &int_val;		// Pointer to value in native format
8178       val_len= 8;
8179       break;
8180     case DECIMAL_RESULT:
8181     {
8182       if (val_len < 3)
8183       {
8184         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8185                     ER_THD(thd, ER_SLAVE_FATAL_ERROR),
8186                     "Invalid variable length at User var event");
8187         return 1;
8188       }
8189       Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
8190       it= dec;
8191       val= (char *)dec->val_decimal(NULL);
8192       val_len= sizeof(my_decimal);
8193       break;
8194     }
8195     case STRING_RESULT:
8196       it= new Item_string(val, val_len, charset);
8197       break;
8198     case ROW_RESULT:
8199     default:
8200       DBUG_ASSERT(1);
8201       return 0;
8202     }
8203   }
8204   Item_func_set_user_var *e=
8205     new Item_func_set_user_var(Name_string(name, name_len, false), it, false);
8206   /*
8207     Item_func_set_user_var can't substitute something else on its place =>
8208     0 can be passed as last argument (reference on item)
8209 
8210     Fix_fields() can fail, in which case a call of update_hash() might
8211     crash the server, so if fix fields fails, we just return with an
8212     error.
8213   */
8214   if (e->fix_fields(thd, 0))
8215     return 1;
8216 
8217   /*
8218     A variable can just be considered as a table with
8219     a single record and with a single column. Thus, like
8220     a column value, it could always have IMPLICIT derivation.
8221    */
8222   e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
8223                  (flags & User_var_log_event::UNSIGNED_F));
8224   if (!is_deferred())
8225     free_root(thd->mem_root, 0);
8226   else
8227     current_thd->query_id= sav_query_id; /* restore current query's context */
8228 
8229   return 0;
8230 }
8231 
do_update_pos(Relay_log_info * rli)8232 int User_var_log_event::do_update_pos(Relay_log_info *rli)
8233 {
8234   rli->inc_event_relay_log_pos();
8235   return 0;
8236 }
8237 
8238 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)8239 User_var_log_event::do_shall_skip(Relay_log_info *rli)
8240 {
8241   /*
8242     It is a common error to set the slave skip counter to 1 instead
8243     of 2 when recovering from an insert which used a auto increment,
8244     rand, or user var.  Therefore, if the slave skip counter is 1, we
8245     just say that this event should be skipped by ignoring it, meaning
8246     that we do not change the value of the slave skip counter since it
8247     will be decreased by the following insert event.
8248   */
8249   return continue_group(rli);
8250 }
8251 #endif /* !MYSQL_CLIENT */
8252 
8253 
8254 /**************************************************************************
8255   Unknown_log_event methods
8256 **************************************************************************/
8257 
8258 #ifdef HAVE_REPLICATION
8259 #ifdef MYSQL_CLIENT
print(FILE * file_arg,PRINT_EVENT_INFO * print_event_info)8260 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
8261 {
8262   if (print_event_info->short_form)
8263     return;
8264   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8265   my_b_printf(&print_event_info->head_cache, "\n# %s", "Unknown event\n");
8266 }
8267 #endif
8268 
8269 /**************************************************************************
8270 	Stop_log_event methods
8271 **************************************************************************/
8272 
8273 /*
8274   Stop_log_event::print()
8275 */
8276 
8277 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8278 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8279 {
8280   if (print_event_info->short_form)
8281     return;
8282 
8283   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8284   my_b_printf(&print_event_info->head_cache, "\tStop\n");
8285 }
8286 #endif /* MYSQL_CLIENT */
8287 
8288 
8289 #ifndef MYSQL_CLIENT
8290 /*
8291   The master stopped.  We used to clean up all temporary tables but
8292   this is useless as, as the master has shut down properly, it has
8293   written all DROP TEMPORARY TABLE (prepared statements' deletion is
8294   TODO only when we binlog prep stmts).  We used to clean up
8295   slave_load_tmpdir, but this is useless as it has been cleared at the
8296   end of LOAD DATA INFILE.  So we have nothing to do here.  The place
8297   were we must do this cleaning is in
8298   Start_log_event_v3::do_apply_event(), not here. Because if we come
8299   here, the master was sane.
8300 
8301   This must only be called from the Slave SQL thread, since it calls
8302   flush_relay_log_info().
8303 */
do_update_pos(Relay_log_info * rli)8304 int Stop_log_event::do_update_pos(Relay_log_info *rli)
8305 {
8306   int error_inc= 0;
8307   int error_flush= 0;
8308   /*
8309     We do not want to update master_log pos because we get a rotate event
8310     before stop, so by now group_master_log_name is set to the next log.
8311     If we updated it, we will have incorrect master coordinates and this
8312     could give false triggers in MASTER_POS_WAIT() that we have reached
8313     the target position when in fact we have not.
8314     The group position is always unchanged in MTS mode because the event
8315     is never executed so can't be scheduled to a Worker.
8316   */
8317   if ((thd->variables.option_bits & OPTION_BEGIN) || rli->is_parallel_exec())
8318     rli->inc_event_relay_log_pos();
8319   else
8320   {
8321     error_inc= rli->inc_group_relay_log_pos(0, true/*need_data_lock=true*/);
8322     error_flush= rli->flush_info(TRUE);
8323   }
8324   return (error_inc || error_flush);
8325 }
8326 
8327 #endif /* !MYSQL_CLIENT */
8328 #endif /* HAVE_REPLICATION */
8329 
8330 
8331 /**************************************************************************
8332 	Create_file_log_event methods
8333 **************************************************************************/
8334 
8335 /*
8336   Create_file_log_event ctor
8337 */
8338 
8339 #ifndef MYSQL_CLIENT
8340 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)8341 Create_file_log_event(THD* thd_arg, sql_exchange* ex,
8342 		      const char* db_arg, const char* table_name_arg,
8343                       List<Item>& fields_arg,
8344                       bool is_concurrent_arg,
8345                       enum enum_duplicates handle_dup,
8346                       bool ignore,
8347 		      uchar* block_arg, uint block_len_arg, bool using_trans)
8348   :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
8349                   is_concurrent_arg,
8350                   handle_dup, ignore, using_trans),
8351    fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
8352    file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
8353 {
8354   DBUG_ENTER("Create_file_log_event");
8355   sql_ex.force_new_format();
8356   DBUG_VOID_RETURN;
8357 }
8358 
8359 
8360 /*
8361   Create_file_log_event::write_data_body()
8362 */
8363 
write_data_body(IO_CACHE * file)8364 bool Create_file_log_event::write_data_body(IO_CACHE* file)
8365 {
8366   bool res;
8367   if ((res= Load_log_event::write_data_body(file)) || fake_base)
8368     return res;
8369   return (my_b_safe_write(file, (uchar*) "", 1) ||
8370           my_b_safe_write(file, (uchar*) block, block_len));
8371 }
8372 
8373 
8374 /*
8375   Create_file_log_event::write_data_header()
8376 */
8377 
write_data_header(IO_CACHE * file)8378 bool Create_file_log_event::write_data_header(IO_CACHE* file)
8379 {
8380   bool res;
8381   uchar buf[CREATE_FILE_HEADER_LEN];
8382   if ((res= Load_log_event::write_data_header(file)) || fake_base)
8383     return res;
8384   int4store(buf + CF_FILE_ID_OFFSET, file_id);
8385   return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
8386 }
8387 
8388 
8389 /*
8390   Create_file_log_event::write_base()
8391 */
8392 
write_base(IO_CACHE * file)8393 bool Create_file_log_event::write_base(IO_CACHE* file)
8394 {
8395   bool res;
8396   fake_base= 1;                                 // pretend we are Load event
8397   res= write(file);
8398   fake_base= 0;
8399   return res;
8400 }
8401 
8402 #endif /* !MYSQL_CLIENT */
8403 
8404 /*
8405   Create_file_log_event ctor
8406 */
8407 
Create_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8408 Create_file_log_event::Create_file_log_event(const char* buf, uint len,
8409                                              const Format_description_log_event* description_event)
8410   :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
8411 {
8412   DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
8413   uint block_offset;
8414   uint header_len= description_event->common_header_len;
8415   uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
8416   uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
8417   if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
8418       copy_log_event(event_buf,len,
8419                      ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
8420                       load_header_len + header_len :
8421                       (fake_base ? (header_len+load_header_len) :
8422                        (header_len+load_header_len) +
8423                        create_file_header_len)),
8424                      description_event))
8425     DBUG_VOID_RETURN;
8426   if (description_event->binlog_version!=1)
8427   {
8428     file_id= uint4korr(buf +
8429                        header_len +
8430 		       load_header_len + CF_FILE_ID_OFFSET);
8431     /*
8432       Note that it's ok to use get_data_size() below, because it is computed
8433       with values we have already read from this event (because we called
8434       copy_log_event()); we are not using slave's format info to decode
8435       master's format, we are really using master's format info.
8436       Anyway, both formats should be identical (except the common_header_len)
8437       as these Load events are not changed between 4.0 and 5.0 (as logging of
8438       LOAD DATA INFILE does not use Load_log_event in 5.0).
8439 
8440       The + 1 is for \0 terminating fname
8441     */
8442     block_offset= (description_event->common_header_len +
8443                    Load_log_event::get_data_size() +
8444                    create_file_header_len + 1);
8445     if (len < block_offset)
8446       DBUG_VOID_RETURN;
8447     block = (uchar*)buf + block_offset;
8448     block_len = len - block_offset;
8449   }
8450   else
8451   {
8452     sql_ex.force_new_format();
8453     inited_from_old = 1;
8454   }
8455   DBUG_VOID_RETURN;
8456 }
8457 
8458 
8459 /*
8460   Create_file_log_event::print()
8461 */
8462 
8463 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info,bool enable_local)8464 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
8465 				  bool enable_local)
8466 {
8467   if (print_event_info->short_form)
8468   {
8469     if (enable_local && check_fname_outside_temp_buf())
8470       Load_log_event::print(file, print_event_info);
8471     return;
8472   }
8473 
8474   if (enable_local)
8475   {
8476     Load_log_event::print(file, print_event_info,
8477 			  !check_fname_outside_temp_buf());
8478     /**
8479       reduce the size of io cache so that the write function is called
8480       for every call to my_b_printf().
8481      */
8482     DBUG_EXECUTE_IF ("simulate_create_event_write_error",
8483                      {(&print_event_info->head_cache)->write_pos=
8484                      (&print_event_info->head_cache)->write_end;
8485                      DBUG_SET("+d,simulate_file_write_error");});
8486     /*
8487        That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
8488        SHOW BINLOG EVENTS we don't.
8489     */
8490     my_b_printf(&print_event_info->head_cache, "#");
8491   }
8492 
8493   my_b_printf(&print_event_info->head_cache,
8494               " file_id: %d  block_len: %d\n", file_id, block_len);
8495 }
8496 
8497 
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8498 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8499 {
8500   print(file, print_event_info, 0);
8501 }
8502 #endif /* MYSQL_CLIENT */
8503 
8504 
8505 /*
8506   Create_file_log_event::pack_info()
8507 */
8508 
8509 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8510 int Create_file_log_event::pack_info(Protocol *protocol)
8511 {
8512   char buf[NAME_LEN*2 + 30 + 21*2], *pos;
8513   pos= strmov(buf, "db=");
8514   memcpy(pos, db, db_len);
8515   pos= strmov(pos + db_len, ";table=");
8516   memcpy(pos, table_name, table_name_len);
8517   pos= strmov(pos + table_name_len, ";file_id=");
8518   pos= int10_to_str((long) file_id, pos, 10);
8519   pos= strmov(pos, ";block_len=");
8520   pos= int10_to_str((long) block_len, pos, 10);
8521   protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8522   return 0;
8523 }
8524 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8525 
8526 
8527 /**
8528   Create_file_log_event::do_apply_event()
8529   Constructor for Create_file_log_event to intantiate an event
8530   from the relay log on the slave.
8531 
8532   @retval
8533     0           Success
8534   @retval
8535     1           Failure
8536 */
8537 
8538 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8539 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
8540 {
8541   char fname_buf[FN_REFLEN+TEMP_FILE_MAX_LEN];
8542   char *ext;
8543   int fd = -1;
8544   IO_CACHE file;
8545   int error = 1;
8546 
8547   lex_start(thd);
8548   mysql_reset_thd_for_next_command(thd);
8549   THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
8550   memset(&file, 0, sizeof(file));
8551   ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
8552   /* old copy may exist already */
8553   mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8554   /**
8555     To simulate file creation failure, convert the file name to a
8556     directory by appending a "/" to the file name.
8557    */
8558   DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event",
8559                   {
8560                   strcat(fname_buf,"/");
8561                   });
8562   if ((fd= mysql_file_create(key_file_log_event_info,
8563                              fname_buf, CREATE_MODE,
8564                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8565                              MYF(MY_WME))) < 0 ||
8566       init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
8567 		    MYF(MY_WME|MY_NABP)))
8568   {
8569     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8570                 "Error in Create_file event: could not open file '%s'",
8571                 fname_buf);
8572     goto err;
8573   }
8574 
8575   // a trick to avoid allocating another buffer
8576   fname= fname_buf;
8577   fname_len= (uint) (strmov(ext, ".data") - fname);
8578   if (write_base(&file))
8579   {
8580     strmov(ext, ".info"); // to have it right in the error message
8581     rli->report(ERROR_LEVEL, my_errno,
8582                 "Error in Create_file event: could not write to file '%s'",
8583                 fname_buf);
8584     goto err;
8585   }
8586   end_io_cache(&file);
8587   mysql_file_close(fd, MYF(0));
8588 
8589   // fname_buf now already has .data, not .info, because we did our trick
8590   /* old copy may exist already */
8591   mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8592   if ((fd= mysql_file_create(key_file_log_event_data,
8593                              fname_buf, CREATE_MODE,
8594                              O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8595                              MYF(MY_WME))) < 0)
8596   {
8597     rli->report(ERROR_LEVEL, my_errno,
8598                 "Error in Create_file event: could not open file '%s'",
8599                 fname_buf);
8600     goto err;
8601   }
8602   /**
8603     To simulate file write failure,close the file before the write operation.
8604     Write will fail with an error reporting file is UNOPENED.
8605    */
8606   DBUG_EXECUTE_IF("simulate_file_write_error_create_log_event",
8607                   {
8608                   mysql_file_close(fd, MYF(0));
8609                   });
8610   if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8611   {
8612     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8613                 "Error in Create_file event: write to '%s' failed",
8614                 fname_buf);
8615     goto err;
8616   }
8617   error=0;					// Everything is ok
8618 
8619 err:
8620   if (error)
8621     end_io_cache(&file);
8622   if (fd >= 0)
8623     mysql_file_close(fd, MYF(0));
8624   return error != 0;
8625 }
8626 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8627 
8628 
8629 /**************************************************************************
8630 	Append_block_log_event methods
8631 **************************************************************************/
8632 
8633 /*
8634   Append_block_log_event ctor
8635 */
8636 
8637 #ifndef MYSQL_CLIENT
Append_block_log_event(THD * thd_arg,const char * db_arg,uchar * block_arg,uint block_len_arg,bool using_trans)8638 Append_block_log_event::Append_block_log_event(THD *thd_arg,
8639                                                const char *db_arg,
8640 					       uchar *block_arg,
8641 					       uint block_len_arg,
8642 					       bool using_trans)
8643   :Log_event(thd_arg, 0,
8644              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8645                            Log_event::EVENT_STMT_CACHE,
8646              Log_event::EVENT_NORMAL_LOGGING),
8647    block(block_arg),
8648    block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
8649 {
8650 }
8651 #endif
8652 
8653 
8654 /*
8655   Append_block_log_event ctor
8656 */
8657 
Append_block_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8658 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
8659                                                const Format_description_log_event* description_event)
8660   :Log_event(buf, description_event),block(0)
8661 {
8662   DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
8663   uint8 common_header_len= description_event->common_header_len;
8664   uint8 append_block_header_len=
8665     description_event->post_header_len[APPEND_BLOCK_EVENT-1];
8666   uint total_header_len= common_header_len+append_block_header_len;
8667   if (len < total_header_len)
8668     DBUG_VOID_RETURN;
8669   file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
8670   block= (uchar*)buf + total_header_len;
8671   block_len= len - total_header_len;
8672   DBUG_VOID_RETURN;
8673 }
8674 
8675 
8676 /*
8677   Append_block_log_event::write()
8678 */
8679 
8680 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8681 bool Append_block_log_event::write(IO_CACHE* file)
8682 {
8683   uchar buf[APPEND_BLOCK_HEADER_LEN];
8684   int4store(buf + AB_FILE_ID_OFFSET, file_id);
8685   return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
8686           wrapper_my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
8687 	  wrapper_my_b_safe_write(file, (uchar*) block, block_len) ||
8688 	  write_footer(file));
8689 }
8690 #endif
8691 
8692 
8693 /*
8694   Append_block_log_event::print()
8695 */
8696 
8697 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8698 void Append_block_log_event::print(FILE* file,
8699 				   PRINT_EVENT_INFO* print_event_info)
8700 {
8701   if (print_event_info->short_form)
8702     return;
8703   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8704   my_b_printf(&print_event_info->head_cache,
8705               "\n#%s: file_id: %d  block_len: %d\n",
8706               get_type_str(), file_id, block_len);
8707 }
8708 #endif /* MYSQL_CLIENT */
8709 
8710 
8711 /*
8712   Append_block_log_event::pack_info()
8713 */
8714 
8715 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8716 int Append_block_log_event::pack_info(Protocol *protocol)
8717 {
8718   char buf[256];
8719   size_t length;
8720   length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
8721                       file_id, block_len);
8722   protocol->store(buf, length, &my_charset_bin);
8723   return 0;
8724 }
8725 
8726 
8727 /*
8728   Append_block_log_event::get_create_or_append()
8729 */
8730 
get_create_or_append() const8731 int Append_block_log_event::get_create_or_append() const
8732 {
8733   return 0; /* append to the file, fail if not exists */
8734 }
8735 
8736 /*
8737   Append_block_log_event::do_apply_event()
8738 */
8739 
do_apply_event(Relay_log_info const * rli)8740 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
8741 {
8742   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8743   int fd;
8744   int error = 1;
8745   DBUG_ENTER("Append_block_log_event::do_apply_event");
8746 
8747   THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
8748   slave_load_file_stem(fname, file_id, server_id, ".data");
8749   if (get_create_or_append())
8750   {
8751     /*
8752       Usually lex_start() is called by mysql_parse(), but we need it here
8753       as the present method does not call mysql_parse().
8754     */
8755     lex_start(thd);
8756     mysql_reset_thd_for_next_command(thd);
8757     /* old copy may exist already */
8758     mysql_file_delete(key_file_log_event_data, fname, MYF(0));
8759     if ((fd= mysql_file_create(key_file_log_event_data,
8760                                fname, CREATE_MODE,
8761                                O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8762                                MYF(MY_WME))) < 0)
8763     {
8764       rli->report(ERROR_LEVEL, my_errno,
8765                   "Error in %s event: could not create file '%s'",
8766                   get_type_str(), fname);
8767       goto err;
8768     }
8769   }
8770   else if ((fd= mysql_file_open(key_file_log_event_data,
8771                                 fname,
8772                                 O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
8773                                 MYF(MY_WME))) < 0)
8774   {
8775     rli->report(ERROR_LEVEL, my_errno,
8776                 "Error in %s event: could not open file '%s'",
8777                 get_type_str(), fname);
8778     goto err;
8779   }
8780 
8781   DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
8782                   {
8783                     my_delete_allow_opened(fname, MYF(0));
8784                   });
8785 
8786   if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8787   {
8788     rli->report(ERROR_LEVEL, my_errno,
8789                 "Error in %s event: write to '%s' failed",
8790                 get_type_str(), fname);
8791     goto err;
8792   }
8793   error=0;
8794 
8795 err:
8796   if (fd >= 0)
8797     mysql_file_close(fd, MYF(0));
8798   DBUG_RETURN(error);
8799 }
8800 #endif
8801 
8802 
8803 /**************************************************************************
8804 	Delete_file_log_event methods
8805 **************************************************************************/
8806 
8807 /*
8808   Delete_file_log_event ctor
8809 */
8810 
8811 #ifndef MYSQL_CLIENT
Delete_file_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8812 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
8813 					     bool using_trans)
8814   :Log_event(thd_arg, 0,
8815              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8816                            Log_event::EVENT_STMT_CACHE,
8817              Log_event::EVENT_NORMAL_LOGGING),
8818   file_id(thd_arg->file_id), db(db_arg)
8819 {
8820 }
8821 #endif
8822 
8823 /*
8824   Delete_file_log_event ctor
8825 */
8826 
Delete_file_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8827 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
8828                                              const Format_description_log_event* description_event)
8829   :Log_event(buf, description_event),file_id(0)
8830 {
8831   uint8 common_header_len= description_event->common_header_len;
8832   uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
8833   if (len < (uint)(common_header_len + delete_file_header_len))
8834     return;
8835   file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
8836 }
8837 
8838 
8839 /*
8840   Delete_file_log_event::write()
8841 */
8842 
8843 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8844 bool Delete_file_log_event::write(IO_CACHE* file)
8845 {
8846  uchar buf[DELETE_FILE_HEADER_LEN];
8847  int4store(buf + DF_FILE_ID_OFFSET, file_id);
8848  return (write_header(file, sizeof(buf)) ||
8849          wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8850 	 write_footer(file));
8851 }
8852 #endif
8853 
8854 
8855 /*
8856   Delete_file_log_event::print()
8857 */
8858 
8859 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8860 void Delete_file_log_event::print(FILE* file,
8861 				  PRINT_EVENT_INFO* print_event_info)
8862 {
8863   if (print_event_info->short_form)
8864     return;
8865   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8866   my_b_printf(&print_event_info->head_cache,
8867               "\n#Delete_file: file_id=%u\n", file_id);
8868 }
8869 #endif /* MYSQL_CLIENT */
8870 
8871 /*
8872   Delete_file_log_event::pack_info()
8873 */
8874 
8875 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8876 int Delete_file_log_event::pack_info(Protocol *protocol)
8877 {
8878   char buf[64];
8879   size_t length;
8880   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8881   protocol->store(buf, length, &my_charset_bin);
8882   return 0;
8883 }
8884 #endif
8885 
8886 /*
8887   Delete_file_log_event::do_apply_event()
8888 */
8889 
8890 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
do_apply_event(Relay_log_info const * rli)8891 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
8892 {
8893   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8894   lex_start(thd);
8895   mysql_reset_thd_for_next_command(thd);
8896   char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
8897   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8898   strmov(ext, ".info");
8899   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8900   return 0;
8901 }
8902 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8903 
8904 
8905 /**************************************************************************
8906 	Execute_load_log_event methods
8907 **************************************************************************/
8908 
8909 /*
8910   Execute_load_log_event ctor
8911 */
8912 
8913 #ifndef MYSQL_CLIENT
Execute_load_log_event(THD * thd_arg,const char * db_arg,bool using_trans)8914 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
8915                                                const char* db_arg,
8916 					       bool using_trans)
8917   :Log_event(thd_arg, 0,
8918              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8919                            Log_event::EVENT_STMT_CACHE,
8920              Log_event::EVENT_NORMAL_LOGGING),
8921   file_id(thd_arg->file_id), db(db_arg)
8922 {
8923 }
8924 #endif
8925 
8926 
8927 /*
8928   Execute_load_log_event ctor
8929 */
8930 
Execute_load_log_event(const char * buf,uint len,const Format_description_log_event * description_event)8931 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
8932                                                const Format_description_log_event* description_event)
8933   :Log_event(buf, description_event), file_id(0)
8934 {
8935   uint8 common_header_len= description_event->common_header_len;
8936   uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
8937   if (len < (uint)(common_header_len+exec_load_header_len))
8938     return;
8939   file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
8940 }
8941 
8942 
8943 /*
8944   Execute_load_log_event::write()
8945 */
8946 
8947 #ifndef MYSQL_CLIENT
write(IO_CACHE * file)8948 bool Execute_load_log_event::write(IO_CACHE* file)
8949 {
8950   uchar buf[EXEC_LOAD_HEADER_LEN];
8951   int4store(buf + EL_FILE_ID_OFFSET, file_id);
8952   return (write_header(file, sizeof(buf)) ||
8953           wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8954 	  write_footer(file));
8955 }
8956 #endif
8957 
8958 
8959 /*
8960   Execute_load_log_event::print()
8961 */
8962 
8963 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)8964 void Execute_load_log_event::print(FILE* file,
8965 				   PRINT_EVENT_INFO* print_event_info)
8966 {
8967   if (print_event_info->short_form)
8968     return;
8969   print_header(&print_event_info->head_cache, print_event_info, FALSE);
8970   my_b_printf(&print_event_info->head_cache, "\n#Exec_load: file_id=%d\n",
8971               file_id);
8972 }
8973 #endif
8974 
8975 /*
8976   Execute_load_log_event::pack_info()
8977 */
8978 
8979 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)8980 int Execute_load_log_event::pack_info(Protocol *protocol)
8981 {
8982   char buf[64];
8983   size_t length;
8984   length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8985   protocol->store(buf, length, &my_charset_bin);
8986   return 0;
8987 }
8988 
8989 
8990 /*
8991   Execute_load_log_event::do_apply_event()
8992 */
8993 
do_apply_event(Relay_log_info const * rli)8994 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
8995 {
8996   char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8997   char *ext;
8998   int fd;
8999   int error= 1;
9000   IO_CACHE file;
9001   Load_log_event *lev= 0;
9002 
9003   lex_start(thd);
9004   mysql_reset_thd_for_next_command(thd);
9005   ext= slave_load_file_stem(fname, file_id, server_id, ".info");
9006   /**
9007     To simulate file open failure, convert the file name to a
9008     directory by appending a "/" to the file name. File open
9009     will fail with an error reporting it is not a directory.
9010    */
9011   DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
9012                   {
9013                   strcat(fname,"/");
9014                   });
9015   if ((fd= mysql_file_open(key_file_log_event_info,
9016                            fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
9017                            MYF(MY_WME))) < 0 ||
9018       init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
9019 		    MYF(MY_WME|MY_NABP)))
9020   {
9021     rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
9022                 "Error in Exec_load event: could not open file '%s'",
9023                 fname);
9024     goto err;
9025   }
9026   if (!(lev= (Load_log_event*)
9027         Log_event::read_log_event(&file,
9028                                   (mysql_mutex_t*) 0,
9029                                   rli->get_rli_description_event(),
9030                                   opt_slave_sql_verify_checksum)) ||
9031       lev->get_type_code() != NEW_LOAD_EVENT)
9032   {
9033     rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
9034                     "file '%s' appears corrupted", fname);
9035     goto err;
9036   }
9037   lev->thd = thd;
9038   /*
9039     lev->do_apply_event should use rli only for errors i.e. should
9040     not advance rli's position.
9041 
9042     lev->do_apply_event is the place where the table is loaded (it
9043     calls mysql_load()).
9044   */
9045   const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
9046   if (lev->do_apply_event(0,rli,1))
9047   {
9048     /*
9049       We want to indicate the name of the file that could not be loaded
9050       (SQL_LOADxxx).
9051       But as we are here we are sure the error is in rli->last_slave_error and
9052       rli->last_slave_errno (example of error: duplicate entry for key), so we
9053       don't want to overwrite it with the filename.
9054       What we want instead is add the filename to the current error message.
9055     */
9056     char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
9057     if (tmp)
9058     {
9059       rli->report(ERROR_LEVEL, rli->last_error().number,
9060                   "%s. Failed executing load from '%s'", tmp, fname);
9061       my_free(tmp);
9062     }
9063     goto err;
9064   }
9065   /*
9066     We have an open file descriptor to the .info file; we need to close it
9067     or Windows will refuse to delete the file in mysql_file_delete().
9068   */
9069   if (fd >= 0)
9070   {
9071     mysql_file_close(fd, MYF(0));
9072     end_io_cache(&file);
9073     fd= -1;
9074   }
9075   mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
9076   memcpy(ext, ".data", 6);
9077   mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9078   error = 0;
9079 
9080 err:
9081   delete lev;
9082   if (fd >= 0)
9083   {
9084     mysql_file_close(fd, MYF(0));
9085     end_io_cache(&file);
9086   }
9087   return error;
9088 }
9089 
9090 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9091 
9092 
9093 /**************************************************************************
9094 	Begin_load_query_log_event methods
9095 **************************************************************************/
9096 
9097 #ifndef MYSQL_CLIENT
9098 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)9099 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
9100                            uint block_len_arg, bool using_trans)
9101   :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
9102                           using_trans)
9103 {
9104    file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
9105 }
9106 #endif
9107 
9108 
9109 Begin_load_query_log_event::
Begin_load_query_log_event(const char * buf,uint len,const Format_description_log_event * desc_event)9110 Begin_load_query_log_event(const char* buf, uint len,
9111                            const Format_description_log_event* desc_event)
9112   :Append_block_log_event(buf, len, desc_event)
9113 {
9114 }
9115 
9116 
9117 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
get_create_or_append() const9118 int Begin_load_query_log_event::get_create_or_append() const
9119 {
9120   return 1; /* create the file */
9121 }
9122 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
9123 
9124 
9125 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9126 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)9127 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
9128 {
9129   /*
9130     If the slave skip counter is 1, then we should not start executing
9131     on the next event.
9132   */
9133   return continue_group(rli);
9134 }
9135 #endif
9136 
9137 
9138 /**************************************************************************
9139 	Execute_load_query_log_event methods
9140 **************************************************************************/
9141 
9142 
9143 #ifndef MYSQL_CLIENT
9144 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)9145 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
9146                              ulong query_length_arg, uint fn_pos_start_arg,
9147                              uint fn_pos_end_arg,
9148                              enum_load_dup_handling dup_handling_arg,
9149                              bool using_trans, bool immediate, bool suppress_use,
9150                              int errcode):
9151   Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
9152                   suppress_use, errcode),
9153   file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
9154   fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
9155 {
9156 }
9157 #endif /* !MYSQL_CLIENT */
9158 
9159 
9160 Execute_load_query_log_event::
Execute_load_query_log_event(const char * buf,uint event_len,const Format_description_log_event * desc_event)9161 Execute_load_query_log_event(const char* buf, uint event_len,
9162                              const Format_description_log_event* desc_event):
9163   Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
9164   file_id(0), fn_pos_start(0), fn_pos_end(0)
9165 {
9166   if (!Query_log_event::is_valid())
9167     return;
9168 
9169   buf+= desc_event->common_header_len;
9170 
9171   fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
9172   fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
9173   dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
9174 
9175   if (fn_pos_start > q_len || fn_pos_end > q_len ||
9176       dup_handling > LOAD_DUP_REPLACE)
9177     return;
9178 
9179   file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
9180 }
9181 
9182 
get_post_header_size_for_derived()9183 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
9184 {
9185   return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
9186 }
9187 
9188 
9189 #ifndef MYSQL_CLIENT
9190 bool
write_post_header_for_derived(IO_CACHE * file)9191 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
9192 {
9193   uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
9194   int4store(buf, file_id);
9195   int4store(buf + 4, fn_pos_start);
9196   int4store(buf + 4 + 4, fn_pos_end);
9197   *(buf + 4 + 4 + 4)= (uchar) dup_handling;
9198   return wrapper_my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
9199 }
9200 #endif
9201 
9202 
9203 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)9204 void Execute_load_query_log_event::print(FILE* file,
9205                                          PRINT_EVENT_INFO* print_event_info)
9206 {
9207   print(file, print_event_info, 0);
9208 }
9209 
9210 /**
9211   Prints the query as LOAD DATA LOCAL and with rewritten filename.
9212 */
print(FILE * file,PRINT_EVENT_INFO * print_event_info,const char * local_fname)9213 void Execute_load_query_log_event::print(FILE* file,
9214                                          PRINT_EVENT_INFO* print_event_info,
9215                                          const char *local_fname)
9216 {
9217   IO_CACHE *const head= &print_event_info->head_cache;
9218 
9219   print_query_header(head, print_event_info);
9220   /**
9221     reduce the size of io cache so that the write function is called
9222     for every call to my_b_printf().
9223    */
9224   DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
9225                    {head->write_pos= head->write_end;
9226                    DBUG_SET("+d,simulate_file_write_error");});
9227 
9228   if (local_fname)
9229   {
9230     my_b_write(head, (uchar*) query, fn_pos_start);
9231     my_b_printf(head, " LOCAL INFILE ");
9232     pretty_print_str(head, local_fname, strlen(local_fname));
9233 
9234     if (dup_handling == LOAD_DUP_REPLACE)
9235       my_b_printf(head, " REPLACE");
9236     my_b_printf(head, " INTO");
9237     my_b_write(head, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
9238     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9239   }
9240   else
9241   {
9242     my_b_write(head, (uchar*) query, q_len);
9243     my_b_printf(head, "\n%s\n", print_event_info->delimiter);
9244   }
9245 
9246   if (!print_event_info->short_form)
9247     my_b_printf(head, "# file_id: %d \n", file_id);
9248 }
9249 #endif
9250 
9251 
9252 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)9253 int Execute_load_query_log_event::pack_info(Protocol *protocol)
9254 {
9255   char *buf, *pos;
9256   if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
9257                                MYF(MY_WME))))
9258     return 1;
9259   pos= buf;
9260   if (db && db_len)
9261   {
9262     /*
9263       Statically allocates room to store '\0' and an identifier
9264       that may have NAME_LEN * 2 due to quoting and there are
9265       two quoting characters that wrap them.
9266     */
9267     char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
9268     size_t size= 0;
9269     size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
9270     pos= strmov(buf, "use ");
9271     memcpy(pos, quoted_db, size);
9272     pos= strmov(pos + size, "; ");
9273   }
9274   if (query && q_len)
9275   {
9276     memcpy(pos, query, q_len);
9277     pos+= q_len;
9278   }
9279   pos= strmov(pos, " ;file_id=");
9280   pos= int10_to_str((long) file_id, pos, 10);
9281   protocol->store(buf, pos-buf, &my_charset_bin);
9282   my_free(buf);
9283   return 0;
9284 }
9285 
9286 
9287 int
do_apply_event(Relay_log_info const * rli)9288 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
9289 {
9290   char *p;
9291   char *buf;
9292   char *fname;
9293   char *fname_end;
9294   int error;
9295 
9296   buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
9297                          (FN_REFLEN + TEMP_FILE_MAX_LEN) + 10 + 8 + 5, MYF(MY_WME));
9298 
9299   DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
9300 
9301   /* Replace filename and LOCAL keyword in query before executing it */
9302   if (buf == NULL)
9303   {
9304     rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
9305                 ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
9306     return 1;
9307   }
9308 
9309   p= buf;
9310   memcpy(p, query, fn_pos_start);
9311   p+= fn_pos_start;
9312   fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
9313   p= slave_load_file_stem(p, file_id, server_id, ".data");
9314   fname_end= p= strend(p);                      // Safer than p=p+5
9315   *(p++)='\'';
9316   switch (dup_handling) {
9317   case LOAD_DUP_IGNORE:
9318     p= strmake(p, STRING_WITH_LEN(" IGNORE"));
9319     break;
9320   case LOAD_DUP_REPLACE:
9321     p= strmake(p, STRING_WITH_LEN(" REPLACE"));
9322     break;
9323   default:
9324     /* Ordinary load data */
9325     break;
9326   }
9327   p= strmake(p, STRING_WITH_LEN(" INTO "));
9328   p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
9329 
9330   error= Query_log_event::do_apply_event(rli, buf, p-buf);
9331 
9332   /* Forging file name for deletion in same buffer */
9333   *fname_end= 0;
9334 
9335   /*
9336     If there was an error the slave is going to stop, leave the
9337     file so that we can re-execute this event at START SLAVE.
9338   */
9339   if (!error)
9340     mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
9341 
9342   my_free(buf);
9343   return error;
9344 }
9345 #endif
9346 
9347 
9348 /**************************************************************************
9349 	sql_ex_info methods
9350 **************************************************************************/
9351 
9352 /*
9353   sql_ex_info::write_data()
9354 */
9355 
write_data(IO_CACHE * file)9356 bool sql_ex_info::write_data(IO_CACHE* file)
9357 {
9358   if (new_format())
9359   {
9360     return (write_str_at_most_255_bytes(file, field_term, (uint) field_term_len) ||
9361 	    write_str_at_most_255_bytes(file, enclosed,   (uint) enclosed_len) ||
9362 	    write_str_at_most_255_bytes(file, line_term,  (uint) line_term_len) ||
9363 	    write_str_at_most_255_bytes(file, line_start, (uint) line_start_len) ||
9364 	    write_str_at_most_255_bytes(file, escaped,    (uint) escaped_len) ||
9365 	    my_b_safe_write(file,(uchar*) &opt_flags,1));
9366   }
9367   else
9368   {
9369     /**
9370       @todo This is sensitive to field padding. We should write a
9371       char[7], not an old_sql_ex. /sven
9372     */
9373     old_sql_ex old_ex;
9374     old_ex.field_term= *field_term;
9375     old_ex.enclosed=   *enclosed;
9376     old_ex.line_term=  *line_term;
9377     old_ex.line_start= *line_start;
9378     old_ex.escaped=    *escaped;
9379     old_ex.opt_flags=  opt_flags;
9380     old_ex.empty_flags=empty_flags;
9381     return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
9382   }
9383 }
9384 
9385 
9386 /*
9387   sql_ex_info::init()
9388 */
9389 
init(const char * buf,const char * buf_end,bool use_new_format)9390 const char *sql_ex_info::init(const char *buf, const char *buf_end,
9391                               bool use_new_format)
9392 {
9393   cached_new_format = use_new_format;
9394   if (use_new_format)
9395   {
9396     empty_flags=0;
9397     /*
9398       The code below assumes that buf will not disappear from
9399       under our feet during the lifetime of the event. This assumption
9400       holds true in the slave thread if the log is in new format, but is not
9401       the case when we have old format because we will be reusing net buffer
9402       to read the actual file before we write out the Create_file event.
9403     */
9404     if (read_str_at_most_255_bytes(&buf, buf_end, &field_term, &field_term_len) ||
9405         read_str_at_most_255_bytes(&buf, buf_end, &enclosed,   &enclosed_len) ||
9406         read_str_at_most_255_bytes(&buf, buf_end, &line_term,  &line_term_len) ||
9407         read_str_at_most_255_bytes(&buf, buf_end, &line_start, &line_start_len) ||
9408         read_str_at_most_255_bytes(&buf, buf_end, &escaped,    &escaped_len))
9409       return 0;
9410     opt_flags = *buf++;
9411   }
9412   else
9413   {
9414     field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
9415     field_term = buf++;			// Use first byte in string
9416     enclosed=	 buf++;
9417     line_term=   buf++;
9418     line_start=  buf++;
9419     escaped=     buf++;
9420     opt_flags =  *buf++;
9421     empty_flags= *buf++;
9422     if (empty_flags & FIELD_TERM_EMPTY)
9423       field_term_len=0;
9424     if (empty_flags & ENCLOSED_EMPTY)
9425       enclosed_len=0;
9426     if (empty_flags & LINE_TERM_EMPTY)
9427       line_term_len=0;
9428     if (empty_flags & LINE_START_EMPTY)
9429       line_start_len=0;
9430     if (empty_flags & ESCAPED_EMPTY)
9431       escaped_len=0;
9432   }
9433   return buf;
9434 }
9435 
9436 #ifndef DBUG_OFF
9437 #ifndef MYSQL_CLIENT
9438 static uchar dbug_extra_row_data_val= 0;
9439 
9440 /**
9441    set_extra_data
9442 
9443    Called during self-test to generate various
9444    self-consistent binlog row event extra
9445    thread data structures which can be checked
9446    when reading the binlog.
9447 
9448    @param arr  Buffer to use
9449 */
set_extra_data(uchar * arr)9450 const uchar* set_extra_data(uchar* arr)
9451 {
9452   uchar val= (dbug_extra_row_data_val++) %
9453     (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
9454   arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
9455   arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
9456   for (uchar i=0; i<val; i++)
9457     arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
9458 
9459   return arr;
9460 }
9461 
9462 #endif // #ifndef MYSQL_CLIENT
9463 
9464 /**
9465    check_extra_data
9466 
9467    Called during self-test to check that
9468    binlog row event extra data is self-
9469    consistent as defined by the set_extra_data
9470    function above.
9471 
9472    Will assert(false) if not.
9473 
9474    @param extra_row_data
9475 */
check_extra_data(uchar * extra_row_data)9476 void check_extra_data(uchar* extra_row_data)
9477 {
9478   assert(extra_row_data);
9479   uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
9480   uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
9481   assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
9482   for (uint16 i= 0; i < val; i++)
9483   {
9484     assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
9485   }
9486 }
9487 
9488 #endif  // #ifndef DBUG_OFF
9489 
9490 /**************************************************************************
9491 	Rows_log_event member functions
9492 **************************************************************************/
9493 
9494 #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)9495 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, const Table_id& tid,
9496                                MY_BITMAP const *cols, bool using_trans,
9497                                Log_event_type event_type,
9498                                const uchar* extra_row_info)
9499   : Log_event(thd_arg, 0,
9500              using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
9501                            Log_event::EVENT_STMT_CACHE,
9502              Log_event::EVENT_NORMAL_LOGGING),
9503     m_row_count(0),
9504     m_table(tbl_arg),
9505     m_table_id(tid),
9506     m_width(tbl_arg ? tbl_arg->s->fields : 1),
9507     m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
9508     m_type(event_type), m_extra_row_data(0)
9509 #ifdef HAVE_REPLICATION
9510     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9511     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9512 #endif
9513 {
9514   DBUG_ASSERT(tbl_arg && tbl_arg->s && tid.is_valid());
9515 
9516   if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
9517       set_flags(NO_FOREIGN_KEY_CHECKS_F);
9518   if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
9519       set_flags(RELAXED_UNIQUE_CHECKS_F);
9520 #ifndef DBUG_OFF
9521   uchar extra_data[255];
9522   DBUG_EXECUTE_IF("extra_row_data_set",
9523                   /* Set extra row data to a known value */
9524                   extra_row_info = set_extra_data(extra_data););
9525 #endif
9526   if (extra_row_info)
9527   {
9528     /* Copy Extra data from thd into new event */
9529     uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
9530     assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
9531 
9532     m_extra_row_data= (uchar*) my_malloc(extra_data_len, MYF(MY_WME));
9533 
9534     if (likely(m_extra_row_data != NULL))
9535     {
9536       memcpy(m_extra_row_data, extra_row_info,
9537              extra_data_len);
9538     }
9539   }
9540 
9541   /* if bitmap_init fails, caught in is_valid() */
9542   if (likely(!bitmap_init(&m_cols,
9543                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9544                           m_width,
9545                           false)))
9546   {
9547     /* Cols can be zero if this is a dummy binrows event */
9548     if (likely(cols != NULL))
9549     {
9550       memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
9551       create_last_word_mask(&m_cols);
9552     }
9553   }
9554   else
9555   {
9556     // Needed because bitmap_init() does not set it to null on failure
9557     m_cols.bitmap= 0;
9558   }
9559 }
9560 #endif
9561 
Rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)9562 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
9563                                const Format_description_log_event
9564                                *description_event)
9565   : Log_event(buf, description_event),
9566     m_row_count(0),
9567 #ifndef MYSQL_CLIENT
9568     m_table(NULL),
9569 #endif
9570     m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
9571     m_extra_row_data(0)
9572 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9573     , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), m_key_info(NULL),
9574     m_distinct_keys(Key_compare(&m_key_info)), m_distinct_key_spare_buf(NULL)
9575 #endif
9576 {
9577   DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
9578   uint8 const common_header_len= description_event->common_header_len;
9579   Log_event_type event_type= (Log_event_type) buf[EVENT_TYPE_OFFSET];
9580   m_type= event_type;
9581 
9582   uint8 const post_header_len= description_event->post_header_len[event_type-1];
9583 
9584   DBUG_PRINT("enter",("event_len: %u  common_header_len: %d  "
9585 		      "post_header_len: %d",
9586 		      event_len, common_header_len,
9587 		      post_header_len));
9588 
9589   const char *post_start= buf + common_header_len;
9590   post_start+= RW_MAPID_OFFSET;
9591   if (post_header_len == 6)
9592   {
9593     /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
9594     m_table_id= uint4korr(post_start);
9595     post_start+= 4;
9596   }
9597   else
9598   {
9599     m_table_id= uint6korr(post_start);
9600     post_start+= RW_FLAGS_OFFSET;
9601   }
9602 
9603   m_flags= uint2korr(post_start);
9604   post_start+= 2;
9605 
9606   uint16 var_header_len= 0;
9607   if (post_header_len == ROWS_HEADER_LEN_V2)
9608   {
9609     /*
9610       Have variable length header, check length,
9611       which includes length bytes
9612     */
9613     var_header_len= uint2korr(post_start);
9614     /* Check length and also avoid out of buffer read */
9615     if (var_header_len < 2 ||
9616         event_len < static_cast<unsigned int>(var_header_len +
9617                                               (post_start - buf)))
9618     {
9619       m_cols.bitmap= NULL;
9620       DBUG_VOID_RETURN;
9621     }
9622 
9623     var_header_len-= 2;
9624 
9625     /* Iterate over var-len header, extracting 'chunks' */
9626     const char* start= post_start + 2;
9627     const char* end= start + var_header_len;
9628     for (const char* pos= start; pos < end;)
9629     {
9630       switch(*pos++)
9631       {
9632       case RW_V_EXTRAINFO_TAG:
9633       {
9634         /* Have an 'extra info' section, read it in */
9635         assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
9636         uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
9637         assert((end - pos) >= infoLen);
9638         /* Just store/use the first tag of this type, skip others */
9639         if (likely(!m_extra_row_data))
9640         {
9641           m_extra_row_data= (uchar*) my_malloc(infoLen,
9642                                                MYF(MY_WME));
9643           if (likely(m_extra_row_data != NULL))
9644           {
9645             memcpy(m_extra_row_data, pos, infoLen);
9646           }
9647           DBUG_EXECUTE_IF("extra_row_data_check",
9648                           /* Check extra data has expected value */
9649                           check_extra_data(m_extra_row_data););
9650         }
9651         pos+= infoLen;
9652         break;
9653       }
9654       default:
9655         /* Unknown code, we will not understand anything further here */
9656         pos= end; /* Break loop */
9657       }
9658     }
9659   }
9660 
9661   uchar const *const var_start=
9662     (const uchar *)buf + common_header_len + post_header_len + var_header_len;
9663   uchar const *const ptr_width= var_start;
9664   uchar *ptr_after_width= (uchar*) ptr_width;
9665   DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9666   m_width = net_field_length(&ptr_after_width);
9667   DBUG_PRINT("debug", ("m_width=%lu", m_width));
9668   /* Avoid reading out of buffer */
9669   if (static_cast<unsigned int>((ptr_after_width +
9670                                  (m_width + 7) / 8) -
9671                                  (uchar*)buf) > event_len)
9672   {
9673     m_cols.bitmap= NULL;
9674     DBUG_VOID_RETURN;
9675   }
9676 
9677   /* if bitmap_init fails, catched in is_valid() */
9678   if (likely(!bitmap_init(&m_cols,
9679                           m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9680                           m_width,
9681                           false)))
9682   {
9683     DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9684     memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
9685     create_last_word_mask(&m_cols);
9686     ptr_after_width+= (m_width + 7) / 8;
9687     DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
9688   }
9689   else
9690   {
9691     // Needed because bitmap_init() does not set it to null on failure
9692     m_cols.bitmap= NULL;
9693     DBUG_VOID_RETURN;
9694   }
9695 
9696   m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
9697 
9698   if ((event_type == UPDATE_ROWS_EVENT) ||
9699       (event_type == UPDATE_ROWS_EVENT_V1))
9700   {
9701     DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9702 
9703     /* if bitmap_init fails, caught in is_valid() */
9704     if (likely(!bitmap_init(&m_cols_ai,
9705                             m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
9706                             m_width,
9707                             false)))
9708     {
9709       DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9710       memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
9711       create_last_word_mask(&m_cols_ai);
9712       ptr_after_width+= (m_width + 7) / 8;
9713       DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
9714                 no_bytes_in_map(&m_cols_ai));
9715     }
9716     else
9717     {
9718       // Needed because bitmap_init() does not set it to null on failure
9719       m_cols_ai.bitmap= 0;
9720       DBUG_VOID_RETURN;
9721     }
9722   }
9723 
9724   const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
9725 
9726   size_t const read_size= ptr_rows_data - (const unsigned char *) buf;
9727   if (read_size > event_len)
9728   {
9729     DBUG_VOID_RETURN;
9730   }
9731 
9732   size_t const data_size= event_len - read_size;
9733   DBUG_PRINT("info",("m_table_id: %llu  m_flags: %d  m_width: %lu  data_size: %lu",
9734                      m_table_id.id(), m_flags, m_width, (ulong) data_size));
9735 
9736   m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
9737   if (likely((bool)m_rows_buf))
9738   {
9739 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9740     m_curr_row= m_rows_buf;
9741 #endif
9742     m_rows_end= m_rows_buf + data_size;
9743     m_rows_cur= m_rows_end;
9744     memcpy(m_rows_buf, ptr_rows_data, data_size);
9745   }
9746   else
9747     m_cols.bitmap= 0; // to not free it
9748 
9749   DBUG_VOID_RETURN;
9750 }
9751 
~Rows_log_event()9752 Rows_log_event::~Rows_log_event()
9753 {
9754   if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
9755     m_cols.bitmap= 0; // so no my_free in bitmap_free
9756   bitmap_free(&m_cols); // To pair with bitmap_init().
9757   my_free(m_rows_buf);
9758   my_free(m_extra_row_data);
9759 }
9760 
get_data_size()9761 int Rows_log_event::get_data_size()
9762 {
9763   int const general_type_code= get_general_type_code();
9764 
9765   uchar buf[sizeof(m_width) + 1];
9766   uchar *end= net_store_length(buf, m_width);
9767 
9768   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9769                   return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
9770                   (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
9771                   (m_rows_cur - m_rows_buf););
9772 
9773   int data_size= 0;
9774   bool is_v2_event= get_type_code() > DELETE_ROWS_EVENT_V1;
9775   if (is_v2_event)
9776   {
9777     data_size= ROWS_HEADER_LEN_V2 +
9778       (m_extra_row_data ?
9779        RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
9780        0);
9781   }
9782   else
9783   {
9784     data_size= ROWS_HEADER_LEN_V1;
9785   }
9786   data_size+= no_bytes_in_map(&m_cols);
9787   data_size+= (uint) (end - buf);
9788 
9789   if (general_type_code == UPDATE_ROWS_EVENT)
9790     data_size+= no_bytes_in_map(&m_cols_ai);
9791 
9792   data_size+= (uint) (m_rows_cur - m_rows_buf);
9793   return data_size;
9794 }
9795 
9796 
9797 #ifndef MYSQL_CLIENT
do_add_row_data(uchar * row_data,size_t length)9798 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
9799 {
9800   /*
9801     When the table has a primary key, we would probably want, by default, to
9802     log only the primary key value instead of the entire "before image". This
9803     would save binlog space. TODO
9804   */
9805   DBUG_ENTER("Rows_log_event::do_add_row_data");
9806   DBUG_PRINT("enter", ("row_data: 0x%lx  length: %lu", (ulong) row_data,
9807                        (ulong) length));
9808 
9809   /*
9810     If length is zero, there is nothing to write, so we just
9811     return. Note that this is not an optimization, since calling
9812     realloc() with size 0 means free().
9813    */
9814   if (length == 0)
9815   {
9816     m_row_count++;
9817     DBUG_RETURN(0);
9818   }
9819 
9820   /*
9821     Don't print debug messages when running valgrind since they can
9822     trigger false warnings.
9823    */
9824 #ifndef HAVE_purify
9825   DBUG_DUMP("row_data", row_data, min<size_t>(length, 32));
9826 #endif
9827 
9828   DBUG_ASSERT(m_rows_buf <= m_rows_cur);
9829   DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
9830   DBUG_ASSERT(m_rows_cur <= m_rows_end);
9831 
9832   /* The cast will always work since m_rows_cur <= m_rows_end */
9833   if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
9834   {
9835     size_t const block_size= 1024;
9836     ulong cur_size= m_rows_cur - m_rows_buf;
9837     DBUG_EXECUTE_IF("simulate_too_big_row_case1",
9838                      cur_size= UINT_MAX32 - (block_size * 10);
9839                      length= UINT_MAX32 - (block_size * 10););
9840     DBUG_EXECUTE_IF("simulate_too_big_row_case2",
9841                      cur_size= UINT_MAX32 - (block_size * 10);
9842                      length= block_size * 10;);
9843     DBUG_EXECUTE_IF("simulate_too_big_row_case3",
9844                      cur_size= block_size * 10;
9845                      length= UINT_MAX32 - (block_size * 10););
9846     DBUG_EXECUTE_IF("simulate_too_big_row_case4",
9847                      cur_size= UINT_MAX32 - (block_size * 10);
9848                      length= (block_size * 10) - block_size + 1;);
9849     ulong remaining_space= UINT_MAX32 - cur_size;
9850     /* Check that the new data fits within remaining space and we can add
9851        block_size without wrapping.
9852      */
9853     if (length > remaining_space ||
9854         ((length + block_size) > remaining_space))
9855     {
9856       sql_print_error("The row data is greater than 4GB, which is too big to "
9857                       "write to the binary log.");
9858       DBUG_RETURN(ER_BINLOG_ROW_LOGGING_FAILED);
9859     }
9860     ulong const new_alloc=
9861         block_size * ((cur_size + length + block_size - 1) / block_size);
9862 
9863     uchar* const new_buf=
9864       (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
9865                          MYF(MY_ALLOW_ZERO_PTR|MY_WME));
9866     if (unlikely(!new_buf))
9867       DBUG_RETURN(HA_ERR_OUT_OF_MEM);
9868 
9869     /* If the memory moved, we need to move the pointers */
9870     if (new_buf != m_rows_buf)
9871     {
9872       m_rows_buf= new_buf;
9873       m_rows_cur= m_rows_buf + cur_size;
9874     }
9875 
9876     /*
9877        The end pointer should always be changed to point to the end of
9878        the allocated memory.
9879     */
9880     m_rows_end= m_rows_buf + new_alloc;
9881   }
9882 
9883   DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
9884   memcpy(m_rows_cur, row_data, length);
9885   m_rows_cur+= length;
9886   m_row_count++;
9887   DBUG_RETURN(0);
9888 }
9889 #endif
9890 
9891 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9892 
9893 /**
9894   Checks if any of the columns in the given table is
9895   signaled in the bitmap.
9896 
9897   For each column in the given table checks if it is
9898   signaled in the bitmap. This is most useful when deciding
9899   whether a before image (BI) can be used or not for
9900   searching a row. If no column is signaled, then the
9901   image cannot be used for searching a record (regardless
9902   of using position(), index scan or table scan). Here is
9903   an example:
9904 
9905   MASTER> SET @@binlog_row_image='MINIMAL';
9906   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9907   SLAVE>  CREATE TABLE t1 (a int, b int);
9908   MASTER> INSERT INTO t1 VALUES (1,2,3);
9909   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9910 
9911   For the update statement only the PK (column c) is
9912   logged in the before image (BI). As such, given that
9913   the slave has no column c, it will not be able to
9914   find the row, because BI has no values for the columns
9915   the slave knows about (column a and b).
9916 
9917   @param table   the table reference on the slave.
9918   @param cols the bitmap signaling columns available in
9919                  the BI.
9920 
9921   @return TRUE if BI contains usable colums for searching,
9922           FALSE otherwise.
9923 */
9924 static
is_any_column_signaled_for_table(TABLE * table,MY_BITMAP * cols)9925 my_bool is_any_column_signaled_for_table(TABLE *table, MY_BITMAP *cols)
9926 {
9927   DBUG_ENTER("is_any_column_signaled_for_table");
9928 
9929   for (Field **ptr= table->field ;
9930        *ptr && ((*ptr)->field_index < cols->n_bits);
9931        ptr++)
9932   {
9933     if (bitmap_is_set(cols, (*ptr)->field_index))
9934       DBUG_RETURN(TRUE);
9935   }
9936 
9937   DBUG_RETURN (FALSE);
9938 }
9939 
9940 /**
9941   Checks if the fields in the given key are signaled in
9942   the bitmap.
9943 
9944   Validates whether the before image is usable for the
9945   given key. It can be the case that the before image
9946   does not contain values for the key (eg, master was
9947   using 'minimal' option for image logging and slave has
9948   different index structure on the table). Here is an
9949   example:
9950 
9951   MASTER> SET @@binlog_row_image='MINIMAL';
9952   MASTER> CREATE TABLE t1 (a int, b int, c int, primary key(c));
9953   SLAVE> CREATE TABLE t1 (a int, b int, c int, key(a,c));
9954   MASTER> INSERT INTO t1 VALUES (1,2,3);
9955   MASTER> UPDATE t1 SET a=2 WHERE b=2;
9956 
9957   When finding the row on the slave, one cannot use the
9958   index (a,c) to search for the row, because there is only
9959   data in the before image for column c. This function
9960   checks the fields needed for a given key and searches
9961   the bitmap to see if all the fields required are
9962   signaled.
9963 
9964   @param keyinfo  reference to key.
9965   @param cols     the bitmap signaling which columns
9966                   have available data.
9967 
9968   @return TRUE if all fields are signaled in the bitmap
9969           for the given key, FALSE otherwise.
9970 */
9971 static
are_all_columns_signaled_for_key(KEY * keyinfo,MY_BITMAP * cols)9972 my_bool are_all_columns_signaled_for_key(KEY *keyinfo, MY_BITMAP *cols)
9973 {
9974   DBUG_ENTER("are_all_columns_signaled_for_key");
9975 
9976   for (uint i=0 ; i < keyinfo->user_defined_key_parts ;i++)
9977   {
9978     uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
9979     if (fieldnr >= cols->n_bits ||
9980         !bitmap_is_set(cols, fieldnr))
9981       DBUG_RETURN(FALSE);
9982   }
9983 
9984   DBUG_RETURN(TRUE);
9985 }
9986 
9987 /**
9988   Searches the table for a given key that can be used
9989   according to the existing values, ie, columns set
9990   in the bitmap.
9991 
9992   The caller can specify which type of key to find by
9993   setting the following flags in the key_type parameter:
9994 
9995     - PRI_KEY_FLAG
9996       Returns the primary key.
9997 
9998     - UNIQUE_KEY_FLAG
9999       Returns a unique key (flagged with HA_NOSAME)
10000 
10001     - MULTIPLE_KEY_FLAG
10002       Returns a key that is not unique (flagged with HA_NOSAME
10003       and without HA_NULL_PART_KEY) nor PK.
10004 
10005   The above flags can be used together, in which case, the
10006   search is conducted in the above listed order. Eg, the
10007   following flag:
10008 
10009     (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG)
10010 
10011   means that a primary key is returned if it is suitable. If
10012   not then the unique keys are searched. If no unique key is
10013   suitable, then the keys are searched. Finally, if no key
10014   is suitable, MAX_KEY is returned.
10015 
10016   @param table    reference to the table.
10017   @param bi_cols  a bitmap that filters out columns that should
10018                   not be considered while searching the key.
10019                   Columns that should be considered are set.
10020   @param key_type the type of key to search for.
10021 
10022   @return MAX_KEY if no key, according to the key_type specified
10023           is suitable. Returns the key otherwise.
10024 
10025 */
10026 static
10027 uint
search_key_in_table(TABLE * table,MY_BITMAP * bi_cols,uint key_type)10028 search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type)
10029 {
10030   DBUG_ENTER("search_key_in_table");
10031 
10032   KEY *keyinfo;
10033   uint res= MAX_KEY;
10034   uint key;
10035 
10036   if (key_type & PRI_KEY_FLAG &&
10037       (table->s->primary_key < MAX_KEY))
10038   {
10039     DBUG_PRINT("debug", ("Searching for PK"));
10040     keyinfo= table->s->key_info + (uint) table->s->primary_key;
10041     if (are_all_columns_signaled_for_key(keyinfo, bi_cols))
10042       DBUG_RETURN(table->s->primary_key);
10043   }
10044 
10045   DBUG_PRINT("debug", ("Unique keys count: %u", table->s->uniques));
10046 
10047   if (key_type & UNIQUE_KEY_FLAG && table->s->uniques)
10048   {
10049     DBUG_PRINT("debug", ("Searching for UK"));
10050     for (key=0,keyinfo= table->key_info ;
10051          (key < table->s->keys) && (res == MAX_KEY);
10052          key++,keyinfo++)
10053     {
10054       /*
10055         - Unique keys cannot be disabled, thence we skip the check.
10056         - Skip unique keys with nullable parts
10057         - Skip primary keys
10058       */
10059       if (!((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10060           (key == table->s->primary_key))
10061         continue;
10062       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10063            key : MAX_KEY;
10064 
10065       if (res < MAX_KEY)
10066         DBUG_RETURN(res);
10067     }
10068     DBUG_PRINT("debug", ("UK has NULLABLE parts or not all columns signaled."));
10069   }
10070 
10071   if (key_type & MULTIPLE_KEY_FLAG && table->s->keys)
10072   {
10073     DBUG_PRINT("debug", ("Searching for K."));
10074     for (key=0,keyinfo= table->key_info ;
10075          (key < table->s->keys) && (res == MAX_KEY);
10076          key++,keyinfo++)
10077     {
10078       /*
10079         - Skip innactive keys
10080         - Skip unique keys without nullable parts
10081         - Skip indices that do not support ha_index_next() e.g. full-text
10082         - Skip primary keys
10083       */
10084       if (!(table->s->keys_in_use.is_set(key)) ||
10085           ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
10086           !(table->file->index_flags(key, 0, true) & HA_READ_NEXT) ||
10087           (key == table->s->primary_key))
10088         continue;
10089 
10090       res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
10091            key : MAX_KEY;
10092 
10093       if (res < MAX_KEY)
10094         DBUG_RETURN(res);
10095     }
10096     DBUG_PRINT("debug", ("Not all columns signaled for K."));
10097   }
10098 
10099   DBUG_RETURN(res);
10100 }
10101 
10102 void
decide_row_lookup_algorithm_and_key()10103 Rows_log_event::decide_row_lookup_algorithm_and_key()
10104 {
10105 
10106   DBUG_ENTER("decide_row_lookup_algorithm_and_key");
10107 
10108   /*
10109     Decision table:
10110     - I  --> Index scan / search
10111     - T  --> Table scan
10112     - Hi --> Hash over index
10113     - Ht --> Hash over the entire table
10114 
10115     |--------------+-----------+------+------+------|
10116     | Index\Option | I , T , H | I, T | I, H | T, H |
10117     |--------------+-----------+------+------+------|
10118     | PK / UK      | I         | I    | I    | Hi   |
10119     | K            | Hi        | I    | Hi   | Hi   |
10120     | No Index     | Ht        | T    | Ht   | Ht   |
10121     |--------------+-----------+------+------+------|
10122 
10123   */
10124 
10125   TABLE *table= this->m_table;
10126   uint event_type= this->get_general_type_code();
10127   MY_BITMAP *cols= &this->m_cols;
10128   this->m_rows_lookup_algorithm= ROW_LOOKUP_NOT_NEEDED;
10129   this->m_key_index= MAX_KEY;
10130   this->m_key_info= NULL;
10131 
10132   if (event_type == WRITE_ROWS_EVENT)  // row lookup not needed
10133     DBUG_VOID_RETURN;
10134 
10135   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN))
10136     goto TABLE_OR_INDEX_HASH_SCAN;
10137 
10138   /* PK or UK => use LOOKUP_INDEX_SCAN */
10139   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG));
10140   if (this->m_key_index != MAX_KEY)
10141   {
10142     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10143     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10144     goto end;
10145   }
10146 
10147 TABLE_OR_INDEX_HASH_SCAN:
10148 
10149   /*
10150      NOTE: Engines like Blackhole cannot use HASH_SCAN, because
10151            they do not syncronize reads .
10152    */
10153   if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_HASH_SCAN) ||
10154       (table->file->ha_table_flags() & HA_READ_OUT_OF_SYNC))
10155     goto TABLE_OR_INDEX_FULL_SCAN;
10156 
10157   /* search for a key to see if we can narrow the lookup domain further. */
10158   this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10159   this->m_rows_lookup_algorithm= ROW_LOOKUP_HASH_SCAN;
10160   if (m_key_index < MAX_KEY)
10161     m_distinct_key_spare_buf= (uchar*) thd->alloc(table->key_info[m_key_index].key_length);
10162   DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - HASH_SCAN"));
10163   goto end;
10164 
10165 TABLE_OR_INDEX_FULL_SCAN:
10166 
10167   this->m_key_index= MAX_KEY;
10168 
10169   /* If we can use an index, try to narrow the scan a bit further. */
10170   if (slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN)
10171     this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
10172 
10173   if (this->m_key_index != MAX_KEY)
10174   {
10175     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
10176     this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
10177   }
10178   else
10179   {
10180     DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - TABLE_SCAN"));
10181     this->m_rows_lookup_algorithm= ROW_LOOKUP_TABLE_SCAN;
10182   }
10183 
10184 end:
10185 
10186   /* m_key_index is ready, set m_key_info now. */
10187   m_key_info= m_table->key_info + m_key_index;
10188   /*
10189     m_key_info will influence key comparison code in HASH_SCAN mode,
10190     so the m_distinct_keys set should still be empty.
10191   */
10192   DBUG_ASSERT(m_distinct_keys.empty());
10193 
10194 #ifndef DBUG_OFF
10195   const char* s= ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
10196                   ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
10197                    "INDEX_SCAN"));
10198 
10199   // only for testing purposes
10200   slave_rows_last_search_algorithm_used= m_rows_lookup_algorithm;
10201   DBUG_PRINT("debug", ("Row lookup method: %s", s));
10202 #endif
10203 
10204   DBUG_VOID_RETURN;
10205 }
10206 
10207 /*
10208   Encapsulates the  operations to be done before applying
10209   row events for update and delete.
10210 
10211   @ret value error code
10212              0 success
10213 */
10214 int
row_operations_scan_and_key_setup()10215 Rows_log_event::row_operations_scan_and_key_setup()
10216 {
10217   int error= 0;
10218   DBUG_ENTER("Row_log_event::row_operations_scan_and_key_setup");
10219 
10220   /*
10221      Prepare memory structures for search operations. If
10222      search is performed:
10223 
10224      1. using hash search => initialize the hash
10225      2. using key => decide on key to use and allocate mem structures
10226      3. using table scan => do nothing
10227    */
10228   decide_row_lookup_algorithm_and_key();
10229 
10230   switch (m_rows_lookup_algorithm)
10231   {
10232   case ROW_LOOKUP_HASH_SCAN:
10233     {
10234       if (m_hash.init())
10235         error= HA_ERR_OUT_OF_MEM;
10236       goto err;
10237     }
10238   case ROW_LOOKUP_INDEX_SCAN:
10239     {
10240       DBUG_ASSERT (m_key_index < MAX_KEY);
10241       // Allocate buffer for key searches
10242       m_key= (uchar*)my_malloc(m_key_info->key_length, MYF(MY_WME));
10243       if (!m_key)
10244         error= HA_ERR_OUT_OF_MEM;
10245       goto err;
10246     }
10247   case ROW_LOOKUP_TABLE_SCAN:
10248   default: break;
10249   }
10250 err:
10251   DBUG_RETURN(error);
10252 }
10253 
10254 /*
10255   Encapsulates the  operations to be done after applying
10256   row events for update and delete.
10257 
10258   @ret value error code
10259              0 success
10260 */
10261 
10262 int
row_operations_scan_and_key_teardown(int error)10263 Rows_log_event::row_operations_scan_and_key_teardown(int error)
10264 {
10265   DBUG_ENTER("Rows_log_event::row_operations_scan_and_key_teardown");
10266 
10267   DBUG_ASSERT(!m_table->file->inited);
10268   switch (m_rows_lookup_algorithm)
10269   {
10270   case ROW_LOOKUP_HASH_SCAN:
10271     {
10272       m_hash.deinit(); // we don't need the hash anymore.
10273       goto err;
10274     }
10275 
10276   case ROW_LOOKUP_INDEX_SCAN:
10277     {
10278       if (m_table->s->keys > 0)
10279       {
10280         my_free(m_key); // Free for multi_malloc
10281         m_key= NULL;
10282         m_key_index= MAX_KEY;
10283         m_key_info= NULL;
10284       }
10285      goto err;
10286     }
10287 
10288   case ROW_LOOKUP_TABLE_SCAN:
10289   default: break;
10290   }
10291 
10292 err:
10293   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
10294   DBUG_RETURN(error);
10295 }
10296 
10297 /*
10298   Compares table->record[0] and table->record[1]
10299 
10300   Returns TRUE if different.
10301 */
record_compare(TABLE * table,MY_BITMAP * cols)10302 static bool record_compare(TABLE *table, MY_BITMAP *cols)
10303 {
10304   DBUG_ENTER("record_compare");
10305 
10306   /*
10307     Need to set the X bit and the filler bits in both records since
10308     there are engines that do not set it correctly.
10309 
10310     In addition, since MyISAM checks that one hasn't tampered with the
10311     record, it is necessary to restore the old bytes into the record
10312     after doing the comparison.
10313 
10314     TODO[record format ndb]: Remove it once NDB returns correct
10315     records. Check that the other engines also return correct records.
10316    */
10317 
10318   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10319   DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
10320 
10321   bool result= false;
10322   uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
10323 
10324   if (table->s->null_bytes > 0)
10325   {
10326     for (int i = 0 ; i < 2 ; ++i)
10327     {
10328       /*
10329         If we have an X bit then we need to take care of it.
10330       */
10331       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10332       {
10333         saved_x[i]= table->record[i][0];
10334         table->record[i][0]|= 1U;
10335       }
10336 
10337       /*
10338          If (last_null_bit_pos == 0 && null_bytes > 1), then:
10339 
10340          X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
10341 
10342          Ie, the entire byte is used.
10343       */
10344       if (table->s->last_null_bit_pos > 0)
10345       {
10346         saved_filler[i]= table->record[i][table->s->null_bytes - 1];
10347         table->record[i][table->s->null_bytes - 1]|=
10348           256U - (1U << table->s->last_null_bit_pos);
10349       }
10350     }
10351   }
10352 
10353   /**
10354     Compare full record only if:
10355     - there are no blob fields (otherwise we would also need
10356       to compare blobs contents as well);
10357     - there are no varchar fields (otherwise we would also need
10358       to compare varchar contents as well);
10359     - there are no null fields, otherwise NULLed fields
10360       contents (i.e., the don't care bytes) may show arbitrary
10361       values, depending on how each engine handles internally.
10362     - if all the bitmap is set (both are full rows)
10363     */
10364   if ((table->s->blob_fields +
10365        table->s->varchar_fields +
10366        table->s->null_fields) == 0 &&
10367       bitmap_is_set_all(cols))
10368   {
10369     result= cmp_record(table,record[1]);
10370   }
10371 
10372   /*
10373     Fallback to field-by-field comparison:
10374     1. start by checking if the field is signaled:
10375     2. if it is, first compare the null bit if the field is nullable
10376     3. then compare the contents of the field, if it is not
10377        set to null
10378    */
10379   else
10380   {
10381     for (Field **ptr=table->field ;
10382          *ptr && ((*ptr)->field_index < cols->n_bits) && !result;
10383          ptr++)
10384     {
10385       Field *field= *ptr;
10386       if (bitmap_is_set(cols, field->field_index))
10387       {
10388         /* compare null bit */
10389         if (field->is_null() != field->is_null_in_record(table->record[1]))
10390           result= true;
10391 
10392         /* compare content, only if fields are not set to NULL */
10393         else if (!field->is_null())
10394           result= field->cmp_binary_offset(table->s->rec_buff_length);
10395       }
10396     }
10397   }
10398 
10399   /*
10400     Restore the saved bytes.
10401 
10402     TODO[record format ndb]: Remove this code once NDB returns the
10403     correct record format.
10404   */
10405   if (table->s->null_bytes > 0)
10406   {
10407     for (int i = 0 ; i < 2 ; ++i)
10408     {
10409       if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
10410         table->record[i][0]= saved_x[i];
10411 
10412       if (table->s->last_null_bit_pos)
10413         table->record[i][table->s->null_bytes - 1]= saved_filler[i];
10414     }
10415   }
10416 
10417   DBUG_RETURN(result);
10418 }
10419 
do_post_row_operations(Relay_log_info const * rli,int error)10420 void Rows_log_event::do_post_row_operations(Relay_log_info const *rli, int error)
10421 {
10422 
10423   /*
10424     If m_curr_row_end  was not set during event execution (e.g., because
10425     of errors) we can't proceed to the next row. If the error is transient
10426     (i.e., error==0 at this point) we must call unpack_current_row() to set
10427     m_curr_row_end.
10428   */
10429 
10430   DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
10431                       (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
10432 
10433   if (!m_curr_row_end && !error)
10434   {
10435     const uchar *previous_m_curr_row= m_curr_row;
10436     error= unpack_current_row(rli, &m_cols);
10437 
10438     if (!error && previous_m_curr_row == m_curr_row)
10439     {
10440       error= 1;
10441     }
10442   }
10443 
10444   // at this moment m_curr_row_end should be set
10445   DBUG_ASSERT(error || m_curr_row_end != NULL);
10446   DBUG_ASSERT(error || m_curr_row <= m_curr_row_end);
10447   DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
10448 
10449   m_curr_row= m_curr_row_end;
10450 
10451   if (error == 0 && !m_table->file->has_transactions())
10452   {
10453     thd->transaction.all.set_unsafe_rollback_flags(TRUE);
10454     thd->transaction.stmt.set_unsafe_rollback_flags(TRUE);
10455   }
10456 }
10457 
handle_idempotent_and_ignored_errors(Relay_log_info const * rli,int * err)10458 int Rows_log_event::handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err)
10459 {
10460   int error= *err;
10461   if (error)
10462   {
10463     int actual_error= convert_handler_error(error, thd, m_table);
10464     bool idempotent_error= (idempotent_error_code(error) &&
10465                            (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
10466     bool ignored_error= (idempotent_error == 0 ?
10467                          ignored_error_code(actual_error) : 0);
10468 
10469     if (idempotent_error || ignored_error)
10470     {
10471       if ( (idempotent_error && log_warnings) ||
10472 		(ignored_error && log_warnings > 1) )
10473         slave_rows_error_report(WARNING_LEVEL, error, rli, thd, m_table,
10474                                 get_type_str(),
10475                                 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
10476                                 (ulong) log_pos);
10477       thd->get_stmt_da()->clear_warning_info(thd->query_id);
10478       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
10479       *err= 0;
10480       if (idempotent_error == 0)
10481         return ignored_error;
10482     }
10483   }
10484 
10485   return *err;
10486 }
10487 
do_apply_row(Relay_log_info const * rli)10488 int Rows_log_event::do_apply_row(Relay_log_info const *rli)
10489 {
10490   DBUG_ENTER("Rows_log_event::do_apply_row");
10491 
10492   int error= 0;
10493 
10494   /* in_use can have been set to NULL in close_tables_for_reopen */
10495   THD* old_thd= m_table->in_use;
10496   if (!m_table->in_use)
10497     m_table->in_use= thd;
10498 
10499   error= do_exec_row(rli);
10500 
10501   if(error)
10502   {
10503     DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10504     DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10505   }
10506 
10507   m_table->in_use = old_thd;
10508 
10509   DBUG_RETURN(error);
10510 }
10511 
10512 /**
10513    Does the cleanup
10514      -  closes the index if opened by open_record_scan
10515      -  closes the table if opened for scanning.
10516 */
10517 int
close_record_scan()10518 Rows_log_event::close_record_scan()
10519 {
10520   DBUG_ENTER("Rows_log_event::close_record_scan");
10521   int error= 0;
10522 
10523   // if there is something to actually close
10524   if (m_key_index < MAX_KEY)
10525   {
10526     if (m_table->file->inited)
10527       error= m_table->file->ha_index_end();
10528   }
10529   else if (m_table->file->inited)
10530     error= m_table->file->ha_rnd_end();
10531 
10532   DBUG_RETURN(error);
10533 }
10534 
10535 /**
10536   Fetches next row. If it is a HASH_SCAN over an index, it populates
10537   table->record[0] with the next row corresponding to the index. If
10538   the indexes are in non-contigous ranges it fetches record corresponding
10539   to the key value in the next range.
10540 
10541   @parms: bool first_read : signifying if this is the first time we are reading a row
10542           over an index.
10543   @return_value: -  error code when there are no more reeords to be fetched or some other
10544                     error occured,
10545                  -  0 otherwise.
10546 */
10547 int
next_record_scan(bool first_read)10548 Rows_log_event::next_record_scan(bool first_read)
10549 {
10550   DBUG_ENTER("Rows_log_event::next_record_scan");
10551   DBUG_ASSERT(m_table->file->inited);
10552   TABLE *table= m_table;
10553   int error= 0;
10554 
10555   if (m_key_index >= MAX_KEY)
10556     error= table->file->ha_rnd_next(table->record[0]);
10557   else
10558   {
10559     /*
10560       We need to set the null bytes to ensure that the filler bit are
10561       all set when returning.  There are storage engines that just set
10562       the necessary bits on the bytes and don't set the filler bits
10563       correctly.
10564     */
10565     if (table->s->null_bytes > 0)
10566       table->record[0][table->s->null_bytes - 1]|=
10567         256U - (1U << table->s->last_null_bit_pos);
10568 
10569     if (!first_read)
10570     {
10571       /*
10572         if we fail to fetch next record corresponding to a key value, we
10573         move to the next key value. If we are out of key values as well an error
10574         will be returned.
10575        */
10576       error= table->file->ha_index_next_same(table->record[0], m_key,
10577                                              m_key_info->key_length);
10578       if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10579       {
10580         /*
10581           if we are out of rows for this particular key value, we reposition the
10582           marker according to the next key value that we have in the list.
10583          */
10584         if (error)
10585         {
10586           if (m_itr != m_distinct_keys.end())
10587           {
10588             m_key= *m_itr;
10589             m_itr++;
10590             first_read= true;
10591           }
10592           else
10593             error= HA_ERR_KEY_NOT_FOUND;
10594         }
10595       }
10596     }
10597 
10598     if (first_read)
10599       if ((error= table->file->ha_index_read_map(table->record[0], m_key,
10600                                                  HA_WHOLE_KEY,
10601                                                  HA_READ_KEY_EXACT)))
10602       {
10603         DBUG_PRINT("info",("no record matching the key found in the table"));
10604         if (error == HA_ERR_RECORD_DELETED)
10605           error= HA_ERR_KEY_NOT_FOUND;
10606       }
10607   }
10608 
10609   DBUG_RETURN(error);
10610 }
10611 
10612 /**
10613   Initializes scanning of rows. Opens an index and initializes an iterator
10614   over a list of distinct keys (m_distinct_keys) if it is a HASH_SCAN
10615   over an index or the table if its a HASH_SCAN over the table.
10616 */
10617 int
open_record_scan()10618 Rows_log_event::open_record_scan()
10619 {
10620   int error= 0;
10621   TABLE *table= m_table;
10622   DBUG_ENTER("Rows_log_event::open_record_scan");
10623 
10624   if (m_key_index < MAX_KEY )
10625   {
10626     if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10627     {
10628       /* initialize the iterator over the list of distinct keys that we have */
10629       m_itr= m_distinct_keys.begin();
10630 
10631       /* get the first element from the list of keys and increment the
10632          iterator
10633        */
10634       m_key= *m_itr;
10635       m_itr++;
10636     }
10637     else {
10638       /* this is an INDEX_SCAN we need to store the key in m_key */
10639       DBUG_ASSERT((m_rows_lookup_algorithm == ROW_LOOKUP_INDEX_SCAN) && m_key);
10640       key_copy(m_key, m_table->record[0], m_key_info, 0);
10641     }
10642 
10643     /*
10644       Save copy of the record in table->record[1]. It might be needed
10645       later if linear search is used to find exact match.
10646      */
10647     store_record(table,record[1]);
10648 
10649     DBUG_PRINT("info",("locating record using a key (index_read)"));
10650 
10651     /* The m_key_index'th key is active and usable: search the table using the index */
10652     if (!table->file->inited && (error= table->file->ha_index_init(m_key_index, FALSE)))
10653     {
10654       DBUG_PRINT("info",("ha_index_init returns error %d",error));
10655       goto end;
10656     }
10657 
10658     /*
10659       Don't print debug messages when running valgrind since they can
10660       trigger false warnings.
10661      */
10662 #ifndef HAVE_purify
10663     DBUG_DUMP("key data", m_key, m_key_info->key_length);
10664 #endif
10665   }
10666   else
10667   {
10668     if ((error= table->file->ha_rnd_init(1)))
10669     {
10670       DBUG_PRINT("info",("error initializing table scan"
10671           " (ha_rnd_init returns %d)",error));
10672       table->file->print_error(error, MYF(0));
10673     }
10674   }
10675 
10676 end:
10677   DBUG_RETURN(error);
10678 }
10679 
10680 /**
10681   Populates the m_distinct_keys with unique keys to be modified
10682   during HASH_SCAN over keys.
10683   @return_value -0 success
10684                 -Err_code
10685 */
10686 int
add_key_to_distinct_keyset()10687 Rows_log_event::add_key_to_distinct_keyset()
10688 {
10689   int error= 0;
10690   DBUG_ENTER("Rows_log_event::add_key_to_distinct_keyset");
10691   DBUG_ASSERT(m_key_index < MAX_KEY);
10692   key_copy(m_distinct_key_spare_buf, m_table->record[0], m_key_info, 0);
10693   std::pair<std::set<uchar *, Key_compare>::iterator,bool> ret=
10694     m_distinct_keys.insert(m_distinct_key_spare_buf);
10695   if (ret.second)
10696   {
10697     /* Insert is successful, so allocate a new buffer for next key */
10698     m_distinct_key_spare_buf= (uchar*) thd->alloc(m_key_info->key_length);
10699     if (!m_distinct_key_spare_buf)
10700     {
10701       error= HA_ERR_OUT_OF_MEM;
10702       goto err;
10703     }
10704   }
10705 err:
10706   DBUG_RETURN(error);
10707 }
10708 
10709 
do_index_scan_and_update(Relay_log_info const * rli)10710 int Rows_log_event::do_index_scan_and_update(Relay_log_info const *rli)
10711 {
10712   DBUG_ENTER("Rows_log_event::do_index_scan_and_update");
10713   DBUG_ASSERT(m_table && m_table->in_use != NULL);
10714 
10715   int error= 0;
10716   const uchar *saved_m_curr_row= m_curr_row;
10717 
10718   /*
10719     rpl_row_tabledefs.test specifies that
10720     if the extra field on the slave does not have a default value
10721     and this is okay with Delete or Update events.
10722     Todo: fix wl3228 hld that requires defaults for all types of events
10723   */
10724 
10725   prepare_record(m_table, &m_cols, FALSE);
10726   if ((error= unpack_current_row(rli, &m_cols)))
10727     goto end;
10728 
10729   // Temporary fix to find out why it fails [/Matz]
10730   memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
10731 
10732   /*
10733     Trying to do an index scan without a usable key
10734     This is a valid state because we allow the user
10735     to set Slave_rows_search_algorithm= 'INDEX_SCAN'.
10736 
10737     Therefore on tables with no indexes we will end
10738     up here.
10739    */
10740   if (m_key_index >= MAX_KEY)
10741   {
10742     error= HA_ERR_END_OF_FILE;
10743     goto end;
10744   }
10745 
10746 #ifndef DBUG_OFF
10747   DBUG_PRINT("info",("looking for the following record"));
10748   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10749 #endif
10750 
10751   if (m_key_index != m_table->s->primary_key)
10752     /* we dont have a PK, or PK is not usable */
10753     goto INDEX_SCAN;
10754 
10755   if ((m_table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL))
10756   {
10757     /*
10758       Read removal is possible since the engine supports write without
10759       previous read using full primary key
10760     */
10761     DBUG_PRINT("info", ("using read before write removal"));
10762     DBUG_ASSERT(m_key_index == m_table->s->primary_key);
10763 
10764     /*
10765       Tell the handler to ignore if key exists or not, since it's
10766       not yet known if the key does exist(when using rbwr)
10767     */
10768     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
10769 
10770     goto end;
10771   }
10772 
10773   if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION))
10774   {
10775     /*
10776       Use a more efficient method to fetch the record given by
10777       table->record[0] if the engine allows it.  We first compute a
10778       row reference using the position() member function (it will be
10779       stored in table->file->ref) and then use rnd_pos() to position
10780       the "cursor" (i.e., record[0] in this case) at the correct row.
10781 
10782       TODO: Check that the correct record has been fetched by
10783       comparing it with the original record. Take into account that the
10784       record on the master and slave can be of different
10785       length. Something along these lines should work:
10786 
10787       ADD>>>  store_record(table,record[1]);
10788               int error= table->file->rnd_pos(table->record[0], table->file->ref);
10789       ADD>>>  DBUG_ASSERT(memcmp(table->record[1], table->record[0],
10790                                  table->s->reclength) == 0);
10791 
10792     */
10793 
10794     DBUG_PRINT("info",("locating record using primary key (position)"));
10795     if (m_table->file->inited && (error= m_table->file->ha_index_end()))
10796       goto end;
10797 
10798     error= m_table->file->rnd_pos_by_record(m_table->record[0]);
10799     if (error)
10800     {
10801       DBUG_PRINT("info",("rnd_pos returns error %d",error));
10802       if (error == HA_ERR_RECORD_DELETED)
10803         error= HA_ERR_KEY_NOT_FOUND;
10804     }
10805 
10806     goto end;
10807   }
10808 
10809   // We can't use position() - try other methods.
10810 
10811 INDEX_SCAN:
10812 
10813   /* Use the m_key_index'th key */
10814 
10815   if ((error= open_record_scan()))
10816     goto end;
10817 
10818   error= next_record_scan(true);
10819   if (error)
10820   {
10821     DBUG_PRINT("info",("no record matching the key found in the table"));
10822     if (error == HA_ERR_RECORD_DELETED)
10823       error= HA_ERR_KEY_NOT_FOUND;
10824     goto end;
10825   }
10826 
10827 
10828   /*
10829     Don't print debug messages when running valgrind since they can
10830     trigger false warnings.
10831    */
10832 #ifndef HAVE_purify
10833   DBUG_PRINT("info",("found first matching record"));
10834   DBUG_DUMP("record[0]", m_table->record[0], m_table->s->reclength);
10835 #endif
10836   /*
10837     Below is a minor "optimization".  If the key (i.e., key number
10838     0) has the HA_NOSAME flag set, we know that we have found the
10839     correct record (since there can be no duplicates); otherwise, we
10840     have to compare the record with the one found to see if it is
10841     the correct one.
10842 
10843     CAVEAT! This behaviour is essential for the replication of,
10844     e.g., the mysql.proc table since the correct record *shall* be
10845     found using the primary key *only*.  There shall be no
10846     comparison of non-PK columns to decide if the correct record is
10847     found.  I can see no scenario where it would be incorrect to
10848     chose the row to change only using a PK or an UNNI.
10849   */
10850   if (m_key_info->flags & HA_NOSAME || m_key_index == m_table->s->primary_key)
10851   {
10852     /* Unique does not have non nullable part */
10853     if (!(m_key_info->flags & (HA_NULL_PART_KEY)))
10854       goto end;  // record found
10855     else
10856     {
10857       /*
10858         Unique has nullable part. We need to check if there is any field in the
10859         BI image that is null and part of UNNI.
10860       */
10861       bool null_found= FALSE;
10862       for (uint i=0; i < m_key_info->user_defined_key_parts && !null_found; i++)
10863       {
10864         uint fieldnr= m_key_info->key_part[i].fieldnr - 1;
10865         Field **f= m_table->field+fieldnr;
10866         null_found= (*f)->is_null();
10867       }
10868 
10869       if (!null_found)
10870         goto end;           // record found
10871 
10872       /* else fall through to index scan */
10873     }
10874   }
10875 
10876   /*
10877     In case key is not unique, we still have to iterate over records found
10878     and find the one which is identical to the row given. A copy of the
10879     record we are looking for is stored in record[1].
10880    */
10881   DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10882 
10883   while (record_compare(m_table, &m_cols))
10884   {
10885     while((error= next_record_scan(false)))
10886     {
10887       /* We just skip records that has already been deleted */
10888       if (error == HA_ERR_RECORD_DELETED)
10889         continue;
10890       DBUG_PRINT("info",("no record matching the given row found"));
10891       goto end;
10892     }
10893   }
10894 
10895 end:
10896 
10897   DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10898 
10899   if (error && error != HA_ERR_RECORD_DELETED)
10900     m_table->file->print_error(error, MYF(0));
10901   else
10902     error= do_apply_row(rli);
10903 
10904   if (!error)
10905     error= close_record_scan();
10906   else
10907     /*
10908       we are already with errors. Keep the error code and
10909       try to close the scan anyway.
10910     */
10911     (void) close_record_scan();
10912 
10913   if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
10914       (saved_m_curr_row == m_curr_row))
10915   {
10916     /* we need to unpack the AI so that positions get updated */
10917     m_curr_row= m_curr_row_end;
10918     unpack_current_row(rli, &m_cols_ai);
10919   }
10920   m_table->default_column_bitmaps();
10921   DBUG_RETURN(error);
10922 
10923 }
10924 
do_hash_row(Relay_log_info const * rli)10925 int Rows_log_event::do_hash_row(Relay_log_info const *rli)
10926 {
10927   DBUG_ENTER("Rows_log_event::do_hash_row");
10928   DBUG_ASSERT(m_table && m_table->in_use != NULL);
10929   int error= 0;
10930 
10931   /* create an empty entry to add to the hash table */
10932   HASH_ROW_ENTRY* entry= m_hash.make_entry();
10933   if (entry == NULL)
10934   {
10935     error= 1;
10936     goto end;
10937   }
10938   /* Prepare the record, unpack and save positions. */
10939   entry->positions->bi_start= m_curr_row;        // save the bi start pos
10940   prepare_record(m_table, &m_cols, false);
10941   if ((error= unpack_current_row(rli, &m_cols)))
10942     goto end;
10943   entry->positions->bi_ends= m_curr_row_end;    // save the bi end pos
10944 
10945   /*
10946     Now that m_table->record[0] is filled in, we can add the entry
10947     to the hash table. Note that the put operation calculates the
10948     key based on record[0] contents (including BLOB fields).
10949    */
10950   m_hash.put(m_table, &m_cols, entry);
10951 
10952   if (m_key_index < MAX_KEY)
10953     add_key_to_distinct_keyset();
10954 
10955   /*
10956     We need to unpack the AI to advance the positions, so we
10957     know when we have reached m_rows_end and that we do not
10958     unpack the AI in the next iteration as if it was a BI.
10959   */
10960   if (get_general_type_code() == UPDATE_ROWS_EVENT)
10961   {
10962     /* Save a copy of the BI. */
10963     store_record(m_table, record[1]);
10964 
10965      /*
10966       This is the situation after hashing the BI:
10967 
10968       ===|=== before image ====|=== after image ===|===
10969          ^                     ^
10970          m_curr_row            m_curr_row_end
10971     */
10972 
10973     /* Set the position to the start of the record to be unpacked. */
10974     m_curr_row= m_curr_row_end;
10975 
10976     /* We shouldn't need this, but lets not leave loose ends */
10977     prepare_record(m_table, &m_cols, false);
10978     error= unpack_current_row(rli, &m_cols_ai);
10979 
10980     /*
10981       This is the situation after unpacking the AI:
10982 
10983       ===|=== before image ====|=== after image ===|===
10984                                ^                   ^
10985                                m_curr_row          m_curr_row_end
10986     */
10987 
10988     /* Restore back the copy of the BI. */
10989     restore_record(m_table, record[1]);
10990   }
10991 
10992 end:
10993   DBUG_RETURN(error);
10994 }
10995 
do_scan_and_update(Relay_log_info const * rli)10996 int Rows_log_event::do_scan_and_update(Relay_log_info const *rli)
10997 {
10998   DBUG_ENTER("Rows_log_event::do_scan_and_update");
10999   DBUG_ASSERT(m_table && m_table->in_use != NULL);
11000   DBUG_ASSERT(m_hash.is_empty() == false);
11001   TABLE *table= m_table;
11002   int error= 0;
11003   const uchar *saved_last_m_curr_row= NULL;
11004   const uchar *saved_last_m_curr_row_end= NULL;
11005   /* create an empty entry to add to the hash table */
11006   HASH_ROW_ENTRY* entry= NULL;
11007   int idempotent_errors= 0;
11008   int i= 0;
11009 
11010   saved_last_m_curr_row=m_curr_row;
11011   saved_last_m_curr_row_end=m_curr_row_end;
11012 
11013   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11014 
11015   /* open table or index depending on whether we have set m_key_index or not. */
11016   if ((error= open_record_scan()))
11017     goto err;
11018 
11019   /*
11020      Scan the table only once and compare against entries in hash.
11021      When a match is found, apply the changes.
11022    */
11023   do
11024   {
11025     /* get the next record from the table */
11026     error= next_record_scan(i == 0);
11027     i++;
11028 
11029     if(error)
11030       DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11031     switch (error) {
11032       case 0:
11033       {
11034         entry= m_hash.get(table, &m_cols);
11035         store_record(table, record[1]);
11036 
11037         /**
11038            If there are collisions we need to be sure that this is
11039            indeed the record we want.  Loop through all records for
11040            the given key and explicitly compare them against the
11041            record we got from the storage engine.
11042          */
11043         while(entry)
11044         {
11045           m_curr_row= entry->positions->bi_start;
11046           m_curr_row_end= entry->positions->bi_ends;
11047 
11048           prepare_record(table, &m_cols, false);
11049           if ((error= unpack_current_row(rli, &m_cols)))
11050             goto close_table;
11051 
11052           if (record_compare(table, &m_cols))
11053             m_hash.next(&entry);
11054           else
11055             break;   // we found a match
11056         }
11057 
11058         /**
11059            We found the entry we needed, just apply the changes.
11060          */
11061         if (entry)
11062         {
11063           // just to be safe, copy the record from the SE to table->record[0]
11064           restore_record(table, record[1]);
11065 
11066           /**
11067              At this point, both table->record[0] and
11068              table->record[1] have the SE row that matched the one
11069              in the hash table.
11070 
11071              Thence if this is a DELETE we wouldn't need to mess
11072              around with positions anymore, but since this can be an
11073              update, we need to provide positions so that AI is
11074              unpacked correctly to table->record[0] in UPDATE
11075              implementation of do_exec_row().
11076           */
11077           m_curr_row= entry->positions->bi_start;
11078           m_curr_row_end= entry->positions->bi_ends;
11079 
11080           /* we don't need this entry anymore, just delete it */
11081           if ((error= m_hash.del(entry)))
11082             goto err;
11083 
11084           if ((error= do_apply_row(rli)))
11085           {
11086             if (handle_idempotent_and_ignored_errors(rli, &error))
11087               goto close_table;
11088 
11089             do_post_row_operations(rli, error);
11090           }
11091         }
11092       }
11093       break;
11094 
11095       case HA_ERR_RECORD_DELETED:
11096         // get next
11097         continue;
11098 
11099       case HA_ERR_KEY_NOT_FOUND:
11100         /* If the slave exec mode is idempotent or the error is
11101             skipped error, then don't break */
11102         if (handle_idempotent_and_ignored_errors(rli, &error))
11103           goto close_table;
11104         idempotent_errors++;
11105         continue;
11106 
11107       case HA_ERR_END_OF_FILE:
11108       default:
11109         // exception (hash is not empty and we have reached EOF or
11110         // other error happened)
11111         goto close_table;
11112     }
11113   }
11114  /**
11115    if the slave_exec_mode is set to Idempotent, we cannot expect the hash to
11116    be empty. In such cases we count the number of idempotent errors and check
11117    if it is equal to or greater than the number of rows left in the hash.
11118   */
11119   while (((idempotent_errors < m_hash.size()) && !m_hash.is_empty()) &&
11120          (!error || (error == HA_ERR_RECORD_DELETED)));
11121 
11122 close_table:
11123   if (error == HA_ERR_RECORD_DELETED)
11124     error= 0;
11125 
11126   if (error)
11127   {
11128     table->file->print_error(error, MYF(0));
11129     DBUG_PRINT("info", ("Failed to get next record"
11130                         " (ha_rnd_next returns %d)",error));
11131     /*
11132       we are already with errors. Keep the error code and
11133       try to close the scan anyway.
11134     */
11135     (void) close_record_scan();
11136   }
11137   else
11138     error= close_record_scan();
11139 
11140   DBUG_ASSERT((m_hash.is_empty() && !error) ||
11141               (!m_hash.is_empty() &&
11142                ((error) || (idempotent_errors >= m_hash.size()))));
11143 
11144 err:
11145 
11146   if ((m_hash.is_empty() && !error) || (idempotent_errors >= m_hash.size()))
11147   {
11148     /**
11149        Reset the last positions, because the positions are lost while
11150        handling entries in the hash.
11151      */
11152     m_curr_row= saved_last_m_curr_row;
11153     m_curr_row_end= saved_last_m_curr_row_end;
11154   }
11155 
11156   DBUG_RETURN(error);
11157 }
11158 
do_hash_scan_and_update(Relay_log_info const * rli)11159 int Rows_log_event::do_hash_scan_and_update(Relay_log_info const *rli)
11160 {
11161   DBUG_ENTER("Rows_log_event::do_hash_scan_and_update");
11162   DBUG_ASSERT(m_table && m_table->in_use != NULL);
11163 
11164   // HASHING PART
11165 
11166   /* unpack the BI (and AI, if it exists) and add it to the hash map. */
11167   if (int error= this->do_hash_row(rli))
11168     DBUG_RETURN(error);
11169 
11170   /* We have not yet hashed all rows in the buffer. Do not proceed to the SCAN part. */
11171   if (m_curr_row_end < m_rows_end)
11172     DBUG_RETURN (0);
11173 
11174   DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
11175   DBUG_ASSERT(m_curr_row_end == m_rows_end);
11176 
11177   // SCANNING & UPDATE PART
11178 
11179   DBUG_RETURN(this->do_scan_and_update(rli));
11180 }
11181 
do_table_scan_and_update(Relay_log_info const * rli)11182 int Rows_log_event::do_table_scan_and_update(Relay_log_info const *rli)
11183 {
11184   int error= 0;
11185   const uchar* saved_m_curr_row= m_curr_row;
11186   TABLE* table= m_table;
11187 
11188   DBUG_ENTER("Rows_log_event::do_table_scan_and_update");
11189   DBUG_ASSERT(m_curr_row != m_rows_end);
11190   DBUG_PRINT("info",("locating record using table scan (ha_rnd_next)"));
11191 
11192   saved_m_curr_row= m_curr_row;
11193 
11194   /** unpack the before image */
11195   prepare_record(table, &m_cols, FALSE);
11196   if (!(error= unpack_current_row(rli, &m_cols)))
11197   {
11198     // Temporary fix to find out why it fails [/Matz]
11199     memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
11200 
11201     /** save a copy so that we can compare against it later */
11202     store_record(m_table, record[1]);
11203 
11204     int restart_count= 0; // Number of times scanning has restarted from top
11205 
11206     if ((error= m_table->file->ha_rnd_init(1)))
11207     {
11208       DBUG_PRINT("info",("error initializing table scan"
11209                          " (ha_rnd_init returns %d)",error));
11210       goto end;
11211     }
11212 
11213     /* Continue until we find the right record or have made a full loop */
11214     do
11215     {
11216   restart_ha_rnd_next:
11217       error= m_table->file->ha_rnd_next(m_table->record[0]);
11218       if (error)
11219         DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
11220       switch (error) {
11221       case HA_ERR_END_OF_FILE:
11222         // restart scan from top
11223         if (++restart_count < 2)
11224         {
11225           if ((error= m_table->file->ha_rnd_init(1)))
11226             goto end;
11227           goto restart_ha_rnd_next;
11228         }
11229         break;
11230 
11231       case HA_ERR_RECORD_DELETED:
11232         // fetch next
11233         goto restart_ha_rnd_next;
11234       case 0:
11235         // we're good, check if record matches
11236         break;
11237 
11238       default:
11239         // exception
11240         goto end;
11241       }
11242     }
11243     while (restart_count < 2 && record_compare(m_table, &m_cols));
11244   }
11245 
11246 end:
11247 
11248   DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
11249 
11250   /* either we report error or apply the changes */
11251   if (error && error != HA_ERR_RECORD_DELETED)
11252   {
11253     DBUG_PRINT("info", ("Failed to get next record"
11254                         " (ha_rnd_next returns %d)",error));
11255     m_table->file->print_error(error, MYF(0));
11256   }
11257   else
11258     error= do_apply_row(rli);
11259 
11260 
11261   if (!error)
11262     error= close_record_scan();
11263   else
11264     /*
11265       we are already with errors. Keep the error code and
11266       try to close the scan anyway.
11267     */
11268     (void) close_record_scan();
11269 
11270   if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11271       (saved_m_curr_row == m_curr_row)) // we need to unpack the AI
11272   {
11273     m_curr_row= m_curr_row_end;
11274     unpack_current_row(rli, &m_cols);
11275   }
11276 
11277   table->default_column_bitmaps();
11278   DBUG_RETURN(error);
11279 }
11280 
do_apply_event(Relay_log_info const * rli)11281 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
11282 {
11283   DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
11284   TABLE *table= NULL;
11285   int error= 0;
11286 
11287   if (opt_bin_log)
11288   {
11289     enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
11290     if (state == GTID_STATEMENT_CANCEL)
11291       // error has already been printed; don't print anything more here
11292       DBUG_RETURN(-1);
11293     else if (state == GTID_STATEMENT_SKIP)
11294       DBUG_RETURN(0);
11295   }
11296 
11297   /*
11298     'thd' has been set by exec_relay_log_event(), just before calling
11299     do_apply_event(). We still check here to prevent future coding
11300     errors.
11301   */
11302   DBUG_ASSERT(rli->info_thd == thd);
11303 
11304   /*
11305     If there is no locks taken, this is the first binrow event seen
11306     after the table map events.  We should then lock all the tables
11307     used in the transaction and proceed with execution of the actual
11308     event.
11309   */
11310   if (!thd->lock)
11311   {
11312     /*
11313       Lock_tables() reads the contents of thd->lex, so they must be
11314       initialized.
11315 
11316       We also call the mysql_reset_thd_for_next_command(), since this
11317       is the logical start of the next "statement". Note that this
11318       call might reset the value of current_stmt_binlog_format, so
11319       we need to do any changes to that value after this function.
11320     */
11321     lex_start(thd);
11322     mysql_reset_thd_for_next_command(thd);
11323     /*
11324       The current statement is just about to begin and
11325       has not yet modified anything. Note, all.modified is reset
11326       by mysql_reset_thd_for_next_command.
11327     */
11328     thd->transaction.stmt.reset_unsafe_rollback_flags();
11329     /*
11330       This is a row injection, so we flag the "statement" as
11331       such. Note that this code is called both when the slave does row
11332       injections and when the BINLOG statement is used to do row
11333       injections.
11334     */
11335     thd->lex->set_stmt_row_injection();
11336 
11337     /*
11338       There are a few flags that are replicated with each row event.
11339       Make sure to set/clear them before executing the main body of
11340       the event.
11341     */
11342     if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
11343         thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
11344     else
11345         thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
11346 
11347     if (get_flags(RELAXED_UNIQUE_CHECKS_F))
11348         thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
11349     else
11350         thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
11351 
11352     thd->binlog_row_event_extra_data = m_extra_row_data;
11353 
11354     /* A small test to verify that objects have consistent types */
11355     DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
11356     DBUG_EXECUTE_IF("rows_log_event_before_open_table",
11357                     {
11358                       const char action[] = "now SIGNAL before_open_table WAIT_FOR go_ahead_sql";
11359                       DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(action)));
11360                     };);
11361     if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
11362     {
11363 #ifdef WITH_WSREP
11364       if (WSREP(thd))
11365       {
11366         WSREP_WARN("BF applier failed to open_and_lock_tables: %u, fatal: %d "
11367                    "wsrep = (exec_mode: %d conflict_state: %d seqno: %lld)",
11368                    thd->get_stmt_da()->sql_errno(),
11369                    thd->is_fatal_error,
11370                    thd->wsrep_exec_mode,
11371                    thd->wsrep_conflict_state,
11372                    (long long)wsrep_thd_trx_seqno(thd));
11373       }
11374 #endif
11375       if (thd->is_error())
11376       {
11377         uint actual_error= thd->get_stmt_da()->sql_errno();
11378         if (ignored_error_code(actual_error))
11379         {
11380           if (log_warnings > 1)
11381             rli->report(WARNING_LEVEL, actual_error,
11382                         "Error executing row event: '%s'",
11383                         thd->get_stmt_da()->message());
11384           thd->get_stmt_da()->clear_warning_info(thd->query_id);
11385           clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11386           error= 0;
11387           goto end;
11388         }
11389         else
11390         {
11391           rli->report(ERROR_LEVEL, actual_error,
11392                       "Error executing row event: '%s'",
11393                       thd->get_stmt_da()->message());
11394           thd->is_slave_error= 1;
11395         }
11396       }
11397       DBUG_RETURN(1);
11398     }
11399     /*
11400       When the open and locking succeeded, we check all tables to
11401       ensure that they still have the correct type.
11402     */
11403 
11404     {
11405       DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
11406                            rli->tables_to_lock));
11407 
11408       /**
11409         When using RBR and MyISAM MERGE tables the base tables that make
11410         up the MERGE table can be appended to the list of tables to lock.
11411 
11412         Thus, we just check compatibility for those that tables that have
11413         a correspondent table map event (ie, those that are actually going
11414         to be accessed while applying the event). That's why the loop stops
11415         at rli->tables_to_lock_count .
11416 
11417         NOTE: The base tables are added here are removed when
11418               close_thread_tables is called.
11419        */
11420       TABLE_LIST *table_list_ptr= rli->tables_to_lock;
11421       for (uint i=0 ; table_list_ptr && (i < rli->tables_to_lock_count);
11422            table_list_ptr= table_list_ptr->next_global, i++)
11423       {
11424         /*
11425           Below if condition takes care of skipping base tables that
11426           make up the MERGE table (which are added by open_tables()
11427           call). They are added next to the merge table in the list.
11428           For eg: If RPL_TABLE_LIST is t3->t1->t2 (where t1 and t2
11429           are base tables for merge table 't3'), open_tables will modify
11430           the list by adding t1 and t2 again immediately after t3 in the
11431           list (*not at the end of the list*). New table_to_lock list will
11432           look like t3->t1'->t2'->t1->t2 (where t1' and t2' are TABLE_LIST
11433           objects added by open_tables() call). There is no flag(or logic) in
11434           open_tables() that can skip adding these base tables to the list.
11435           So the logic here should take care of skipping them.
11436 
11437           tables_to_lock_count logic will take care of skipping base tables
11438           that are added at the end of the list.
11439           For eg: If RPL_TABLE_LIST is t1->t2->t3, open_tables will modify
11440           the list into t1->t2->t3->t1'->t2'. t1' and t2' will be skipped
11441           because tables_to_lock_count logic in this for loop.
11442         */
11443         if (table_list_ptr->parent_l)
11444           continue;
11445         /*
11446           We can use a down cast here since we know that every table added
11447           to the tables_to_lock is a RPL_TABLE_LIST (or child table which is
11448           skipped above).
11449         */
11450         RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(table_list_ptr);
11451         DBUG_ASSERT(ptr->m_tabledef_valid);
11452         TABLE *conv_table;
11453         if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
11454                                              ptr->table, &conv_table))
11455         {
11456           DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
11457                                ptr->table->s->db.str,
11458                                ptr->table->s->table_name.str));
11459           if (thd->is_slave_error)
11460           {
11461             const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
11462             DBUG_RETURN(ERR_BAD_TABLE_DEF);
11463           }
11464           else
11465           {
11466             thd->get_stmt_da()->clear_warning_info(thd->query_id);
11467             clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11468             error= 0;
11469             goto end;
11470           }
11471         }
11472         DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
11473                              " - conv_table: %p",
11474                              ptr->table->s->db.str,
11475                              ptr->table->s->table_name.str, conv_table));
11476         ptr->m_conv_table= conv_table;
11477       }
11478     }
11479 
11480     /*
11481       ... and then we add all the tables to the table map and but keep
11482       them in the tables to lock list.
11483 
11484       We also invalidate the query cache for all the tables, since
11485       they will now be changed.
11486 
11487       TODO [/Matz]: Maybe the query cache should not be invalidated
11488       here? It might be that a table is not changed, even though it
11489       was locked for the statement.  We do know that each
11490       Rows_log_event contain at least one row, so after processing one
11491       Rows_log_event, we can invalidate the query cache for the
11492       associated table.
11493      */
11494     TABLE_LIST *ptr= rli->tables_to_lock;
11495     for (uint i=0 ;  ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
11496     {
11497       /*
11498         Please see comment in above 'for' loop to know the reason
11499         for this if condition
11500       */
11501       if (ptr->parent_l)
11502         continue;
11503       const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
11504     }
11505 
11506 #ifdef HAVE_QUERY_CACHE
11507 #ifdef WITH_WSREP
11508     /*
11509       Moved invalidation right before the call to rows_event_stmt_cleanup(),
11510       to avoid query cache being polluted with stale entries,
11511     */
11512     if (! (WSREP(thd) && (thd->wsrep_exec_mode == REPL_RECV)))
11513     {
11514 #endif /* WITH_WSREP */
11515       query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11516 #ifdef WITH_WSREP
11517     }
11518 #endif /* WITH_WSREP */
11519 #endif
11520   }
11521 
11522   table=
11523     m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
11524 
11525   DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %llu", (ulong) m_table,
11526                        m_table_id.id()));
11527 
11528   /*
11529     A row event comprising of a P_S table
11530     - should not be replicated (i.e executed) by the slave SQL thread.
11531     - should not be executed by the client in the  form BINLOG '...' stmts.
11532   */
11533   if (table && table->s->table_category == TABLE_CATEGORY_PERFORMANCE)
11534     table= NULL;
11535 
11536   if (table)
11537   {
11538     /*
11539       table == NULL means that this table should not be replicated
11540       (this was set up by Table_map_log_event::do_apply_event()
11541       which tested replicate-* rules).
11542     */
11543 
11544     /*
11545       It's not needed to set_time() but
11546       1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11547       much slave is behind
11548       2) it will be needed when we allow replication from a table with no
11549       TIMESTAMP column to a table with one.
11550       So we call set_time(), like in SBR. Presently it changes nothing.
11551     */
11552     thd->set_time(&when);
11553 
11554     thd->binlog_row_event_extra_data = m_extra_row_data;
11555 
11556     /*
11557       Now we are in a statement and will stay in a statement until we
11558       see a STMT_END_F.
11559 
11560       We set this flag here, before actually applying any rows, in
11561       case the SQL thread is stopped and we need to detect that we're
11562       inside a statement and halting abruptly might cause problems
11563       when restarting.
11564      */
11565     const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
11566 
11567      if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11568       set_flags(COMPLETE_ROWS_F);
11569 
11570     /*
11571       Set tables write and read sets.
11572 
11573       Read_set contains all slave columns (in case we are going to fetch
11574       a complete record from slave)
11575 
11576       Write_set equals the m_cols bitmap sent from master but it can be
11577       longer if slave has extra columns.
11578      */
11579 
11580     DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11581 
11582     bitmap_set_all(table->read_set);
11583     if (get_general_type_code() == DELETE_ROWS_EVENT ||
11584         get_general_type_code() == UPDATE_ROWS_EVENT)
11585         bitmap_intersect(table->read_set,&m_cols);
11586 
11587     bitmap_set_all(table->write_set);
11588 
11589     /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11590     MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
11591                              &m_cols_ai : &m_cols);
11592     bitmap_intersect(table->write_set, after_image);
11593 
11594     this->slave_exec_mode= slave_exec_mode_options; // fix the mode
11595 
11596     // Do event specific preparations
11597     error= do_before_row_operations(rli);
11598 
11599     /*
11600       Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11601       Don't allow generation of auto_increment value when processing
11602       rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'. The exception
11603       to this rule happens when the auto_inc column exists on some
11604       extra columns on the slave. In that case, do not force
11605       MODE_NO_AUTO_VALUE_ON_ZERO.
11606     */
11607     ulong saved_sql_mode= thd->variables.sql_mode;
11608     if (!is_auto_inc_in_extra_columns())
11609       thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11610 
11611     // row processing loop
11612 
11613     /*
11614       set the initial time of this ROWS statement if it was not done
11615       before in some other ROWS event.
11616      */
11617     const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
11618 
11619     const uchar *saved_m_curr_row= m_curr_row;
11620 
11621     int (Rows_log_event::*do_apply_row_ptr)(Relay_log_info const *)= NULL;
11622 
11623     /**
11624        Skip update rows events that don't have data for this slave's
11625        table.
11626      */
11627     if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11628         !is_any_column_signaled_for_table(table, &m_cols_ai))
11629       goto AFTER_MAIN_EXEC_ROW_LOOP;
11630 
11631     /**
11632        If there are no columns marked in the read_set for this table,
11633        that means that we cannot lookup any row using the available BI
11634        in the binarr log. Thence, we immediatly raise an error:
11635        HA_ERR_END_OF_FILE.
11636      */
11637 
11638     if ((m_rows_lookup_algorithm != ROW_LOOKUP_NOT_NEEDED) &&
11639         !is_any_column_signaled_for_table(table, &m_cols))
11640     {
11641       error= HA_ERR_END_OF_FILE;
11642       goto AFTER_MAIN_EXEC_ROW_LOOP;
11643     }
11644     switch (m_rows_lookup_algorithm)
11645     {
11646       case ROW_LOOKUP_HASH_SCAN:
11647         do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11648         break;
11649 
11650       case ROW_LOOKUP_INDEX_SCAN:
11651         do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11652         break;
11653 
11654       case ROW_LOOKUP_TABLE_SCAN:
11655         do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11656         break;
11657 
11658       case ROW_LOOKUP_NOT_NEEDED:
11659         DBUG_ASSERT(get_general_type_code() == WRITE_ROWS_EVENT);
11660 
11661         /* No need to scan for rows, just apply it */
11662         do_apply_row_ptr= &Rows_log_event::do_apply_row;
11663         break;
11664 
11665       default:
11666         DBUG_ASSERT(0);
11667         error= 1;
11668         goto AFTER_MAIN_EXEC_ROW_LOOP;
11669         break;
11670     }
11671 
11672     do {
11673 
11674       error= (this->*do_apply_row_ptr)(rli);
11675 
11676       if (handle_idempotent_and_ignored_errors(rli, &error))
11677         break;
11678 
11679       /* this advances m_curr_row */
11680       do_post_row_operations(rli, error);
11681 
11682     } while (!error && (m_curr_row != m_rows_end));
11683 
11684 AFTER_MAIN_EXEC_ROW_LOOP:
11685 
11686     if (saved_m_curr_row != m_curr_row && !table->file->has_transactions())
11687     {
11688       /*
11689         Usually, the trans_commit_stmt() propagates unsafe_rollback_flags
11690         from statement to transaction level. However, we cannot rely on
11691         this when row format is in use as several events can be processed
11692         before calling this function. This happens because it is called
11693         only when the latest event generated by a statement is processed.
11694 
11695         There are however upper level functions that execute per event
11696         and check transaction's status. So if the unsafe_rollback_flags
11697         are not propagated here, this can lead to errors.
11698 
11699         For example, a transaction that updates non-transactional tables
11700         may be stopped in the middle thus leading to inconsistencies
11701         after a restart.
11702       */
11703       thd->transaction.stmt.mark_modified_non_trans_table();
11704       thd->transaction.merge_unsafe_rollback_flags();
11705     }
11706 
11707     /*
11708       Restore the sql_mode after the rows event is processed.
11709     */
11710     thd->variables.sql_mode= saved_sql_mode;
11711 
11712     {/*
11713          The following failure injecion works in cooperation with tests
11714          setting @@global.debug= 'd,stop_slave_middle_group'.
11715          The sql thread receives the killed status and will proceed
11716          to shutdown trying to finish incomplete events group.
11717      */
11718       DBUG_EXECUTE_IF("stop_slave_middle_group",
11719                       if (thd->transaction.all.cannot_safely_rollback())
11720                         const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11721     }
11722 
11723     if ((error= do_after_row_operations(rli, error)) &&
11724         ignored_error_code(convert_handler_error(error, thd, table)))
11725     {
11726 
11727       if (log_warnings > 1)
11728         slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
11729                                 get_type_str(),
11730                                 const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11731                                 (ulong) log_pos);
11732       thd->get_stmt_da()->clear_warning_info(thd->query_id);
11733       clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11734       error= 0;
11735     }
11736   } // if (table)
11737 
11738   if (error)
11739   {
11740     slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
11741                              get_type_str(),
11742                              const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11743                              (ulong) log_pos);
11744     /*
11745       @todo We should probably not call
11746       reset_current_stmt_binlog_format_row() from here.
11747 
11748       Note: this applies to log_event_old.cc too.
11749       /Sven
11750     */
11751     thd->reset_current_stmt_binlog_format_row();
11752     thd->is_slave_error= 1;
11753     DBUG_RETURN(error);
11754   }
11755 end:
11756   if (get_flags(STMT_END_F))
11757   {
11758 
11759 #if defined(WITH_WSREP) && defined(HAVE_QUERY_CACHE)
11760     if (WSREP(thd) && thd->wsrep_exec_mode == REPL_RECV)
11761     {
11762       query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11763     }
11764 #endif /* WITH_WSREP && HAVE_QUERY_CACHE */
11765 
11766    if((error= rows_event_stmt_cleanup(rli, thd)))
11767    {
11768      if (table)
11769        slave_rows_error_report(ERROR_LEVEL,
11770                                thd->is_error() ? 0 : error,
11771                                rli, thd, table,
11772                                get_type_str(),
11773                                const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11774                                (ulong) log_pos);
11775      else
11776      {
11777        rli->report(ERROR_LEVEL,
11778                    thd->is_error() ? thd->get_stmt_da()->sql_errno() : error,
11779                    "Error in cleaning up after an event of type:%s; %s; the group"
11780                    " log file/position: %s %lu", get_type_str(),
11781                    thd->is_error() ? thd->get_stmt_da()->message() : "unexpected error",
11782                    const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11783                    (ulong) log_pos);
11784      }
11785    }
11786    /* We are at end of the statement (STMT_END_F flag), lets clean
11787      the memory which was used from thd's mem_root now.
11788      This needs to be done only if we are here in SQL thread context.
11789      In other flow ( in case of a regular thread which can happen
11790      when the thread is applying BINLOG'...' row event) we should
11791      *not* try to free the memory here. It will be done latter
11792      in dispatch_command() after command execution is completed.
11793     */
11794    if (thd->slave_thread)
11795      free_root(thd->mem_root, MYF(MY_KEEP_PREALLOC));
11796   }
11797   DBUG_RETURN(error);
11798 }
11799 
11800 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)11801 Rows_log_event::do_shall_skip(Relay_log_info *rli)
11802 {
11803   /*
11804     If the slave skip counter is 1 and this event does not end a
11805     statement, then we should not start executing on the next event.
11806     Otherwise, we defer the decision to the normal skipping logic.
11807   */
11808   if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11809     return Log_event::EVENT_SKIP_IGNORE;
11810   else
11811     return Log_event::do_shall_skip(rli);
11812 }
11813 
11814 /**
11815    The function is called at Rows_log_event statement commit time,
11816    normally from Rows_log_event::do_update_pos() and possibly from
11817    Query_log_event::do_apply_event() of the COMMIT.
11818    The function commits the last statement for engines, binlog and
11819    releases resources have been allocated for the statement.
11820 
11821    @retval  0         Ok.
11822    @retval  non-zero  Error at the commit.
11823  */
11824 
rows_event_stmt_cleanup(Relay_log_info const * rli,THD * thd)11825 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
11826 {
11827   DBUG_EXECUTE_IF("simulate_rows_event_cleanup_failure",
11828                   {
11829                     my_error(ER_ERROR_DURING_COMMIT, MYF(0), 1);
11830                     return (1);
11831                   });
11832   int error;
11833   {
11834     /*
11835       This is the end of a statement or transaction, so close (and
11836       unlock) the tables we opened when processing the
11837       Table_map_log_event starting the statement.
11838 
11839       OBSERVER.  This will clear *all* mappings, not only those that
11840       are open for the table. There is not good handle for on-close
11841       actions for tables.
11842 
11843       NOTE. Even if we have no table ('table' == 0) we still need to be
11844       here, so that we increase the group relay log position. If we didn't, we
11845       could have a group relay log position which lags behind "forever"
11846       (assume the last master's transaction is ignored by the slave because of
11847       replicate-ignore rules).
11848     */
11849     error= thd->binlog_flush_pending_rows_event(TRUE);
11850 
11851     /*
11852       If this event is not in a transaction, the call below will, if some
11853       transactional storage engines are involved, commit the statement into
11854       them and flush the pending event to binlog.
11855       If this event is in a transaction, the call will do nothing, but a
11856       Xid_log_event will come next which will, if some transactional engines
11857       are involved, commit the transaction and flush the pending event to the
11858       binlog.
11859       If there was a deadlock the transaction should have been rolled back
11860       already. So there should be no need to rollback the transaction.
11861     */
11862     DBUG_ASSERT(! thd->transaction_rollback_request);
11863     error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11864 
11865     /*
11866       Now what if this is not a transactional engine? we still need to
11867       flush the pending event to the binlog; we did it with
11868       thd->binlog_flush_pending_rows_event(). Note that we imitate
11869       what is done for real queries: a call to
11870       ha_autocommit_or_rollback() (sometimes only if involves a
11871       transactional engine), and a call to be sure to have the pending
11872       event flushed.
11873     */
11874 
11875     /*
11876       @todo We should probably not call
11877       reset_current_stmt_binlog_format_row() from here.
11878 
11879       Note: this applies to log_event_old.cc too
11880 
11881       Btw, the previous comment about transactional engines does not
11882       seem related to anything that happens here.
11883       /Sven
11884     */
11885     thd->reset_current_stmt_binlog_format_row();
11886 
11887     const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
11888 
11889     /*
11890       Clean sql_command value
11891     */
11892     thd->lex->sql_command= SQLCOM_END;
11893 
11894   }
11895   return error;
11896 }
11897 
11898 /**
11899    The method either increments the relay log position or
11900    commits the current statement and increments the master group
11901    possition if the event is STMT_END_F flagged and
11902    the statement corresponds to the autocommit query (i.e replicated
11903    without wrapping in BEGIN/COMMIT)
11904 
11905    @retval 0         Success
11906    @retval non-zero  Error in the statement commit
11907  */
11908 int
do_update_pos(Relay_log_info * rli)11909 Rows_log_event::do_update_pos(Relay_log_info *rli)
11910 {
11911   DBUG_ENTER("Rows_log_event::do_update_pos");
11912   int error= 0;
11913 
11914   DBUG_PRINT("info", ("flags: %s",
11915                       get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11916 
11917   /* Worker does not execute binlog update position logics */
11918   DBUG_ASSERT(!is_mts_worker(rli->info_thd));
11919 
11920   if (get_flags(STMT_END_F))
11921   {
11922     /*
11923       Indicate that a statement is finished.
11924       Step the group log position if we are not in a transaction,
11925       otherwise increase the event log position.
11926     */
11927     error= rli->stmt_done(log_pos);
11928   }
11929   else
11930   {
11931     rli->inc_event_relay_log_pos();
11932   }
11933 
11934   DBUG_RETURN(error);
11935 }
11936 
11937 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11938 
11939 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)11940 bool Rows_log_event::write_data_header(IO_CACHE *file)
11941 {
11942   uchar buf[ROWS_HEADER_LEN_V2];	// No need to init the buffer
11943   DBUG_ASSERT(m_table_id.is_valid());
11944   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11945                   {
11946                     int4store(buf + 0, (ulong) m_table_id.id());
11947                     int2store(buf + 4, m_flags);
11948                     return (wrapper_my_b_safe_write(file, buf, 6));
11949                   });
11950   int6store(buf + RW_MAPID_OFFSET, m_table_id.id());
11951   int2store(buf + RW_FLAGS_OFFSET, m_flags);
11952   int rc = 0;
11953   if (likely(!log_bin_use_v1_row_events))
11954   {
11955     /*
11956        v2 event, with variable header portion.
11957        Determine length of variable header payload
11958     */
11959     uint16 vhlen= 2;
11960     uint16 vhpayloadlen= 0;
11961     uint16 extra_data_len= 0;
11962     if (m_extra_row_data)
11963     {
11964       extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
11965       vhpayloadlen= RW_V_TAG_LEN + extra_data_len;
11966     }
11967 
11968     /* Var-size header len includes len itself */
11969     int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);
11970     rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);
11971 
11972     /* Write var-sized payload, if any */
11973     if ((vhpayloadlen > 0) &&
11974         (rc == 0))
11975     {
11976       /* Add tag and extra row info */
11977       uchar type_code= RW_V_EXTRAINFO_TAG;
11978       rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);
11979       if (rc==0)
11980         rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
11981     }
11982   }
11983   else
11984   {
11985     rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);
11986   }
11987 
11988   return (rc != 0);
11989 }
11990 
write_data_body(IO_CACHE * file)11991 bool Rows_log_event::write_data_body(IO_CACHE*file)
11992 {
11993   /*
11994      Note that this should be the number of *bits*, not the number of
11995      bytes.
11996   */
11997   uchar sbuf[sizeof(m_width) + 1];
11998   my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
11999   bool res= false;
12000   uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
12001   DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
12002 
12003   DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
12004   res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
12005 
12006   DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
12007   res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
12008                               no_bytes_in_map(&m_cols));
12009   /*
12010     TODO[refactor write]: Remove the "down cast" here (and elsewhere).
12011    */
12012   if (get_general_type_code() == UPDATE_ROWS_EVENT)
12013   {
12014     DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
12015               no_bytes_in_map(&m_cols_ai));
12016     res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
12017                                 no_bytes_in_map(&m_cols_ai));
12018   }
12019   DBUG_DUMP("rows", m_rows_buf, data_size);
12020   res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
12021 
12022   return res;
12023 
12024 }
12025 #endif
12026 
12027 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12028 int Rows_log_event::pack_info(Protocol *protocol)
12029 {
12030   char buf[256];
12031   char const *const flagstr=
12032     get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
12033   size_t bytes= my_snprintf(buf, sizeof(buf),
12034                             "table_id: %llu%s", m_table_id.id(), flagstr);
12035   protocol->store(buf, bytes, &my_charset_bin);
12036   return 0;
12037 }
12038 #endif
12039 
12040 #ifdef MYSQL_CLIENT
print_helper(FILE * file,PRINT_EVENT_INFO * print_event_info,char const * const name)12041 void Rows_log_event::print_helper(FILE *file,
12042                                   PRINT_EVENT_INFO *print_event_info,
12043                                   char const *const name)
12044 {
12045   IO_CACHE *const head= &print_event_info->head_cache;
12046   IO_CACHE *const body= &print_event_info->body_cache;
12047   if (!print_event_info->short_form)
12048   {
12049     bool const last_stmt_event= get_flags(STMT_END_F);
12050     print_header(head, print_event_info, !last_stmt_event);
12051     my_b_printf(head, "\t%s: table id %llu%s\n",
12052                 name, m_table_id.id(),
12053                 last_stmt_event ? " flags: STMT_END_F" : "");
12054     print_base64(body, print_event_info, !last_stmt_event);
12055   }
12056 }
12057 #endif
12058 
12059 /**************************************************************************
12060 	Table_map_log_event member functions and support functions
12061 **************************************************************************/
12062 
12063 /**
12064   @page How replication of field metadata works.
12065 
12066   When a table map is created, the master first calls
12067   Table_map_log_event::save_field_metadata() which calculates how many
12068   values will be in the field metadata. Only those fields that require the
12069   extra data are added. The method also loops through all of the fields in
12070   the table calling the method Field::save_field_metadata() which returns the
12071   values for the field that will be saved in the metadata and replicated to
12072   the slave. Once all fields have been processed, the table map is written to
12073   the binlog adding the size of the field metadata and the field metadata to
12074   the end of the body of the table map.
12075 
12076   When a table map is read on the slave, the field metadata is read from the
12077   table map and passed to the table_def class constructor which saves the
12078   field metadata from the table map into an array based on the type of the
12079   field. Field metadata values not present (those fields that do not use extra
12080   data) in the table map are initialized as zero (0). The array size is the
12081   same as the columns for the table on the slave.
12082 
12083   Additionally, values saved for field metadata on the master are saved as a
12084   string of bytes (uchar) in the binlog. A field may require 1 or more bytes
12085   to store the information. In cases where values require multiple bytes
12086   (e.g. values > 255), the endian-safe methods are used to properly encode
12087   the values on the master and decode them on the slave. When the field
12088   metadata values are captured on the slave, they are stored in an array of
12089   type uint16. This allows the least number of casts to prevent casting bugs
12090   when the field metadata is used in comparisons of field attributes. When
12091   the field metadata is used for calculating addresses in pointer math, the
12092   type used is uint32.
12093 */
12094 
12095 #if !defined(MYSQL_CLIENT)
12096 /**
12097   Save the field metadata based on the real_type of the field.
12098   The metadata saved depends on the type of the field. Some fields
12099   store a single byte for pack_length() while others store two bytes
12100   for field_length (max length).
12101 
12102   @retval  0  Ok.
12103 
12104   @todo
12105   We may want to consider changing the encoding of the information.
12106   Currently, the code attempts to minimize the number of bytes written to
12107   the tablemap. There are at least two other alternatives; 1) using
12108   net_store_length() to store the data allowing it to choose the number of
12109   bytes that are appropriate thereby making the code much easier to
12110   maintain (only 1 place to change the encoding), or 2) use a fixed number
12111   of bytes for each field. The problem with option 1 is that net_store_length()
12112   will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
12113   for fields like CHAR which can be no larger than 255 characters, the method
12114   will use 3 bytes when the value is > 250. Further, every value that is
12115   encoded using 2 parts (e.g., pack_length, field_length) will be numerically
12116   > 250 therefore will use 3 bytes for eah value. The problem with option 2
12117   is less wasteful for space but does waste 1 byte for every field that does
12118   not encode 2 parts.
12119 */
save_field_metadata()12120 int Table_map_log_event::save_field_metadata()
12121 {
12122   DBUG_ENTER("Table_map_log_event::save_field_metadata");
12123   int index= 0;
12124   for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
12125   {
12126     DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
12127     index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
12128   }
12129   DBUG_RETURN(index);
12130 }
12131 #endif /* !defined(MYSQL_CLIENT) */
12132 
12133 /*
12134   Constructor used to build an event for writing to the binary log.
12135   Mats says tbl->s lives longer than this event so it's ok to copy pointers
12136   (tbl->s->db etc) and not pointer content.
12137  */
12138 #if !defined(MYSQL_CLIENT)
Table_map_log_event(THD * thd,TABLE * tbl,const Table_id & tid,bool using_trans)12139 Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl,
12140                                          const Table_id& tid,
12141                                          bool using_trans)
12142   : Log_event(thd, 0,
12143               using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
12144                             Log_event::EVENT_STMT_CACHE,
12145               Log_event::EVENT_NORMAL_LOGGING),
12146     m_table(tbl),
12147     m_dbnam(tbl->s->db.str),
12148     m_dblen(m_dbnam ? tbl->s->db.length : 0),
12149     m_tblnam(tbl->s->table_name.str),
12150     m_tbllen(tbl->s->table_name.length),
12151     m_colcnt(tbl->s->fields),
12152     m_memory(NULL),
12153     m_table_id(tid),
12154     m_flags(TM_BIT_LEN_EXACT_F),
12155     m_data_size(0),
12156     m_field_metadata(0),
12157     m_field_metadata_size(0),
12158     m_null_bits(0),
12159     m_meta_memory(NULL)
12160 {
12161   uchar cbuf[sizeof(m_colcnt) + 1];
12162   uchar *cbuf_end;
12163   DBUG_ASSERT(m_table_id.is_valid());
12164   /*
12165     In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
12166     table.cc / alloc_table_share():
12167       Use the fact the key is db/0/table_name/0
12168     As we rely on this let's assert it.
12169   */
12170   DBUG_ASSERT((tbl->s->db.str == 0) ||
12171               (tbl->s->db.str[tbl->s->db.length] == 0));
12172   DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
12173 
12174 
12175   m_data_size=  TABLE_MAP_HEADER_LEN;
12176   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
12177   m_data_size+= m_dblen + 2;	// Include length and terminating \0
12178   m_data_size+= m_tbllen + 2;	// Include length and terminating \0
12179   cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12180   DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12181   m_data_size+= (cbuf_end - cbuf) + m_colcnt;	// COLCNT and column types
12182 
12183   /* If malloc fails, caught in is_valid() */
12184   if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
12185   {
12186     m_coltype= reinterpret_cast<uchar*>(m_memory);
12187     for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12188       m_coltype[i]= m_table->field[i]->binlog_type();
12189   }
12190 
12191   /*
12192     Calculate a bitmap for the results of maybe_null() for all columns.
12193     The bitmap is used to determine when there is a column from the master
12194     that is not on the slave and is null and thus not in the row data during
12195     replication.
12196   */
12197   uint num_null_bytes= (m_table->s->fields + 7) / 8;
12198   m_data_size+= num_null_bytes;
12199   m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12200                                  &m_null_bits, num_null_bytes,
12201                                  &m_field_metadata, (m_colcnt * 2),
12202                                  NULL);
12203 
12204   memset(m_field_metadata, 0, (m_colcnt * 2));
12205 
12206   /*
12207     Create an array for the field metadata and store it.
12208   */
12209   m_field_metadata_size= save_field_metadata();
12210   DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
12211 
12212   /*
12213     Now set the size of the data to the size of the field metadata array
12214     plus one or three bytes (see pack.c:net_store_length) for number of
12215     elements in the field metadata array.
12216   */
12217   if (m_field_metadata_size < 251)
12218     m_data_size+= m_field_metadata_size + 1;
12219   else
12220     m_data_size+= m_field_metadata_size + 3;
12221 
12222   memset(m_null_bits, 0, num_null_bytes);
12223   for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
12224     if (m_table->field[i]->maybe_null())
12225       m_null_bits[(i / 8)]+= 1 << (i % 8);
12226   /*
12227     Marking event to require sequential execution in MTS
12228     if the query might have updated FK-referenced db.
12229     Unlike Query_log_event where this fact is encoded through
12230     the accessed db list in the Table_map case m_flags is exploited.
12231   */
12232   uchar dbs= thd->get_binlog_accessed_db_names() ?
12233     thd->get_binlog_accessed_db_names()->elements : 0;
12234   if (dbs == 1)
12235   {
12236     char *db_name= thd->get_binlog_accessed_db_names()->head();
12237     if (!strcmp(db_name, ""))
12238       m_flags |= TM_REFERRED_FK_DB_F;
12239   }
12240 }
12241 #endif /* !defined(MYSQL_CLIENT) */
12242 
12243 /*
12244   Constructor used by slave to read the event from the binary log.
12245  */
12246 #if defined(HAVE_REPLICATION)
Table_map_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12247 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
12248                                          const Format_description_log_event
12249                                          *description_event)
12250 
12251   : Log_event(buf, description_event),
12252 #ifndef MYSQL_CLIENT
12253     m_table(NULL),
12254 #endif
12255     m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
12256     m_colcnt(0), m_coltype(0),
12257     m_memory(NULL), m_table_id(ULONGLONG_MAX), m_flags(0),
12258     m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
12259     m_null_bits(0), m_meta_memory(NULL)
12260 {
12261   unsigned int bytes_read= 0;
12262   DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
12263 
12264   uint8 common_header_len= description_event->common_header_len;
12265   uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
12266   DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
12267                      event_len, common_header_len, post_header_len));
12268 
12269   /*
12270     Don't print debug messages when running valgrind since they can
12271     trigger false warnings.
12272    */
12273 #ifndef HAVE_purify
12274   DBUG_DUMP("event buffer", (uchar*) buf, event_len);
12275 #endif
12276 
12277   /* Read the post-header */
12278   const char *post_start= buf + common_header_len;
12279 
12280   post_start+= TM_MAPID_OFFSET;
12281   if (post_header_len == 6)
12282   {
12283     /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
12284     m_table_id= uint4korr(post_start);
12285     post_start+= 4;
12286   }
12287   else
12288   {
12289     DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
12290     m_table_id= uint6korr(post_start);
12291     post_start+= TM_FLAGS_OFFSET;
12292   }
12293 
12294   m_flags= uint2korr(post_start);
12295 
12296   /* Read the variable part of the event */
12297   const char *const vpart= buf + common_header_len + post_header_len;
12298 
12299   /* Extract the length of the various parts from the buffer */
12300   uchar const *const ptr_dblen= (uchar const*)vpart + 0;
12301   m_dblen= *(uchar*) ptr_dblen;
12302 
12303   /* Length of database name + counter + terminating null */
12304   uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
12305   m_tbllen= *(uchar*) ptr_tbllen;
12306 
12307   /* Length of table name + counter + terminating null */
12308   uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
12309   uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
12310   m_colcnt= net_field_length(&ptr_after_colcnt);
12311 
12312   DBUG_PRINT("info",("m_dblen: %lu  off: %ld  m_tbllen: %lu  off: %ld  m_colcnt: %lu  off: %ld",
12313                      (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
12314                      (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
12315                      m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
12316 
12317   bytes_read= (unsigned int) (ptr_after_colcnt - (unsigned char *)buf);
12318   /* Avoid reading out of buffer */
12319   if (event_len <= bytes_read || event_len - bytes_read < m_colcnt)
12320   {
12321     m_coltype= NULL;
12322     m_memory= NULL;
12323     DBUG_VOID_RETURN;
12324   }
12325 
12326   /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
12327   m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
12328                                      &m_dbnam, (uint) m_dblen + 1,
12329                                      &m_tblnam, (uint) m_tbllen + 1,
12330                                      &m_coltype, (uint) m_colcnt,
12331                                      NullS);
12332 
12333   if (m_memory)
12334   {
12335     /* Copy the different parts into their memory */
12336     strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen  + 1, m_dblen + 1);
12337     strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
12338     memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
12339 
12340     ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
12341     bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
12342     DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
12343     if (bytes_read < event_len)
12344     {
12345       m_field_metadata_size= net_field_length(&ptr_after_colcnt);
12346       if (m_field_metadata_size <= (m_colcnt * 2))
12347       {
12348         uint num_null_bytes= (m_colcnt + 7) / 8;
12349         m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
12350                                        &m_null_bits, num_null_bytes,
12351                                        &m_field_metadata, m_field_metadata_size,
12352                                        NULL);
12353         memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
12354         ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
12355         memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
12356       }
12357       else
12358       {
12359         m_coltype= NULL;
12360         my_free(m_memory);
12361         m_memory= NULL;
12362         DBUG_VOID_RETURN;
12363       }
12364     }
12365   }
12366 
12367   DBUG_VOID_RETURN;
12368 }
12369 #endif
12370 
~Table_map_log_event()12371 Table_map_log_event::~Table_map_log_event()
12372 {
12373   if (m_meta_memory != NULL)
12374     my_free(m_meta_memory);
12375   if (m_memory != NULL)
12376     my_free(m_memory);
12377 }
12378 
12379 /*
12380   Return value is an error code, one of:
12381 
12382       -1     Failure to open table   [from open_tables()]
12383        0     Success
12384        1     No room for more tables [from set_table()]
12385        2     Out of memory           [from set_table()]
12386        3     Wrong table definition
12387        4     Daisy-chaining RBR with SBR not possible
12388  */
12389 
12390 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12391 
12392 enum enum_tbl_map_status
12393 {
12394   /* no duplicate identifier found */
12395   OK_TO_PROCESS= 0,
12396 
12397   /* this table map must be filtered out */
12398   FILTERED_OUT= 1,
12399 
12400   /* identifier mapping table with different properties */
12401   SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
12402 
12403   /* a duplicate identifier was found mapping the same table */
12404   SAME_ID_MAPPING_SAME_TABLE= 3
12405 };
12406 
12407 /*
12408   Checks if this table map event should be processed or not. First
12409   it checks the filtering rules, and then looks for duplicate identifiers
12410   in the existing list of rli->tables_to_lock.
12411 
12412   It checks that there hasn't been any corruption by verifying that there
12413   are no duplicate entries with different properties.
12414 
12415   In some cases, some binary logs could get corrupted, showing several
12416   tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
12417   early sanity check for such cases and avoid that the server crashes
12418   later.
12419 
12420   In some corner cases, the master logs duplicate table map events, i.e.,
12421   same id, same database name, same table name (see: BUG#37137). This is
12422   different from the above as it's the same table that is mapped again
12423   to the same identifier. Thus we cannot just check for same ids and
12424   assume that the event is corrupted we need to check every property.
12425 
12426   NOTE: in the event that BUG#37137 ever gets fixed, this extra check
12427         will still be valid because we would need to support old binary
12428         logs anyway.
12429 
12430   @param rli The relay log info reference.
12431   @param table_list A list element containing the table to check against.
12432   @return OK_TO_PROCESS
12433             if there was no identifier already in rli->tables_to_lock
12434 
12435           FILTERED_OUT
12436             if the event is filtered according to the filtering rules
12437 
12438           SAME_ID_MAPPING_DIFFERENT_TABLE
12439             if the same identifier already maps a different table in
12440             rli->tables_to_lock
12441 
12442           SAME_ID_MAPPING_SAME_TABLE
12443             if the same identifier already maps the same table in
12444             rli->tables_to_lock.
12445 */
12446 static enum_tbl_map_status
check_table_map(Relay_log_info const * rli,RPL_TABLE_LIST * table_list)12447 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
12448 {
12449   DBUG_ENTER("check_table_map");
12450   enum_tbl_map_status res= OK_TO_PROCESS;
12451 
12452 #ifdef WITH_WSREP
12453   if ((rli->info_thd->slave_thread /* filtering is for slave only */  ||
12454        (WSREP(rli->info_thd) && rli->info_thd->wsrep_applier))        &&
12455 #else
12456   if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
12457 #endif /* WITH_WSREP */
12458       (!rpl_filter->db_ok(table_list->db) ||
12459        (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
12460     res= FILTERED_OUT;
12461   else
12462   {
12463     RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
12464     for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
12465         ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
12466     {
12467       if (ptr->table_id == table_list->table_id)
12468       {
12469 
12470         if (strcmp(ptr->db, table_list->db) ||
12471             strcmp(ptr->alias, table_list->table_name) ||
12472             ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
12473           res= SAME_ID_MAPPING_DIFFERENT_TABLE;
12474         else
12475           res= SAME_ID_MAPPING_SAME_TABLE;
12476 
12477         break;
12478       }
12479     }
12480   }
12481 
12482   DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
12483 
12484   DBUG_RETURN(res);
12485 }
12486 
do_apply_event(Relay_log_info const * rli)12487 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
12488 {
12489   RPL_TABLE_LIST *table_list;
12490   char *db_mem, *tname_mem, *ptr;
12491   size_t dummy_len;
12492   void *memory;
12493   DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
12494   DBUG_ASSERT(rli->info_thd == thd);
12495 
12496   /* Step the query id to mark what columns that are actually used. */
12497   thd->set_query_id(next_query_id());
12498 
12499   if (!(memory= my_multi_malloc(MYF(MY_WME),
12500                                 &table_list, (uint) sizeof(RPL_TABLE_LIST),
12501                                 &db_mem, (uint) NAME_LEN + 1,
12502                                 &tname_mem, (uint) NAME_LEN + 1,
12503                                 NullS)))
12504     DBUG_RETURN(HA_ERR_OUT_OF_MEM);
12505 
12506   strmov(db_mem, m_dbnam);
12507   strmov(tname_mem, m_tblnam);
12508 
12509   if (lower_case_table_names == 1)
12510   {
12511     my_casedn_str(system_charset_info, db_mem);
12512     my_casedn_str(system_charset_info, tname_mem);
12513   }
12514 
12515   /* rewrite rules changed the database */
12516   if (((ptr= (char*) rpl_filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem))
12517     strmov(db_mem, ptr);
12518 
12519   table_list->init_one_table(db_mem, strlen(db_mem),
12520                              tname_mem, strlen(tname_mem),
12521                              tname_mem, TL_WRITE);
12522 
12523   table_list->table_id=
12524     DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id.id());
12525   table_list->updating= 1;
12526   table_list->required_type= FRMTYPE_TABLE;
12527   DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name,
12528                        table_list->table_id.id()));
12529 
12530   enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
12531   if (tblmap_status == OK_TO_PROCESS)
12532   {
12533     DBUG_ASSERT(thd->lex->query_tables != table_list);
12534 
12535     /*
12536       Use placement new to construct the table_def instance in the
12537       memory allocated for it inside table_list.
12538 
12539       The memory allocated by the table_def structure (i.e., not the
12540       memory allocated *for* the table_def structure) is released
12541       inside Relay_log_info::clear_tables_to_lock() by calling the
12542       table_def destructor explicitly.
12543     */
12544     new (&table_list->m_tabledef)
12545       table_def(m_coltype, m_colcnt,
12546                 m_field_metadata, m_field_metadata_size,
12547                 m_null_bits, m_flags);
12548     table_list->m_tabledef_valid= TRUE;
12549     table_list->m_conv_table= NULL;
12550     table_list->open_type= OT_BASE_ONLY;
12551 
12552     /*
12553       We record in the slave's information that the table should be
12554       locked by linking the table into the list of tables to lock.
12555     */
12556     table_list->next_global= table_list->next_local= rli->tables_to_lock;
12557     const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
12558     const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
12559     /* 'memory' is freed in clear_tables_to_lock */
12560   }
12561   else  // FILTERED_OUT, SAME_ID_MAPPING_*
12562   {
12563     /*
12564       If mapped already but with different properties, we raise an
12565       error.
12566       If mapped already but with same properties we skip the event.
12567       If filtered out we skip the event.
12568 
12569       In all three cases, we need to free the memory previously
12570       allocated.
12571      */
12572     if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
12573     {
12574       /*
12575         Something bad has happened. We need to stop the slave as strange things
12576         could happen if we proceed: slave crash, wrong table being updated, ...
12577         As a consequence we push an error in this case.
12578        */
12579 
12580       char buf[256];
12581 
12582       my_snprintf(buf, sizeof(buf),
12583                   "Found table map event mapping table id %llu which "
12584                   "was already mapped but with different settings.",
12585                   table_list->table_id.id());
12586 
12587       if (thd->slave_thread)
12588         rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
12589                     ER(ER_SLAVE_FATAL_ERROR), buf);
12590       else
12591         /*
12592           For the cases in which a 'BINLOG' statement is set to
12593           execute in a user session
12594          */
12595         my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
12596                         MYF(0), buf);
12597     }
12598 
12599     my_free(memory);
12600   }
12601 
12602   DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12603 }
12604 
12605 Log_event::enum_skip_reason
do_shall_skip(Relay_log_info * rli)12606 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
12607 {
12608   /*
12609     If the slave skip counter is 1, then we should not start executing
12610     on the next event.
12611   */
12612   return continue_group(rli);
12613 }
12614 
do_update_pos(Relay_log_info * rli)12615 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
12616 {
12617   rli->inc_event_relay_log_pos();
12618   return 0;
12619 }
12620 
12621 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12622 
12623 #ifndef MYSQL_CLIENT
write_data_header(IO_CACHE * file)12624 bool Table_map_log_event::write_data_header(IO_CACHE *file)
12625 {
12626   DBUG_ASSERT(m_table_id.is_valid());
12627   uchar buf[TABLE_MAP_HEADER_LEN];
12628   DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12629                   {
12630                     int4store(buf + 0, m_table_id.id());
12631                     int2store(buf + 4, m_flags);
12632                     return (wrapper_my_b_safe_write(file, buf, 6));
12633                   });
12634   int6store(buf + TM_MAPID_OFFSET, m_table_id.id());
12635   int2store(buf + TM_FLAGS_OFFSET, m_flags);
12636   return (wrapper_my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
12637 }
12638 
write_data_body(IO_CACHE * file)12639 bool Table_map_log_event::write_data_body(IO_CACHE *file)
12640 {
12641   DBUG_ASSERT(m_dbnam != NULL);
12642   DBUG_ASSERT(m_tblnam != NULL);
12643   /* We use only one byte per length for storage in event: */
12644   DBUG_ASSERT(m_dblen < 128);
12645   DBUG_ASSERT(m_tbllen < 128);
12646 
12647   uchar const dbuf[]= { (uchar) m_dblen };
12648   uchar const tbuf[]= { (uchar) m_tbllen };
12649 
12650   uchar cbuf[sizeof(m_colcnt) + 1];
12651   uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12652   DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12653 
12654   /*
12655     Store the size of the field metadata.
12656   */
12657   uchar mbuf[sizeof(m_field_metadata_size)];
12658   uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12659 
12660   return (wrapper_my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
12661           wrapper_my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
12662           wrapper_my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
12663           wrapper_my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
12664           wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
12665           wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
12666           wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
12667           wrapper_my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
12668           wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
12669  }
12670 #endif
12671 
12672 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12673 
12674 /*
12675   Print some useful information for the SHOW BINARY LOG information
12676   field.
12677  */
12678 
12679 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
pack_info(Protocol * protocol)12680 int Table_map_log_event::pack_info(Protocol *protocol)
12681 {
12682   char buf[256];
12683   size_t bytes= my_snprintf(buf, sizeof(buf),
12684                             "table_id: %llu (%s.%s)",
12685                             m_table_id.id(), m_dbnam, m_tblnam);
12686   protocol->store(buf, bytes, &my_charset_bin);
12687   return 0;
12688 }
12689 #endif
12690 
12691 
12692 #endif
12693 
12694 
12695 #ifdef MYSQL_CLIENT
print(FILE *,PRINT_EVENT_INFO * print_event_info)12696 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
12697 {
12698   if (!print_event_info->short_form)
12699   {
12700     print_header(&print_event_info->head_cache, print_event_info, TRUE);
12701     my_b_printf(&print_event_info->head_cache,
12702                 "\tTable_map: `%s`.`%s` mapped to number %llu\n",
12703                 m_dbnam, m_tblnam, m_table_id.id());
12704     print_base64(&print_event_info->body_cache, print_event_info, TRUE);
12705   }
12706 }
12707 #endif
12708 
12709 /**************************************************************************
12710 	Write_rows_log_event member functions
12711 **************************************************************************/
12712 
12713 /*
12714   Constructor used to build an event for writing to the binary log.
12715  */
12716 #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)12717 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12718                                            const Table_id& tid_arg,
12719                                            bool is_transactional,
12720                                            const uchar* extra_row_info)
12721   : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
12722                    log_bin_use_v1_row_events?
12723                    WRITE_ROWS_EVENT_V1:
12724                    WRITE_ROWS_EVENT,
12725                    extra_row_info)
12726 {
12727 }
12728 #endif
12729 
12730 /*
12731   Constructor used by slave to read the event from the binary log.
12732  */
12733 #ifdef HAVE_REPLICATION
Write_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)12734 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12735                                            const Format_description_log_event
12736                                            *description_event)
12737 : Rows_log_event(buf, event_len, description_event)
12738 {
12739 }
12740 #endif
12741 
12742 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12743 int
do_before_row_operations(const Slave_reporting_capability * const)12744 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12745 {
12746   int error= 0;
12747 
12748   /*
12749     Increment the global status insert count variable
12750   */
12751   if (get_flags(STMT_END_F))
12752     status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
12753 
12754   /*
12755     Let storage engines treat this event as an INSERT command.
12756 
12757     Set 'sql_command' as SQLCOM_INSERT after the tables are locked.
12758     When locking the tables, it should be SQLCOM_END.
12759     THD::decide_binlog_format which is called from "lock tables"
12760     assumes that row_events will have 'sql_command' as SQLCOM_END.
12761   */
12762   thd->lex->sql_command= SQLCOM_INSERT;
12763 
12764   /**
12765      todo: to introduce a property for the event (handler?) which forces
12766      applying the event in the replace (idempotent) fashion.
12767   */
12768   if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12769       (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
12770   {
12771     /*
12772       We are using REPLACE semantics and not INSERT IGNORE semantics
12773       when writing rows, that is: new rows replace old rows.  We need to
12774       inform the storage engine that it should use this behaviour.
12775     */
12776 
12777     /* Tell the storage engine that we are using REPLACE semantics. */
12778     thd->lex->duplicates= DUP_REPLACE;
12779 
12780     /*
12781       Pretend we're executing a REPLACE command: this is needed for
12782       InnoDB and NDB Cluster since they are not (properly) checking the
12783       lex->duplicates flag.
12784     */
12785     thd->lex->sql_command= SQLCOM_REPLACE;
12786     /*
12787        Do not raise the error flag in case of hitting to an unique attribute
12788     */
12789     m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12790     /*
12791        NDB specific: update from ndb master wrapped as Write_rows
12792        so that the event should be applied to replace slave's row
12793     */
12794     m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12795     /*
12796        NDB specific: if update from ndb master wrapped as Write_rows
12797        does not find the row it's assumed idempotent binlog applying
12798        is taking place; don't raise the error.
12799     */
12800     m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12801     /*
12802       TODO: the cluster team (Tomas?) says that it's better if the engine knows
12803       how many rows are going to be inserted, then it can allocate needed memory
12804       from the start.
12805     */
12806   }
12807 
12808 
12809   /* Honor next number column if present */
12810   m_table->next_number_field= m_table->found_next_number_field;
12811   /*
12812    * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12813    * sequence numbers for auto_increment fields if the values of them are 0.
12814    * If generateing a sequence number is decided by the values of
12815    * table->auto_increment_field_not_null and SQL_MODE(if includes
12816    * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12817    * SQL_MODE of slave sql thread is always consistency with master's.
12818    * In RBR, auto_increment fields never are NULL, except if the auto_inc
12819    * column exists only on the slave side (i.e., in an extra column
12820    * on the slave's table).
12821    */
12822   if (!is_auto_inc_in_extra_columns())
12823     m_table->auto_increment_field_not_null= TRUE;
12824   else
12825   {
12826     /*
12827       Here we have checked that there is an extra field
12828       on this server's table that has an auto_inc column.
12829 
12830       Mark that the auto_increment field is null and mark
12831       the read and write set bits.
12832 
12833       (There can only be one AUTO_INC column, it is always
12834        indexed and it cannot have a DEFAULT value).
12835     */
12836     m_table->auto_increment_field_not_null= FALSE;
12837     m_table->mark_auto_increment_column();
12838   }
12839 
12840   /**
12841      Sets it to ROW_LOOKUP_NOT_NEEDED.
12842    */
12843   decide_row_lookup_algorithm_and_key();
12844   DBUG_ASSERT(m_rows_lookup_algorithm==ROW_LOOKUP_NOT_NEEDED);
12845 
12846   return error;
12847 }
12848 
12849 int
do_after_row_operations(const Slave_reporting_capability * const,int error)12850 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12851                                               int error)
12852 {
12853   int local_error= 0;
12854 
12855   /**
12856     Clear the write_set bit for auto_inc field that only
12857     existed on the destination table as an extra column.
12858    */
12859   if (is_auto_inc_in_extra_columns())
12860   {
12861     bitmap_clear_bit(m_table->write_set, m_table->next_number_field->field_index);
12862     bitmap_clear_bit( m_table->read_set, m_table->next_number_field->field_index);
12863 
12864     if (get_flags(STMT_END_F))
12865       m_table->file->ha_release_auto_increment();
12866   }
12867   m_table->next_number_field=0;
12868   m_table->auto_increment_field_not_null= FALSE;
12869   if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12870       m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
12871   {
12872     m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
12873     m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
12874     /*
12875       resetting the extra with
12876       table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
12877       fires bug#27077
12878       explanation: file->reset() performs this duty
12879       ultimately. Still todo: fix
12880     */
12881   }
12882   if ((local_error= m_table->file->ha_end_bulk_insert()))
12883   {
12884     m_table->file->print_error(local_error, MYF(0));
12885   }
12886 
12887   m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
12888 
12889   return error? error : local_error;
12890 }
12891 
12892 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12893 
12894 /*
12895   Check if there are more UNIQUE keys after the given key.
12896 */
12897 static int
last_uniq_key(TABLE * table,uint keyno)12898 last_uniq_key(TABLE *table, uint keyno)
12899 {
12900   while (++keyno < table->s->keys)
12901     if (table->key_info[keyno].flags & HA_NOSAME)
12902       return 0;
12903   return 1;
12904 }
12905 
12906 /**
12907    Check if an error is a duplicate key error.
12908 
12909    This function is used to check if an error code is one of the
12910    duplicate key error, i.e., and error code for which it is sensible
12911    to do a <code>get_dup_key()</code> to retrieve the duplicate key.
12912 
12913    @param errcode The error code to check.
12914 
12915    @return <code>true</code> if the error code is such that
12916    <code>get_dup_key()</code> will return true, <code>false</code>
12917    otherwise.
12918  */
12919 bool
is_duplicate_key_error(int errcode)12920 is_duplicate_key_error(int errcode)
12921 {
12922   switch (errcode)
12923   {
12924   case HA_ERR_FOUND_DUPP_KEY:
12925   case HA_ERR_FOUND_DUPP_UNIQUE:
12926     return true;
12927   }
12928   return false;
12929 }
12930 
12931 /**
12932   Write the current row into event's table.
12933 
12934   The row is located in the row buffer, pointed by @c m_curr_row member.
12935   Number of columns of the row is stored in @c m_width member (it can be
12936   different from the number of columns in the table to which we insert).
12937   Bitmap @c m_cols indicates which columns are present in the row. It is assumed
12938   that event's table is already open and pointed by @c m_table.
12939 
12940   If the same record already exists in the table it can be either overwritten
12941   or an error is reported depending on the value of @c overwrite flag
12942   (error reporting not yet implemented). Note that the matching record can be
12943   different from the row we insert if we use primary keys to identify records in
12944   the table.
12945 
12946   The row to be inserted can contain values only for selected columns. The
12947   missing columns are filled with default values using @c prepare_record()
12948   function. If a matching record is found in the table and @c overwritte is
12949   true, the missing columns are taken from it.
12950 
12951   @param  rli   Relay log info (needed for row unpacking).
12952   @param  overwrite
12953                 Shall we overwrite if the row already exists or signal
12954                 error (currently ignored).
12955 
12956   @returns Error code on failure, 0 on success.
12957 
12958   This method, if successful, sets @c m_curr_row_end pointer to point at the
12959   next row in the rows buffer. This is done when unpacking the row to be
12960   inserted.
12961 
12962   @note If a matching record is found, it is either updated using
12963   @c ha_update_row() or first deleted and then new record written.
12964 */
12965 
12966 int
write_row(const Relay_log_info * const rli,const bool overwrite)12967 Write_rows_log_event::write_row(const Relay_log_info *const rli,
12968                                 const bool overwrite)
12969 {
12970   DBUG_ENTER("write_row");
12971   DBUG_ASSERT(m_table != NULL && thd != NULL);
12972 
12973   TABLE *table= m_table;  // pointer to event's table
12974   int error;
12975   int UNINIT_VAR(keynum);
12976   auto_afree_ptr<char> key(NULL);
12977 
12978   prepare_record(table, &m_cols,
12979                  table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
12980 
12981   /* unpack row into table->record[0] */
12982   if ((error= unpack_current_row(rli, &m_cols)))
12983     DBUG_RETURN(error);
12984 
12985   /*
12986     When m_curr_row == m_curr_row_end, it means a row that contains nothing,
12987     so all the pointers shall be pointing to the same address, or else
12988     we have corrupt data and shall throw the error.
12989   */
12990   DBUG_PRINT("debug",("m_rows_buf= %p, m_rows_cur= %p, m_rows_end= %p",
12991                       m_rows_buf, m_rows_cur, m_rows_end));
12992   DBUG_PRINT("debug",("m_curr_row= %p, m_curr_row_end= %p",
12993                       m_curr_row, m_curr_row_end));
12994   if (m_curr_row == m_curr_row_end &&
12995       !((m_rows_buf == m_rows_cur) && (m_rows_cur == m_rows_end)))
12996   {
12997     my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
12998     DBUG_RETURN(ER_SLAVE_CORRUPT_EVENT);
12999   }
13000 
13001   if (m_curr_row == m_rows_buf)
13002   {
13003     /* this is the first row to be inserted, we estimate the rows with
13004        the size of the first row and use that value to initialize
13005        storage engine for bulk insertion */
13006     DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
13007     ulong estimated_rows= 0;
13008     if (m_curr_row < m_curr_row_end)
13009       estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
13010     else if (m_curr_row == m_curr_row_end)
13011       estimated_rows= 1;
13012 
13013     m_table->file->ha_start_bulk_insert(estimated_rows);
13014   }
13015 
13016   /*
13017     Explicitly set the auto_inc to null to make sure that
13018     it gets an auto_generated value.
13019   */
13020   if (is_auto_inc_in_extra_columns())
13021     m_table->next_number_field->set_null();
13022 
13023 #ifndef DBUG_OFF
13024   DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
13025   DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
13026   DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
13027 #endif
13028 
13029   /*
13030     Try to write record. If a corresponding record already exists in the table,
13031     we try to change it using ha_update_row() if possible. Otherwise we delete
13032     it and repeat the whole process again.
13033 
13034     TODO: Add safety measures against infinite looping.
13035    */
13036 
13037   m_table->mark_columns_per_binlog_row_image();
13038 
13039   while ((error= table->file->ha_write_row(table->record[0])))
13040   {
13041     if (error == HA_ERR_LOCK_DEADLOCK ||
13042         error == HA_ERR_LOCK_WAIT_TIMEOUT ||
13043         (keynum= table->file->get_dup_key(error)) < 0 ||
13044         !overwrite)
13045     {
13046       DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
13047       /*
13048         Deadlock, waiting for lock or just an error from the handler
13049         such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
13050         Retrieval of the duplicate key number may fail
13051         - either because the error was not "duplicate key" error
13052         - or because the information which key is not available
13053       */
13054       table->file->print_error(error, MYF(0));
13055       goto error;
13056     }
13057     /*
13058        We need to retrieve the old row into record[1] to be able to
13059        either update or delete the offending record.  We either:
13060 
13061        - use ha_rnd_pos() with a row-id (available as dupp_row) to the
13062          offending row, if that is possible (MyISAM and Blackhole), or else
13063 
13064        - use ha_index_read_idx_map() with the key that is duplicated, to
13065          retrieve the offending row.
13066      */
13067     if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
13068     {
13069       DBUG_PRINT("info",("Locating offending record using ha_rnd_pos()"));
13070 
13071       if (table->file->inited && (error= table->file->ha_index_end()))
13072       {
13073         table->file->print_error(error, MYF(0));
13074         goto error;
13075       }
13076       if ((error= table->file->ha_rnd_init(FALSE)))
13077       {
13078         table->file->print_error(error, MYF(0));
13079         goto error;
13080       }
13081 
13082       error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
13083 
13084       table->file->ha_rnd_end();
13085       if (error)
13086       {
13087         DBUG_PRINT("info",("ha_rnd_pos() returns error %d",error));
13088         if (error == HA_ERR_RECORD_DELETED)
13089           error= HA_ERR_KEY_NOT_FOUND;
13090         table->file->print_error(error, MYF(0));
13091         goto error;
13092       }
13093     }
13094     else
13095     {
13096       DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
13097 
13098       if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
13099       {
13100         DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
13101         error= my_errno;
13102         goto error;
13103       }
13104 
13105       if (key.get() == NULL)
13106       {
13107         key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
13108         if (key.get() == NULL)
13109         {
13110           DBUG_PRINT("info",("Can't allocate key buffer"));
13111           error= ENOMEM;
13112           goto error;
13113         }
13114       }
13115 
13116       key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
13117                0);
13118       error= table->file->ha_index_read_idx_map(table->record[1], keynum,
13119                                                 (const uchar*)key.get(),
13120                                                 HA_WHOLE_KEY,
13121                                                 HA_READ_KEY_EXACT);
13122       if (error)
13123       {
13124         DBUG_PRINT("info",("ha_index_read_idx_map() returns %s", HA_ERR(error)));
13125         if (error == HA_ERR_RECORD_DELETED)
13126           error= HA_ERR_KEY_NOT_FOUND;
13127         table->file->print_error(error, MYF(0));
13128         goto error;
13129       }
13130     }
13131 
13132     /*
13133        Now, record[1] should contain the offending row.  That
13134        will enable us to update it or, alternatively, delete it (so
13135        that we can insert the new row afterwards).
13136      */
13137 
13138     /*
13139       If row is incomplete we will use the record found to fill
13140       missing columns.
13141     */
13142     if (!get_flags(COMPLETE_ROWS_F))
13143     {
13144       restore_record(table,record[1]);
13145       error= unpack_current_row(rli, &m_cols);
13146     }
13147 
13148 #ifndef DBUG_OFF
13149     DBUG_PRINT("debug",("preparing for update: before and after image"));
13150     DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
13151     DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
13152 #endif
13153 
13154     /*
13155        REPLACE is defined as either INSERT or DELETE + INSERT.  If
13156        possible, we can replace it with an UPDATE, but that will not
13157        work on InnoDB if FOREIGN KEY checks are necessary.
13158 
13159        I (Matz) am not sure of the reason for the last_uniq_key()
13160        check as, but I'm guessing that it's something along the
13161        following lines.
13162 
13163        Suppose that we got the duplicate key to be a key that is not
13164        the last unique key for the table and we perform an update:
13165        then there might be another key for which the unique check will
13166        fail, so we're better off just deleting the row and inserting
13167        the correct row.
13168      */
13169     if (last_uniq_key(table, keynum) &&
13170         !table->file->referenced_by_foreign_key())
13171     {
13172       DBUG_PRINT("info",("Updating row using ha_update_row()"));
13173       error=table->file->ha_update_row(table->record[1],
13174                                        table->record[0]);
13175       switch (error) {
13176 
13177       case HA_ERR_RECORD_IS_THE_SAME:
13178         DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
13179                            " ha_update_row()"));
13180         error= 0;
13181 
13182       case 0:
13183         break;
13184 
13185       default:
13186         DBUG_PRINT("info",("ha_update_row() returns error %d",error));
13187         table->file->print_error(error, MYF(0));
13188       }
13189 
13190       goto error;
13191     }
13192     else
13193     {
13194       DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
13195       if ((error= table->file->ha_delete_row(table->record[1])))
13196       {
13197         DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
13198         table->file->print_error(error, MYF(0));
13199         goto error;
13200       }
13201       /* Will retry ha_write_row() with the offending row removed. */
13202     }
13203   }
13204 
13205 error:
13206   m_table->default_column_bitmaps();
13207   DBUG_RETURN(error);
13208 }
13209 
13210 #endif
13211 
13212 int
do_exec_row(const Relay_log_info * const rli)13213 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13214 {
13215   DBUG_ASSERT(m_table != NULL);
13216 #ifdef WITH_WSREP
13217 #ifdef WSREP_PROC_INFO
13218   char info[64];
13219   info[sizeof(info) - 1] = '\0';
13220   snprintf(info, sizeof(info) - 1, "Write_rows_log_event::write_row(%lld)",
13221            (long long) wsrep_thd_trx_seqno(thd));
13222   const char* tmp = (WSREP(thd)) ? thd_proc_info(thd, info) : NULL;
13223 #else
13224   const char* tmp = (WSREP(thd)) ?
13225     thd_proc_info(thd,"Write_rows_log_event::write_row()") :  NULL;
13226 #endif /* WSREP_PROC_INFO */
13227 #endif /* WITH_WSREP */
13228   int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
13229 
13230 #ifdef WITH_WSREP
13231   if (WSREP(thd)) thd_proc_info(thd, tmp);
13232 #endif /* WITH_WSREP */
13233   if (error && !thd->is_error())
13234   {
13235     DBUG_ASSERT(0);
13236     my_error(ER_UNKNOWN_ERROR, MYF(0));
13237   }
13238 
13239   return error;
13240 }
13241 
13242 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13243 
13244 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13245 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
13246 {
13247   DBUG_EXECUTE_IF("simulate_cache_read_error",
13248                   {DBUG_SET("+d,simulate_my_b_fill_error");});
13249   Rows_log_event::print_helper(file, print_event_info, "Write_rows");
13250 }
13251 #endif
13252 
13253 /**************************************************************************
13254 	Delete_rows_log_event member functions
13255 **************************************************************************/
13256 
13257 /*
13258   Constructor used to build an event for writing to the binary log.
13259  */
13260 
13261 #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)13262 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13263                                              const Table_id& tid,
13264                                              bool is_transactional,
13265                                              const uchar* extra_row_info)
13266   : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13267                    log_bin_use_v1_row_events?
13268                    DELETE_ROWS_EVENT_V1:
13269                    DELETE_ROWS_EVENT,
13270                    extra_row_info)
13271 {
13272 }
13273 #endif /* #if !defined(MYSQL_CLIENT) */
13274 
13275 /*
13276   Constructor used by slave to read the event from the binary log.
13277  */
13278 #ifdef HAVE_REPLICATION
Delete_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13279 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
13280                                              const Format_description_log_event
13281                                              *description_event)
13282   : Rows_log_event(buf, event_len, description_event)
13283 {
13284 }
13285 #endif
13286 
13287 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13288 
13289 int
do_before_row_operations(const Slave_reporting_capability * const)13290 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13291 {
13292   int error= 0;
13293   DBUG_ENTER("Delete_rows_log_event::do_before_row_operations");
13294   /*
13295     Increment the global status delete count variable
13296    */
13297   if (get_flags(STMT_END_F))
13298     status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
13299 
13300   /*
13301     Let storage engines treat this event as a DELETE command.
13302 
13303     Set 'sql_command' as SQLCOM_UPDATE after the tables are locked.
13304     When locking the tables, it should be SQLCOM_END.
13305     THD::decide_binlog_format which is called from "lock tables"
13306     assumes that row_events will have 'sql_command' as SQLCOM_END.
13307   */
13308   thd->lex->sql_command= SQLCOM_DELETE;
13309 
13310   error= row_operations_scan_and_key_setup();
13311   DBUG_RETURN(error);
13312 
13313 }
13314 
13315 int
do_after_row_operations(const Slave_reporting_capability * const,int error)13316 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13317                                                int error)
13318 {
13319   DBUG_ENTER("Delete_rows_log_event::do_after_row_operations");
13320   error= row_operations_scan_and_key_teardown(error);
13321   DBUG_RETURN(error);
13322 }
13323 
do_exec_row(const Relay_log_info * const rli)13324 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13325 {
13326   int error;
13327   DBUG_ASSERT(m_table != NULL);
13328   /* m_table->record[0] contains the BI */
13329   m_table->mark_columns_per_binlog_row_image();
13330   error= m_table->file->ha_delete_row(m_table->record[0]);
13331   m_table->default_column_bitmaps();
13332   return error;
13333 }
13334 
13335 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13336 
13337 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13338 void Delete_rows_log_event::print(FILE *file,
13339                                   PRINT_EVENT_INFO* print_event_info)
13340 {
13341   Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
13342 }
13343 #endif
13344 
13345 
13346 /**************************************************************************
13347 	Update_rows_log_event member functions
13348 **************************************************************************/
13349 
13350 /*
13351   Constructor used to build an event for writing to the binary log.
13352  */
13353 #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)13354 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
13355                                              const Table_id& tid,
13356                                              bool is_transactional,
13357                                              const uchar* extra_row_info)
13358 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
13359                  log_bin_use_v1_row_events?
13360                  UPDATE_ROWS_EVENT_V1:
13361                  UPDATE_ROWS_EVENT,
13362                  extra_row_info)
13363 {
13364   init(tbl_arg->write_set);
13365 }
13366 
init(MY_BITMAP const * cols)13367 void Update_rows_log_event::init(MY_BITMAP const *cols)
13368 {
13369   /* if bitmap_init fails, caught in is_valid() */
13370   if (likely(!bitmap_init(&m_cols_ai,
13371                           m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
13372                           m_width,
13373                           false)))
13374   {
13375     /* Cols can be zero if this is a dummy binrows event */
13376     if (likely(cols != NULL))
13377     {
13378       memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
13379       create_last_word_mask(&m_cols_ai);
13380     }
13381   }
13382 }
13383 #endif /* !defined(MYSQL_CLIENT) */
13384 
13385 
~Update_rows_log_event()13386 Update_rows_log_event::~Update_rows_log_event()
13387 {
13388   if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
13389     m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
13390   bitmap_free(&m_cols_ai); // To pair with bitmap_init().
13391 }
13392 
13393 
13394 /*
13395   Constructor used by slave to read the event from the binary log.
13396  */
13397 #ifdef HAVE_REPLICATION
Update_rows_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)13398 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
13399                                              const
13400                                              Format_description_log_event
13401                                              *description_event)
13402   : Rows_log_event(buf, event_len, description_event)
13403 {
13404 }
13405 #endif
13406 
13407 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
13408 
13409 int
do_before_row_operations(const Slave_reporting_capability * const)13410 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
13411 {
13412   int error= 0;
13413   DBUG_ENTER("Update_rows_log_event::do_before_row_operations");
13414   /*
13415     Increment the global status update count variable
13416   */
13417   if (get_flags(STMT_END_F))
13418     status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
13419 
13420   /*
13421     Let storage engines treat this event as an UPDATE 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_UPDATE;
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 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
13437                                                int error)
13438 {
13439   DBUG_ENTER("Update_rows_log_event::do_after_row_operations");
13440   error= row_operations_scan_and_key_teardown(error);
13441   DBUG_RETURN(error);
13442 }
13443 
13444 int
do_exec_row(const Relay_log_info * const rli)13445 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
13446 {
13447   DBUG_ASSERT(m_table != NULL);
13448   int error= 0;
13449 
13450   /*
13451     This is the situation after locating BI:
13452 
13453     ===|=== before image ====|=== after image ===|===
13454        ^                     ^
13455        m_curr_row            m_curr_row_end
13456 
13457     BI found in the table is stored in record[0]. We copy it to record[1]
13458     and unpack AI to record[0].
13459    */
13460 
13461   store_record(m_table,record[1]);
13462 
13463   m_curr_row= m_curr_row_end;
13464   /* this also updates m_curr_row_end */
13465   if ((error= unpack_current_row(rli, &m_cols_ai)))
13466     return error;
13467 
13468   /*
13469     Now we have the right row to update.  The old row (the one we're
13470     looking for) is in record[1] and the new row is in record[0].
13471   */
13472 #ifndef HAVE_purify
13473   /*
13474     Don't print debug messages when running valgrind since they can
13475     trigger false warnings.
13476    */
13477   DBUG_PRINT("info",("Updating row in table"));
13478   DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
13479   DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
13480 #endif
13481 
13482   // Temporary fix to find out why it fails [/Matz]
13483   memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
13484   memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
13485 
13486   m_table->mark_columns_per_binlog_row_image();
13487   error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
13488   if (error == HA_ERR_RECORD_IS_THE_SAME)
13489     error= 0;
13490   m_table->default_column_bitmaps();
13491 
13492   return error;
13493 }
13494 
13495 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
13496 
13497 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13498 void Update_rows_log_event::print(FILE *file,
13499 				  PRINT_EVENT_INFO* print_event_info)
13500 {
13501   Rows_log_event::print_helper(file, print_event_info, "Update_rows");
13502 }
13503 #endif
13504 
13505 
Incident_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13506 Incident_log_event::Incident_log_event(const char *buf, uint event_len,
13507                                        const Format_description_log_event *descr_event)
13508   : Log_event(buf, descr_event)
13509 {
13510   DBUG_ENTER("Incident_log_event::Incident_log_event");
13511   uint8 const common_header_len=
13512     descr_event->common_header_len;
13513   uint8 const post_header_len=
13514     descr_event->post_header_len[INCIDENT_EVENT-1];
13515 
13516   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13517                      event_len, common_header_len, post_header_len));
13518 
13519   m_message.str= NULL;
13520   m_message.length= 0;
13521   int incident_number= uint2korr(buf + common_header_len);
13522   if (incident_number >= INCIDENT_COUNT ||
13523       incident_number <= INCIDENT_NONE)
13524   {
13525     // If the incident is not recognized, this binlog event is
13526     // invalid.  If we set incident_number to INCIDENT_NONE, the
13527     // invalidity will be detected by is_valid().
13528     m_incident= INCIDENT_NONE;
13529     DBUG_VOID_RETURN;
13530   }
13531   m_incident= static_cast<Incident>(incident_number);
13532   char const *ptr= buf + common_header_len + post_header_len;
13533   char const *const str_end= buf + event_len;
13534   uint8 len= 0;                   // Assignment to keep compiler happy
13535   const char *str= NULL;          // Assignment to keep compiler happy
13536   read_str_at_most_255_bytes(&ptr, str_end, &str, &len);
13537   if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
13538   {
13539     /* Mark this event invalid */
13540     m_incident= INCIDENT_NONE;
13541     DBUG_VOID_RETURN;
13542   }
13543   strmake(m_message.str, str, len);
13544   m_message.length= len;
13545   DBUG_PRINT("info", ("m_incident: %d", m_incident));
13546   DBUG_VOID_RETURN;
13547 }
13548 
13549 
~Incident_log_event()13550 Incident_log_event::~Incident_log_event()
13551 {
13552   if (m_message.str)
13553     my_free(m_message.str);
13554 }
13555 
13556 
13557 const char *
description() const13558 Incident_log_event::description() const
13559 {
13560   static const char *const description[]= {
13561     "NOTHING",                                  // Not used
13562     "LOST_EVENTS"
13563   };
13564 
13565   DBUG_PRINT("info", ("m_incident: %d", m_incident));
13566 
13567   return description[m_incident];
13568 }
13569 
13570 
13571 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13572 int Incident_log_event::pack_info(Protocol *protocol)
13573 {
13574   char buf[256];
13575   size_t bytes;
13576   if (m_message.length > 0)
13577     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
13578                        m_incident, description());
13579   else
13580     bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
13581                        m_incident, description(), m_message.str);
13582   protocol->store(buf, bytes, &my_charset_bin);
13583   return 0;
13584 }
13585 #endif
13586 
13587 
13588 #ifdef MYSQL_CLIENT
13589 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13590 Incident_log_event::print(FILE *file,
13591                           PRINT_EVENT_INFO *print_event_info)
13592 {
13593   if (print_event_info->short_form)
13594     return;
13595 
13596   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13597   my_b_printf(&print_event_info->head_cache,
13598               "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n",
13599               description());
13600 }
13601 #endif
13602 
13603 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
13604 int
do_apply_event(Relay_log_info const * rli)13605 Incident_log_event::do_apply_event(Relay_log_info const *rli)
13606 {
13607   DBUG_ENTER("Incident_log_event::do_apply_event");
13608 
13609   if (ignored_error_code(ER_SLAVE_INCIDENT))
13610   {
13611     DBUG_PRINT("info", ("Ignoring Incident"));
13612     DBUG_RETURN(0);
13613   }
13614 
13615   rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
13616               ER(ER_SLAVE_INCIDENT),
13617               description(),
13618               m_message.length > 0 ? m_message.str : "<none>");
13619   DBUG_RETURN(1);
13620 }
13621 #endif
13622 
13623 bool
write_data_header(IO_CACHE * file)13624 Incident_log_event::write_data_header(IO_CACHE *file)
13625 {
13626   DBUG_ENTER("Incident_log_event::write_data_header");
13627   DBUG_PRINT("enter", ("m_incident: %d", m_incident));
13628   uchar buf[sizeof(int16)];
13629   int2store(buf, (int16) m_incident);
13630 #ifndef MYSQL_CLIENT
13631   DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
13632 #else
13633    DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
13634 #endif
13635 }
13636 
13637 bool
write_data_body(IO_CACHE * file)13638 Incident_log_event::write_data_body(IO_CACHE *file)
13639 {
13640   uchar tmp[1];
13641   DBUG_ENTER("Incident_log_event::write_data_body");
13642   tmp[0]= (uchar) m_message.length;
13643   crc= my_checksum(crc, (uchar*) tmp, 1);
13644   if (m_message.length > 0)
13645   {
13646     crc= my_checksum(crc, (uchar*) m_message.str, m_message.length);
13647     // todo: report a bug on write_str accepts uint but treats it as uchar
13648   }
13649   DBUG_RETURN(write_str_at_most_255_bytes(file, m_message.str, (uint) m_message.length));
13650 }
13651 
13652 
Ignorable_log_event(const char * buf,const Format_description_log_event * descr_event)13653 Ignorable_log_event::Ignorable_log_event(const char *buf,
13654                                          const Format_description_log_event *descr_event)
13655   : Log_event(buf, descr_event)
13656 {
13657   DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
13658   DBUG_VOID_RETURN;
13659 }
13660 
~Ignorable_log_event()13661 Ignorable_log_event::~Ignorable_log_event()
13662 {
13663 }
13664 
13665 #ifndef MYSQL_CLIENT
13666 /* Pack info for its unrecognized ignorable event */
pack_info(Protocol * protocol)13667 int Ignorable_log_event::pack_info(Protocol *protocol)
13668 {
13669   char buf[256];
13670   size_t bytes;
13671   bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized ignorable event");
13672   protocol->store(buf, bytes, &my_charset_bin);
13673   return 0;
13674 }
13675 #endif
13676 
13677 #ifdef MYSQL_CLIENT
13678 /* Print for its unrecognized ignorable event */
13679 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13680 Ignorable_log_event::print(FILE *file,
13681                            PRINT_EVENT_INFO *print_event_info)
13682 {
13683   if (print_event_info->short_form)
13684     return;
13685 
13686   print_header(&print_event_info->head_cache, print_event_info, FALSE);
13687   my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
13688   my_b_printf(&print_event_info->head_cache,
13689               "# Unrecognized ignorable event\n");
13690 }
13691 #endif
13692 
13693 
Rows_query_log_event(const char * buf,uint event_len,const Format_description_log_event * descr_event)13694 Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
13695                                            const Format_description_log_event *descr_event)
13696   : Ignorable_log_event(buf, descr_event)
13697 {
13698   DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
13699   uint8 const common_header_len=
13700     descr_event->common_header_len;
13701   uint8 const post_header_len=
13702     descr_event->post_header_len[ROWS_QUERY_LOG_EVENT-1];
13703 
13704   m_rows_query= NULL;
13705 
13706   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13707                      event_len, common_header_len, post_header_len));
13708 
13709   /*
13710    m_rows_query length is stored using only one byte, but that length is
13711    ignored and the complete query is read.
13712   */
13713   unsigned int offset= common_header_len + post_header_len + 1;
13714   /* Avoid reading out of buffer */
13715   if (offset > event_len)
13716     DBUG_VOID_RETURN;
13717 
13718   unsigned int len= event_len - offset;
13719   if (!(m_rows_query= (char*) my_malloc(len+1, MYF(MY_WME))))
13720     return;
13721   strmake(m_rows_query, buf + offset, len);
13722   DBUG_PRINT("info", ("m_rows_query: %s", m_rows_query));
13723   DBUG_VOID_RETURN;
13724 }
13725 
~Rows_query_log_event()13726 Rows_query_log_event::~Rows_query_log_event()
13727 {
13728   my_free(m_rows_query);
13729 }
13730 
13731 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13732 int Rows_query_log_event::pack_info(Protocol *protocol)
13733 {
13734   char *buf;
13735   size_t bytes;
13736   ulong len= sizeof("# ") + (ulong) strlen(m_rows_query);
13737   if (!(buf= (char*) my_malloc(len, MYF(MY_WME))))
13738     return 1;
13739   bytes= my_snprintf(buf, len, "# %s", m_rows_query);
13740   protocol->store(buf, bytes, &my_charset_bin);
13741   my_free(buf);
13742   return 0;
13743 }
13744 #endif
13745 
13746 #ifdef MYSQL_CLIENT
13747 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13748 Rows_query_log_event::print(FILE *file,
13749                             PRINT_EVENT_INFO *print_event_info)
13750 {
13751   if (!print_event_info->short_form && print_event_info->verbose > 1)
13752   {
13753     IO_CACHE *const head= &print_event_info->head_cache;
13754     IO_CACHE *const body= &print_event_info->body_cache;
13755     char *token= NULL, *saveptr= NULL;
13756     char *rows_query_copy= NULL;
13757     if (!(rows_query_copy= my_strdup(m_rows_query, MYF(MY_WME))))
13758       return;
13759 
13760     print_header(head, print_event_info, FALSE);
13761     my_b_printf(head, "\tRows_query\n");
13762     /*
13763       Prefix every line of a multi-line query with '#' to prevent the
13764       statement from being executed when binary log will be processed
13765       using 'mysqlbinlog --verbose --verbose'.
13766     */
13767     for (token= strtok_r(rows_query_copy, "\n", &saveptr); token;
13768          token= strtok_r(NULL, "\n", &saveptr))
13769       my_b_printf(head, "# %s\n", token);
13770     my_free(rows_query_copy);
13771     print_base64(body, print_event_info, true);
13772   }
13773 }
13774 #endif
13775 
13776 bool
write_data_body(IO_CACHE * file)13777 Rows_query_log_event::write_data_body(IO_CACHE *file)
13778 {
13779   DBUG_ENTER("Rows_query_log_event::write_data_body");
13780   /*
13781    m_rows_query length will be stored using only one byte, but on read
13782    that length will be ignored and the complete query will be read.
13783   */
13784   DBUG_RETURN(write_str_at_most_255_bytes(file, m_rows_query,
13785               (uint) strlen(m_rows_query)));
13786 }
13787 
13788 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13789 int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
13790 {
13791   DBUG_ENTER("Rows_query_log_event::do_apply_event");
13792   DBUG_ASSERT(rli->info_thd == thd);
13793   /* Set query for writing Rows_query log event into binlog later.*/
13794   thd->set_query(m_rows_query, (uint32) strlen(m_rows_query));
13795   thd->set_query_for_display(m_rows_query, strlen(m_rows_query));
13796 
13797   DBUG_ASSERT(rli->rows_query_ev == NULL);
13798 
13799   const_cast<Relay_log_info*>(rli)->rows_query_ev= this;
13800 
13801   DBUG_RETURN(0);
13802 }
13803 #endif
13804 
13805 
13806 const char *Gtid_log_event::SET_STRING_PREFIX= "SET @@SESSION.GTID_NEXT= '";
13807 
13808 
Gtid_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)13809 Gtid_log_event::Gtid_log_event(const char *buffer, uint event_len,
13810                                const Format_description_log_event *descr_event)
13811   : Log_event(buffer, descr_event)
13812 {
13813   DBUG_ENTER("Gtid_log_event::Gtid_log_event(const char *, uint, const Format_description_log_event *");
13814   uint8 const common_header_len=
13815     descr_event->common_header_len;
13816 
13817 #ifndef DBUG_OFF
13818   uint8 const post_header_len=
13819     buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13820     descr_event->post_header_len[ANONYMOUS_GTID_LOG_EVENT - 1] :
13821     descr_event->post_header_len[GTID_LOG_EVENT - 1];
13822   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13823                      event_len, common_header_len, post_header_len));
13824 #endif
13825 
13826   char const *ptr_buffer= buffer + common_header_len;
13827 
13828   spec.type= buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13829     ANONYMOUS_GROUP : GTID_GROUP;
13830 
13831   commit_flag= *ptr_buffer != 0;
13832   ptr_buffer+= ENCODED_FLAG_LENGTH;
13833 
13834   sid.copy_from((uchar *)ptr_buffer);
13835   ptr_buffer+= ENCODED_SID_LENGTH;
13836 
13837   // SIDNO is only generated if needed, in get_sidno().
13838   spec.gtid.sidno= -1;
13839 
13840   spec.gtid.gno= uint8korr(ptr_buffer);
13841   ptr_buffer+= ENCODED_GNO_LENGTH;
13842 
13843   DBUG_VOID_RETURN;
13844 }
13845 
13846 #ifndef MYSQL_CLIENT
Gtid_log_event(THD * thd_arg,bool using_trans,const Gtid_specification * spec_arg)13847 Gtid_log_event::Gtid_log_event(THD* thd_arg, bool using_trans,
13848                                const Gtid_specification *spec_arg)
13849 : Log_event(thd_arg, thd_arg->variables.gtid_next.type == ANONYMOUS_GROUP ?
13850             LOG_EVENT_IGNORABLE_F : 0,
13851             using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13852             Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING),
13853   commit_flag(true)
13854 {
13855   DBUG_ENTER("Gtid_log_event::Gtid_log_event(THD *)");
13856   spec= spec_arg ? *spec_arg : thd_arg->variables.gtid_next;
13857   if (spec.type == GTID_GROUP)
13858   {
13859     global_sid_lock->rdlock();
13860     sid= global_sid_map->sidno_to_sid(spec.gtid.sidno);
13861     global_sid_lock->unlock();
13862   }
13863   else
13864     sid.clear();
13865 #ifndef DBUG_OFF
13866   char buf[MAX_SET_STRING_LENGTH + 1];
13867   to_string(buf);
13868   DBUG_PRINT("info", ("%s", buf));
13869 #endif
13870   DBUG_VOID_RETURN;
13871 }
13872 #endif
13873 
13874 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)13875 int Gtid_log_event::pack_info(Protocol *protocol)
13876 {
13877   char buffer[MAX_SET_STRING_LENGTH + 1];
13878   size_t len= to_string(buffer);
13879   protocol->store(buffer, len, &my_charset_bin);
13880   return 0;
13881 }
13882 #endif
13883 
to_string(char * buf) const13884 size_t Gtid_log_event::to_string(char *buf) const
13885 {
13886   char *p= buf;
13887   DBUG_ASSERT(strlen(SET_STRING_PREFIX) == SET_STRING_PREFIX_LENGTH);
13888   strcpy(p, SET_STRING_PREFIX);
13889   p+= SET_STRING_PREFIX_LENGTH;
13890   p+= spec.to_string(&sid, p);
13891   *p++= '\'';
13892   *p= '\0';
13893   return p - buf;
13894 }
13895 
13896 #ifdef MYSQL_CLIENT
13897 void
print(FILE * file,PRINT_EVENT_INFO * print_event_info)13898 Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
13899 {
13900   char buffer[MAX_SET_STRING_LENGTH + 1];
13901   IO_CACHE *const head= &print_event_info->head_cache;
13902   if (!print_event_info->short_form)
13903   {
13904     print_header(head, print_event_info, FALSE);
13905     my_b_printf(head, "\tGTID [commit=%s]\n", commit_flag ? "yes" : "no");
13906   }
13907   to_string(buffer);
13908   my_b_printf(head, "%s%s\n", buffer, print_event_info->delimiter);
13909 }
13910 #endif
13911 
13912 #ifdef MYSQL_SERVER
write_data_header(IO_CACHE * file)13913 bool Gtid_log_event::write_data_header(IO_CACHE *file)
13914 {
13915   DBUG_ENTER("Gtid_log_event::write_data_header");
13916   char buffer[POST_HEADER_LENGTH];
13917   char* ptr_buffer= buffer;
13918 
13919   *ptr_buffer= commit_flag ? 1 : 0;
13920   ptr_buffer+= ENCODED_FLAG_LENGTH;
13921 
13922 #ifndef DBUG_OFF
13923   char buf[rpl_sid::TEXT_LENGTH + 1];
13924   sid.to_string(buf);
13925   DBUG_PRINT("info", ("sid=%s sidno=%d gno=%lld",
13926                       buf, spec.gtid.sidno, spec.gtid.gno));
13927 #endif
13928 
13929   sid.copy_to((uchar *)ptr_buffer);
13930   ptr_buffer+= ENCODED_SID_LENGTH;
13931 
13932   int8store(ptr_buffer, spec.gtid.gno);
13933   ptr_buffer+= ENCODED_GNO_LENGTH;
13934 
13935   DBUG_ASSERT(ptr_buffer == (buffer + sizeof(buffer)));
13936   DBUG_RETURN(wrapper_my_b_safe_write(file, (uchar *) buffer, sizeof(buffer)));
13937 }
13938 #endif // MYSQL_SERVER
13939 
13940 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_apply_event(Relay_log_info const * rli)13941 int Gtid_log_event::do_apply_event(Relay_log_info const *rli)
13942 {
13943   DBUG_ENTER("Gtid_log_event::do_apply_event");
13944   DBUG_ASSERT(rli->info_thd == thd);
13945 
13946   if (get_type_code() == ANONYMOUS_GTID_LOG_EVENT)
13947   {
13948     if (gtid_mode == GTID_MODE_ON)
13949     {
13950       my_error(ER_CANT_SET_GTID_NEXT_TO_ANONYMOUS_WHEN_GTID_MODE_IS_ON, MYF(0));
13951       DBUG_RETURN(1);
13952     }
13953     thd->variables.gtid_next.set_anonymous();
13954     /*
13955       We do not need to write the anonymous gtid log event into binary log,
13956       since we should not add new fields to include logical timestamps used
13957       for applying transactions in parallel in the GA version.
13958     */
13959     DBUG_RETURN(0);
13960   }
13961 
13962   /* Applying Gtid_log_event should report an error when GTID_MODE is OFF */
13963   if (gtid_mode == GTID_MODE_OFF)
13964   {
13965     my_error(ER_CANT_SET_GTID_NEXT_TO_GTID_WHEN_GTID_MODE_IS_OFF, MYF(0));
13966     DBUG_RETURN(1);
13967   }
13968 
13969   rpl_sidno sidno= get_sidno(true);
13970   if (sidno < 0)
13971     DBUG_RETURN(1); // out of memory
13972   if (thd->owned_gtid.sidno)
13973   {
13974     /*
13975       Slave will execute this code if a previous Gtid_log_event was applied
13976       but the GTID wasn't consumed yet (the transaction was not committed
13977       nor rolled back).
13978       On a client session we cannot do consecutive SET GTID_NEXT without
13979       a COMMIT or a ROLLBACK in the middle.
13980       Applying this event without rolling back the current transaction may
13981       lead to problems, as a "BEGIN" event following this GTID will
13982       implicitly commit the "partial transaction" and will consume the
13983       GTID. If this "partial transaction" was left in the relay log by the
13984       IO thread restarting in the middle of a transaction, you could have
13985       the partial transaction being logged with the GTID on the slave,
13986       causing data corruption on replication.
13987     */
13988     if (thd->transaction.all.ha_list)
13989     {
13990       /* This is not an error (XA is safe), just an information */
13991       rli->report(INFORMATION_LEVEL, 0,
13992                   "Rolling back unfinished transaction (no COMMIT "
13993                   "or ROLLBACK in relay log). A probable cause is partial "
13994                   "transaction left on relay log because of restarting IO "
13995                   "thread with auto-positioning protocol.");
13996       const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
13997     }
13998     gtid_rollback(thd);
13999   }
14000   thd->variables.gtid_next.set(sidno, spec.gtid.gno);
14001   DBUG_PRINT("info", ("setting gtid_next=%d:%lld",
14002                       sidno, spec.gtid.gno));
14003 
14004   if (gtid_acquire_ownership_single(thd))
14005     DBUG_RETURN(1);
14006 
14007   DBUG_RETURN(0);
14008 }
14009 
do_update_pos(Relay_log_info * rli)14010 int Gtid_log_event::do_update_pos(Relay_log_info *rli)
14011 {
14012   /*
14013     This event does not increment group positions. This means
14014     that if there is a failure after it has been processed,
14015     it will be automatically re-executed.
14016   */
14017   rli->inc_event_relay_log_pos();
14018   DBUG_EXECUTE_IF("crash_after_update_pos_gtid",
14019                   sql_print_information("Crashing crash_after_update_pos_gtid.");
14020                   DBUG_SUICIDE(););
14021   return 0;
14022 }
14023 #endif
14024 
Previous_gtids_log_event(const char * buffer,uint event_len,const Format_description_log_event * descr_event)14025 Previous_gtids_log_event::Previous_gtids_log_event(
14026   const char *buffer, uint event_len,
14027   const Format_description_log_event *descr_event)
14028   : Log_event(buffer, descr_event)
14029 {
14030   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event");
14031   uint8 const common_header_len=
14032     descr_event->common_header_len;
14033   uint8 const post_header_len=
14034     descr_event->post_header_len[PREVIOUS_GTIDS_LOG_EVENT - 1];
14035 
14036   DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
14037                      event_len, common_header_len, post_header_len));
14038 
14039   buf= (const uchar *)buffer + common_header_len + post_header_len;
14040   buf_size= (const uchar *)buffer + event_len - buf;
14041   DBUG_PRINT("info", ("data size of the event: %d", buf_size));
14042   DBUG_VOID_RETURN;
14043 }
14044 
14045 #ifndef MYSQL_CLIENT
Previous_gtids_log_event(const Gtid_set * set)14046 Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set)
14047 : Log_event(Log_event::EVENT_NO_CACHE,
14048             Log_event::EVENT_IMMEDIATE_LOGGING)
14049 {
14050   DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event(THD *, const Gtid_set *)");
14051   global_sid_lock->assert_some_lock();
14052   buf_size= set->get_encoded_length();
14053   uchar *buffer= (uchar *) my_malloc(buf_size, MYF(MY_WME));
14054   if (buffer != NULL)
14055   {
14056     set->encode(buffer);
14057     register_temp_buf((char *)buffer);
14058   }
14059   this->buf= buffer;
14060   // if buf == NULL, is_valid will return false
14061   DBUG_VOID_RETURN;
14062 }
14063 #endif
14064 
14065 #ifndef MYSQL_CLIENT
pack_info(Protocol * protocol)14066 int Previous_gtids_log_event::pack_info(Protocol *protocol)
14067 {
14068   size_t length= 0;
14069   global_sid_lock->rdlock();
14070   char *str= get_str(&length, &Gtid_set::default_string_format);
14071   global_sid_lock->unlock();
14072   if (str == NULL)
14073     return 1;
14074   protocol->store(str, length, &my_charset_bin);
14075   my_free(str);
14076   return 0;
14077 }
14078 #endif
14079 
14080 #ifdef MYSQL_CLIENT
print(FILE * file,PRINT_EVENT_INFO * print_event_info)14081 void Previous_gtids_log_event::print(FILE *file,
14082                                      PRINT_EVENT_INFO *print_event_info)
14083 {
14084   IO_CACHE *const head= &print_event_info->head_cache;
14085 
14086   global_sid_lock->rdlock();
14087   char *str= get_str(NULL, &Gtid_set::commented_string_format);
14088   global_sid_lock->unlock();
14089   if (str != NULL)
14090   {
14091     if (!print_event_info->short_form)
14092     {
14093       print_header(head, print_event_info, FALSE);
14094       my_b_printf(head, "\tPrevious-GTIDs\n");
14095     }
14096     my_b_printf(head, "%s\n", str);
14097     my_free(str);
14098   }
14099 }
14100 #endif
14101 
add_to_set(Gtid_set * target) const14102 int Previous_gtids_log_event::add_to_set(Gtid_set *target) const
14103 {
14104   DBUG_ENTER("Previous_gtids_log_event::add_to_set(Gtid_set *)");
14105   size_t end_pos= 0;
14106   size_t add_size= DBUG_EVALUATE_IF("gtid_has_extra_data", 10, 0);
14107   /* Silently ignore additional unknown data at the end of the encoding */
14108   PROPAGATE_REPORTED_ERROR_INT(target->add_gtid_encoding(buf,
14109                                                          buf_size + add_size,
14110                                                          &end_pos));
14111   DBUG_ASSERT(end_pos <= (size_t) buf_size);
14112   DBUG_RETURN(0);
14113 }
14114 
get_str(size_t * length_p,const Gtid_set::String_format * string_format) const14115 char *Previous_gtids_log_event::get_str(
14116   size_t *length_p, const Gtid_set::String_format *string_format) const
14117 {
14118   DBUG_ENTER("Previous_gtids_log_event::get_str(size_t *)");
14119   Sid_map sid_map(NULL);
14120   Gtid_set set(&sid_map, NULL);
14121   DBUG_PRINT("info", ("temp_buf=%p buf=%p", temp_buf, buf));
14122   if (set.add_gtid_encoding(buf, buf_size) != RETURN_STATUS_OK)
14123     DBUG_RETURN(NULL);
14124   set.dbug_print("set");
14125   size_t length= set.get_string_length(string_format);
14126   DBUG_PRINT("info", ("string length= %lu", (ulong) length));
14127   char* str= (char *)my_malloc(length + 1, MYF(MY_WME));
14128   if (str != NULL)
14129   {
14130     set.to_string(str, string_format);
14131     if (length_p != NULL)
14132       *length_p= length;
14133   }
14134   DBUG_RETURN(str);
14135 }
14136 
14137 #ifndef MYSQL_CLIENT
write_data_body(IO_CACHE * file)14138 bool Previous_gtids_log_event::write_data_body(IO_CACHE *file)
14139 {
14140   DBUG_ENTER("Previous_gtids_log_event::write_data_body");
14141   DBUG_PRINT("info", ("size=%d", buf_size));
14142   bool ret= wrapper_my_b_safe_write(file, buf, buf_size);
14143   DBUG_RETURN(ret);
14144 }
14145 #endif
14146 
14147 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
do_update_pos(Relay_log_info * rli)14148 int Previous_gtids_log_event::do_update_pos(Relay_log_info *rli)
14149 {
14150   rli->inc_event_relay_log_pos();
14151   return 0;
14152 }
14153 #endif
14154 
14155 
14156 #ifdef MYSQL_CLIENT
14157 /**
14158   The default values for these variables should be values that are
14159   *incorrect*, i.e., values that cannot occur in an event.  This way,
14160   they will always be printed for the first event.
14161 */
st_print_event_info()14162 st_print_event_info::st_print_event_info()
14163   :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
14164    auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
14165    lc_time_names_number(~0),
14166    charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
14167    thread_id(0), thread_id_printed(false),server_id_from_fd_event(0),
14168    base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE),
14169    have_unflushed_events(false), skipped_event_in_transaction(false),
14170    is_gtid_next_set(false), is_gtid_next_valid(true)
14171 {
14172   /*
14173     Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
14174     program's startup, but these explicit memset() is for the day someone
14175     creates dynamic instances.
14176   */
14177   memset(db, 0, sizeof(db));
14178   memset(charset, 0, sizeof(charset));
14179   memset(time_zone_str, 0, sizeof(time_zone_str));
14180   delimiter[0]= ';';
14181   delimiter[1]= 0;
14182   myf const flags = MYF(MY_WME | MY_NABP);
14183   open_cached_file(&head_cache, NULL, NULL, 0, flags);
14184   open_cached_file(&body_cache, NULL, NULL, 0, flags);
14185 }
14186 #endif
14187 
14188 
14189 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
Heartbeat_log_event(const char * buf,uint event_len,const Format_description_log_event * description_event)14190 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
14191                     const Format_description_log_event* description_event)
14192   :Log_event(buf, description_event)
14193 {
14194   uint8 header_size= description_event->common_header_len;
14195   ident_len = event_len - header_size;
14196   set_if_smaller(ident_len,FN_REFLEN-1);
14197   log_ident= buf + header_size;
14198 }
14199 #endif
14200 
14201 #ifdef MYSQL_SERVER
14202 /*
14203   This is a utility function that adds a quoted identifier into the a buffer.
14204   This also escapes any existance of the quote string inside the identifier.
14205 
14206   SYNOPSIS
14207     my_strmov_quoted_identifier
14208     thd                   thread handler
14209     buffer                target buffer
14210     identifier            the identifier to be quoted
14211     length                length of the identifier
14212 */
my_strmov_quoted_identifier(THD * thd,char * buffer,const char * identifier,uint length)14213 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
14214                                    const char* identifier,
14215                                    uint length)
14216 {
14217   int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
14218   return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
14219 }
14220 #else
my_strmov_quoted_identifier(char * buffer,const char * identifier)14221 size_t my_strmov_quoted_identifier(char *buffer,  const char* identifier)
14222 {
14223   int q= '`';
14224   return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
14225 }
14226 
14227 #endif
14228 
my_strmov_quoted_identifier_helper(int q,char * buffer,const char * identifier,uint length)14229 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
14230                                           const char* identifier,
14231                                           uint length)
14232 {
14233   size_t written= 0;
14234   char quote_char;
14235   uint id_length= (length) ? length : strlen(identifier);
14236 
14237   if (q == EOF)
14238   {
14239     (void) strncpy(buffer, identifier, id_length);
14240     return id_length;
14241   }
14242   quote_char= (char) q;
14243   *buffer++= quote_char;
14244   written++;
14245   while (id_length--)
14246   {
14247     if (*identifier == quote_char)
14248     {
14249       *buffer++= quote_char;
14250       written++;
14251     }
14252     *buffer++= *identifier++;
14253     written++;
14254   }
14255   *buffer++= quote_char;
14256   return ++written;
14257 }
14258 
14259