MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
log_event.cc
1 /*
2  Copyright (c) 2000, 2013, 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 as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
16 
17 
18 #ifdef MYSQL_CLIENT
19 
20 #include "sql_priv.h"
21 
22 #else
23 
24 #include "binlog.h"
25 #include "sql_priv.h"
26 #include "unireg.h"
27 #include "my_global.h" // REQUIRED by log_event.h > m_string.h > my_bitmap.h
28 #include "log_event.h"
29 #include "sql_base.h" // close_thread_tables
30 #include "sql_cache.h" // QUERY_CACHE_FLAGS_SIZE
31 #include "sql_locale.h" // MY_LOCALE, my_locale_by_number, my_locale_en_US
32 #include "key.h" // key_copy
33 #include "lock.h" // mysql_unlock_tables
34 #include "sql_parse.h" // mysql_test_parse_for_slave
35 #include "tztime.h" // struct Time_zone
36 #include "sql_load.h" // mysql_load
37 #include "sql_db.h" // load_db_opt_by_name
38 #include "rpl_slave.h"
39 #include "rpl_rli.h"
40 #include "rpl_mi.h"
41 #include "rpl_filter.h"
42 #include "rpl_record.h"
43 #include "transaction.h"
44 #include <my_dir.h>
45 #include "rpl_rli_pdb.h"
46 #include "sql_show.h" // append_identifier
48 
49 #endif /* MYSQL_CLIENT */
50 
51 #include <base64.h>
52 #include <my_bitmap.h>
53 #include "rpl_utility.h"
54 
55 using std::min;
56 using std::max;
57 
61 const char *binlog_checksum_type_names[]= {
62  "NONE",
63  "CRC32",
64  NullS
65 };
66 
67 unsigned int binlog_checksum_type_length[]= {
68  sizeof("NONE") - 1,
69  sizeof("CRC32") - 1,
70  0
71 };
72 
73 TYPELIB binlog_checksum_typelib=
74 {
75  array_elements(binlog_checksum_type_names) - 1, "",
76  binlog_checksum_type_names,
77  binlog_checksum_type_length
78 };
79 
80 
81 #define log_cs &my_charset_latin1
82 
83 #define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
84 
85 /*
86  Size of buffer for printing a double in format %.<PREC>g
87 
88  optional '-' + optional zero + '.' + PREC digits + 'e' + sign +
89  exponent digits + '\0'
90 */
91 #define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
92 
93 /*
94  Explicit instantiation to unsigned int of template available_buffer
95  function.
96 */
97 template unsigned int available_buffer<unsigned int>(const char*,
98  const char*,
99  unsigned int);
100 
101 /*
102  Explicit instantiation to unsigned int of template valid_buffer_range
103  function.
104 */
105 template bool valid_buffer_range<unsigned int>(unsigned int,
106  const char*,
107  const char*,
108  unsigned int);
109 
110 /*
111  replication event checksum is introduced in the following "checksum-home" version.
112  The checksum-aware servers extract FD's version to decide whether the FD event
113  carries checksum info.
114 */
115 const uchar checksum_version_split[3]= {5, 6, 1};
116 const ulong checksum_version_product=
117  (checksum_version_split[0] * 256 + checksum_version_split[1]) * 256 +
118  checksum_version_split[2];
119 
120 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
121 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD* thd);
122 
123 static const char *HA_ERR(int i)
124 {
125  /*
126  This function should only be called in case of an error
127  was detected
128  */
129  DBUG_ASSERT(i != 0);
130  switch (i) {
131  case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
132  case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
133  case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
134  case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
135  case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
136  case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
137  case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
138  case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
139  case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
140  case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
141  case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
142  case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
143  case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
144  case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
145  case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
146  case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
147  case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
148  case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
149  case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
150  case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
151  case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
152  case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
153  case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
154  case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
155  case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
156  case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
157  case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
158  case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
159  case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
160  case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
161  case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
162  case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
163  case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
164  case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
165  case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
166  case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
167  case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
168  case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
169  case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
170  case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
171  case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
172  case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
173  case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
174  case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
175  case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
176  case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
177  case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
178  case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
179  case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
180  case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
181  case HA_ERR_INNODB_READ_ONLY: return "HA_ERR_INNODB_READ_ONLY";
182  }
183  return "No Error!";
184 }
185 
199 static void inline slave_rows_error_report(enum loglevel level, int ha_error,
200  Relay_log_info const *rli, THD *thd,
201  TABLE *table, const char * type,
202  const char *log_name, ulong pos)
203 {
204  const char *handler_error= (ha_error ? HA_ERR(ha_error) : NULL);
205  char buff[MAX_SLAVE_ERRMSG], *slider;
206  const char *buff_end= buff + sizeof(buff);
207  uint len;
209  thd->get_stmt_da()->sql_conditions();
210  const Sql_condition *err;
211  buff[0]= 0;
212 
213  for (err= it++, slider= buff; err && slider < buff_end - 1;
214  slider += len, err= it++)
215  {
216  len= my_snprintf(slider, buff_end - slider,
217  " %s, Error_code: %d;", err->get_message_text(),
218  err->get_sql_errno());
219  }
220 
221  if (ha_error != 0)
222  rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
223  "Could not execute %s event on table %s.%s;"
224  "%s handler error %s; "
225  "the event's master log %s, end_log_pos %lu",
226  type, table->s->db.str, table->s->table_name.str,
227  buff, handler_error == NULL ? "<unknown>" : handler_error,
228  log_name, pos);
229  else
230  rli->report(level, thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0,
231  "Could not execute %s event on table %s.%s;"
232  "%s the event's master log %s, end_log_pos %lu",
233  type, table->s->db.str, table->s->table_name.str,
234  buff, log_name, pos);
235 }
236 
237 static void set_thd_db(THD *thd, const char *db, uint32 db_len)
238 {
239  char lcase_db_buf[NAME_LEN +1];
240  LEX_STRING new_db;
241  new_db.length= db_len;
242  if (lower_case_table_names == 1)
243  {
244  strmov(lcase_db_buf, db);
245  my_casedn_str(system_charset_info, lcase_db_buf);
246  new_db.str= lcase_db_buf;
247  }
248  else
249  new_db.str= (char*) db;
250 
251  new_db.str= (char*) rpl_filter->get_rewrite_db(new_db.str,
252  &new_db.length);
253  thd->set_db(new_db.str, new_db.length);
254 }
255 
256 #endif
257 
258 
259 /*
260  pretty_print_str()
261 */
262 
263 #ifdef MYSQL_CLIENT
264 static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
265 {
266  const char* end = str + len;
267  my_b_printf(cache, "\'");
268  while (str < end)
269  {
270  char c;
271  switch ((c=*str++)) {
272  case '\n': my_b_printf(cache, "\\n"); break;
273  case '\r': my_b_printf(cache, "\\r"); break;
274  case '\\': my_b_printf(cache, "\\\\"); break;
275  case '\b': my_b_printf(cache, "\\b"); break;
276  case '\t': my_b_printf(cache, "\\t"); break;
277  case '\'': my_b_printf(cache, "\\'"); break;
278  case 0 : my_b_printf(cache, "\\0"); break;
279  default:
280  my_b_printf(cache, "%c", c);
281  break;
282  }
283  }
284  my_b_printf(cache, "\'");
285 }
286 #endif /* MYSQL_CLIENT */
287 
288 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
289 
290 static void clear_all_errors(THD *thd, Relay_log_info *rli)
291 {
292  thd->is_slave_error = 0;
293  thd->clear_error();
294  rli->clear_error();
295 }
296 
297 inline int idempotent_error_code(int err_code)
298 {
299  int ret= 0;
300 
301  switch (err_code)
302  {
303  case 0:
304  ret= 1;
305  break;
306  /*
307  The following list of "idempotent" errors
308  means that an error from the list might happen
309  because of idempotent (more than once)
310  applying of a binlog file.
311  Notice, that binlog has a ddl operation its
312  second applying may cause
313 
314  case HA_ERR_TABLE_DEF_CHANGED:
315  case HA_ERR_CANNOT_ADD_FOREIGN:
316 
317  which are not included into to the list.
318 
319  Note that HA_ERR_RECORD_DELETED is not in the list since
320  do_exec_row() should not return that error code.
321  */
322  case HA_ERR_RECORD_CHANGED:
323  case HA_ERR_KEY_NOT_FOUND:
324  case HA_ERR_END_OF_FILE:
325  case HA_ERR_FOUND_DUPP_KEY:
326  case HA_ERR_FOUND_DUPP_UNIQUE:
327  case HA_ERR_FOREIGN_DUPLICATE_KEY:
328  case HA_ERR_NO_REFERENCED_ROW:
329  case HA_ERR_ROW_IS_REFERENCED:
330  ret= 1;
331  break;
332  default:
333  ret= 0;
334  break;
335  }
336  return (ret);
337 }
338 
343 inline int ignored_error_code(int err_code)
344 {
345 #ifdef HAVE_NDB_BINLOG
346  /*
347  The following error codes are hard-coded and will always be ignored.
348  */
349  switch (err_code)
350  {
351  case ER_DB_CREATE_EXISTS:
352  case ER_DB_DROP_EXISTS:
353  return 1;
354  default:
355  /* Nothing to do */
356  break;
357  }
358 #endif
359  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
360  (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
361 }
362 
363 /*
364  This function converts an engine's error to a server error.
365 
366  If the thread does not have an error already reported, it tries to
367  define it by calling the engine's method print_error. However, if a
368  mapping is not found, it uses the ER_UNKNOWN_ERROR and prints out a
369  warning message.
370 */
371 int convert_handler_error(int error, THD* thd, TABLE *table)
372 {
373  uint actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
374  0);
375 
376  if (actual_error == 0)
377  {
378  table->file->print_error(error, MYF(0));
379  actual_error= (thd->is_error() ? thd->get_stmt_da()->sql_errno() :
380  ER_UNKNOWN_ERROR);
381  if (actual_error == ER_UNKNOWN_ERROR)
382  if (log_warnings)
383  sql_print_warning("Unknown error detected %d in handler", error);
384  }
385 
386  return (actual_error);
387 }
388 
389 inline bool concurrency_error_code(int error)
390 {
391  switch (error)
392  {
393  case ER_LOCK_WAIT_TIMEOUT:
394  case ER_LOCK_DEADLOCK:
395  case ER_XA_RBDEADLOCK:
396  return TRUE;
397  default:
398  return (FALSE);
399  }
400 }
401 
402 inline bool unexpected_error_code(int unexpected_error)
403 {
404  switch (unexpected_error)
405  {
406  case ER_NET_READ_ERROR:
407  case ER_NET_ERROR_ON_WRITE:
408  case ER_QUERY_INTERRUPTED:
409  case ER_SERVER_SHUTDOWN:
410  case ER_NEW_ABORTING_CONNECTION:
411  return(TRUE);
412  default:
413  return(FALSE);
414  }
415 }
416 
417 /*
418  pretty_print_str()
419 */
420 
421 static char *pretty_print_str(char *packet, const char *str, int len)
422 {
423  const char *end= str + len;
424  char *pos= packet;
425  *pos++= '\'';
426  while (str < end)
427  {
428  char c;
429  switch ((c=*str++)) {
430  case '\n': *pos++= '\\'; *pos++= 'n'; break;
431  case '\r': *pos++= '\\'; *pos++= 'r'; break;
432  case '\\': *pos++= '\\'; *pos++= '\\'; break;
433  case '\b': *pos++= '\\'; *pos++= 'b'; break;
434  case '\t': *pos++= '\\'; *pos++= 't'; break;
435  case '\'': *pos++= '\\'; *pos++= '\''; break;
436  case 0 : *pos++= '\\'; *pos++= '0'; break;
437  default:
438  *pos++= c;
439  break;
440  }
441  }
442  *pos++= '\'';
443  return pos;
444 }
445 #endif /* !MYSQL_CLIENT */
446 
447 
448 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
449 
462 static char *slave_load_file_stem(char *buf, uint file_id,
463  int event_server_id, const char *ext)
464 {
465  char *res;
466  fn_format(buf,PREFIX_SQL_LOAD,slave_load_tmpdir, "", MY_UNPACK_FILENAME);
467  to_unix_path(buf);
468 
469  buf= strend(buf);
470  int appended_length= sprintf(buf, "%s-%d-", server_uuid, event_server_id);
471  buf+= appended_length;
472  res= int10_to_str(file_id, buf, 10);
473  strmov(res, ext); // Add extension last
474  return res; // Pointer to extension
475 }
476 #endif
477 
478 
479 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
480 
485 static void cleanup_load_tmpdir()
486 {
487  MY_DIR *dirp;
488  FILEINFO *file;
489  uint i;
490  char fname[FN_REFLEN], prefbuf[TEMP_FILE_MAX_LEN], *p;
491 
492  if (!(dirp=my_dir(slave_load_tmpdir,MYF(0))))
493  return;
494 
495  /*
496  When we are deleting temporary files, we should only remove
497  the files associated with the server id of our server.
498  We don't use event_server_id here because since we've disabled
499  direct binlogging of Create_file/Append_file/Exec_load events
500  we cannot meet Start_log event in the middle of events from one
501  LOAD DATA.
502  */
503  p= strmake(prefbuf, STRING_WITH_LEN(PREFIX_SQL_LOAD));
504  sprintf(p,"%s-",server_uuid);
505 
506  for (i=0 ; i < (uint)dirp->number_off_files; i++)
507  {
508  file=dirp->dir_entry+i;
509  if (is_prefix(file->name, prefbuf))
510  {
511  fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
512  mysql_file_delete(key_file_misc, fname, MYF(0));
513  }
514  }
515 
516  my_dirend(dirp);
517 }
518 #endif
519 
520 
521 /*
522  Stores string to IO_CACHE file.
523 
524  Writes str to file in the following format:
525  1. Stores length using only one byte (255 maximum value);
526  2. Stores complete str.
527 */
528 
529 static bool write_str_at_most_255_bytes(IO_CACHE *file, const char *str,
530  uint length)
531 {
532  uchar tmp[1];
533  tmp[0]= (uchar) length;
534  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
535  my_b_safe_write(file, (uchar*) str, length));
536 }
537 
538 
539 /*
540  Reads string from buf.
541 
542  Reads str from buf in the following format:
543  1. Read length stored on buf first index, as it only has 1 byte values
544  bigger than 255 where lost.
545  2. Set str pointer to buf second index.
546  Despite str contains the complete stored string, when it is read until
547  len its value will be truncated if original length was bigger than 255.
548 */
549 
550 static inline int read_str_at_most_255_bytes(const char **buf,
551  const char *buf_end,
552  const char **str,
553  uint8 *len)
554 {
555  if (*buf + ((uint) (uchar) **buf) >= buf_end)
556  return 1;
557  *len= (uint8) **buf;
558  *str= (*buf)+1;
559  (*buf)+= (uint) *len+1;
560  return 0;
561 }
562 
563 
568 char *str_to_hex(char *to, const char *from, uint len)
569 {
570  if (len)
571  {
572  *to++= '0';
573  *to++= 'x';
574  to= octet2hex(to, from, len);
575  }
576  else
577  to= strmov(to, "\"\"");
578  return to; // pointer to end 0 of 'to'
579 }
580 
581 #ifndef MYSQL_CLIENT
582 
589 int
590 append_query_string(THD *thd, const CHARSET_INFO *csinfo,
591  String const *from, String *to)
592 {
593  char *beg, *ptr;
594  uint32 const orig_len= to->length();
595  if (to->reserve(orig_len + from->length()*2+3))
596  return 1;
597 
598  beg= to->c_ptr_quick() + to->length();
599  ptr= beg;
600  if (csinfo->escape_with_backslash_is_dangerous)
601  ptr= str_to_hex(ptr, from->ptr(), from->length());
602  else
603  {
604  *ptr++= '\'';
605  if (!(thd->variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES))
606  {
607  ptr+= escape_string_for_mysql(csinfo, ptr, 0,
608  from->ptr(), from->length());
609  }
610  else
611  {
612  const char *frm_str= from->ptr();
613 
614  for (; frm_str < (from->ptr() + from->length()); frm_str++)
615  {
616  /* Using '' way to represent "'" */
617  if (*frm_str == '\'')
618  *ptr++= *frm_str;
619 
620  *ptr++= *frm_str;
621  }
622  }
623 
624  *ptr++= '\'';
625  }
626  to->length(orig_len + ptr - beg);
627  return 0;
628 }
629 #endif
630 
631 
637 #ifdef MYSQL_CLIENT
638 
639 static void print_set_option(IO_CACHE* file, uint32 bits_changed,
640  uint32 option, uint32 flags, const char* name,
641  bool* need_comma)
642 {
643  if (bits_changed & option)
644  {
645  if (*need_comma)
646  my_b_printf(file,", ");
647  my_b_printf(file,"%s=%d", name, test(flags & option));
648  *need_comma= 1;
649  }
650 }
651 #endif
652 /**************************************************************************
653  Log_event methods (= the parent class of all events)
654 **************************************************************************/
655 
662 {
663  switch(type) {
664  case START_EVENT_V3: return "Start_v3";
665  case STOP_EVENT: return "Stop";
666  case QUERY_EVENT: return "Query";
667  case ROTATE_EVENT: return "Rotate";
668  case INTVAR_EVENT: return "Intvar";
669  case LOAD_EVENT: return "Load";
670  case NEW_LOAD_EVENT: return "New_load";
671  case CREATE_FILE_EVENT: return "Create_file";
672  case APPEND_BLOCK_EVENT: return "Append_block";
673  case DELETE_FILE_EVENT: return "Delete_file";
674  case EXEC_LOAD_EVENT: return "Exec_load";
675  case RAND_EVENT: return "RAND";
676  case XID_EVENT: return "Xid";
677  case USER_VAR_EVENT: return "User var";
678  case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
679  case TABLE_MAP_EVENT: return "Table_map";
680  case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
681  case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
682  case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
683  case WRITE_ROWS_EVENT_V1: return "Write_rows_v1";
684  case UPDATE_ROWS_EVENT_V1: return "Update_rows_v1";
685  case DELETE_ROWS_EVENT_V1: return "Delete_rows_v1";
686  case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
687  case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
688  case INCIDENT_EVENT: return "Incident";
689  case IGNORABLE_LOG_EVENT: return "Ignorable";
690  case ROWS_QUERY_LOG_EVENT: return "Rows_query";
691  case WRITE_ROWS_EVENT: return "Write_rows";
692  case UPDATE_ROWS_EVENT: return "Update_rows";
693  case DELETE_ROWS_EVENT: return "Delete_rows";
694  case GTID_LOG_EVENT: return "Gtid";
695  case ANONYMOUS_GTID_LOG_EVENT: return "Anonymous_Gtid";
696  case PREVIOUS_GTIDS_LOG_EVENT: return "Previous_gtids";
697  case HEARTBEAT_LOG_EVENT: return "Heartbeat";
698  default: return "Unknown"; /* impossible */
699  }
700 }
701 
703 {
704  return get_type_str(get_type_code());
705 }
706 
707 
708 /*
709  Log_event::Log_event()
710 */
711 
712 #ifndef MYSQL_CLIENT
713 Log_event::Log_event(THD* thd_arg, uint16 flags_arg,
714  enum_event_cache_type cache_type_arg,
715  enum_event_logging_type logging_type_arg)
716  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg),
717  event_cache_type(cache_type_arg),
718  event_logging_type(logging_type_arg),
719  crc(0), thd(thd_arg), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
720 {
721  server_id= thd->server_id;
722  unmasked_server_id= server_id;
723  when= thd->start_time;
724 }
725 
733 Log_event::Log_event(enum_event_cache_type cache_type_arg,
734  enum_event_logging_type logging_type_arg)
735  :temp_buf(0), exec_time(0), flags(0), event_cache_type(cache_type_arg),
736  event_logging_type(logging_type_arg), crc(0), thd(0),
737  checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
738 {
739  server_id= ::server_id;
740  unmasked_server_id= server_id;
741  /*
742  We can't call my_time() here as this would cause a call before
743  my_init() is called
744  */
745  when.tv_sec= 0;
746  when.tv_usec= 0;
747  log_pos= 0;
748 }
749 #endif /* !MYSQL_CLIENT */
750 
751 
752 /*
753  Log_event::Log_event()
754 */
755 
756 Log_event::Log_event(const char* buf,
757  const Format_description_log_event* description_event)
758  :temp_buf(0), exec_time(0),
759  event_cache_type(EVENT_INVALID_CACHE),
760  event_logging_type(EVENT_INVALID_LOGGING),
761  crc(0), checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF)
762 {
763 #ifndef MYSQL_CLIENT
764  thd = 0;
765 #endif
766  when.tv_sec= uint4korr(buf);
767  when.tv_usec= 0;
768  server_id = uint4korr(buf + SERVER_ID_OFFSET);
769  unmasked_server_id = server_id;
770  /*
771  Mask out any irrelevant parts of the server_id
772  */
773 #ifdef HAVE_REPLICATION
774  server_id = unmasked_server_id & opt_server_id_mask;
775 #else
776  server_id = unmasked_server_id;
777 #endif
778  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
779  if (description_event->binlog_version==1)
780  {
781  log_pos= 0;
782  flags= 0;
783  return;
784  }
785  /* 4.0 or newer */
786  log_pos= uint4korr(buf + LOG_POS_OFFSET);
787  /*
788  If the log is 4.0 (so here it can only be a 4.0 relay log read by
789  the SQL thread or a 4.0 master binlog read by the I/O thread),
790  log_pos is the beginning of the event: we transform it into the end
791  of the event, which is more useful.
792  But how do you know that the log is 4.0: you know it if
793  description_event is version 3 *and* you are not reading a
794  Format_desc (remember that mysqlbinlog starts by assuming that 5.0
795  logs are in 4.0 format, until it finds a Format_desc).
796  */
797  if (description_event->binlog_version==3 &&
798  buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
799  {
800  /*
801  If log_pos=0, don't change it. log_pos==0 is a marker to mean
802  "don't change rli->group_master_log_pos" (see
803  inc_group_relay_log_pos()). As it is unreal log_pos, adding the
804  event len's is nonsense. For example, a fake Rotate event should
805  not have its log_pos (which is 0) changed or it will modify
806  Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
807  value of (a non-zero offset which does not exist in the master's
808  binlog, so which will cause problems if the user uses this value
809  in CHANGE MASTER).
810  */
811  log_pos+= data_written; /* purecov: inspected */
812  }
813  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
814 
815  flags= uint2korr(buf + FLAGS_OFFSET);
816  if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
817  (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
818  {
819  /*
820  These events always have a header which stops here (i.e. their
821  header is FROZEN).
822  */
823  /*
824  Initialization to zero of all other Log_event members as they're
825  not specified. Currently there are no such members; in the future
826  there will be an event UID (but Format_description and Rotate
827  don't need this UID, as they are not propagated through
828  --log-slave-updates (remember the UID is used to not play a query
829  twice when you have two masters which are slaves of a 3rd master).
830  Then we are done.
831  */
832  return;
833  }
834  /* otherwise, go on with reading the header from buf (nothing now) */
835 }
836 
837 #ifndef MYSQL_CLIENT
838 #ifdef HAVE_REPLICATION
839 inline int Log_event::do_apply_event_worker(Slave_worker *w)
840 {
841  return do_apply_event(w);
842 }
843 
844 int Log_event::do_update_pos(Relay_log_info *rli)
845 {
846  int error= 0;
847  DBUG_ASSERT(!rli->belongs_to_client());
848  /*
849  rli is null when (as far as I (Guilhem) know) the caller is
850  Load_log_event::do_apply_event *and* that one is called from
851  Execute_load_log_event::do_apply_event. In this case, we don't
852  do anything here ; Execute_load_log_event::do_apply_event will
853  call Log_event::do_apply_event again later with the proper rli.
854  Strictly speaking, if we were sure that rli is null only in the
855  case discussed above, 'if (rli)' is useless here. But as we are
856  not 100% sure, keep it for now.
857 
858  Matz: I don't think we will need this check with this refactoring.
859  */
860 
861  DBUG_ASSERT(!is_mts_worker(rli->info_thd));
862 
863  if (rli)
864  error= rli->stmt_done(log_pos);
865  return error;
866 }
867 
868 
870 Log_event::do_shall_skip(Relay_log_info *rli)
871 {
872  DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
873  " rli->replicate_same_server_id=%d,"
874  " rli->slave_skip_counter=%d",
875  (ulong) server_id, (ulong) ::server_id,
876  rli->replicate_same_server_id,
877  rli->slave_skip_counter));
878  if ((server_id == ::server_id && !rli->replicate_same_server_id) ||
879  (rli->slave_skip_counter == 1 && rli->is_in_group()))
880  return EVENT_SKIP_IGNORE;
881  else if (rli->slave_skip_counter > 0)
882  return EVENT_SKIP_COUNT;
883  else
884  return EVENT_SKIP_NOT;
885 }
886 
887 
888 /*
889  Log_event::pack_info()
890 */
891 
892 int Log_event::pack_info(Protocol *protocol)
893 {
894  protocol->store("", &my_charset_bin);
895  return 0;
896 }
897 
898 
902 int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
903 {
904  const char *p= strrchr(log_name, FN_LIBCHAR);
905  const char *event_type;
906  if (p)
907  log_name = p + 1;
908 
909  protocol->prepare_for_resend();
910  protocol->store(log_name, &my_charset_bin);
911  protocol->store((ulonglong) pos);
912  event_type = get_type_str();
913  protocol->store(event_type, strlen(event_type), &my_charset_bin);
914  protocol->store((uint32) server_id);
915  protocol->store((ulonglong) log_pos);
916  if (pack_info(protocol))
917  return 1;
918  return protocol->write();
919 }
920 #endif /* HAVE_REPLICATION */
921 
922 
929 void Log_event::init_show_field_list(List<Item>* field_list)
930 {
931  field_list->push_back(new Item_empty_string("Log_name", 20));
932  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
933  MYSQL_TYPE_LONGLONG));
934  field_list->push_back(new Item_empty_string("Event_type", 20));
935  field_list->push_back(new Item_return_int("Server_id", 10,
936  MYSQL_TYPE_LONG));
937  field_list->push_back(new Item_return_int("End_log_pos",
938  MY_INT32_NUM_DECIMAL_DIGITS,
939  MYSQL_TYPE_LONGLONG));
940  field_list->push_back(new Item_empty_string("Info", 20));
941 }
942 
961 my_bool Log_event::need_checksum()
962 {
963  DBUG_ENTER("Log_event::need_checksum");
964  my_bool ret= FALSE;
965  /*
966  few callers of Log_event::write
967  (incl FD::write, FD constructing code on the slave side, Rotate relay log
968  and Stop event)
969  provides their checksum alg preference through Log_event::checksum_alg.
970  */
971  if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
972  ret= (checksum_alg != BINLOG_CHECKSUM_ALG_OFF);
973  else if (binlog_checksum_options != BINLOG_CHECKSUM_ALG_OFF &&
974  event_cache_type == Log_event::EVENT_NO_CACHE)
975  ret= binlog_checksum_options;
976  else
977  ret= FALSE;
978 
979  /*
980  FD calls the methods before data_written has been calculated.
981  The following invariant claims if the current is not the first
982  call (and therefore data_written is not zero) then `ret' must be
983  TRUE. It may not be null because FD is always checksummed.
984  */
985 
986  DBUG_ASSERT(get_type_code() != FORMAT_DESCRIPTION_EVENT || ret ||
987  data_written == 0);
988 
989  if (checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF)
990  checksum_alg= ret ? // calculated value stored
991  binlog_checksum_options : (uint8) BINLOG_CHECKSUM_ALG_OFF;
992 
993  DBUG_ASSERT(!ret ||
994  ((checksum_alg == binlog_checksum_options ||
995  /*
996  Stop event closes the relay-log and its checksum alg
997  preference is set by the caller can be different
998  from the server's binlog_checksum_options.
999  */
1000  get_type_code() == STOP_EVENT ||
1001  /*
1002  Rotate:s can be checksummed regardless of the server's
1003  binlog_checksum_options. That applies to both
1004  the local RL's Rotate and the master's Rotate
1005  which IO thread instantiates via queue_binlog_ver_3_event.
1006  */
1007  get_type_code() == ROTATE_EVENT ||
1008  /*
1009  The previous event has its checksum option defined
1010  according to the format description event.
1011  */
1012  get_type_code() == PREVIOUS_GTIDS_LOG_EVENT ||
1013  /* FD is always checksummed */
1014  get_type_code() == FORMAT_DESCRIPTION_EVENT) &&
1015  checksum_alg != BINLOG_CHECKSUM_ALG_OFF));
1016 
1017  DBUG_ASSERT(checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF);
1018  DBUG_ASSERT(((get_type_code() != ROTATE_EVENT &&
1019  get_type_code() != STOP_EVENT) ||
1020  get_type_code() != FORMAT_DESCRIPTION_EVENT) ||
1021  event_cache_type == Log_event::EVENT_NO_CACHE);
1022 
1023  DBUG_RETURN(ret);
1024 }
1025 
1026 bool Log_event::wrapper_my_b_safe_write(IO_CACHE* file, const uchar* buf, ulong size)
1027 {
1028  if (need_checksum() && size != 0)
1029  crc= my_checksum(crc, buf, size);
1030 
1031  return my_b_safe_write(file, buf, size);
1032 }
1033 
1034 bool Log_event::write_footer(IO_CACHE* file)
1035 {
1036  /*
1037  footer contains the checksum-algorithm descriptor
1038  followed by the checksum value
1039  */
1040  if (need_checksum())
1041  {
1042  uchar buf[BINLOG_CHECKSUM_LEN];
1043  int4store(buf, crc);
1044  return (my_b_safe_write(file, (uchar*) buf, sizeof(buf)));
1045  }
1046  return 0;
1047 }
1048 
1049 /*
1050  Log_event::write()
1051 */
1052 
1053 bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
1054 {
1055  uchar header[LOG_EVENT_HEADER_LEN];
1056  ulong now;
1057  bool ret;
1058  DBUG_ENTER("Log_event::write_header");
1059 
1060  /* Store number of bytes that will be written by this event */
1061  data_written= event_data_length + sizeof(header);
1062 
1063  if (need_checksum())
1064  {
1065  crc= my_checksum(0L, NULL, 0);
1066  data_written += BINLOG_CHECKSUM_LEN;
1067  }
1068 
1069  /*
1070  log_pos != 0 if this is relay-log event. In this case we should not
1071  change the position
1072  */
1073 
1074  if (is_artificial_event())
1075  {
1076  /*
1077  Artificial events are automatically generated and do not exist
1078  in master's binary log, so log_pos should be set to 0.
1079  */
1080  log_pos= 0;
1081  }
1082  else if (!log_pos)
1083  {
1084  /*
1085  Calculate position of end of event
1086 
1087  Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
1088  work well. So this will give slightly wrong positions for the
1089  Format_desc/Rotate/Stop events which the slave writes to its
1090  relay log. For example, the initial Format_desc will have
1091  end_log_pos=91 instead of 95. Because after writing the first 4
1092  bytes of the relay log, my_b_tell() still reports 0. Because
1093  my_b_append() does not update the counter which my_b_tell()
1094  later uses (one should probably use my_b_append_tell() to work
1095  around this). To get right positions even when writing to the
1096  relay log, we use the (new) my_b_safe_tell().
1097 
1098  Note that this raises a question on the correctness of all these
1099  DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
1100 
1101  If in a transaction, the log_pos which we calculate below is not
1102  very good (because then my_b_safe_tell() returns start position
1103  of the BEGIN, so it's like the statement was at the BEGIN's
1104  place), but it's not a very serious problem (as the slave, when
1105  it is in a transaction, does not take those end_log_pos into
1106  account (as it calls inc_event_relay_log_pos()). To be fixed
1107  later, so that it looks less strange. But not bug.
1108  */
1109 
1110  log_pos= my_b_safe_tell(file)+data_written;
1111  }
1112 
1113  now= (ulong) get_time(); // Query start time
1114  if (DBUG_EVALUATE_IF("inc_event_time_by_1_hour",1,0) &&
1115  DBUG_EVALUATE_IF("dec_event_time_by_1_hour",1,0))
1116  {
1121  DBUG_ASSERT(0);
1122  }
1123  else
1124  {
1125  DBUG_EXECUTE_IF("inc_event_time_by_1_hour", now= now + 3600;);
1126  DBUG_EXECUTE_IF("dec_event_time_by_1_hour", now= now - 3600;);
1127  }
1128 
1129  /*
1130  Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
1131  FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
1132  LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
1133  because we read them before knowing the format).
1134  */
1135 
1136  int4store(header, now); // timestamp
1137  header[EVENT_TYPE_OFFSET]= get_type_code();
1138  int4store(header+ SERVER_ID_OFFSET, server_id);
1139  int4store(header+ EVENT_LEN_OFFSET, data_written);
1140  int4store(header+ LOG_POS_OFFSET, log_pos);
1141  /*
1142  recording checksum of FD event computed with dropped
1143  possibly active LOG_EVENT_BINLOG_IN_USE_F flag.
1144  Similar step at verication: the active flag is dropped before
1145  checksum computing.
1146  */
1147  if (header[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT ||
1148  !need_checksum() || !(flags & LOG_EVENT_BINLOG_IN_USE_F))
1149  {
1150  int2store(header+ FLAGS_OFFSET, flags);
1151  ret= wrapper_my_b_safe_write(file, header, sizeof(header)) != 0;
1152  }
1153  else
1154  {
1155  ret= (wrapper_my_b_safe_write(file, header, FLAGS_OFFSET) != 0);
1156  if (!ret)
1157  {
1158  flags &= ~LOG_EVENT_BINLOG_IN_USE_F;
1159  int2store(header + FLAGS_OFFSET, flags);
1160  crc= my_checksum(crc, header + FLAGS_OFFSET, sizeof(flags));
1161  flags |= LOG_EVENT_BINLOG_IN_USE_F;
1162  int2store(header + FLAGS_OFFSET, flags);
1163  ret= (my_b_safe_write(file, header + FLAGS_OFFSET, sizeof(flags)) != 0);
1164  }
1165  if (!ret)
1166  ret= (wrapper_my_b_safe_write(file, header + FLAGS_OFFSET + sizeof(flags),
1167  sizeof(header)
1168  - (FLAGS_OFFSET + sizeof(flags))) != 0);
1169  }
1170  DBUG_RETURN( ret);
1171 }
1172 
1173 
1179 int Log_event::read_log_event(IO_CACHE* file, String* packet,
1180  mysql_mutex_t* log_lock,
1181  uint8 checksum_alg_arg,
1182  const char *log_file_name_arg,
1183  bool* is_binlog_active)
1184 {
1185  ulong data_len;
1186  int result=0;
1187  char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
1188  uchar ev_offset= packet->length();
1189  DBUG_ENTER("Log_event::read_log_event(IO_CACHE *, String *, mysql_mutex_t, uint8)");
1190 
1191  if (log_lock)
1192  mysql_mutex_lock(log_lock);
1193 
1194  if (log_file_name_arg)
1195  *is_binlog_active= mysql_bin_log.is_active(log_file_name_arg);
1196 
1197  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
1198  {
1199  /*
1200  If the read hits eof, we must report it as eof so the caller
1201  will know it can go into cond_wait to be woken up on the next
1202  update to the log.
1203  */
1204  DBUG_PRINT("error",("my_b_read failed. file->error: %d", file->error));
1205  if (!file->error)
1206  result= LOG_READ_EOF;
1207  else
1208  result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
1209  goto end;
1210  }
1211  data_len= uint4korr(buf + EVENT_LEN_OFFSET);
1212  if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
1213  data_len > max(current_thd->variables.max_allowed_packet,
1214  opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER))
1215  {
1216  DBUG_PRINT("error",("data_len is out of bounds. data_len: %lu", data_len));
1217  result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
1218  LOG_READ_TOO_LARGE);
1219  goto end;
1220  }
1221 
1222  /* Append the log event header to packet */
1223  if (packet->append(buf, sizeof(buf)))
1224  {
1225  DBUG_PRINT("info", ("first packet->append failed (out of memory)"));
1226  /* Failed to allocate packet */
1227  result= LOG_READ_MEM;
1228  goto end;
1229  }
1230  data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
1231  if (data_len)
1232  {
1233  /* Append rest of event, read directly from file into packet */
1234  if (packet->append(file, data_len))
1235  {
1236  /*
1237  Fatal error occured when appending rest of the event
1238  to packet, possible failures:
1239  1. EOF occured when reading from file, it's really an error
1240  as data_len is >=0 there's supposed to be more bytes available.
1241  file->error will have been set to number of bytes left to read
1242  2. Read was interrupted, file->error would normally be set to -1
1243  3. Failed to allocate memory for packet, my_errno
1244  will be ENOMEM(file->error shuold be 0, but since the
1245  memory allocation occurs before the call to read it might
1246  be uninitialized)
1247  */
1248  DBUG_PRINT("info", ("second packet->append failed (out of memory)"));
1249  result= (my_errno == ENOMEM ? LOG_READ_MEM :
1250  (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
1251  goto end;
1252  }
1253  else
1254  {
1255  /* Corrupt the event for Dump thread*/
1256  DBUG_EXECUTE_IF("corrupt_read_log_event",
1257  uchar *debug_event_buf_c = (uchar*) packet->ptr() + ev_offset;
1258  if (debug_event_buf_c[EVENT_TYPE_OFFSET] != FORMAT_DESCRIPTION_EVENT)
1259  {
1260  int debug_cor_pos = rand() % (data_len + sizeof(buf) - BINLOG_CHECKSUM_LEN);
1261  debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1262  DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event: byte on position %d", debug_cor_pos));
1263  DBUG_SET("-d,corrupt_read_log_event");
1264  }
1265  );
1266  /*
1267  CRC verification of the Dump thread
1268  */
1269  if (opt_master_verify_checksum &&
1270  event_checksum_test((uchar*) packet->ptr() + ev_offset,
1271  data_len + sizeof(buf),
1272  checksum_alg_arg))
1273  {
1274  DBUG_PRINT("info", ("checksum test failed"));
1275  result= LOG_READ_CHECKSUM_FAILURE;
1276  goto end;
1277  }
1278  }
1279  }
1280 
1281 end:
1282  if (log_lock)
1283  mysql_mutex_unlock(log_lock);
1284  DBUG_PRINT("info", ("read_log_event returns %d", result));
1285  DBUG_RETURN(result);
1286 }
1287 #endif /* !MYSQL_CLIENT */
1288 
1289 #ifndef MYSQL_CLIENT
1290 #define UNLOCK_MUTEX if (log_lock) mysql_mutex_unlock(log_lock);
1291 #define LOCK_MUTEX if (log_lock) mysql_mutex_lock(log_lock);
1292 #else
1293 #define UNLOCK_MUTEX
1294 #define LOCK_MUTEX
1295 #endif
1296 
1297 #ifndef MYSQL_CLIENT
1298 
1302 Log_event* Log_event::read_log_event(IO_CACHE* file,
1303  mysql_mutex_t* log_lock,
1305  *description_event,
1306  my_bool crc_check)
1307 #else
1308 Log_event* Log_event::read_log_event(IO_CACHE* file,
1310  *description_event,
1311  my_bool crc_check)
1312 #endif
1313 {
1314  DBUG_ENTER("Log_event::read_log_event(IO_CACHE *[, mysql_mutex_t *], Format_description_log_event *, my_bool)");
1315  DBUG_ASSERT(description_event != 0);
1316  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
1317  /*
1318  First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
1319  check the event for sanity and to know its length; no need to really parse
1320  it. We say "at most" because this could be a 3.23 master, which has header
1321  of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
1322  "minimal" over the set {MySQL >=4.0}).
1323  */
1324  uint header_size= min<uint>(description_event->common_header_len,
1325  LOG_EVENT_MINIMAL_HEADER_LEN);
1326 
1327  LOCK_MUTEX;
1328  DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
1329  if (my_b_read(file, (uchar *) head, header_size))
1330  {
1331  DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) "
1332  "failed in my_b_read((IO_CACHE*)%p, (uchar*)%p, %u)",
1333  file, head, header_size));
1334  UNLOCK_MUTEX;
1335  /*
1336  No error here; it could be that we are at the file's end. However
1337  if the next my_b_read() fails (below), it will be an error as we
1338  were able to read the first bytes.
1339  */
1340  DBUG_RETURN(0);
1341  }
1342  ulong data_len = uint4korr(head + EVENT_LEN_OFFSET);
1343  char *buf= 0;
1344  const char *error= 0;
1345  Log_event *res= 0;
1346 #ifndef max_allowed_packet
1347  THD *thd=current_thd;
1348  uint max_allowed_packet= thd ? slave_max_allowed_packet : ~0U;
1349 #endif
1350 
1351  ulong const max_size=
1352  max<ulong>(max_allowed_packet,
1353  opt_binlog_rows_event_max_size + MAX_LOG_EVENT_HEADER);
1354  if (data_len > max_size)
1355  {
1356  error = "Event too big";
1357  goto err;
1358  }
1359 
1360  if (data_len < header_size)
1361  {
1362  error = "Event too small";
1363  goto err;
1364  }
1365 
1366  // some events use the extra byte to null-terminate strings
1367  if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
1368  {
1369  error = "Out of memory";
1370  goto err;
1371  }
1372  buf[data_len] = 0;
1373  memcpy(buf, head, header_size);
1374  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
1375  {
1376  error = "read error";
1377  goto err;
1378  }
1379  if ((res= read_log_event(buf, data_len, &error, description_event, crc_check)))
1380  res->register_temp_buf(buf);
1381 
1382 err:
1383  UNLOCK_MUTEX;
1384  if (!res)
1385  {
1386  DBUG_ASSERT(error != 0);
1387  sql_print_error("Error in Log_event::read_log_event(): "
1388  "'%s', data_len: %lu, event_type: %d",
1389  error,data_len,head[EVENT_TYPE_OFFSET]);
1390  my_free(buf);
1391  /*
1392  The SQL slave thread will check if file->error<0 to know
1393  if there was an I/O error. Even if there is no "low-level" I/O errors
1394  with 'file', any of the high-level above errors is worrying
1395  enough to stop the SQL thread now ; as we are skipping the current event,
1396  going on with reading and successfully executing other events can
1397  only corrupt the slave's databases. So stop.
1398  The file->error is also checked to record the position of
1399  the last valid event when master server recovers.
1400  */
1401  file->error= -1;
1402  }
1403  DBUG_RETURN(res);
1404 }
1405 
1406 
1412 Log_event* Log_event::read_log_event(const char* buf, uint event_len,
1413  const char **error,
1414  const Format_description_log_event *description_event,
1415  my_bool crc_check)
1416 {
1417  Log_event* ev;
1418  uint8 alg;
1419  DBUG_ENTER("Log_event::read_log_event(char *, uint, char **, Format_description_log_event *, my_bool)");
1420  DBUG_ASSERT(description_event != 0);
1421  DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
1422  DBUG_DUMP("data", (unsigned char*) buf, event_len);
1423 
1424  /* Check the integrity */
1425  if (event_len < EVENT_LEN_OFFSET ||
1426  buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
1427  (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
1428  {
1429  DBUG_PRINT("error", ("event_len=%u EVENT_LEN_OFFSET=%d "
1430  "buf[EVENT_TYPE_OFFSET]=%d ENUM_END_EVENT=%d "
1431  "uint4korr(buf+EVENT_LEN_OFFSET)=%d",
1432  event_len, EVENT_LEN_OFFSET,
1433  buf[EVENT_TYPE_OFFSET], ENUM_END_EVENT,
1434  uint4korr(buf+EVENT_LEN_OFFSET)));
1435  *error="Sanity check failed"; // Needed to free buffer
1436  DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
1437  }
1438 
1439  uint event_type= buf[EVENT_TYPE_OFFSET];
1440  // all following START events in the current file are without checksum
1441  if (event_type == START_EVENT_V3)
1442  (const_cast< Format_description_log_event *>(description_event))->checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
1443  /*
1444  CRC verification by SQL and Show-Binlog-Events master side.
1445  The caller has to provide @description_event->checksum_alg to
1446  be the last seen FD's (A) descriptor.
1447  If event is FD the descriptor is in it.
1448  Notice, FD of the binlog can be only in one instance and therefore
1449  Show-Binlog-Events executing master side thread needs just to know
1450  the only FD's (A) value - whereas RL can contain more.
1451  In the RL case, the alg is kept in FD_e (@description_event) which is reset
1452  to the newer read-out event after its execution with possibly new alg descriptor.
1453  Therefore in a typical sequence of RL:
1454  {FD_s^0, FD_m, E_m^1} E_m^1
1455  will be verified with (A) of FD_m.
1456 
1457  See legends definition on MYSQL_BIN_LOG::relay_log_checksum_alg docs
1458  lines (log.h).
1459 
1460  Notice, a pre-checksum FD version forces alg := BINLOG_CHECKSUM_ALG_UNDEF.
1461  */
1462  alg= (event_type != FORMAT_DESCRIPTION_EVENT) ?
1463  description_event->checksum_alg : get_checksum_alg(buf, event_len);
1464  // Emulate the corruption during reading an event
1465  DBUG_EXECUTE_IF("corrupt_read_log_event_char",
1466  if (event_type != FORMAT_DESCRIPTION_EVENT)
1467  {
1468  char *debug_event_buf_c = (char *)buf;
1469  int debug_cor_pos = rand() % (event_len - BINLOG_CHECKSUM_LEN);
1470  debug_event_buf_c[debug_cor_pos] =~ debug_event_buf_c[debug_cor_pos];
1471  DBUG_PRINT("info", ("Corrupt the event at Log_event::read_log_event(char*,...): byte on position %d", debug_cor_pos));
1472  DBUG_SET("");
1473  }
1474  );
1475  if (crc_check &&
1476  event_checksum_test((uchar *) buf, event_len, alg))
1477  {
1478  *error= "Event crc check failed! Most likely there is event corruption.";
1479 #ifdef MYSQL_CLIENT
1480  if (force_opt)
1481  {
1482  ev= new Unknown_log_event(buf, description_event);
1483  DBUG_RETURN(ev);
1484  }
1485 #endif
1486  DBUG_RETURN(NULL);
1487  }
1488 
1489  if (event_type > description_event->number_of_event_types &&
1490  event_type != FORMAT_DESCRIPTION_EVENT)
1491  {
1492  /*
1493  It is unsafe to use the description_event if its post_header_len
1494  array does not include the event type.
1495  */
1496  DBUG_PRINT("error", ("event type %d found, but the current "
1497  "Format_description_log_event supports only %d event "
1498  "types", event_type,
1499  description_event->number_of_event_types));
1500  ev= NULL;
1501  }
1502  else
1503  {
1504  /*
1505  In some previuos versions (see comment in
1506  Format_description_log_event::Format_description_log_event(char*,...)),
1507  event types were assigned different id numbers than in the
1508  present version. In order to replicate from such versions to the
1509  present version, we must map those event type id's to our event
1510  type id's. The mapping is done with the event_type_permutation
1511  array, which was set up when the Format_description_log_event
1512  was read.
1513  */
1514  if (description_event->event_type_permutation)
1515  {
1516  int new_event_type= description_event->event_type_permutation[event_type];
1517  DBUG_PRINT("info", ("converting event type %d to %d (%s)",
1518  event_type, new_event_type,
1519  get_type_str((Log_event_type)new_event_type)));
1520  event_type= new_event_type;
1521  }
1522 
1523  if (alg != BINLOG_CHECKSUM_ALG_UNDEF &&
1524  (event_type == FORMAT_DESCRIPTION_EVENT ||
1525  alg != BINLOG_CHECKSUM_ALG_OFF))
1526  event_len= event_len - BINLOG_CHECKSUM_LEN;
1527 
1528  switch(event_type) {
1529  case QUERY_EVENT:
1530  ev = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
1531  break;
1532  case LOAD_EVENT:
1533  ev = new Load_log_event(buf, event_len, description_event);
1534  break;
1535  case NEW_LOAD_EVENT:
1536  ev = new Load_log_event(buf, event_len, description_event);
1537  break;
1538  case ROTATE_EVENT:
1539  ev = new Rotate_log_event(buf, event_len, description_event);
1540  break;
1541  case CREATE_FILE_EVENT:
1542  ev = new Create_file_log_event(buf, event_len, description_event);
1543  break;
1544  case APPEND_BLOCK_EVENT:
1545  ev = new Append_block_log_event(buf, event_len, description_event);
1546  break;
1547  case DELETE_FILE_EVENT:
1548  ev = new Delete_file_log_event(buf, event_len, description_event);
1549  break;
1550  case EXEC_LOAD_EVENT:
1551  ev = new Execute_load_log_event(buf, event_len, description_event);
1552  break;
1553  case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
1554  ev = new Start_log_event_v3(buf, description_event);
1555  break;
1556  case STOP_EVENT:
1557  ev = new Stop_log_event(buf, description_event);
1558  break;
1559  case INTVAR_EVENT:
1560  ev = new Intvar_log_event(buf, description_event);
1561  break;
1562  case XID_EVENT:
1563  ev = new Xid_log_event(buf, description_event);
1564  break;
1565  case RAND_EVENT:
1566  ev = new Rand_log_event(buf, description_event);
1567  break;
1568  case USER_VAR_EVENT:
1569  ev = new User_var_log_event(buf, event_len, description_event);
1570  break;
1571  case FORMAT_DESCRIPTION_EVENT:
1572  ev = new Format_description_log_event(buf, event_len, description_event);
1573  break;
1574 #if defined(HAVE_REPLICATION)
1575  case PRE_GA_WRITE_ROWS_EVENT:
1576  ev = new Write_rows_log_event_old(buf, event_len, description_event);
1577  break;
1578  case PRE_GA_UPDATE_ROWS_EVENT:
1579  ev = new Update_rows_log_event_old(buf, event_len, description_event);
1580  break;
1581  case PRE_GA_DELETE_ROWS_EVENT:
1582  ev = new Delete_rows_log_event_old(buf, event_len, description_event);
1583  break;
1584  case WRITE_ROWS_EVENT_V1:
1585  ev = new Write_rows_log_event(buf, event_len, description_event);
1586  break;
1587  case UPDATE_ROWS_EVENT_V1:
1588  ev = new Update_rows_log_event(buf, event_len, description_event);
1589  break;
1590  case DELETE_ROWS_EVENT_V1:
1591  ev = new Delete_rows_log_event(buf, event_len, description_event);
1592  break;
1593  case TABLE_MAP_EVENT:
1594  ev = new Table_map_log_event(buf, event_len, description_event);
1595  break;
1596 #endif
1597  case BEGIN_LOAD_QUERY_EVENT:
1598  ev = new Begin_load_query_log_event(buf, event_len, description_event);
1599  break;
1600  case EXECUTE_LOAD_QUERY_EVENT:
1601  ev= new Execute_load_query_log_event(buf, event_len, description_event);
1602  break;
1603  case INCIDENT_EVENT:
1604  ev = new Incident_log_event(buf, event_len, description_event);
1605  break;
1606  case ROWS_QUERY_LOG_EVENT:
1607  ev= new Rows_query_log_event(buf, event_len, description_event);
1608  break;
1609  case GTID_LOG_EVENT:
1610  case ANONYMOUS_GTID_LOG_EVENT:
1611  ev= new Gtid_log_event(buf, event_len, description_event);
1612  break;
1613  case PREVIOUS_GTIDS_LOG_EVENT:
1614  ev= new Previous_gtids_log_event(buf, event_len, description_event);
1615  break;
1616 #if defined(HAVE_REPLICATION)
1617  case WRITE_ROWS_EVENT:
1618  ev = new Write_rows_log_event(buf, event_len, description_event);
1619  break;
1620  case UPDATE_ROWS_EVENT:
1621  ev = new Update_rows_log_event(buf, event_len, description_event);
1622  break;
1623  case DELETE_ROWS_EVENT:
1624  ev = new Delete_rows_log_event(buf, event_len, description_event);
1625  break;
1626 #endif
1627  default:
1628  /*
1629  Create an object of Ignorable_log_event for unrecognized sub-class.
1630  So that SLAVE SQL THREAD will only update the position and continue.
1631  */
1632  if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F)
1633  {
1634  ev= new Ignorable_log_event(buf, description_event);
1635  }
1636  else
1637  {
1638  DBUG_PRINT("error",("Unknown event code: %d",
1639  (int) buf[EVENT_TYPE_OFFSET]));
1640  ev= NULL;
1641  }
1642  break;
1643  }
1644  }
1645 
1646  if (ev)
1647  {
1648  ev->checksum_alg= alg;
1649  if (ev->checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1650  ev->checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1651  ev->crc= uint4korr(buf + (event_len));
1652  }
1653 
1654  DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
1655  ev ? ev->get_type_str() : "<unknown>",
1656  buf[EVENT_TYPE_OFFSET],
1657  event_len));
1658  /*
1659  is_valid() are small event-specific sanity tests which are
1660  important; for example there are some my_malloc() in constructors
1661  (e.g. Query_log_event::Query_log_event(char*...)); when these
1662  my_malloc() fail we can't return an error out of the constructor
1663  (because constructor is "void") ; so instead we leave the pointer we
1664  wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1665  Same for Format_description_log_event, member 'post_header_len'.
1666 
1667  SLAVE_EVENT is never used, so it should not be read ever.
1668  */
1669  if (!ev || !ev->is_valid() || (event_type == SLAVE_EVENT))
1670  {
1671  DBUG_PRINT("error",("Found invalid event in binary log"));
1672 
1673  delete ev;
1674 #ifdef MYSQL_CLIENT
1675  if (!force_opt) /* then mysqlbinlog dies */
1676  {
1677  *error= "Found invalid event in binary log";
1678  DBUG_RETURN(0);
1679  }
1680  ev= new Unknown_log_event(buf, description_event);
1681 #else
1682  *error= "Found invalid event in binary log";
1683  DBUG_RETURN(0);
1684 #endif
1685  }
1686  DBUG_RETURN(ev);
1687 }
1688 
1689 #ifdef MYSQL_CLIENT
1690 
1691 /*
1692  Log_event::print_header()
1693 */
1694 
1695 void Log_event::print_header(IO_CACHE* file,
1696  PRINT_EVENT_INFO* print_event_info,
1697  bool is_more __attribute__((unused)))
1698 {
1699  char llbuff[22];
1700  my_off_t hexdump_from= print_event_info->hexdump_from;
1701  DBUG_ENTER("Log_event::print_header");
1702 
1703  my_b_printf(file, "#");
1704  print_timestamp(file, NULL);
1705  my_b_printf(file, " server id %lu end_log_pos %s ", (ulong) server_id,
1706  llstr(log_pos,llbuff));
1707 
1708  /* print the checksum */
1709 
1710  if (checksum_alg != BINLOG_CHECKSUM_ALG_OFF &&
1711  checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF)
1712  {
1713  char checksum_buf[BINLOG_CHECKSUM_LEN * 2 + 4]; // to fit to "0x%lx "
1714  size_t const bytes_written=
1715  my_snprintf(checksum_buf, sizeof(checksum_buf), "0x%08lx ", (ulong) crc);
1716  my_b_printf(file, "%s ", get_type(&binlog_checksum_typelib, checksum_alg));
1717  my_b_printf(file, checksum_buf, bytes_written);
1718  }
1719 
1720  /* mysqlbinlog --hexdump */
1721  if (print_event_info->hexdump_from)
1722  {
1723  my_b_printf(file, "\n");
1724  uchar *ptr= (uchar*)temp_buf;
1725  my_off_t size=
1726  uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1727  my_off_t i;
1728 
1729  /* Header len * 4 >= header len * (2 chars + space + extra space) */
1730  char *h, hex_string[49]= {0};
1731  char *c, char_string[16+1]= {0};
1732 
1733  /* Pretty-print event common header if header is exactly 19 bytes */
1734  if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1735  {
1736  char emit_buf[256]; // Enough for storing one line
1737  my_b_printf(file, "# Position Timestamp Type Master ID "
1738  "Size Master Pos Flags \n");
1739  size_t const bytes_written=
1740  my_snprintf(emit_buf, sizeof(emit_buf),
1741  "# %8.8lx %02x %02x %02x %02x %02x "
1742  "%02x %02x %02x %02x %02x %02x %02x %02x "
1743  "%02x %02x %02x %02x %02x %02x\n",
1744  (unsigned long) hexdump_from,
1745  ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1746  ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1747  ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1748  DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1749  my_b_write(file, (uchar*) emit_buf, bytes_written);
1750  ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1751  hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1752  }
1753 
1754  /* Rest of event (without common header) */
1755  for (i= 0, c= char_string, h=hex_string;
1756  i < size;
1757  i++, ptr++)
1758  {
1759  my_snprintf(h, 4, (i % 16 <= 7) ? "%02x " : " %02x", *ptr);
1760  h += 3;
1761 
1762  *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1763 
1764  if (i % 16 == 15)
1765  {
1766  /*
1767  my_b_printf() does not support full printf() formats, so we
1768  have to do it this way.
1769 
1770  TODO: Rewrite my_b_printf() to support full printf() syntax.
1771  */
1772  char emit_buf[256];
1773  size_t const bytes_written=
1774  my_snprintf(emit_buf, sizeof(emit_buf),
1775  "# %8.8lx %-48.48s |%16s|\n",
1776  (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1777  hex_string, char_string);
1778  DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1779  my_b_write(file, (uchar*) emit_buf, bytes_written);
1780  hex_string[0]= 0;
1781  char_string[0]= 0;
1782  c= char_string;
1783  h= hex_string;
1784  }
1785  }
1786  *c= '\0';
1787  DBUG_ASSERT(hex_string[48] == 0);
1788 
1789  if (hex_string[0])
1790  {
1791  char emit_buf[256];
1792  // Right-pad hex_string with spaces, up to 48 characters.
1793  memset(h, ' ', (sizeof(hex_string) -1) - (h - hex_string));
1794  size_t const bytes_written=
1795  my_snprintf(emit_buf, sizeof(emit_buf),
1796  "# %8.8lx %-48.48s |%s|\n",
1797  (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1798  hex_string, char_string);
1799  DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1800  my_b_write(file, (uchar*) emit_buf, bytes_written);
1801  }
1802  /*
1803  need a # to prefix the rest of printouts for example those of
1804  Rows_log_event::print_helper().
1805  */
1806  my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1807  }
1808  DBUG_VOID_RETURN;
1809 }
1810 
1811 
1822 static void
1823 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length, bool esc_all)
1824 {
1825  const uchar *s;
1826  my_b_printf(file, "'");
1827  for (s= ptr; length > 0 ; s++, length--)
1828  {
1829  if (*s > 0x1F && !esc_all)
1830  my_b_write(file, s, 1);
1831  else
1832  {
1833  uchar hex[10];
1834  size_t len= my_snprintf((char*) hex, sizeof(hex), "%s%02x", "\\x", *s);
1835  my_b_write(file, hex, len);
1836  }
1837  }
1838  my_b_printf(file, "'");
1839 }
1840 
1841 
1842 static void
1843 my_b_write_quoted(IO_CACHE *file, const uchar *ptr, uint length)
1844 {
1845  my_b_write_quoted(file, ptr, length, false);
1846 }
1847 
1848 
1856 static void
1857 my_b_write_bit(IO_CACHE *file, const uchar *ptr, uint nbits)
1858 {
1859  uint bitnum, nbits8= ((nbits + 7) / 8) * 8, skip_bits= nbits8 - nbits;
1860  my_b_printf(file, "b'");
1861  for (bitnum= skip_bits ; bitnum < nbits8; bitnum++)
1862  {
1863  int is_set= (ptr[(bitnum) / 8] >> (7 - bitnum % 8)) & 0x01;
1864  my_b_write(file, (const uchar*) (is_set ? "1" : "0"), 1);
1865  }
1866  my_b_printf(file, "'");
1867 }
1868 
1869 
1881 static size_t
1882 my_b_write_quoted_with_length(IO_CACHE *file, const uchar *ptr, uint length)
1883 {
1884  if (length < 256)
1885  {
1886  length= *ptr;
1887  my_b_write_quoted(file, ptr + 1, length);
1888  return length + 1;
1889  }
1890  else
1891  {
1892  length= uint2korr(ptr);
1893  my_b_write_quoted(file, ptr + 2, length);
1894  return length + 2;
1895  }
1896 }
1897 
1898 
1906 static void
1907 my_b_write_sint32_and_uint32(IO_CACHE *file, int32 si, uint32 ui)
1908 {
1909  my_b_printf(file, "%d", si);
1910  if (si < 0)
1911  my_b_printf(file, " (%u)", ui);
1912 }
1913 
1914 
1927 static size_t
1928 log_event_print_value(IO_CACHE *file, const uchar *ptr,
1929  uint type, uint meta,
1930  char *typestr, size_t typestr_length)
1931 {
1932  uint32 length= 0;
1933 
1934  if (type == MYSQL_TYPE_STRING)
1935  {
1936  if (meta >= 256)
1937  {
1938  uint byte0= meta >> 8;
1939  uint byte1= meta & 0xFF;
1940 
1941  if ((byte0 & 0x30) != 0x30)
1942  {
1943  /* a long CHAR() field: see #37426 */
1944  length= byte1 | (((byte0 & 0x30) ^ 0x30) << 4);
1945  type= byte0 | 0x30;
1946  }
1947  else
1948  length = meta & 0xFF;
1949  }
1950  else
1951  length= meta;
1952  }
1953 
1954  switch (type) {
1955  case MYSQL_TYPE_LONG:
1956  {
1957  int32 si= sint4korr(ptr);
1958  uint32 ui= uint4korr(ptr);
1959  my_b_write_sint32_and_uint32(file, si, ui);
1960  my_snprintf(typestr, typestr_length, "INT");
1961  return 4;
1962  }
1963 
1964  case MYSQL_TYPE_TINY:
1965  {
1966  my_b_write_sint32_and_uint32(file, (int) (signed char) *ptr,
1967  (uint) (unsigned char) *ptr);
1968  my_snprintf(typestr, typestr_length, "TINYINT");
1969  return 1;
1970  }
1971 
1972  case MYSQL_TYPE_SHORT:
1973  {
1974  int32 si= (int32) sint2korr(ptr);
1975  uint32 ui= (uint32) uint2korr(ptr);
1976  my_b_write_sint32_and_uint32(file, si, ui);
1977  my_snprintf(typestr, typestr_length, "SHORTINT");
1978  return 2;
1979  }
1980 
1981  case MYSQL_TYPE_INT24:
1982  {
1983  int32 si= sint3korr(ptr);
1984  uint32 ui= uint3korr(ptr);
1985  my_b_write_sint32_and_uint32(file, si, ui);
1986  my_snprintf(typestr, typestr_length, "MEDIUMINT");
1987  return 3;
1988  }
1989 
1990  case MYSQL_TYPE_LONGLONG:
1991  {
1992  char tmp[64];
1993  longlong si= sint8korr(ptr);
1994  longlong10_to_str(si, tmp, -10);
1995  my_b_printf(file, "%s", tmp);
1996  if (si < 0)
1997  {
1998  ulonglong ui= uint8korr(ptr);
1999  longlong10_to_str((longlong) ui, tmp, 10);
2000  my_b_printf(file, " (%s)", tmp);
2001  }
2002  my_snprintf(typestr, typestr_length, "LONGINT");
2003  return 8;
2004  }
2005 
2006  case MYSQL_TYPE_NEWDECIMAL:
2007  {
2008  uint precision= meta >> 8;
2009  uint decimals= meta & 0xFF;
2010  uint bin_size= my_decimal_get_binary_size(precision, decimals);
2011  my_decimal dec;
2012  binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) ptr, &dec,
2013  precision, decimals);
2014  int i, end;
2015  char buff[512], *pos;
2016  pos= buff;
2017  pos+= sprintf(buff, "%s", dec.sign() ? "-" : "");
2018  end= ROUND_UP(dec.frac) + ROUND_UP(dec.intg)-1;
2019  for (i=0; i < end; i++)
2020  pos+= sprintf(pos, "%09d.", dec.buf[i]);
2021  pos+= sprintf(pos, "%09d", dec.buf[i]);
2022  my_b_printf(file, "%s", buff);
2023  my_snprintf(typestr, typestr_length, "DECIMAL(%d,%d)",
2024  precision, decimals);
2025  return bin_size;
2026  }
2027 
2028  case MYSQL_TYPE_FLOAT:
2029  {
2030  float fl;
2031  float4get(fl, ptr);
2032  char tmp[320];
2033  sprintf(tmp, "%-20g", (double) fl);
2034  my_b_printf(file, "%s", tmp); /* my_snprintf doesn't support %-20g */
2035  my_snprintf(typestr, typestr_length, "FLOAT");
2036  return 4;
2037  }
2038 
2039  case MYSQL_TYPE_DOUBLE:
2040  {
2041  double dbl;
2042  float8get(dbl, ptr);
2043  char tmp[320];
2044  sprintf(tmp, "%-.20g", dbl); /* my_snprintf doesn't support %-20g */
2045  my_b_printf(file, "%s", tmp);
2046  strcpy(typestr, "DOUBLE");
2047  return 8;
2048  }
2049 
2050  case MYSQL_TYPE_BIT:
2051  {
2052  /* Meta-data: bit_len, bytes_in_rec, 2 bytes */
2053  uint nbits= ((meta >> 8) * 8) + (meta & 0xFF);
2054  length= (nbits + 7) / 8;
2055  my_b_write_bit(file, ptr, nbits);
2056  my_snprintf(typestr, typestr_length, "BIT(%d)", nbits);
2057  return length;
2058  }
2059 
2060  case MYSQL_TYPE_TIMESTAMP:
2061  {
2062  uint32 i32= uint4korr(ptr);
2063  my_b_printf(file, "%d", i32);
2064  my_snprintf(typestr, typestr_length, "TIMESTAMP");
2065  return 4;
2066  }
2067 
2068  case MYSQL_TYPE_TIMESTAMP2:
2069  {
2070  char buf[MAX_DATE_STRING_REP_LENGTH];
2071  struct timeval tm;
2072  my_timestamp_from_binary(&tm, ptr, meta);
2073  int buflen= my_timeval_to_str(&tm, buf, meta);
2074  my_b_write(file, buf, buflen);
2075  my_snprintf(typestr, typestr_length, "TIMESTAMP(%d)", meta);
2076  return my_timestamp_binary_length(meta);
2077  }
2078 
2079  case MYSQL_TYPE_DATETIME:
2080  {
2081  size_t d, t;
2082  uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */
2083  d= i64 / 1000000;
2084  t= i64 % 1000000;
2085  my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d",
2086  static_cast<int>(d / 10000),
2087  static_cast<int>(d % 10000) / 100,
2088  static_cast<int>(d % 100),
2089  static_cast<int>(t / 10000),
2090  static_cast<int>(t % 10000) / 100,
2091  static_cast<int>(t % 100));
2092  my_snprintf(typestr, typestr_length, "DATETIME");
2093  return 8;
2094  }
2095 
2096  case MYSQL_TYPE_DATETIME2:
2097  {
2098  char buf[MAX_DATE_STRING_REP_LENGTH];
2099  MYSQL_TIME ltime;
2100  longlong packed= my_datetime_packed_from_binary(ptr, meta);
2101  TIME_from_longlong_datetime_packed(&ltime, packed);
2102  int buflen= my_datetime_to_str(&ltime, buf, meta);
2103  my_b_write_quoted(file, (uchar *) buf, buflen);
2104  my_snprintf(typestr, typestr_length, "DATETIME(%d)", meta);
2105  return my_datetime_binary_length(meta);
2106  }
2107 
2108  case MYSQL_TYPE_TIME:
2109  {
2110  uint32 i32= uint3korr(ptr);
2111  my_b_printf(file, "'%02d:%02d:%02d'",
2112  i32 / 10000, (i32 % 10000) / 100, i32 % 100);
2113  my_snprintf(typestr, typestr_length, "TIME");
2114  return 3;
2115  }
2116 
2117  case MYSQL_TYPE_TIME2:
2118  {
2119  char buf[MAX_DATE_STRING_REP_LENGTH];
2120  MYSQL_TIME ltime;
2121  longlong packed= my_time_packed_from_binary(ptr, meta);
2122  TIME_from_longlong_time_packed(&ltime, packed);
2123  int buflen= my_time_to_str(&ltime, buf, meta);
2124  my_b_write_quoted(file, (uchar *) buf, buflen);
2125  my_snprintf(typestr, typestr_length, "TIME(%d)", meta);
2126  return my_time_binary_length(meta);
2127  }
2128 
2129  case MYSQL_TYPE_NEWDATE:
2130  {
2131  uint32 tmp= uint3korr(ptr);
2132  int part;
2133  char buf[11];
2134  char *pos= &buf[10]; // start from '\0' to the beginning
2135 
2136  /* Copied from field.cc */
2137  *pos--=0; // End NULL
2138  part=(int) (tmp & 31);
2139  *pos--= (char) ('0'+part%10);
2140  *pos--= (char) ('0'+part/10);
2141  *pos--= ':';
2142  part=(int) (tmp >> 5 & 15);
2143  *pos--= (char) ('0'+part%10);
2144  *pos--= (char) ('0'+part/10);
2145  *pos--= ':';
2146  part=(int) (tmp >> 9);
2147  *pos--= (char) ('0'+part%10); part/=10;
2148  *pos--= (char) ('0'+part%10); part/=10;
2149  *pos--= (char) ('0'+part%10); part/=10;
2150  *pos= (char) ('0'+part);
2151  my_b_printf(file , "'%s'", buf);
2152  my_snprintf(typestr, typestr_length, "DATE");
2153  return 3;
2154  }
2155 
2156  case MYSQL_TYPE_YEAR:
2157  {
2158  uint32 i32= *ptr;
2159  my_b_printf(file, "%04d", i32+ 1900);
2160  my_snprintf(typestr, typestr_length, "YEAR");
2161  return 1;
2162  }
2163 
2164  case MYSQL_TYPE_ENUM:
2165  switch (meta & 0xFF) {
2166  case 1:
2167  my_b_printf(file, "%d", (int) *ptr);
2168  my_snprintf(typestr, typestr_length, "ENUM(1 byte)");
2169  return 1;
2170  case 2:
2171  {
2172  int32 i32= uint2korr(ptr);
2173  my_b_printf(file, "%d", i32);
2174  my_snprintf(typestr, typestr_length, "ENUM(2 bytes)");
2175  return 2;
2176  }
2177  default:
2178  my_b_printf(file, "!! Unknown ENUM packlen=%d", meta & 0xFF);
2179  return 0;
2180  }
2181  break;
2182 
2183  case MYSQL_TYPE_SET:
2184  my_b_write_bit(file, ptr , (meta & 0xFF) * 8);
2185  my_snprintf(typestr, typestr_length, "SET(%d bytes)", meta & 0xFF);
2186  return meta & 0xFF;
2187 
2188  case MYSQL_TYPE_BLOB:
2189  switch (meta) {
2190  case 1:
2191  length= *ptr;
2192  my_b_write_quoted(file, ptr + 1, length);
2193  my_snprintf(typestr, typestr_length, "TINYBLOB/TINYTEXT");
2194  return length + 1;
2195  case 2:
2196  length= uint2korr(ptr);
2197  my_b_write_quoted(file, ptr + 2, length);
2198  my_snprintf(typestr, typestr_length, "BLOB/TEXT");
2199  return length + 2;
2200  case 3:
2201  length= uint3korr(ptr);
2202  my_b_write_quoted(file, ptr + 3, length);
2203  my_snprintf(typestr, typestr_length, "MEDIUMBLOB/MEDIUMTEXT");
2204  return length + 3;
2205  case 4:
2206  length= uint4korr(ptr);
2207  my_b_write_quoted(file, ptr + 4, length);
2208  my_snprintf(typestr, typestr_length, "LONGBLOB/LONGTEXT");
2209  return length + 4;
2210  default:
2211  my_b_printf(file, "!! Unknown BLOB packlen=%d", length);
2212  return 0;
2213  }
2214 
2215  case MYSQL_TYPE_VARCHAR:
2216  case MYSQL_TYPE_VAR_STRING:
2217  length= meta;
2218  my_snprintf(typestr, typestr_length, "VARSTRING(%d)", length);
2219  return my_b_write_quoted_with_length(file, ptr, length);
2220 
2221  case MYSQL_TYPE_STRING:
2222  my_snprintf(typestr, typestr_length, "STRING(%d)", length);
2223  return my_b_write_quoted_with_length(file, ptr, length);
2224 
2225  default:
2226  {
2227  char tmp[5];
2228  my_snprintf(tmp, sizeof(tmp), "%04x", meta);
2229  my_b_printf(file,
2230  "!! Don't know how to handle column type=%d meta=%d (%s)",
2231  type, meta, tmp);
2232  }
2233  break;
2234  }
2235  *typestr= 0;
2236  return 0;
2237 }
2238 
2239 
2254 size_t
2255 Rows_log_event::print_verbose_one_row(IO_CACHE *file, table_def *td,
2256  PRINT_EVENT_INFO *print_event_info,
2257  MY_BITMAP *cols_bitmap,
2258  const uchar *value, const uchar *prefix)
2259 {
2260  const uchar *value0= value;
2261  const uchar *null_bits= value;
2262  uint null_bit_index= 0;
2263  char typestr[64]= "";
2264 
2265  value+= (m_width + 7) / 8;
2266 
2267  my_b_printf(file, "%s", prefix);
2268 
2269  for (size_t i= 0; i < td->size(); i ++)
2270  {
2271  int is_null= (null_bits[null_bit_index / 8]
2272  >> (null_bit_index % 8)) & 0x01;
2273 
2274  if (bitmap_is_set(cols_bitmap, i) == 0)
2275  continue;
2276 
2277  if (is_null)
2278  {
2279  my_b_printf(file, "### @%d=NULL", static_cast<int>(i + 1));
2280  }
2281  else
2282  {
2283  my_b_printf(file, "### @%d=", static_cast<int>(i + 1));
2284  size_t size= log_event_print_value(file, value,
2285  td->type(i), td->field_metadata(i),
2286  typestr, sizeof(typestr));
2287  if (!size)
2288  return 0;
2289 
2290  value+= size;
2291  }
2292 
2293  if (print_event_info->verbose > 1)
2294  {
2295  my_b_printf(file, " /* ");
2296 
2297  if (typestr[0])
2298  my_b_printf(file, "%s ", typestr);
2299  else
2300  my_b_printf(file, "type=%d ", td->type(i));
2301 
2302  my_b_printf(file, "meta=%d nullable=%d is_null=%d ",
2303  td->field_metadata(i),
2304  td->maybe_null(i), is_null);
2305  my_b_printf(file, "*/");
2306  }
2307 
2308  my_b_printf(file, "\n");
2309 
2310  null_bit_index++;
2311  }
2312  return value - value0;
2313 }
2314 
2315 
2322 void Rows_log_event::print_verbose(IO_CACHE *file,
2323  PRINT_EVENT_INFO *print_event_info)
2324 {
2325  // Quoted length of the identifier can be twice the original length
2326  char quoted_db[1 + NAME_LEN * 2 + 2];
2327  char quoted_table[1 + NAME_LEN * 2 + 2];
2328  int quoted_db_len, quoted_table_len;
2329  Table_map_log_event *map;
2330  table_def *td;
2331  const char *sql_command, *sql_clause1, *sql_clause2;
2332  Log_event_type general_type_code= get_general_type_code();
2333 
2334  if (m_extra_row_data)
2335  {
2336  uint8 extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
2337  uint8 extra_payload_len= extra_data_len - EXTRA_ROW_INFO_HDR_BYTES;
2338  assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
2339 
2340  my_b_printf(file, "### Extra row data format: %u, len: %u :",
2341  m_extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET],
2342  extra_payload_len);
2343  if (extra_payload_len)
2344  {
2345  /*
2346  Buffer for hex view of string, including '0x' prefix,
2347  2 hex chars / byte and trailing 0
2348  */
2349  const int buff_len= 2 + (256 * 2) + 1;
2350  char buff[buff_len];
2351  str_to_hex(buff, (const char*) &m_extra_row_data[EXTRA_ROW_INFO_HDR_BYTES],
2352  extra_payload_len);
2353  my_b_printf(file, "%s", buff);
2354  }
2355  my_b_printf(file, "\n");
2356  }
2357 
2358  switch (general_type_code) {
2359  case WRITE_ROWS_EVENT:
2360  sql_command= "INSERT INTO";
2361  sql_clause1= "### SET\n";
2362  sql_clause2= NULL;
2363  break;
2364  case DELETE_ROWS_EVENT:
2365  sql_command= "DELETE FROM";
2366  sql_clause1= "### WHERE\n";
2367  sql_clause2= NULL;
2368  break;
2369  case UPDATE_ROWS_EVENT:
2370  sql_command= "UPDATE";
2371  sql_clause1= "### WHERE\n";
2372  sql_clause2= "### SET\n";
2373  break;
2374  default:
2375  sql_command= sql_clause1= sql_clause2= NULL;
2376  DBUG_ASSERT(0); /* Not possible */
2377  }
2378 
2379  if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
2380  !(td= map->create_table_def()))
2381  {
2382  char llbuff[22];
2383  my_b_printf(file, "### Row event for unknown table #%s",
2384  llstr(m_table_id, llbuff));
2385  return;
2386  }
2387 
2388  /* If the write rows event contained no values for the AI */
2389  if (((general_type_code == WRITE_ROWS_EVENT) && (m_rows_buf==m_rows_end)))
2390  {
2391  my_b_printf(file, "### INSERT INTO `%s`.`%s` VALUES ()\n",
2392  map->get_db_name(), map->get_table_name());
2393  goto end;
2394  }
2395 
2396  for (const uchar *value= m_rows_buf; value < m_rows_end; )
2397  {
2398  size_t length;
2399 #ifdef MYSQL_SERVER
2400  quoted_db_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_db,
2401  map->get_db_name(), 0);
2402  quoted_table_len= my_strmov_quoted_identifier(this->thd,
2403  (char *) quoted_table,
2404  map->get_table_name(), 0);
2405 #else
2406  quoted_db_len= my_strmov_quoted_identifier((char *) quoted_db,
2407  map->get_db_name());
2408  quoted_table_len= my_strmov_quoted_identifier((char *) quoted_table,
2409  map->get_table_name());
2410 #endif
2411  quoted_db[quoted_db_len]= '\0';
2412  quoted_table[quoted_table_len]= '\0';
2413  my_b_printf(file, "### %s %s.%s\n",
2414  sql_command,
2415  quoted_db, quoted_table);
2416  /* Print the first image */
2417  if (!(length= print_verbose_one_row(file, td, print_event_info,
2418  &m_cols, value,
2419  (const uchar*) sql_clause1)))
2420  goto end;
2421  value+= length;
2422 
2423  /* Print the second image (for UPDATE only) */
2424  if (sql_clause2)
2425  {
2426  if (!(length= print_verbose_one_row(file, td, print_event_info,
2427  &m_cols_ai, value,
2428  (const uchar*) sql_clause2)))
2429  goto end;
2430  value+= length;
2431  }
2432  }
2433 
2434 end:
2435  delete td;
2436 }
2437 
2438 #ifdef MYSQL_CLIENT
2439 void free_table_map_log_event(Table_map_log_event *event)
2440 {
2441  delete event;
2442 }
2443 #endif
2444 
2445 void Log_event::print_base64(IO_CACHE* file,
2446  PRINT_EVENT_INFO* print_event_info,
2447  bool more)
2448 {
2449  const uchar *ptr= (const uchar *)temp_buf;
2450  uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
2451  DBUG_ENTER("Log_event::print_base64");
2452 
2453  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
2454  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
2455  if (!tmp_str) {
2456  fprintf(stderr, "\nError: Out of memory. "
2457  "Could not print correct binlog event.\n");
2458  DBUG_VOID_RETURN;
2459  }
2460 
2461  if (base64_encode(ptr, (size_t) size, tmp_str))
2462  {
2463  DBUG_ASSERT(0);
2464  }
2465 
2466  if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
2467  {
2468  if (my_b_tell(file) == 0)
2469  my_b_printf(file, "\nBINLOG '\n");
2470 
2471  my_b_printf(file, "%s\n", tmp_str);
2472 
2473  if (!more)
2474  my_b_printf(file, "'%s\n", print_event_info->delimiter);
2475  }
2476 
2477  if (print_event_info->verbose)
2478  {
2479  Rows_log_event *ev= NULL;
2480  Log_event_type et= (Log_event_type) ptr[EVENT_TYPE_OFFSET];
2481 
2482  if (checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF &&
2483  checksum_alg != BINLOG_CHECKSUM_ALG_OFF)
2484  size-= BINLOG_CHECKSUM_LEN; // checksum is displayed through the header
2485 
2486  switch(et)
2487  {
2488  case TABLE_MAP_EVENT:
2489  {
2490  Table_map_log_event *map;
2491  map= new Table_map_log_event((const char*) ptr, size,
2492  glob_description_event);
2493  print_event_info->m_table_map.set_table(map->get_table_id(), map);
2494  break;
2495  }
2496  case WRITE_ROWS_EVENT:
2497  case WRITE_ROWS_EVENT_V1:
2498  {
2499  ev= new Write_rows_log_event((const char*) ptr, size,
2500  glob_description_event);
2501  break;
2502  }
2503  case DELETE_ROWS_EVENT:
2504  case DELETE_ROWS_EVENT_V1:
2505  {
2506  ev= new Delete_rows_log_event((const char*) ptr, size,
2507  glob_description_event);
2508  break;
2509  }
2510  case UPDATE_ROWS_EVENT:
2511  case UPDATE_ROWS_EVENT_V1:
2512  {
2513  ev= new Update_rows_log_event((const char*) ptr, size,
2514  glob_description_event);
2515  break;
2516  }
2517  default:
2518  break;
2519  }
2520 
2521  if (ev)
2522  {
2523  ev->print_verbose(file, print_event_info);
2524  delete ev;
2525  }
2526  }
2527 
2528  my_free(tmp_str);
2529  DBUG_VOID_RETURN;
2530 }
2531 
2532 
2533 /*
2534  Log_event::print_timestamp()
2535 */
2536 
2537 void Log_event::print_timestamp(IO_CACHE* file, time_t *ts)
2538 {
2539  struct tm *res;
2540  /*
2541  In some Windows versions timeval.tv_sec is defined as "long",
2542  not as "time_t" and can be of a different size.
2543  Let's use a temporary time_t variable to execute localtime()
2544  with a correct argument type.
2545  */
2546  time_t ts_tmp= ts ? *ts : (ulong)when.tv_sec;
2547  DBUG_ENTER("Log_event::print_timestamp");
2548 #ifdef MYSQL_SERVER // This is always false
2549  struct tm tm_tmp;
2550  localtime_r(&ts_tmp, (res= &tm_tmp));
2551 #else
2552  res= localtime(&ts_tmp);
2553 #endif
2554 
2555  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
2556  res->tm_year % 100,
2557  res->tm_mon+1,
2558  res->tm_mday,
2559  res->tm_hour,
2560  res->tm_min,
2561  res->tm_sec);
2562  DBUG_VOID_RETURN;
2563 }
2564 
2565 #endif /* MYSQL_CLIENT */
2566 
2567 
2568 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
2570 Log_event::continue_group(Relay_log_info *rli)
2571 {
2572  if (rli->slave_skip_counter == 1)
2574  return Log_event::do_shall_skip(rli);
2575 }
2576 
2591 bool Log_event::contains_partition_info(bool end_group_sets_max_dbs)
2592 {
2593  bool res;
2594 
2595  switch (get_type_code()) {
2596  case TABLE_MAP_EVENT:
2597  case EXECUTE_LOAD_QUERY_EVENT:
2598  res= true;
2599 
2600  break;
2601 
2602  case QUERY_EVENT:
2603  if (ends_group() && end_group_sets_max_dbs)
2604  {
2605  res= true;
2606  static_cast<Query_log_event*>(this)->mts_accessed_dbs=
2607  OVER_MAX_DBS_IN_EVENT_MTS;
2608  }
2609  else
2610  res= (!ends_group() && !starts_group()) ? true : false;
2611 
2612  break;
2613 
2614  default:
2615  res= false;
2616  }
2617 
2618  return res;
2619 }
2620 
2658 Slave_worker *Log_event::get_slave_worker(Relay_log_info *rli)
2659 {
2660  Slave_job_group group, *ptr_group= NULL;
2661  bool is_s_event;
2662  int num_dbs= 0;
2663  Slave_worker *ret_worker= NULL;
2664  char llbuff[22];
2665 #ifndef DBUG_OFF
2666  THD *thd= rli->info_thd;
2667 #endif
2668  Slave_committed_queue *gaq= rli->gaq;
2669 
2670  /* checking partioning properties and perform corresponding actions */
2671 
2672  // Beginning of a group designated explicitly with BEGIN or GTID
2673  if ((is_s_event= starts_group()) || is_gtid_event(this) ||
2674  // or DDL:s or autocommit queries possibly associated with own p-events
2675  (!rli->curr_group_seen_begin && !rli->curr_group_seen_gtid &&
2676  /*
2677  the following is a special case of B-free still multi-event group like
2678  { p_1,p_2,...,p_k, g }.
2679  In that case either GAQ is empty (the very first group is being
2680  assigned) or the last assigned group index points at one of
2681  mapped-to-a-worker.
2682  */
2683  (gaq->empty() ||
2684  gaq->get_job_group(rli->gaq->assigned_group_index)->
2685  worker_id != MTS_WORKER_UNDEF)))
2686  {
2687  if (!rli->curr_group_seen_gtid && !rli->curr_group_seen_begin)
2688  {
2689  ulong gaq_idx;
2690  rli->mts_groups_assigned++;
2691 
2692  rli->curr_group_isolated= FALSE;
2693  group.reset(log_pos, rli->mts_groups_assigned);
2694  // the last occupied GAQ's array index
2695  gaq_idx= gaq->assigned_group_index= gaq->en_queue((void *) &group);
2696 
2697  DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF && gaq_idx < gaq->size);
2698  DBUG_ASSERT(gaq->get_job_group(rli->gaq->assigned_group_index)->
2699  group_relay_log_name == NULL);
2700  DBUG_ASSERT(gaq_idx != MTS_WORKER_UNDEF); // gaq must have room
2701  DBUG_ASSERT(rli->last_assigned_worker == NULL);
2702 
2703  if (is_s_event || is_gtid_event(this))
2704  {
2705  Log_event *ptr_curr_ev= this;
2706  // B-event is appended to the Deferred Array associated with GCAP
2707  insert_dynamic(&rli->curr_group_da,
2708  (uchar*) &ptr_curr_ev);
2709 
2710  DBUG_ASSERT(rli->curr_group_da.elements == 1);
2711 
2712  if (starts_group())
2713  {
2714  // mark the current group as started with explicit B-event
2715  rli->mts_end_group_sets_max_dbs= true;
2716  rli->curr_group_seen_begin= true;
2717  }
2718 
2719  if (is_gtid_event(this))
2720  // mark the current group as started with explicit Gtid-event
2721  rli->curr_group_seen_gtid= true;
2722 
2723  return ret_worker;
2724  }
2725  }
2726  else
2727  {
2728  Log_event *ptr_curr_ev= this;
2729  // B-event is appended to the Deferred Array associated with GCAP
2730  insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2731  rli->curr_group_seen_begin= true;
2732  rli->mts_end_group_sets_max_dbs= true;
2733  DBUG_ASSERT(rli->curr_group_da.elements == 2);
2734  DBUG_ASSERT(starts_group());
2735  return ret_worker;
2736  }
2737  }
2738 
2739  // mini-group representative
2740 
2741  if (contains_partition_info(rli->mts_end_group_sets_max_dbs))
2742  {
2743  int i= 0;
2744  num_dbs= mts_number_dbs();
2745  List_iterator<char> it(*get_mts_dbs(&rli->mts_coor_mem_root));
2746  it++;
2747 
2748  /*
2749  Bug 12982188 - MTS: SBR ABORTS WITH ERROR 1742 ON LOAD DATA
2750  Logging on master can create a group with no events holding
2751  the partition info.
2752  The following assert proves there's the only reason
2753  for such group.
2754  */
2755  DBUG_ASSERT(!ends_group() ||
2756  /*
2757  This is an empty group being processed due to gtids.
2758  */
2759  (rli->curr_group_seen_begin && rli->curr_group_seen_gtid &&
2760  ends_group()) ||
2761  (rli->mts_end_group_sets_max_dbs &&
2762  ((rli->curr_group_da.elements == 3 && rli->curr_group_seen_gtid) ||
2763  (rli->curr_group_da.elements == 2 && !rli->curr_group_seen_gtid)) &&
2764  ((*(Log_event **)
2765  dynamic_array_ptr(&rli->curr_group_da,
2766  rli->curr_group_da.elements - 1))->
2767  get_type_code() == BEGIN_LOAD_QUERY_EVENT)));
2768 
2769  // partioning info is found which drops the flag
2770  rli->mts_end_group_sets_max_dbs= false;
2771  ret_worker= rli->last_assigned_worker;
2772  if (num_dbs == OVER_MAX_DBS_IN_EVENT_MTS)
2773  {
2774  // Worker with id 0 to handle serial execution
2775  if (!ret_worker)
2776  ret_worker= *(Slave_worker**) dynamic_array_ptr(&rli->workers, 0);
2777  // No need to know a possible error out of synchronization call.
2778  (void) wait_for_workers_to_finish(rli, ret_worker);
2779  /*
2780  this marking is transferred further into T-event of the current group.
2781  */
2782  rli->curr_group_isolated= TRUE;
2783  }
2784 
2785  do
2786  {
2787  char **ref_cur_db= it.ref();
2788 
2789  if (!(ret_worker=
2790  map_db_to_worker(*ref_cur_db, rli,
2791  &mts_assigned_partitions[i],
2792  /*
2793  todo: optimize it. Although pure
2794  rows- event load in insensetive to the flag value
2795  */
2796  TRUE,
2797  ret_worker)))
2798  {
2799  llstr(rli->get_event_relay_log_pos(), llbuff);
2800  my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2801  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2802  "could not distribute the event to a Worker");
2803  return ret_worker;
2804  }
2805  // all temporary tables are transferred from Coordinator in over-max case
2806  DBUG_ASSERT(num_dbs != OVER_MAX_DBS_IN_EVENT_MTS || !thd->temporary_tables);
2807  DBUG_ASSERT(!strcmp(mts_assigned_partitions[i]->db, *ref_cur_db));
2808  DBUG_ASSERT(ret_worker == mts_assigned_partitions[i]->worker);
2809  DBUG_ASSERT(mts_assigned_partitions[i]->usage >= 0);
2810 
2811  i++;
2812  } while (it++);
2813 
2814  if ((ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index))->
2815  worker_id == MTS_WORKER_UNDEF)
2816  {
2817  ptr_group->worker_id= ret_worker->id;
2818 
2819  DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2820  }
2821 
2822  DBUG_ASSERT(i == num_dbs || num_dbs == OVER_MAX_DBS_IN_EVENT_MTS);
2823  }
2824  else
2825  {
2826  // a mini-group internal "regular" event
2827  if (rli->last_assigned_worker)
2828  {
2829  ret_worker= rli->last_assigned_worker;
2830 
2831  DBUG_ASSERT(rli->curr_group_assigned_parts.elements > 0 ||
2832  ret_worker->id == 0);
2833  }
2834  else // int_, rand_, user_ var:s, load-data events
2835  {
2836  Log_event *ptr_curr_ev= this;
2837 
2838  if (!(get_type_code() == INTVAR_EVENT ||
2839  get_type_code() == RAND_EVENT ||
2840  get_type_code() == USER_VAR_EVENT ||
2841  get_type_code() == ROWS_QUERY_LOG_EVENT ||
2842  get_type_code() == BEGIN_LOAD_QUERY_EVENT ||
2843  get_type_code() == APPEND_BLOCK_EVENT))
2844  {
2845  DBUG_ASSERT(!ret_worker);
2846 
2847  llstr(rli->get_event_relay_log_pos(), llbuff);
2848  my_error(ER_MTS_CANT_PARALLEL, MYF(0),
2849  get_type_str(), rli->get_event_relay_log_name(), llbuff,
2850  "the event is a part of a group that is unsupported in "
2851  "the parallel execution mode");
2852 
2853  return ret_worker;
2854  }
2855 
2856  insert_dynamic(&rli->curr_group_da, (uchar*) &ptr_curr_ev);
2857 
2858  DBUG_ASSERT(!ret_worker);
2859  return ret_worker;
2860  }
2861  }
2862 
2863  DBUG_ASSERT(ret_worker);
2864 
2865  /*
2866  Preparing event physical coordinates info for Worker before any
2867  event got scheduled so when Worker error-stopped at the first
2868  event it would be aware of where exactly in the event stream.
2869  */
2870  if (!ret_worker->master_log_change_notified)
2871  {
2872  if (!ptr_group)
2873  ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2874  ptr_group->group_master_log_name=
2875  my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2876  ret_worker->master_log_change_notified= true;
2877 
2878  DBUG_ASSERT(!ptr_group->notified);
2879 #ifndef DBUG_OFF
2880  ptr_group->notified= true;
2881 #endif
2882  }
2883 
2884  // T-event: Commit, Xid, a DDL query or dml query of B-less group.
2885  if (ends_group() || !rli->curr_group_seen_begin)
2886  {
2887  rli->mts_group_status= Relay_log_info::MTS_END_GROUP;
2888  if (rli->curr_group_isolated)
2889  set_mts_isolate_group();
2890  if (!ptr_group)
2891  ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2892 
2893  DBUG_ASSERT(ret_worker != NULL);
2894 
2895  /*
2896  The following two blocks are executed if the worker has not been
2897  notified about new relay-log or a new checkpoints.
2898  Relay-log string is freed by Coordinator, Worker deallocates
2899  strings in the checkpoint block.
2900  However if the worker exits earlier reclaiming for both happens anyway at
2901  GAQ delete.
2902  */
2903  if (!ret_worker->relay_log_change_notified)
2904  {
2905  /*
2906  Prior this event, C rotated the relay log to drop each
2907  Worker's notified flag. Now group terminating event initiates
2908  the new relay-log (where the current event is from) name
2909  delivery to Worker that will receive it in commit_positions().
2910  */
2911  DBUG_ASSERT(ptr_group->group_relay_log_name == NULL);
2912 
2913  ptr_group->group_relay_log_name= (char *)
2914  my_malloc(strlen(rli->
2915  get_group_relay_log_name()) + 1, MYF(MY_WME));
2916  strcpy(ptr_group->group_relay_log_name,
2917  rli->get_event_relay_log_name());
2918 
2919  DBUG_ASSERT(ptr_group->group_relay_log_name != NULL);
2920 
2921  ret_worker->relay_log_change_notified= TRUE;
2922  }
2923 
2924  if (!ret_worker->checkpoint_notified)
2925  {
2926  if (!ptr_group)
2927  ptr_group= gaq->get_job_group(rli->gaq->assigned_group_index);
2928  ptr_group->checkpoint_log_name=
2929  my_strdup(rli->get_group_master_log_name(), MYF(MY_WME));
2930  ptr_group->checkpoint_log_pos= rli->get_group_master_log_pos();
2931  ptr_group->checkpoint_relay_log_name=
2932  my_strdup(rli->get_group_relay_log_name(), MYF(MY_WME));
2933  ptr_group->checkpoint_relay_log_pos= rli->get_group_relay_log_pos();
2934  ptr_group->shifted= ret_worker->bitmap_shifted;
2935  ret_worker->bitmap_shifted= 0;
2936  ret_worker->checkpoint_notified= TRUE;
2937  }
2938  ptr_group->checkpoint_seqno= rli->checkpoint_seqno;
2939  ptr_group->ts= when.tv_sec + (time_t) exec_time; // Seconds_behind_master related
2940  rli->checkpoint_seqno++;
2941 
2942  // reclaiming resources allocated during the group scheduling
2943  free_root(&rli->mts_coor_mem_root, MYF(MY_KEEP_PREALLOC));
2944 
2945 #ifndef DBUG_OFF
2946  w_rr++;
2947 #endif
2948 
2949  }
2950 
2951  return ret_worker;
2952 }
2953 
2966 int Log_event::apply_event(Relay_log_info *rli)
2967 {
2968  DBUG_ENTER("LOG_EVENT:apply_event");
2969  bool parallel= FALSE;
2970  enum enum_mts_event_exec_mode actual_exec_mode= EVENT_EXEC_PARALLEL;
2971  THD *thd= rli->info_thd;
2972 
2973  worker= rli;
2974 
2975  if (rli->is_mts_recovery())
2976  {
2977  bool skip=
2978  bitmap_is_set(&rli->recovery_groups, rli->mts_recovery_index) &&
2979  (get_mts_execution_mode(::server_id,
2980  rli->mts_group_status == Relay_log_info::MTS_IN_GROUP)
2981  == EVENT_EXEC_PARALLEL);
2982  if (skip)
2983  {
2984  DBUG_RETURN(0);
2985  }
2986  else
2987  {
2988  DBUG_RETURN(do_apply_event(rli));
2989  }
2990  }
2991 
2992  if (!(parallel= rli->is_parallel_exec()) ||
2993  ((actual_exec_mode=
2994  get_mts_execution_mode(::server_id,
2995  rli->mts_group_status == Relay_log_info::MTS_IN_GROUP))
2996  != EVENT_EXEC_PARALLEL))
2997  {
2998  if (parallel)
2999  {
3000  /*
3001  There are two classes of events that Coordinator executes
3002  itself. One e.g the master Rotate requires all Workers to finish up
3003  their assignments. The other async class, e.g the slave Rotate,
3004  can't have this such synchronization because Worker might be waiting
3005  for terminal events to finish.
3006  */
3007 
3008  if (actual_exec_mode != EVENT_EXEC_ASYNC)
3009  {
3010  /*
3011  this event does not split the current group but is indeed
3012  a separator beetwen two master's binlog therefore requiring
3013  Workers to sync.
3014  */
3015  if (rli->curr_group_da.elements > 0)
3016  {
3017  char llbuff[22];
3018  /*
3019  Possible reason is a old version binlog sequential event
3020  wrappped with BEGIN/COMMIT or preceeded by User|Int|Random- var.
3021  MTS has to stop to suggest restart in the permanent sequential mode.
3022  */
3023  llstr(rli->get_event_relay_log_pos(), llbuff);
3024  my_error(ER_MTS_CANT_PARALLEL, MYF(0),
3025  get_type_str(), rli->get_event_relay_log_name(), llbuff,
3026  "possible malformed group of events from an old master");
3027 
3028  /* Coordinator cant continue, it marks MTS group status accordingly */
3029  rli->mts_group_status= Relay_log_info::MTS_KILLED_GROUP;
3030 
3031  goto err;
3032  }
3033  /*
3034  Marking sure the event will be executed in sequential mode.
3035  */
3036  if (wait_for_workers_to_finish(rli) == -1)
3037  {
3038  // handle synchronization error
3039  rli->report(WARNING_LEVEL, 0,
3040  "Slave worker thread has failed to apply an event. As a "
3041  "consequence, the coordinator thread is stopping "
3042  "execution.");
3043  DBUG_RETURN(-1);
3044  }
3045  /*
3046  Given not in-group mark the event handler can invoke checkpoint
3047  update routine in the following course.
3048  */
3049  DBUG_ASSERT(rli->mts_group_status == Relay_log_info::MTS_NOT_IN_GROUP);
3050 
3051 #ifndef DBUG_OFF
3052  /* all Workers are idle as done through wait_for_workers_to_finish */
3053  for (uint k= 0; k < rli->curr_group_da.elements; k++)
3054  {
3055  DBUG_ASSERT(!(*(Slave_worker **)
3056  dynamic_array_ptr(&rli->workers, k))->usage_partition);
3057  DBUG_ASSERT(!(*(Slave_worker **)
3058  dynamic_array_ptr(&rli->workers, k))->jobs.len);
3059  }
3060 #endif
3061  }
3062  else
3063  {
3064  DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_ASYNC);
3065  }
3066  }
3067  DBUG_RETURN(do_apply_event(rli));
3068  }
3069 
3070  DBUG_ASSERT(actual_exec_mode == EVENT_EXEC_PARALLEL);
3071  DBUG_ASSERT(!(rli->curr_group_seen_begin && ends_group()) ||
3072  /*
3073  This is an empty group being processed due to gtids.
3074  */
3075  (rli->curr_group_seen_begin && rli->curr_group_seen_gtid
3076  && ends_group()) ||
3077  rli->last_assigned_worker ||
3078  /*
3079  Begin_load_query can be logged w/o db info and within
3080  Begin/Commit. That's a pattern forcing sequential
3081  applying of LOAD-DATA.
3082  */
3083  (*(Log_event **)
3084  dynamic_array_ptr(&rli->curr_group_da,
3085  rli->curr_group_da.elements - 1))->
3086  get_type_code() == BEGIN_LOAD_QUERY_EVENT);
3087 
3088  worker= NULL;
3089  rli->mts_group_status= Relay_log_info::MTS_IN_GROUP;
3090 
3092  (rli->last_assigned_worker= get_slave_worker(rli));
3093 
3094 #ifndef DBUG_OFF
3095  if (rli->last_assigned_worker)
3096  DBUG_PRINT("mts", ("Assigning job to worker %lu",
3097  rli->last_assigned_worker->id));
3098 #endif
3099 
3100 err:
3101  if (thd->is_error())
3102  {
3103  DBUG_ASSERT(!worker);
3104 
3105  /*
3106  Destroy all deferred buffered events but the current prior to exit.
3107  The current one will be deleted as an event never destined/assigned
3108  to any Worker in Coordinator's regular execution path.
3109  */
3110  for (uint k= 0; k < rli->curr_group_da.elements; k++)
3111  {
3112  Log_event *ev_buf=
3113  *(Log_event**) dynamic_array_ptr(&rli->curr_group_da, k);
3114  if (this != ev_buf)
3115  delete ev_buf;
3116  }
3117  rli->curr_group_da.elements= 0;
3118  }
3119  else
3120  {
3121  DBUG_ASSERT(worker || rli->curr_group_assigned_parts.elements == 0);
3122  }
3123 
3124  DBUG_RETURN((!thd->is_error() ||
3125  DBUG_EVALUATE_IF("fault_injection_get_slave_worker", 1, 0)) ?
3126  0 : -1);
3127 }
3128 
3129 #endif
3130 
3131 /**************************************************************************
3132  Query_log_event methods
3133 **************************************************************************/
3134 
3135 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3136 
3146 int Query_log_event::pack_info(Protocol *protocol)
3147 {
3148  // TODO: show the catalog ??
3149  String temp_buf;
3150  // Add use `DB` to the string if required
3151  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
3152  && db && db_len)
3153  {
3154  temp_buf.append("use ");
3155  append_identifier(this->thd, &temp_buf, db, db_len);
3156  temp_buf.append("; ");
3157  }
3158  // Add the query to the string
3159  if (query && q_len)
3160  temp_buf.append(query);
3161  // persist the buffer in protocol
3162  protocol->store(temp_buf.ptr(), temp_buf.length(), &my_charset_bin);
3163  return 0;
3164 }
3165 #endif
3166 
3167 #ifndef MYSQL_CLIENT
3168 
3172 static void write_str_with_code_and_len(uchar **dst, const char *src,
3173  uint len, uint code)
3174 {
3175  /*
3176  only 1 byte to store the length of catalog, so it should not
3177  surpass 255
3178  */
3179  DBUG_ASSERT(len <= 255);
3180  DBUG_ASSERT(src);
3181  *((*dst)++)= code;
3182  *((*dst)++)= (uchar) len;
3183  bmove(*dst, src, len);
3184  (*dst)+= len;
3185 }
3186 
3187 
3197 bool Query_log_event::write(IO_CACHE* file)
3198 {
3199  uchar buf[QUERY_HEADER_LEN + MAX_SIZE_LOG_EVENT_STATUS];
3200  uchar *start, *start_of_status;
3201  ulong event_length;
3202 
3203  if (!query)
3204  return 1; // Something wrong with event
3205 
3206  /*
3207  We want to store the thread id:
3208  (- as an information for the user when he reads the binlog)
3209  - if the query uses temporary table: for the slave SQL thread to know to
3210  which master connection the temp table belongs.
3211  Now imagine we (write()) are called by the slave SQL thread (we are
3212  logging a query executed by this thread; the slave runs with
3213  --log-slave-updates). Then this query will be logged with
3214  thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
3215  the same name were created simultaneously on the master (in the master
3216  binlog you have
3217  CREATE TEMPORARY TABLE t; (thread 1)
3218  CREATE TEMPORARY TABLE t; (thread 2)
3219  ...)
3220  then in the slave's binlog there will be
3221  CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3222  CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
3223  which is bad (same thread id!).
3224 
3225  To avoid this, we log the thread's thread id EXCEPT for the SQL
3226  slave thread for which we log the original (master's) thread id.
3227  Now this moves the bug: what happens if the thread id on the
3228  master was 10 and when the slave replicates the query, a
3229  connection number 10 is opened by a normal client on the slave,
3230  and updates a temp table of the same name? We get a problem
3231  again. To avoid this, in the handling of temp tables (sql_base.cc)
3232  we use thread_id AND server_id. TODO when this is merged into
3233  4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
3234  and is a session variable: that's to make mysqlbinlog work with
3235  temp tables. We probably need to introduce
3236 
3237  SET PSEUDO_SERVER_ID
3238  for mysqlbinlog in 4.1. mysqlbinlog would print:
3239  SET PSEUDO_SERVER_ID=
3240  SET PSEUDO_THREAD_ID=
3241  for each query using temp tables.
3242  */
3243  int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
3244  int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
3245  buf[Q_DB_LEN_OFFSET] = (char) db_len;
3246  int2store(buf + Q_ERR_CODE_OFFSET, error_code);
3247 
3248  /*
3249  You MUST always write status vars in increasing order of code. This
3250  guarantees that a slightly older slave will be able to parse those he
3251  knows.
3252  */
3253  start_of_status= start= buf+QUERY_HEADER_LEN;
3254  if (flags2_inited)
3255  {
3256  *start++= Q_FLAGS2_CODE;
3257  int4store(start, flags2);
3258  start+= 4;
3259  }
3260  if (sql_mode_inited)
3261  {
3262  *start++= Q_SQL_MODE_CODE;
3263  int8store(start, sql_mode);
3264  start+= 8;
3265  }
3266  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
3267  {
3268  write_str_with_code_and_len(&start,
3269  catalog, catalog_len, Q_CATALOG_NZ_CODE);
3270  /*
3271  In 5.0.x where x<4 masters we used to store the end zero here. This was
3272  a waste of one byte so we don't do it in x>=4 masters. We change code to
3273  Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
3274  of this x>=4 master segfault (expecting a zero when there is
3275  none). Remaining compatibility problems are: the older slave will not
3276  find the catalog; but it is will not crash, and it's not an issue
3277  that it does not find the catalog as catalogs were not used in these
3278  older MySQL versions (we store it in binlog and read it from relay log
3279  but do nothing useful with it). What is an issue is that the older slave
3280  will stop processing the Q_* blocks (and jumps to the db/query) as soon
3281  as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
3282  Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
3283  various ways. Documented that you should not mix alpha/beta versions if
3284  they are not exactly the same version, with example of 5.0.3->5.0.2 and
3285  5.0.4->5.0.3. If replication is from older to new, the new will
3286  recognize Q_CATALOG_CODE and have no problem.
3287  */
3288  }
3289  if (auto_increment_increment != 1 || auto_increment_offset != 1)
3290  {
3291  *start++= Q_AUTO_INCREMENT;
3292  int2store(start, auto_increment_increment);
3293  int2store(start+2, auto_increment_offset);
3294  start+= 4;
3295  }
3296  if (charset_inited)
3297  {
3298  *start++= Q_CHARSET_CODE;
3299  memcpy(start, charset, 6);
3300  start+= 6;
3301  }
3302  if (time_zone_len)
3303  {
3304  /* In the TZ sys table, column Name is of length 64 so this should be ok */
3305  DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
3306  write_str_with_code_and_len(&start,
3307  time_zone_str, time_zone_len, Q_TIME_ZONE_CODE);
3308  }
3309  if (lc_time_names_number)
3310  {
3311  DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
3312  *start++= Q_LC_TIME_NAMES_CODE;
3313  int2store(start, lc_time_names_number);
3314  start+= 2;
3315  }
3316  if (charset_database_number)
3317  {
3318  DBUG_ASSERT(charset_database_number <= 0xFFFF);
3319  *start++= Q_CHARSET_DATABASE_CODE;
3320  int2store(start, charset_database_number);
3321  start+= 2;
3322  }
3323  if (table_map_for_update)
3324  {
3325  *start++= Q_TABLE_MAP_FOR_UPDATE_CODE;
3326  int8store(start, table_map_for_update);
3327  start+= 8;
3328  }
3329  if (master_data_written != 0)
3330  {
3331  /*
3332  Q_MASTER_DATA_WRITTEN_CODE only exists in relay logs where the master
3333  has binlog_version<4 and the slave has binlog_version=4. See comment
3334  for master_data_written in log_event.h for details.
3335  */
3336  *start++= Q_MASTER_DATA_WRITTEN_CODE;
3337  int4store(start, master_data_written);
3338  start+= 4;
3339  }
3340 
3341  if (thd && thd->need_binlog_invoker())
3342  {
3343  LEX_STRING user;
3344  LEX_STRING host;
3345  memset(&user, 0, sizeof(user));
3346  memset(&host, 0, sizeof(host));
3347 
3348  if (thd->slave_thread && thd->has_invoker())
3349  {
3350  /* user will be null, if master is older than this patch */
3351  user= thd->get_invoker_user();
3352  host= thd->get_invoker_host();
3353  }
3354  else if (thd->security_ctx->priv_user)
3355  {
3356  Security_context *ctx= thd->security_ctx;
3357 
3358  user.length= strlen(ctx->priv_user);
3359  user.str= ctx->priv_user;
3360  if (ctx->priv_host[0] != '\0')
3361  {
3362  host.str= ctx->priv_host;
3363  host.length= strlen(ctx->priv_host);
3364  }
3365  }
3366 
3367  if (user.length > 0)
3368  {
3369  *start++= Q_INVOKER;
3370 
3371  /*
3372  Store user length and user. The max length of use is 16, so 1 byte is
3373  enough to store the user's length.
3374  */
3375  *start++= (uchar)user.length;
3376  memcpy(start, user.str, user.length);
3377  start+= user.length;
3378 
3379  /*
3380  Store host length and host. The max length of host is 60, so 1 byte is
3381  enough to store the host's length.
3382  */
3383  *start++= (uchar)host.length;
3384  memcpy(start, host.str, host.length);
3385  start+= host.length;
3386  }
3387  }
3388 
3389  if (thd && thd->get_binlog_accessed_db_names() != NULL)
3390  {
3391  uchar dbs;
3392  *start++= Q_UPDATED_DB_NAMES;
3393 
3394  compile_time_assert(MAX_DBS_IN_EVENT_MTS <= OVER_MAX_DBS_IN_EVENT_MTS);
3395 
3396  /*
3397  In case of the number of db:s exceeds MAX_DBS_IN_EVENT_MTS
3398  no db:s is written and event will require the sequential applying on slave.
3399  */
3400  dbs=
3401  (thd->get_binlog_accessed_db_names()->elements <= MAX_DBS_IN_EVENT_MTS) ?
3402  thd->get_binlog_accessed_db_names()->elements : OVER_MAX_DBS_IN_EVENT_MTS;
3403 
3404  DBUG_ASSERT(dbs != 0);
3405 
3406  if (dbs <= MAX_DBS_IN_EVENT_MTS)
3407  {
3408  List_iterator_fast<char> it(*thd->get_binlog_accessed_db_names());
3409  char *db_name= it++;
3410  /*
3411  the single "" db in the acccessed db list corresponds to the same as
3412  exceeds MAX_DBS_IN_EVENT_MTS case, so dbs is set to the over-max.
3413  */
3414  if (dbs == 1 && !strcmp(db_name, ""))
3415  dbs= OVER_MAX_DBS_IN_EVENT_MTS;
3416  *start++= dbs;
3417  if (dbs != OVER_MAX_DBS_IN_EVENT_MTS)
3418  do
3419  {
3420  strcpy((char*) start, db_name);
3421  start += strlen(db_name) + 1;
3422  } while ((db_name= it++));
3423  }
3424  else
3425  {
3426  *start++= dbs;
3427  }
3428  }
3429 
3430  if (thd && thd->query_start_usec_used)
3431  {
3432  *start++= Q_MICROSECONDS;
3433  get_time();
3434  int3store(start, when.tv_usec);
3435  start+= 3;
3436  }
3437 
3438  /*
3439  NOTE: When adding new status vars, please don't forget to update
3440  the MAX_SIZE_LOG_EVENT_STATUS in log_event.h and update the function
3441  code_name() in this file.
3442 
3443  Here there could be code like
3444  if (command-line-option-which-says-"log_this_variable" && inited)
3445  {
3446  *start++= Q_THIS_VARIABLE_CODE;
3447  int4store(start, this_variable);
3448  start+= 4;
3449  }
3450  */
3451 
3452  /* Store length of status variables */
3453  status_vars_len= (uint) (start-start_of_status);
3454  DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
3455  int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
3456 
3457  /*
3458  Calculate length of whole event
3459  The "1" below is the \0 in the db's length
3460  */
3461  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
3462 
3463  return (write_header(file, event_length) ||
3464  wrapper_my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
3465  write_post_header_for_derived(file) ||
3466  wrapper_my_b_safe_write(file, (uchar*) start_of_status,
3467  (uint) (start-start_of_status)) ||
3468  wrapper_my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
3469  wrapper_my_b_safe_write(file, (uchar*) query, q_len) ||
3470  write_footer(file)) ? 1 : 0;
3471 }
3472 
3479  :Log_event(), data_buf(0)
3480 {
3481  memset(&user, 0, sizeof(user));
3482  memset(&host, 0, sizeof(host));
3483 }
3484 
3485 
3501 Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
3502  ulong query_length, bool using_trans,
3503  bool immediate, bool suppress_use,
3504  int errcode, bool ignore_cmd_internals)
3505 
3506  :Log_event(thd_arg,
3507  (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
3508  0) |
3509  (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
3510  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
3511  Log_event::EVENT_STMT_CACHE,
3512  Log_event::EVENT_NORMAL_LOGGING),
3513  data_buf(0), query(query_arg), catalog(thd_arg->catalog),
3514  db(thd_arg->db), q_len((uint32) query_length),
3515  thread_id(thd_arg->thread_id),
3516  /* save the original thread id; we already know the server id */
3517  slave_proxy_id(thd_arg->variables.pseudo_thread_id),
3518  flags2_inited(1), sql_mode_inited(1), charset_inited(1),
3519  sql_mode(thd_arg->variables.sql_mode),
3520  auto_increment_increment(thd_arg->variables.auto_increment_increment),
3521  auto_increment_offset(thd_arg->variables.auto_increment_offset),
3522  lc_time_names_number(thd_arg->variables.lc_time_names->number),
3523  charset_database_number(0),
3524  table_map_for_update((ulonglong)thd_arg->table_map_for_update),
3525  master_data_written(0), mts_accessed_dbs(0)
3526 {
3527  time_t end_time;
3528 
3529  memset(&user, 0, sizeof(user));
3530  memset(&host, 0, sizeof(host));
3531 
3532  error_code= errcode;
3533 
3534  time(&end_time);
3535  exec_time = (ulong) (end_time - thd_arg->start_time.tv_sec);
3540  catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
3541  /* status_vars_len is set just before writing the event */
3542  db_len = (db) ? (uint32) strlen(db) : 0;
3543  if (thd_arg->variables.collation_database != thd_arg->db_charset)
3544  charset_database_number= thd_arg->variables.collation_database->number;
3545 
3546  /*
3547  We only replicate over the bits of flags2 that we need: the rest
3548  are masked out by "& OPTIONS_WRITTEN_TO_BINLOG".
3549 
3550  We also force AUTOCOMMIT=1. Rationale (cf. BUG#29288): After
3551  fixing BUG#26395, we always write BEGIN and COMMIT around all
3552  transactions (even single statements in autocommit mode). This is
3553  so that replication from non-transactional to transactional table
3554  and error recovery from XA to non-XA table should work as
3555  expected. The BEGIN/COMMIT are added in log.cc. However, there is
3556  one exception: MyISAM bypasses log.cc and writes directly to the
3557  binlog. So if autocommit is off, master has MyISAM, and slave has
3558  a transactional engine, then the slave will just see one long
3559  never-ending transaction. The only way to bypass explicit
3560  BEGIN/COMMIT in the binlog is by using a non-transactional table.
3561  So setting AUTOCOMMIT=1 will make this work as expected.
3562 
3563  Note: explicitly replicate AUTOCOMMIT=1 from master. We do not
3564  assume AUTOCOMMIT=1 on slave; the slave still reads the state of
3565  the autocommit flag as written by the master to the binlog. This
3566  behavior may change after WL#4162 has been implemented.
3567  */
3568  flags2= (uint32) (thd_arg->variables.option_bits &
3569  (OPTIONS_WRITTEN_TO_BIN_LOG & ~OPTION_NOT_AUTOCOMMIT));
3570  DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
3571  DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
3572  DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
3573  DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
3574  int2store(charset, thd_arg->variables.character_set_client->number);
3575  int2store(charset+2, thd_arg->variables.collation_connection->number);
3576  int2store(charset+4, thd_arg->variables.collation_server->number);
3577  if (thd_arg->time_zone_used)
3578  {
3579  /*
3580  Note that our event becomes dependent on the Time_zone object
3581  representing the time zone. Fortunately such objects are never deleted
3582  or changed during mysqld's lifetime.
3583  */
3584  time_zone_len= thd_arg->variables.time_zone->get_name()->length();
3585  time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
3586  }
3587  else
3588  time_zone_len= 0;
3589 
3590  /*
3591  In what follows, we define in which cache, trx-cache or stmt-cache,
3592  this Query Log Event will be written to.
3593 
3594  If ignore_cmd_internals is defined, we rely on the is_trans flag to
3595  choose the cache and this is done in the base class Log_event. False
3596  means that the stmt-cache will be used and upon statement commit/rollback
3597  the cache will be flushed to disk. True means that the trx-cache will
3598  be used and upon transaction commit/rollback the cache will be flushed
3599  to disk.
3600 
3601  If set immediate cache is defined, for convenience, we automatically
3602  use the stmt-cache. This mean that the statement will be written
3603  to the stmt-cache and immediately flushed to disk without waiting
3604  for a commit/rollback notification.
3605 
3606  For example, the cluster/ndb captures a request to execute a DDL
3607  statement and synchronously propagate it to all available MySQL
3608  servers. Unfortunately, the current protocol assumes that the
3609  generated events are immediately written to diks and does not check
3610  for commit/rollback.
3611 
3612  Upon dropping a connection, DDLs (i.e. DROP TEMPORARY TABLE) are
3613  generated and in this case the statements have the immediate flag
3614  set because there is no commit/rollback.
3615 
3616  If the immediate flag is not set, the decision on the cache is based
3617  on the current statement and the flag is_trans, which indicates if
3618  a transactional engine was updated.
3619 
3620  Statements are classifed as row producers (i.e. can_generate_row_events())
3621  or non-row producers. Non-row producers, DDL in general, are treated
3622  as the immediate flag was set and for convenience are written to the
3623  stmt-cache and immediately flushed to disk.
3624 
3625  Row producers are handled in general according to the is_trans flag.
3626  False means that the stmt-cache will be used and upon statement
3627  commit/rollback the cache will be flushed to disk. True means that the
3628  trx-cache will be used and upon transaction commit/rollback the cache
3629  will be flushed to disk.
3630 
3631  Unfortunately, there are exceptions to this non-row and row producer
3632  rules:
3633 
3634  . The SAVEPOINT, ROLLBACK TO SAVEPOINT, RELEASE SAVEPOINT does not
3635  have the flag is_trans set because there is no updated engine but
3636  must be written to the trx-cache.
3637 
3638  . SET If auto-commit is on, it must not go through a cache.
3639 
3640  . CREATE TABLE is classfied as non-row producer but CREATE TEMPORARY
3641  must be handled as row producer.
3642 
3643  . DROP TABLE is classfied as non-row producer but DROP TEMPORARY
3644  must be handled as row producer.
3645 
3646  Finally, some statements that does not have the flag is_trans set may
3647  be written to the trx-cache based on the following criteria:
3648 
3649  . updated both a transactional and a non-transactional engine (i.e.
3650  stmt_has_updated_trans_table()).
3651 
3652  . accessed both a transactional and a non-transactional engine and
3653  is classified as unsafe (i.e. is_mixed_stmt_unsafe()).
3654 
3655  . is executed within a transaction and previously a transactional
3656  engine was updated and the flag binlog_direct_non_trans_update
3657  is set.
3658  */
3659  if (ignore_cmd_internals)
3660  return;
3661 
3662  /*
3663  TRUE defines that the trx-cache must be used.
3664  */
3665  bool cmd_can_generate_row_events= FALSE;
3666  /*
3667  TRUE defines that the trx-cache must be used.
3668  */
3669  bool cmd_must_go_to_trx_cache= FALSE;
3670 
3671  LEX *lex= thd->lex;
3672  if (!immediate)
3673  {
3674  switch (lex->sql_command)
3675  {
3676  case SQLCOM_DROP_TABLE:
3677  cmd_can_generate_row_events= lex->drop_temporary &&
3678  thd->in_multi_stmt_transaction_mode();
3679  break;
3680  case SQLCOM_CREATE_TABLE:
3681  cmd_must_go_to_trx_cache= lex->select_lex.item_list.elements &&
3682  thd->is_current_stmt_binlog_format_row();
3683  cmd_can_generate_row_events=
3684  ((lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
3685  thd->in_multi_stmt_transaction_mode()) || cmd_must_go_to_trx_cache;
3686  break;
3687  case SQLCOM_SET_OPTION:
3688  if (lex->autocommit)
3689  cmd_can_generate_row_events= cmd_must_go_to_trx_cache= FALSE;
3690  else
3691  cmd_can_generate_row_events= TRUE;
3692  break;
3693  case SQLCOM_RELEASE_SAVEPOINT:
3694  case SQLCOM_ROLLBACK_TO_SAVEPOINT:
3695  case SQLCOM_SAVEPOINT:
3696  cmd_can_generate_row_events= cmd_must_go_to_trx_cache= TRUE;
3697  break;
3698  default:
3699  cmd_can_generate_row_events= sqlcom_can_generate_row_events(thd);
3700  break;
3701  }
3702  }
3703 
3704  if (cmd_can_generate_row_events)
3705  {
3706  cmd_must_go_to_trx_cache= cmd_must_go_to_trx_cache || using_trans;
3707  if (cmd_must_go_to_trx_cache || stmt_has_updated_trans_table(thd) ||
3708  thd->lex->is_mixed_stmt_unsafe(thd->in_multi_stmt_transaction_mode(),
3709  thd->variables.binlog_direct_non_trans_update,
3711  thd->tx_isolation) ||
3712  (!thd->variables.binlog_direct_non_trans_update && trans_has_updated_trans_table(thd)))
3713  {
3714  event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3715  event_cache_type= Log_event::EVENT_TRANSACTIONAL_CACHE;
3716  }
3717  else
3718  {
3719  event_logging_type= Log_event::EVENT_NORMAL_LOGGING;
3720  event_cache_type= Log_event::EVENT_STMT_CACHE;
3721  }
3722  }
3723  else
3724  {
3725  event_logging_type= Log_event::EVENT_IMMEDIATE_LOGGING;
3726  event_cache_type= Log_event::EVENT_STMT_CACHE;
3727  }
3728 
3729  DBUG_ASSERT(event_cache_type != Log_event::EVENT_INVALID_CACHE);
3730  DBUG_ASSERT(event_logging_type != Log_event::EVENT_INVALID_LOGGING);
3731  DBUG_PRINT("info",("Query_log_event has flags2: %lu sql_mode: %llu",
3732  (ulong) flags2, sql_mode));
3733 }
3734 #endif /* MYSQL_CLIENT */
3735 
3736 
3737 /* 2 utility functions for the next method */
3738 
3763 static int
3764 get_str_len_and_pointer(const Log_event::Byte **src,
3765  const char **dst,
3766  uint *len,
3767  const Log_event::Byte *end)
3768 {
3769  if (*src >= end)
3770  return -1; // Will be UINT_MAX in two-complement arithmetics
3771  uint length= **src;
3772  if (length > 0)
3773  {
3774  if (*src + length >= end)
3775  return *src + length - end + 1; // Number of bytes missing
3776  *dst= (char *)*src + 1; // Will be copied later
3777  }
3778  *len= length;
3779  *src+= length + 1;
3780  return 0;
3781 }
3782 
3783 static void copy_str_and_move(const char **src,
3784  Log_event::Byte **dst,
3785  uint len)
3786 {
3787  memcpy(*dst, *src, len);
3788  *src= (const char *)*dst;
3789  (*dst)+= len;
3790  *(*dst)++= 0;
3791 }
3792 
3793 
3794 #ifndef DBUG_OFF
3795 static char const *
3796 code_name(int code)
3797 {
3798  static char buf[255];
3799  switch (code) {
3800  case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
3801  case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
3802  case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
3803  case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
3804  case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
3805  case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
3806  case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
3807  case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
3808  case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
3809  case Q_TABLE_MAP_FOR_UPDATE_CODE: return "Q_TABLE_MAP_FOR_UPDATE_CODE";
3810  case Q_MASTER_DATA_WRITTEN_CODE: return "Q_MASTER_DATA_WRITTEN_CODE";
3811  case Q_UPDATED_DB_NAMES: return "Q_UPDATED_DB_NAMES";
3812  case Q_MICROSECONDS: return "Q_MICROSECONDS";
3813  }
3814  sprintf(buf, "CODE#%d", code);
3815  return buf;
3816 }
3817 #endif
3818 
3826 #define CHECK_SPACE(PTR,END,CNT) \
3827  do { \
3828  DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
3829  DBUG_ASSERT((PTR) + (CNT) <= (END)); \
3830  if ((PTR) + (CNT) > (END)) { \
3831  DBUG_PRINT("info", ("query= 0")); \
3832  query= 0; \
3833  DBUG_VOID_RETURN; \
3834  } \
3835  } while (0)
3836 
3837 
3841 Query_log_event::Query_log_event(const char* buf, uint event_len,
3843  *description_event,
3844  Log_event_type event_type)
3845  :Log_event(buf, description_event), data_buf(0), query(NullS),
3846  db(NullS), catalog_len(0), status_vars_len(0),
3847  flags2_inited(0), sql_mode_inited(0), charset_inited(0),
3848  auto_increment_increment(1), auto_increment_offset(1),
3849  time_zone_len(0), lc_time_names_number(0), charset_database_number(0),
3850  table_map_for_update(0), master_data_written(0),
3851  mts_accessed_dbs(OVER_MAX_DBS_IN_EVENT_MTS)
3852 {
3853  ulong data_len;
3854  uint32 tmp;
3855  uint8 common_header_len, post_header_len;
3856  Log_event::Byte *start;
3857  const Log_event::Byte *end;
3858  bool catalog_nz= 1;
3859  DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
3860 
3861  memset(&user, 0, sizeof(user));
3862  memset(&host, 0, sizeof(host));
3863  common_header_len= description_event->common_header_len;
3864  post_header_len= description_event->post_header_len[event_type-1];
3865  DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
3866  event_len, common_header_len, post_header_len));
3867 
3868  /*
3869  We test if the event's length is sensible, and if so we compute data_len.
3870  We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
3871  We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
3872  */
3873  if (event_len < (uint)(common_header_len + post_header_len))
3874  DBUG_VOID_RETURN;
3875  data_len = event_len - (common_header_len + post_header_len);
3876  buf+= common_header_len;
3877 
3878  slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
3879  exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
3880  db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
3881  error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
3882 
3883  /*
3884  5.0 format starts here.
3885  Depending on the format, we may or not have affected/warnings etc
3886  The remnent post-header to be parsed has length:
3887  */
3888  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
3889  if (tmp)
3890  {
3891  status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
3892  /*
3893  Check if status variable length is corrupt and will lead to very
3894  wrong data. We could be even more strict and require data_len to
3895  be even bigger, but this will suffice to catch most corruption
3896  errors that can lead to a crash.
3897  */
3898  if (status_vars_len > min<ulong>(data_len, MAX_SIZE_LOG_EVENT_STATUS))
3899  {
3900  DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
3901  status_vars_len, data_len));
3902  query= 0;
3903  DBUG_VOID_RETURN;
3904  }
3905  data_len-= status_vars_len;
3906  DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
3907  (uint) status_vars_len));
3908  tmp-= 2;
3909  }
3910  else
3911  {
3912  /*
3913  server version < 5.0 / binlog_version < 4 master's event is
3914  relay-logged with storing the original size of the event in
3915  Q_MASTER_DATA_WRITTEN_CODE status variable.
3916  The size is to be restored at reading Q_MASTER_DATA_WRITTEN_CODE-marked
3917  event from the relay log.
3918  */
3919  DBUG_ASSERT(description_event->binlog_version < 4);
3920  master_data_written= data_written;
3921  }
3922  /*
3923  We have parsed everything we know in the post header for QUERY_EVENT,
3924  the rest of post header is either comes from older version MySQL or
3925  dedicated to derived events (e.g. Execute_load_query...)
3926  */
3927 
3928  /* variable-part: the status vars; only in MySQL 5.0 */
3929 
3930  start= (Log_event::Byte*) (buf+post_header_len);
3931  end= (const Log_event::Byte*) (start+status_vars_len);
3932  for (const Log_event::Byte* pos= start; pos < end;)
3933  {
3934  switch (*pos++) {
3935  case Q_FLAGS2_CODE:
3936  CHECK_SPACE(pos, end, 4);
3937  flags2_inited= 1;
3938  flags2= uint4korr(pos);
3939  DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
3940  pos+= 4;
3941  break;
3942  case Q_SQL_MODE_CODE:
3943  {
3944 #ifndef DBUG_OFF
3945  char buff[22];
3946 #endif
3947  CHECK_SPACE(pos, end, 8);
3948  sql_mode_inited= 1;
3949  sql_mode= uint8korr(pos);
3950  DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
3951  llstr(sql_mode, buff)));
3952  pos+= 8;
3953  break;
3954  }
3955  case Q_CATALOG_NZ_CODE:
3956  DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
3957  (ulong) pos, (ulong) end));
3958  if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
3959  {
3960  DBUG_PRINT("info", ("query= 0"));
3961  query= 0;
3962  DBUG_VOID_RETURN;
3963  }
3964  break;
3965  case Q_AUTO_INCREMENT:
3966  CHECK_SPACE(pos, end, 4);
3967  auto_increment_increment= uint2korr(pos);
3968  auto_increment_offset= uint2korr(pos+2);
3969  pos+= 4;
3970  break;
3971  case Q_CHARSET_CODE:
3972  {
3973  CHECK_SPACE(pos, end, 6);
3974  charset_inited= 1;
3975  memcpy(charset, pos, 6);
3976  pos+= 6;
3977  break;
3978  }
3979  case Q_TIME_ZONE_CODE:
3980  {
3981  if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
3982  {
3983  DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
3984  query= 0;
3985  DBUG_VOID_RETURN;
3986  }
3987  break;
3988  }
3989  case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
3990  CHECK_SPACE(pos, end, 1);
3991  if ((catalog_len= *pos))
3992  catalog= (char*) pos+1; // Will be copied later
3993  CHECK_SPACE(pos, end, catalog_len + 2);
3994  pos+= catalog_len+2; // leap over end 0
3995  catalog_nz= 0; // catalog has end 0 in event
3996  break;
3997  case Q_LC_TIME_NAMES_CODE:
3998  CHECK_SPACE(pos, end, 2);
3999  lc_time_names_number= uint2korr(pos);
4000  pos+= 2;
4001  break;
4002  case Q_CHARSET_DATABASE_CODE:
4003  CHECK_SPACE(pos, end, 2);
4004  charset_database_number= uint2korr(pos);
4005  pos+= 2;
4006  break;
4007  case Q_TABLE_MAP_FOR_UPDATE_CODE:
4008  CHECK_SPACE(pos, end, 8);
4009  table_map_for_update= uint8korr(pos);
4010  pos+= 8;
4011  break;
4012  case Q_MASTER_DATA_WRITTEN_CODE:
4013  CHECK_SPACE(pos, end, 4);
4014  data_written= master_data_written= uint4korr(pos);
4015  pos+= 4;
4016  break;
4017  case Q_MICROSECONDS:
4018  {
4019  CHECK_SPACE(pos, end, 3);
4020  when.tv_usec= uint3korr(pos);
4021  pos+= 3;
4022  break;
4023  }
4024  case Q_INVOKER:
4025  {
4026  CHECK_SPACE(pos, end, 1);
4027  user.length= *pos++;
4028  CHECK_SPACE(pos, end, user.length);
4029  user.str= (char *)pos;
4030  pos+= user.length;
4031 
4032  CHECK_SPACE(pos, end, 1);
4033  host.length= *pos++;
4034  CHECK_SPACE(pos, end, host.length);
4035  host.str= (char *)pos;
4036  pos+= host.length;
4037  break;
4038  }
4039  case Q_UPDATED_DB_NAMES:
4040  {
4041  uchar i= 0;
4042  CHECK_SPACE(pos, end, 1);
4043  mts_accessed_dbs= *pos++;
4044  /*
4045  Notice, the following check is positive also in case of
4046  the master's MAX_DBS_IN_EVENT_MTS > the slave's one and the event
4047  contains e.g the master's MAX_DBS_IN_EVENT_MTS db:s.
4048  */
4049  if (mts_accessed_dbs > MAX_DBS_IN_EVENT_MTS)
4050  {
4051  mts_accessed_dbs= OVER_MAX_DBS_IN_EVENT_MTS;
4052  break;
4053  }
4054 
4055  DBUG_ASSERT(mts_accessed_dbs != 0);
4056 
4057  for (i= 0; i < mts_accessed_dbs && pos < start + status_vars_len; i++)
4058  {
4059  DBUG_EXECUTE_IF("query_log_event_mts_corrupt_db_names",
4060  {
4061  if (mts_accessed_dbs == 2)
4062  {
4063  DBUG_ASSERT(pos[sizeof("d?") - 1] == 0);
4064  ((char*) pos)[sizeof("d?") - 1]= 'a';
4065  }});
4066  strncpy(mts_accessed_db_names[i], (char*) pos,
4067  min<ulong>(NAME_LEN, start + status_vars_len - pos));
4068  mts_accessed_db_names[i][NAME_LEN - 1]= 0;
4069  pos+= 1 + strlen((const char*) pos);
4070  }
4071  if (i != mts_accessed_dbs || pos > start + status_vars_len)
4072  DBUG_VOID_RETURN;
4073  break;
4074  }
4075  default:
4076  /* That's why you must write status vars in growing order of code */
4077  DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
4078  code: %u), skipping the rest of them", (uint) *(pos-1)));
4079  pos= (const uchar*) end; // Break loop
4080  }
4081  }
4082 
4099 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4100  if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4101  + time_zone_len + 1
4102  + user.length + 1
4103  + host.length + 1
4104  + data_len + 1
4105  + sizeof(size_t)//for db_len
4106  + db_len + 1
4107  + QUERY_CACHE_FLAGS_SIZE,
4108  MYF(MY_WME))))
4109 #else
4110  if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1
4111  + time_zone_len + 1
4112  + user.length + 1
4113  + host.length + 1
4114  + data_len + 1,
4115  MYF(MY_WME))))
4116 #endif
4117  DBUG_VOID_RETURN;
4118  if (catalog_len) // If catalog is given
4119  {
4125  if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
4126  copy_str_and_move(&catalog, &start, catalog_len);
4127  else
4128  {
4129  memcpy(start, catalog, catalog_len+1); // copy end 0
4130  catalog= (const char *)start;
4131  start+= catalog_len+1;
4132  }
4133  }
4134  if (time_zone_len)
4135  copy_str_and_move(&time_zone_str, &start, time_zone_len);
4136 
4137  if (user.length > 0)
4138  copy_str_and_move((const char **)&(user.str), &start, user.length);
4139  if (host.length > 0)
4140  copy_str_and_move((const char **)&(host.str), &start, host.length);
4141 
4149  /* A 2nd variable part; this is common to all versions */
4150  memcpy((char*) start, end, data_len); // Copy db and query
4151  start[data_len]= '\0'; // End query with \0 (For safetly)
4152  db= (char *)start;
4153  query= (char *)(start + db_len + 1);
4154  q_len= data_len - db_len -1;
4159 #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE)
4160  size_t db_length= (size_t)db_len;
4161  memcpy(start + data_len + 1, &db_length, sizeof(size_t));
4162 #endif
4163  DBUG_VOID_RETURN;
4164 }
4165 
4166 
4167 #ifdef MYSQL_CLIENT
4168 
4174 void Query_log_event::print_query_header(IO_CACHE* file,
4175  PRINT_EVENT_INFO* print_event_info)
4176 {
4177  // TODO: print the catalog ??
4178  char buff[48], *end; // Enough for "SET TIMESTAMP=1305535348.123456"
4179  char quoted_id[1+ 2*FN_REFLEN+ 2];
4180  int quoted_len= 0;
4181  bool different_db= 1;
4182  uint32 tmp;
4183 
4184  if (!print_event_info->short_form)
4185  {
4186  print_header(file, print_event_info, FALSE);
4187  my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
4188  get_type_str(), (ulong) thread_id, (ulong) exec_time,
4189  error_code);
4190  }
4191 
4192  if ((flags & LOG_EVENT_SUPPRESS_USE_F))
4193  {
4194  if (!is_trans_keyword())
4195  print_event_info->db[0]= '\0';
4196  }
4197  else if (db)
4198  {
4199 #ifdef MYSQL_SERVER
4200  quoted_len= my_strmov_quoted_identifier(this->thd, (char*)quoted_id, db, 0);
4201 #else
4202  quoted_len= my_strmov_quoted_identifier((char*)quoted_id, db);
4203 #endif
4204  quoted_id[quoted_len]= '\0';
4205  different_db= memcmp(print_event_info->db, db, db_len + 1);
4206  if (different_db)
4207  memcpy(print_event_info->db, db, db_len + 1);
4208  if (db[0] && different_db)
4209  my_b_printf(file, "use %s%s\n", quoted_id, print_event_info->delimiter);
4210  }
4211 
4212  end=int10_to_str((long) when.tv_sec, strmov(buff,"SET TIMESTAMP="),10);
4213  if (when.tv_usec)
4214  end+= sprintf(end, ".%06d", (int) when.tv_usec);
4215  end= strmov(end, print_event_info->delimiter);
4216  *end++='\n';
4217  DBUG_ASSERT(end < buff + sizeof(buff));
4218  my_b_write(file, (uchar*) buff, (uint) (end-buff));
4219  if ((!print_event_info->thread_id_printed ||
4220  ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
4221  thread_id != print_event_info->thread_id)))
4222  {
4223  // If --short-form, print deterministic value instead of pseudo_thread_id.
4224  my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
4225  short_form ? 999999999 : (ulong)thread_id,
4226  print_event_info->delimiter);
4227  print_event_info->thread_id= thread_id;
4228  print_event_info->thread_id_printed= 1;
4229  }
4230 
4231  /*
4232  If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
4233  print (remember we don't produce mixed relay logs so there cannot be
4234  5.0 events before that one so there is nothing to reset).
4235  */
4236  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
4237  {
4238  /* tmp is a bitmask of bits which have changed. */
4239  if (likely(print_event_info->flags2_inited))
4240  /* All bits which have changed */
4241  tmp= (print_event_info->flags2) ^ flags2;
4242  else /* that's the first Query event we read */
4243  {
4244  print_event_info->flags2_inited= 1;
4245  tmp= ~((uint32)0); /* all bits have changed */
4246  }
4247 
4248  if (unlikely(tmp)) /* some bits have changed */
4249  {
4250  bool need_comma= 0;
4251  my_b_printf(file, "SET ");
4252  print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
4253  "@@session.foreign_key_checks", &need_comma);
4254  print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
4255  "@@session.sql_auto_is_null", &need_comma);
4256  print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
4257  "@@session.unique_checks", &need_comma);
4258  print_set_option(file, tmp, OPTION_NOT_AUTOCOMMIT, ~flags2,
4259  "@@session.autocommit", &need_comma);
4260  my_b_printf(file,"%s\n", print_event_info->delimiter);
4261  print_event_info->flags2= flags2;
4262  }
4263  }
4264 
4265  /*
4266  Now the session variables;
4267  it's more efficient to pass SQL_MODE as a number instead of a
4268  comma-separated list.
4269  FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
4270  variables (they have no global version; they're not listed in
4271  sql_class.h), The tests below work for pure binlogs or pure relay
4272  logs. Won't work for mixed relay logs but we don't create mixed
4273  relay logs (that is, there is no relay log with a format change
4274  except within the 3 first events, which mysqlbinlog handles
4275  gracefully). So this code should always be good.
4276  */
4277 
4278  if (likely(sql_mode_inited) &&
4279  (unlikely(print_event_info->sql_mode != sql_mode ||
4280  !print_event_info->sql_mode_inited)))
4281  {
4282  my_b_printf(file,"SET @@session.sql_mode=%lu%s\n",
4283  (ulong)sql_mode, print_event_info->delimiter);
4284  print_event_info->sql_mode= sql_mode;
4285  print_event_info->sql_mode_inited= 1;
4286  }
4287  if (print_event_info->auto_increment_increment != auto_increment_increment ||
4288  print_event_info->auto_increment_offset != auto_increment_offset)
4289  {
4290  my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
4291  auto_increment_increment,auto_increment_offset,
4292  print_event_info->delimiter);
4293  print_event_info->auto_increment_increment= auto_increment_increment;
4294  print_event_info->auto_increment_offset= auto_increment_offset;
4295  }
4296 
4297  /* TODO: print the catalog when we feature SET CATALOG */
4298 
4299  if (likely(charset_inited) &&
4300  (unlikely(!print_event_info->charset_inited ||
4301  memcmp(print_event_info->charset, charset, 6))))
4302  {
4303  char *charset_p= charset; // Avoid type-punning warning.
4304  CHARSET_INFO *cs_info= get_charset(uint2korr(charset_p), MYF(MY_WME));
4305  if (cs_info)
4306  {
4307  /* for mysql client */
4308  my_b_printf(file, "/*!\\C %s */%s\n",
4309  cs_info->csname, print_event_info->delimiter);
4310  }
4311  my_b_printf(file,"SET "
4312  "@@session.character_set_client=%d,"
4313  "@@session.collation_connection=%d,"
4314  "@@session.collation_server=%d"
4315  "%s\n",
4316  uint2korr(charset_p),
4317  uint2korr(charset+2),
4318  uint2korr(charset+4),
4319  print_event_info->delimiter);
4320  memcpy(print_event_info->charset, charset, 6);
4321  print_event_info->charset_inited= 1;
4322  }
4323  if (time_zone_len)
4324  {
4325  if (memcmp(print_event_info->time_zone_str,
4326  time_zone_str, time_zone_len+1))
4327  {
4328  my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
4329  time_zone_str, print_event_info->delimiter);
4330  memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
4331  }
4332  }
4333  if (lc_time_names_number != print_event_info->lc_time_names_number)
4334  {
4335  my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
4336  lc_time_names_number, print_event_info->delimiter);
4337  print_event_info->lc_time_names_number= lc_time_names_number;
4338  }
4339  if (charset_database_number != print_event_info->charset_database_number)
4340  {
4341  if (charset_database_number)
4342  my_b_printf(file, "SET @@session.collation_database=%d%s\n",
4343  charset_database_number, print_event_info->delimiter);
4344  else
4345  my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
4346  print_event_info->delimiter);
4347  print_event_info->charset_database_number= charset_database_number;
4348  }
4349 }
4350 
4351 
4352 void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4353 {
4354  IO_CACHE *const head= &print_event_info->head_cache;
4355 
4360  DBUG_EXECUTE_IF ("simulate_file_write_error",
4361  {head->write_pos= head->write_end- 500;});
4362  print_query_header(head, print_event_info);
4363  my_b_write(head, (uchar*) query, q_len);
4364  my_b_printf(head, "\n%s\n", print_event_info->delimiter);
4365 }
4366 #endif /* MYSQL_CLIENT */
4367 
4368 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4369 
4377 void Query_log_event::attach_temp_tables_worker(THD *thd)
4378 {
4379  if (!is_mts_worker(thd) || (ends_group() || starts_group()))
4380  return;
4381 
4382  // in over max-db:s case just one special partition is locked
4383  int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4384  1 : mts_accessed_dbs);
4385 
4386  DBUG_ASSERT(!thd->temporary_tables);
4387 
4388  for (int i= 0; i < parts; i++)
4389  {
4390  mts_move_temp_tables_to_thd(thd,
4391  mts_assigned_partitions[i]->temporary_tables);
4392  mts_assigned_partitions[i]->temporary_tables= NULL;
4393  }
4394 }
4395 
4403 void Query_log_event::detach_temp_tables_worker(THD *thd)
4404 {
4405  if (!is_mts_worker(thd))
4406  return;
4407 
4408  int parts= ((mts_accessed_dbs == OVER_MAX_DBS_IN_EVENT_MTS) ?
4409  1 : mts_accessed_dbs);
4410  /*
4411  todo: optimize for a case of
4412 
4413  a. one db
4414  Only detaching temporary_tables from thd to entry would require
4415  instead of the double-loop below.
4416 
4417  b. unchanged thd->temporary_tables.
4418  In such case the involved entries would continue to hold the
4419  unmodified lists provided that the attach_ method does not
4420  destroy references to them.
4421  */
4422  for (int i= 0; i < parts; i++)
4423  {
4424  mts_assigned_partitions[i]->temporary_tables= NULL;
4425  }
4426 
4427  for (TABLE *table= thd->temporary_tables; table;)
4428  {
4429  int i;
4430  char *db_name= NULL;
4431 
4432  // find which entry to go
4433  for (i= 0; i < parts; i++)
4434  {
4435  db_name= mts_accessed_db_names[i];
4436 
4437  if (!strlen(db_name))
4438  break;
4439 
4440  // Only default database is rewritten.
4441  if (!rpl_filter->is_rewrite_empty() && !strcmp(get_db(), db_name))
4442  {
4443  size_t dummy_len;
4444  const char *db_filtered= rpl_filter->get_rewrite_db(db_name, &dummy_len);
4445  // db_name != db_filtered means that db_name is rewritten.
4446  if (strcmp(db_name, db_filtered))
4447  db_name= (char*)db_filtered;
4448  }
4449 
4450  if (strcmp(table->s->db.str, db_name) < 0)
4451  continue;
4452  else
4453  {
4454  // When rewrite db rules are used we can not rely on
4455  // mts_accessed_db_names elements order.
4456  if (!rpl_filter->is_rewrite_empty() &&
4457  strcmp(table->s->db.str, db_name))
4458  continue;
4459  else
4460  break;
4461  }
4462  }
4463 
4464  DBUG_ASSERT(db_name && (
4465  !strcmp(table->s->db.str, db_name) ||
4466  !strlen(db_name))
4467  );
4468  DBUG_ASSERT(i < mts_accessed_dbs);
4469 
4470  // table pointer is shifted inside the function
4471  table= mts_move_temp_table_to_entry(table, thd, mts_assigned_partitions[i]);
4472  }
4473 
4474  DBUG_ASSERT(!thd->temporary_tables);
4475 #ifndef DBUG_OFF
4476  for (int i= 0; i < parts; i++)
4477  {
4478  DBUG_ASSERT(!mts_assigned_partitions[i]->temporary_tables ||
4479  !mts_assigned_partitions[i]->temporary_tables->prev);
4480  }
4481 #endif
4482 }
4483 
4484 /*
4485  Query_log_event::do_apply_event()
4486 */
4487 int Query_log_event::do_apply_event(Relay_log_info const *rli)
4488 {
4489  return do_apply_event(rli, query, q_len);
4490 }
4491 
4492 /*
4493  is_silent_error
4494 
4495  Return true if the thread has an error which should be
4496  handled silently
4497 */
4498 
4499 static bool is_silent_error(THD* thd)
4500 {
4501  DBUG_ENTER("is_silent_error");
4503  thd->get_stmt_da()->sql_conditions();
4504  const Sql_condition *err;
4505  while ((err= it++))
4506  {
4507  DBUG_PRINT("info", ("has condition %d %s", err->get_sql_errno(),
4508  err->get_message_text()));
4509  switch (err->get_sql_errno())
4510  {
4511  case ER_SLAVE_SILENT_RETRY_TRANSACTION:
4512  {
4513  DBUG_RETURN(true);
4514  }
4515  default:
4516  break;
4517  }
4518  }
4519  DBUG_RETURN(false);
4520 }
4521 
4539 int Query_log_event::do_apply_event(Relay_log_info const *rli,
4540  const char *query_arg, uint32 q_len_arg)
4541 {
4542  int expected_error,actual_error= 0;
4543  HA_CREATE_INFO db_options;
4544 
4545  /*
4546  Colleagues: please never free(thd->catalog) in MySQL. This would
4547  lead to bugs as here thd->catalog is a part of an alloced block,
4548  not an entire alloced block (see
4549  Query_log_event::do_apply_event()). Same for thd->db. Thank
4550  you.
4551  */
4552  thd->catalog= catalog_len ? (char *) catalog : (char *)"";
4553  set_thd_db(thd, db, db_len);
4554 
4555  /*
4556  Setting the character set and collation of the current database thd->db.
4557  */
4558  load_db_opt_by_name(thd, thd->db, &db_options);
4559  if (db_options.default_table_charset)
4560  thd->db_charset= db_options.default_table_charset;
4561  thd->variables.auto_increment_increment= auto_increment_increment;
4562  thd->variables.auto_increment_offset= auto_increment_offset;
4563 
4564  /*
4565  InnoDB internally stores the master log position it has executed so far,
4566  i.e. the position just after the COMMIT event.
4567  When InnoDB will want to store, the positions in rli won't have
4568  been updated yet, so group_master_log_* will point to old BEGIN
4569  and event_master_log* will point to the beginning of current COMMIT.
4570  But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
4571  END of the current log event (COMMIT). We save it in rli so that InnoDB can
4572  access it.
4573  */
4574  const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
4575  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
4576 
4577  /*
4578  todo: such cleanup should not be specific to Query event and therefore
4579  is preferable at a common with other event pre-execution point
4580  */
4581  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4582  if (strcmp("COMMIT", query) == 0 && rli->tables_to_lock != NULL)
4583  {
4584  /*
4585  Cleaning-up the last statement context:
4586  the terminal event of the current statement flagged with
4587  STMT_END_F got filtered out in ndb circular replication.
4588  */
4589  int error;
4590  char llbuff[22];
4591  if ((error= rows_event_stmt_cleanup(const_cast<Relay_log_info*>(rli), thd)))
4592  {
4593  const_cast<Relay_log_info*>(rli)->report(ERROR_LEVEL, error,
4594  "Error in cleaning up after an event preceeding the commit; "
4595  "the group log file/position: %s %s",
4596  const_cast<Relay_log_info*>(rli)->get_group_master_log_name(),
4597  llstr(const_cast<Relay_log_info*>(rli)->get_group_master_log_pos(),
4598  llbuff));
4599  }
4600  /*
4601  Executing a part of rli->stmt_done() logics that does not deal
4602  with group position change. The part is redundant now but is
4603  future-change-proof addon, e.g if COMMIT handling will start checking
4604  invariants like IN_STMT flag must be off at committing the transaction.
4605  */
4606  const_cast<Relay_log_info*>(rli)->inc_event_relay_log_pos();
4607  const_cast<Relay_log_info*>(rli)->clear_flag(Relay_log_info::IN_STMT);
4608  }
4609  else
4610  {
4611  const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
4612  }
4613 
4614  /*
4615  Note: We do not need to execute reset_one_shot_variables() if this
4616  db_ok() test fails.
4617  Reason: The db stored in binlog events is the same for SET and for
4618  its companion query. If the SET is ignored because of
4619  db_ok(), the companion query will also be ignored, and if
4620  the companion query is ignored in the db_ok() test of
4621  ::do_apply_event(), then the companion SET also have so
4622  we don't need to reset_one_shot_variables().
4623  */
4624  if (is_trans_keyword() || rpl_filter->db_ok(thd->db))
4625  {
4626  thd->set_time(&when);
4627  thd->set_query_and_id((char*)query_arg, q_len_arg,
4628  thd->charset(), next_query_id());
4629  thd->variables.pseudo_thread_id= thread_id; // for temp tables
4630  attach_temp_tables_worker(thd);
4631  DBUG_PRINT("query",("%s", thd->query()));
4632 
4633  if (ignored_error_code((expected_error= error_code)) ||
4634  !unexpected_error_code(expected_error))
4635  {
4636  if (flags2_inited)
4637  /*
4638  all bits of thd->variables.option_bits which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
4639  must take their value from flags2.
4640  */
4641  thd->variables.option_bits= flags2|(thd->variables.option_bits & ~OPTIONS_WRITTEN_TO_BIN_LOG);
4642  /*
4643  else, we are in a 3.23/4.0 binlog; we previously received a
4644  Rotate_log_event which reset thd->variables.option_bits and sql_mode etc, so
4645  nothing to do.
4646  */
4647  /*
4648  We do not replicate MODE_NO_DIR_IN_CREATE. That is, if the master is a
4649  slave which runs with SQL_MODE=MODE_NO_DIR_IN_CREATE, this should not
4650  force us to ignore the dir too. Imagine you are a ring of machines, and
4651  one has a disk problem so that you temporarily need
4652  MODE_NO_DIR_IN_CREATE on this machine; you don't want it to propagate
4653  elsewhere (you don't want all slaves to start ignoring the dirs).
4654  */
4655  if (sql_mode_inited)
4656  thd->variables.sql_mode=
4657  (sql_mode_t) ((thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE) |
4658  (sql_mode & ~(ulonglong) MODE_NO_DIR_IN_CREATE));
4659  if (charset_inited)
4660  {
4661  if (rli->cached_charset_compare(charset))
4662  {
4663  char *charset_p= charset; // Avoid type-punning warning.
4664  /* Verify that we support the charsets found in the event. */
4665  if (!(thd->variables.character_set_client=
4666  get_charset(uint2korr(charset_p), MYF(MY_WME))) ||
4667  !(thd->variables.collation_connection=
4668  get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
4669  !(thd->variables.collation_server=
4670  get_charset(uint2korr(charset+4), MYF(MY_WME))))
4671  {
4672  /*
4673  We updated the thd->variables with nonsensical values (0). Let's
4674  set them to something safe (i.e. which avoids crash), and we'll
4675  stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
4676  ignore this error).
4677  */
4678  set_slave_thread_default_charset(thd, rli);
4679  goto compare_errors;
4680  }
4681  thd->update_charset(); // for the charset change to take effect
4682  /*
4683  Reset thd->query_string.cs to the newly set value.
4684  Note, there is a small flaw here. For a very short time frame
4685  if the new charset is different from the old charset and
4686  if another thread executes "SHOW PROCESSLIST" after
4687  the above thd->set_query_and_id() and before this thd->set_query(),
4688  and if the current query has some non-ASCII characters,
4689  the another thread may see some '?' marks in the PROCESSLIST
4690  result. This should be acceptable now. This is a reminder
4691  to fix this if any refactoring happens here sometime.
4692  */
4693  thd->set_query((char*) query_arg, q_len_arg, thd->charset());
4694  }
4695  }
4696  if (time_zone_len)
4697  {
4698  String tmp(time_zone_str, time_zone_len, &my_charset_bin);
4699  if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
4700  {
4701  my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
4702  thd->variables.time_zone= global_system_variables.time_zone;
4703  goto compare_errors;
4704  }
4705  }
4706  if (lc_time_names_number)
4707  {
4708  if (!(thd->variables.lc_time_names=
4709  my_locale_by_number(lc_time_names_number)))
4710  {
4711  my_printf_error(ER_UNKNOWN_ERROR,
4712  "Unknown locale: '%d'", MYF(0), lc_time_names_number);
4713  thd->variables.lc_time_names= &my_locale_en_US;
4714  goto compare_errors;
4715  }
4716  }
4717  else
4718  thd->variables.lc_time_names= &my_locale_en_US;
4719  if (charset_database_number)
4720  {
4721  CHARSET_INFO *cs;
4722  if (!(cs= get_charset(charset_database_number, MYF(0))))
4723  {
4724  char buf[20];
4725  int10_to_str((int) charset_database_number, buf, -10);
4726  my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
4727  goto compare_errors;
4728  }
4729  thd->variables.collation_database= cs;
4730  }
4731  else
4732  thd->variables.collation_database= thd->db_charset;
4733 
4734  thd->table_map_for_update= (table_map)table_map_for_update;
4735  thd->set_invoker(&user, &host);
4736  /*
4737  Flag if we need to rollback the statement transaction on
4738  slave if it by chance succeeds.
4739  If we expected a non-zero error code and get nothing and,
4740  it is a concurrency issue or ignorable issue, effects
4741  of the statement should be rolled back.
4742  */
4743  if (expected_error &&
4744  (ignored_error_code(expected_error) ||
4745  concurrency_error_code(expected_error)))
4746  {
4747  thd->variables.option_bits|= OPTION_MASTER_SQL_ERROR;
4748  }
4749  /* Execute the query (note that we bypass dispatch_command()) */
4750  Parser_state parser_state;
4751  if (!parser_state.init(thd, thd->query(), thd->query_length()))
4752  {
4753  thd->m_statement_psi= MYSQL_START_STATEMENT(&thd->m_statement_state,
4754  stmt_info_rpl.m_key,
4755  thd->db, thd->db_length,
4756  thd->charset());
4757  THD_STAGE_INFO(thd, stage_init);
4758  MYSQL_SET_STATEMENT_TEXT(thd->m_statement_psi, thd->query(), thd->query_length());
4759 
4760  mysql_parse(thd, thd->query(), thd->query_length(), &parser_state);
4761  /* Finalize server status flags after executing a statement. */
4762  thd->update_server_status();
4763  log_slow_statement(thd);
4764  }
4765 
4766  thd->variables.option_bits&= ~OPTION_MASTER_SQL_ERROR;
4767 
4768  /*
4769  Resetting the enable_slow_log thd variable.
4770 
4771  We need to reset it back to the opt_log_slow_slave_statements
4772  value after the statement execution (and slow logging
4773  is done). It might have changed if the statement was an
4774  admin statement (in which case, down in mysql_parse execution
4775  thd->enable_slow_log is set to the value of
4776  opt_log_slow_admin_statements).
4777  */
4778  thd->enable_slow_log= opt_log_slow_slave_statements;
4779  }
4780  else
4781  {
4782  /*
4783  The query got a really bad error on the master (thread killed etc),
4784  which could be inconsistent. Parse it to test the table names: if the
4785  replicate-*-do|ignore-table rules say "this query must be ignored" then
4786  we exit gracefully; otherwise we warn about the bad error and tell DBA
4787  to check/fix it.
4788  */
4789  if (mysql_test_parse_for_slave(thd, thd->query(), thd->query_length()))
4790  clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
4791  else
4792  {
4793  rli->report(ERROR_LEVEL, expected_error,
4794  "\
4795 Query partially completed on the master (error on master: %d) \
4796 and was aborted. There is a chance that your master is inconsistent at this \
4797 point. If you are sure that your master is ok, run this query manually on the \
4798 slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
4799 START SLAVE; . Query: '%s'", expected_error, thd->query());
4800  thd->is_slave_error= 1;
4801  }
4802  goto end;
4803  }
4804 
4805  /* If the query was not ignored, it is printed to the general log */
4806  if (!thd->is_error() || thd->get_stmt_da()->sql_errno() != ER_SLAVE_IGNORED_TABLE)
4807  {
4808  /* log the rewritten query if the query was rewritten
4809  and the option to log raw was not set.
4810 
4811  There is an assumption here. We assume that query log
4812  events can never have multi-statement queries, thus the
4813  parsed statement is the same as the raw one.
4814  */
4815  if (opt_log_raw || thd->rewritten_query.length() == 0)
4816  general_log_write(thd, COM_QUERY, thd->query(), thd->query_length());
4817  else
4818  general_log_write(thd, COM_QUERY, thd->rewritten_query.c_ptr_safe(),
4819  thd->rewritten_query.length());
4820  }
4821 
4822 compare_errors:
4823  /*
4824  In the slave thread, we may sometimes execute some DROP / * 40005
4825  TEMPORARY * / TABLE that come from parts of binlogs (likely if we
4826  use RESET SLAVE or CHANGE MASTER TO), while the temporary table
4827  has already been dropped. To ignore such irrelevant "table does
4828  not exist errors", we silently clear the error if TEMPORARY was used.
4829  */
4830  if (thd->lex->sql_command == SQLCOM_DROP_TABLE && thd->lex->drop_temporary &&
4831  thd->is_error() && thd->get_stmt_da()->sql_errno() == ER_BAD_TABLE_ERROR &&
4832  !expected_error)
4833  thd->get_stmt_da()->reset_diagnostics_area();
4834  /*
4835  If we expected a non-zero error code, and we don't get the same error
4836  code, and it should be ignored or is related to a concurrency issue.
4837  */
4838  actual_error= thd->is_error() ? thd->get_stmt_da()->sql_errno() : 0;
4839  DBUG_PRINT("info",("expected_error: %d sql_errno: %d",
4840  expected_error, actual_error));
4841 
4842  if ((expected_error && expected_error != actual_error &&
4843  !concurrency_error_code(expected_error)) &&
4844  !ignored_error_code(actual_error) &&
4845  !ignored_error_code(expected_error))
4846  {
4847  rli->report(ERROR_LEVEL, 0,
4848  "\
4849 Query caused different errors on master and slave. \
4850 Error on master: message (format)='%s' error code=%d ; \
4851 Error on slave: actual message='%s', error code=%d. \
4852 Default database: '%s'. Query: '%s'",
4853  ER_SAFE(expected_error),
4854  expected_error,
4855  actual_error ? thd->get_stmt_da()->message() : "no error",
4856  actual_error,
4857  print_slave_db_safe(db), query_arg);
4858  thd->is_slave_error= 1;
4859  }
4860  /*
4861  If we get the same error code as expected and it is not a concurrency
4862  issue, or should be ignored.
4863  */
4864  else if ((expected_error == actual_error &&
4865  !concurrency_error_code(expected_error)) ||
4866  ignored_error_code(actual_error))
4867  {
4868  DBUG_PRINT("info",("error ignored"));
4869  if (log_warnings > 1 && ignored_error_code(actual_error))
4870  {
4871  rli->report(WARNING_LEVEL, actual_error,
4872  "Could not execute %s event. Detailed error: %s;",
4873  get_type_str(), thd->get_stmt_da()->message());
4874  }
4875  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
4876  thd->killed= THD::NOT_KILLED;
4877  }
4878  /*
4879  Other cases: mostly we expected no error and get one.
4880  */
4881  else if (thd->is_slave_error || thd->is_fatal_error)
4882  {
4883  if (!is_silent_error(thd))
4884  {
4885  rli->report(ERROR_LEVEL, actual_error,
4886  "Error '%s' on query. Default database: '%s'. Query: '%s'",
4887  (actual_error ? thd->get_stmt_da()->message() :
4888  "unexpected success or fatal error"),
4889  print_slave_db_safe(thd->db), query_arg);
4890  }
4891  thd->is_slave_error= 1;
4892  }
4893 
4894  /*
4895  TODO: compare the values of "affected rows" around here. Something
4896  like:
4897  if ((uint32) affected_in_event != (uint32) affected_on_slave)
4898  {
4899  sql_print_error("Slave: did not get the expected number of affected \
4900  rows running query from master - expected %d, got %d (this numbers \
4901  should have matched modulo 4294967296).", 0, ...);
4902  thd->is_slave_error = 1;
4903  }
4904  We may also want an option to tell the slave to ignore "affected"
4905  mismatch. This mismatch could be implemented with a new ER_ code, and
4906  to ignore it you would use --slave-skip-errors...
4907 
4908  To do the comparison we need to know the value of "affected" which the
4909  above mysql_parse() computed. And we need to know the value of
4910  "affected" in the master's binlog. Both will be implemented later. The
4911  important thing is that we now have the format ready to log the values
4912  of "affected" in the binlog. So we can release 5.0.0 before effectively
4913  logging "affected" and effectively comparing it.
4914  */
4915  } /* End of if (db_ok(... */
4916 
4917  {
4925  // TODO: address the middle-group killing in MTS case
4926 
4927  DBUG_EXECUTE_IF("stop_slave_middle_group",
4928  if (strcmp("COMMIT", query) != 0 &&
4929  strcmp("BEGIN", query) != 0)
4930  {
4931  if (thd->transaction.all.cannot_safely_rollback())
4932  const_cast<Relay_log_info*>(rli)->abort_slave= 1;
4933  };);
4934  }
4935 
4936 end:
4937 
4938  if (thd->temporary_tables)
4939  detach_temp_tables_worker(thd);
4940  /*
4941  Probably we have set thd->query, thd->db, thd->catalog to point to places
4942  in the data_buf of this event. Now the event is going to be deleted
4943  probably, so data_buf will be freed, so the thd->... listed above will be
4944  pointers to freed memory.
4945  So we must set them to 0, so that those bad pointers values are not later
4946  used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
4947  don't suffer from these assignments to 0 as DROP TEMPORARY
4948  TABLE uses the db.table syntax.
4949  */
4950  thd->catalog= 0;
4951  thd->set_db(NULL, 0); /* will free the current database */
4952  thd->reset_query();
4953  thd->lex->sql_command= SQLCOM_END;
4954  DBUG_PRINT("info", ("end: query= 0"));
4955 
4956  /* Mark the statement completed. */
4957  MYSQL_END_STATEMENT(thd->m_statement_psi, thd->get_stmt_da());
4958  thd->m_statement_psi= NULL;
4959 
4960  /*
4961  As a disk space optimization, future masters will not log an event for
4962  LAST_INSERT_ID() if that function returned 0 (and thus they will be able
4963  to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
4964  variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
4965  resetting below we are ready to support that.
4966  */
4967  thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
4968  thd->first_successful_insert_id_in_prev_stmt= 0;
4969  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
4970  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
4971  return thd->is_slave_error;
4972 }
4973 
4974 int Query_log_event::do_update_pos(Relay_log_info *rli)
4975 {
4976  /*
4977  Note that we will not increment group* positions if we are just
4978  after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
4979  from its following updating query.
4980  */
4981  int ret= 0;
4982  if (thd->one_shot_set)
4983  {
4984  rli->inc_event_relay_log_pos();
4985  }
4986  else
4987  ret= Log_event::do_update_pos(rli);
4988 
4989  DBUG_EXECUTE_IF("crash_after_commit_and_update_pos",
4990  if (!strcmp("COMMIT", query))
4991  {
4992  sql_print_information("Crashing crash_after_commit_and_update_pos.");
4993  rli->flush_info(true);
4994  ha_flush_logs(0);
4995  DBUG_SUICIDE();
4996  }
4997  );
4998 
4999  return ret;
5000 }
5001 
5002 
5004 Query_log_event::do_shall_skip(Relay_log_info *rli)
5005 {
5006  DBUG_ENTER("Query_log_event::do_shall_skip");
5007  DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
5008  DBUG_ASSERT(query && q_len > 0);
5009 
5010  if (rli->slave_skip_counter > 0)
5011  {
5012  if (strcmp("BEGIN", query) == 0)
5013  {
5014  thd->variables.option_bits|= OPTION_BEGIN;
5015  DBUG_RETURN(Log_event::continue_group(rli));
5016  }
5017 
5018  if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
5019  {
5020  thd->variables.option_bits&= ~OPTION_BEGIN;
5021  DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
5022  }
5023  }
5024  DBUG_RETURN(Log_event::do_shall_skip(rli));
5025 }
5026 
5027 #endif
5028 
5029 
5030 /**************************************************************************
5031  Start_log_event_v3 methods
5032 **************************************************************************/
5033 
5034 #ifndef MYSQL_CLIENT
5035 Start_log_event_v3::Start_log_event_v3()
5036  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
5037  dont_set_created(0)
5038 {
5039  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5040 }
5041 #endif
5042 
5043 /*
5044  Start_log_event_v3::pack_info()
5045 */
5046 
5047 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5048 int Start_log_event_v3::pack_info(Protocol *protocol)
5049 {
5050  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
5051  pos= strmov(buf, "Server ver: ");
5052  pos= strmov(pos, server_version);
5053  pos= strmov(pos, ", Binlog ver: ");
5054  pos= int10_to_str(binlog_version, pos, 10);
5055  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5056  return 0;
5057 }
5058 #endif
5059 
5060 
5061 /*
5062  Start_log_event_v3::print()
5063 */
5064 
5065 #ifdef MYSQL_CLIENT
5066 void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5067 {
5068  DBUG_ENTER("Start_log_event_v3::print");
5069 
5070  IO_CACHE *const head= &print_event_info->head_cache;
5071 
5072  if (!print_event_info->short_form)
5073  {
5074  print_header(head, print_event_info, FALSE);
5075  my_b_printf(head, "\tStart: binlog v %d, server v %s created ",
5076  binlog_version, server_version);
5077  print_timestamp(head, NULL);
5078  if (created)
5079  my_b_printf(head," at startup");
5080  my_b_printf(head, "\n");
5081  if (flags & LOG_EVENT_BINLOG_IN_USE_F)
5082  my_b_printf(head, "# Warning: this binlog is either in use or was not "
5083  "closed properly.\n");
5084  }
5085  if (!is_artificial_event() && created)
5086  {
5087 #ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
5088  /*
5089  This is for mysqlbinlog: like in replication, we want to delete the stale
5090  tmp files left by an unclean shutdown of mysqld (temporary tables)
5091  and rollback unfinished transaction.
5092  Probably this can be done with RESET CONNECTION (syntax to be defined).
5093  */
5094  my_b_printf(head,"RESET CONNECTION%s\n", print_event_info->delimiter);
5095 #else
5096  my_b_printf(head,"ROLLBACK%s\n", print_event_info->delimiter);
5097 #endif
5098  }
5099  if (temp_buf &&
5100  print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
5101  !print_event_info->short_form)
5102  {
5103  if (print_event_info->base64_output_mode != BASE64_OUTPUT_DECODE_ROWS)
5104  my_b_printf(head, "BINLOG '\n");
5105  print_base64(head, print_event_info, FALSE);
5106  print_event_info->printed_fd_event= TRUE;
5107  }
5108  DBUG_VOID_RETURN;
5109 }
5110 #endif /* MYSQL_CLIENT */
5111 
5112 /*
5113  Start_log_event_v3::Start_log_event_v3()
5114 */
5115 
5116 Start_log_event_v3::Start_log_event_v3(const char* buf,
5118  *description_event)
5119  :Log_event(buf, description_event)
5120 {
5121  buf+= description_event->common_header_len;
5122  binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
5123  memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
5124  ST_SERVER_VER_LEN);
5125  // prevent overrun if log is corrupted on disk
5126  server_version[ST_SERVER_VER_LEN-1]= 0;
5127  created= uint4korr(buf+ST_CREATED_OFFSET);
5128  dont_set_created= 1;
5129 }
5130 
5131 
5132 /*
5133  Start_log_event_v3::write()
5134 */
5135 
5136 #ifndef MYSQL_CLIENT
5137 bool Start_log_event_v3::write(IO_CACHE* file)
5138 {
5139  char buff[START_V3_HEADER_LEN];
5140  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5141  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5142  if (!dont_set_created)
5143  created= get_time();
5144  int4store(buff + ST_CREATED_OFFSET,created);
5145  return (write_header(file, sizeof(buff)) ||
5146  wrapper_my_b_safe_write(file, (uchar*) buff, sizeof(buff)) ||
5147  write_footer(file));
5148 }
5149 #endif
5150 
5151 
5152 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5153 
5172 int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
5173 {
5174  DBUG_ENTER("Start_log_event_v3::do_apply_event");
5175  int error= 0;
5176  switch (binlog_version)
5177  {
5178  case 3:
5179  case 4:
5180  /*
5181  This can either be 4.x (then a Start_log_event_v3 is only at master
5182  startup so we are sure the master has restarted and cleared his temp
5183  tables; the event always has 'created'>0) or 5.0 (then we have to test
5184  'created').
5185  */
5186  if (created)
5187  {
5188  error= close_temporary_tables(thd);
5189  cleanup_load_tmpdir();
5190  }
5191  else
5192  {
5193  /*
5194  Set all temporary tables thread references to the current thread
5195  as they may point to the "old" SQL slave thread in case of its
5196  restart.
5197  */
5198  TABLE *table;
5199  for (table= thd->temporary_tables; table; table= table->next)
5200  table->in_use= thd;
5201  }
5202  break;
5203 
5204  /*
5205  Now the older formats; in that case load_tmpdir is cleaned up by the I/O
5206  thread.
5207  */
5208  case 1:
5209  if (strncmp(rli->get_rli_description_event()->server_version,
5210  "3.23.57",7) >= 0 && created)
5211  {
5212  /*
5213  Can distinguish, based on the value of 'created': this event was
5214  generated at master startup.
5215  */
5216  error= close_temporary_tables(thd);
5217  }
5218  /*
5219  Otherwise, can't distinguish a Start_log_event generated at
5220  master startup and one generated by master FLUSH LOGS, so cannot
5221  be sure temp tables have to be dropped. So do nothing.
5222  */
5223  break;
5224  default:
5225  /* this case is impossible */
5226  DBUG_RETURN(1);
5227  }
5228  DBUG_RETURN(error);
5229 }
5230 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5231 
5232 /***************************************************************************
5233  Format_description_log_event methods
5234 ****************************************************************************/
5235 
5254 Format_description_log_event(uint8 binlog_ver, const char* server_ver)
5255  :Start_log_event_v3(), event_type_permutation(0)
5256 {
5257  binlog_version= binlog_ver;
5258  switch (binlog_ver) {
5259  case 4: /* MySQL 5.0 */
5260  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
5261  DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
5262  strmov(server_version, "5.0.34"););
5263  common_header_len= LOG_EVENT_HEADER_LEN;
5264  number_of_event_types= LOG_EVENT_TYPES;
5265  /* we'll catch my_malloc() error in is_valid() */
5266  post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8)
5267  + BINLOG_CHECKSUM_ALG_DESC_LEN,
5268  MYF(0));
5269  /*
5270  This long list of assignments is not beautiful, but I see no way to
5271  make it nicer, as the right members are #defines, not array members, so
5272  it's impossible to write a loop.
5273  */
5274  if (post_header_len)
5275  {
5276 #ifndef DBUG_OFF
5277  // Allows us to sanity-check that all events initialized their
5278  // events (see the end of this 'if' block).
5279  memset(post_header_len, 255, number_of_event_types*sizeof(uint8));
5280 #endif
5281 
5282  /* Note: all event types must explicitly fill in their lengths here. */
5283  post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5284  post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
5285  post_header_len[STOP_EVENT-1]= STOP_HEADER_LEN;
5286  post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
5287  post_header_len[INTVAR_EVENT-1]= INTVAR_HEADER_LEN;
5288  post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5289  post_header_len[SLAVE_EVENT-1]= 0; /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5290  post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5291  post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5292  post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5293  post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5294  post_header_len[NEW_LOAD_EVENT-1]= NEW_LOAD_HEADER_LEN;
5295  post_header_len[RAND_EVENT-1]= RAND_HEADER_LEN;
5296  post_header_len[USER_VAR_EVENT-1]= USER_VAR_HEADER_LEN;
5297  post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
5298  post_header_len[XID_EVENT-1]= XID_HEADER_LEN;
5299  post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= BEGIN_LOAD_QUERY_HEADER_LEN;
5300  post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
5301  /*
5302  The PRE_GA events are never be written to any binlog, but
5303  their lengths are included in Format_description_log_event.
5304  Hence, we need to be assign some value here, to avoid reading
5305  uninitialized memory when the array is written to disk.
5306  */
5307  post_header_len[PRE_GA_WRITE_ROWS_EVENT-1] = 0;
5308  post_header_len[PRE_GA_UPDATE_ROWS_EVENT-1] = 0;
5309  post_header_len[PRE_GA_DELETE_ROWS_EVENT-1] = 0;
5310 
5311  post_header_len[TABLE_MAP_EVENT-1]= TABLE_MAP_HEADER_LEN;
5312  post_header_len[WRITE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5313  post_header_len[UPDATE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5314  post_header_len[DELETE_ROWS_EVENT_V1-1]= ROWS_HEADER_LEN_V1;
5315  /*
5316  We here have the possibility to simulate a master of before we changed
5317  the table map id to be stored in 6 bytes: when it was stored in 4
5318  bytes (=> post_header_len was 6). This is used to test backward
5319  compatibility.
5320  This code can be removed after a few months (today is Dec 21st 2005),
5321  when we know that the 4-byte masters are not deployed anymore (check
5322  with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
5323  too.
5324  */
5325  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
5326  post_header_len[TABLE_MAP_EVENT-1]=
5327  post_header_len[WRITE_ROWS_EVENT_V1-1]=
5328  post_header_len[UPDATE_ROWS_EVENT_V1-1]=
5329  post_header_len[DELETE_ROWS_EVENT_V1-1]= 6;);
5330  post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
5331  post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
5332  post_header_len[IGNORABLE_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5333  post_header_len[ROWS_QUERY_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5334  post_header_len[WRITE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5335  post_header_len[UPDATE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5336  post_header_len[DELETE_ROWS_EVENT-1]= ROWS_HEADER_LEN_V2;
5337  post_header_len[GTID_LOG_EVENT-1]=
5338  post_header_len[ANONYMOUS_GTID_LOG_EVENT-1]=
5340  post_header_len[PREVIOUS_GTIDS_LOG_EVENT-1]= IGNORABLE_HEADER_LEN;
5341 
5342  // Sanity-check that all post header lengths are initialized.
5343  int i;
5344  for (i=0; i<number_of_event_types; i++)
5345  DBUG_ASSERT(post_header_len[i] != 255);
5346  }
5347  break;
5348 
5349  case 1: /* 3.23 */
5350  case 3: /* 4.0.x x>=2 */
5351  /*
5352  We build an artificial (i.e. not sent by the master) event, which
5353  describes what those old master versions send.
5354  */
5355  if (binlog_ver==1)
5356  strmov(server_version, server_ver ? server_ver : "3.23");
5357  else
5358  strmov(server_version, server_ver ? server_ver : "4.0");
5359  common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
5360  LOG_EVENT_MINIMAL_HEADER_LEN;
5361  /*
5362  The first new event in binlog version 4 is Format_desc. So any event type
5363  after that does not exist in older versions. We use the events known by
5364  version 3, even if version 1 had only a subset of them (this is not a
5365  problem: it uses a few bytes for nothing but unifies code; it does not
5366  make the slave detect less corruptions).
5367  */
5368  number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
5369  post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
5370  MYF(0));
5371  if (post_header_len)
5372  {
5373  post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
5374  post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
5375  post_header_len[STOP_EVENT-1]= 0;
5376  post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
5377  post_header_len[INTVAR_EVENT-1]= 0;
5378  post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
5379  post_header_len[SLAVE_EVENT-1]= 0; /* Unused because the code for Slave log event was removed. (15th Oct. 2010) */
5380  post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
5381  post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
5382  post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
5383  post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
5384  post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
5385  post_header_len[RAND_EVENT-1]= 0;
5386  post_header_len[USER_VAR_EVENT-1]= 0;
5387  }
5388  break;
5389  default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
5390  post_header_len= 0; /* will make is_valid() fail */
5391  break;
5392  }
5394  checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5395 }
5396 
5397 
5418  uint event_len,
5419  const
5421  description_event)
5422  :Start_log_event_v3(buf, description_event), event_type_permutation(0)
5423 {
5424  ulong ver_calc;
5425  DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
5426  buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
5427  if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
5428  DBUG_VOID_RETURN; /* sanity check */
5429  number_of_event_types=
5430  event_len - (LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET + 1);
5431  DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
5432  common_header_len, number_of_event_types));
5433  /* If alloc fails, we'll detect it in is_valid() */
5434 
5435  post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
5436  number_of_event_types*
5437  sizeof(*post_header_len),
5438  MYF(0));
5440  if ((ver_calc= get_version_product()) >= checksum_version_product)
5441  {
5442  /* the last bytes are the checksum alg desc and value (or value's room) */
5443  number_of_event_types -= BINLOG_CHECKSUM_ALG_DESC_LEN;
5444  /*
5445  FD from the checksum-home version server (ver_calc ==
5446  checksum_version_product) must have
5447  number_of_event_types == LOG_EVENT_TYPES.
5448  */
5449  DBUG_ASSERT(ver_calc != checksum_version_product ||
5450  number_of_event_types == LOG_EVENT_TYPES);
5451  checksum_alg= post_header_len[number_of_event_types];
5452  }
5453  else
5454  {
5455  checksum_alg= (uint8) BINLOG_CHECKSUM_ALG_UNDEF;
5456  }
5457 
5458  /*
5459  In some previous versions, the events were given other event type
5460  id numbers than in the present version. When replicating from such
5461  a version, we therefore set up an array that maps those id numbers
5462  to the id numbers of the present server.
5463 
5464  If post_header_len is null, it means malloc failed, and is_valid
5465  will fail, so there is no need to do anything.
5466 
5467  The trees in which events have wrong id's are:
5468 
5469  mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
5470  mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
5471  mysql-5.1-wl2325-no-dd
5472 
5473  (this was found by grepping for two lines in sequence where the
5474  first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
5475  "TABLE_MAP_EVENT," in log_event.h in all trees)
5476 
5477  In these trees, the following server_versions existed since
5478  TABLE_MAP_EVENT was introduced:
5479 
5480  5.1.1-a_drop5p3 5.1.1-a_drop5p4 5.1.1-alpha
5481  5.1.2-a_drop5p10 5.1.2-a_drop5p11 5.1.2-a_drop5p12
5482  5.1.2-a_drop5p13 5.1.2-a_drop5p14 5.1.2-a_drop5p15
5483  5.1.2-a_drop5p16 5.1.2-a_drop5p16b 5.1.2-a_drop5p16c
5484  5.1.2-a_drop5p17 5.1.2-a_drop5p4 5.1.2-a_drop5p5
5485  5.1.2-a_drop5p6 5.1.2-a_drop5p7 5.1.2-a_drop5p8
5486  5.1.2-a_drop5p9 5.1.3-a_drop5p17 5.1.3-a_drop5p17b
5487  5.1.3-a_drop5p17c 5.1.4-a_drop5p18 5.1.4-a_drop5p19
5488  5.1.4-a_drop5p20 5.1.4-a_drop6p0 5.1.4-a_drop6p1
5489  5.1.4-a_drop6p2 5.1.5-a_drop5p20 5.2.0-a_drop6p3
5490  5.2.0-a_drop6p4 5.2.0-a_drop6p5 5.2.0-a_drop6p6
5491  5.2.1-a_drop6p10 5.2.1-a_drop6p11 5.2.1-a_drop6p12
5492  5.2.1-a_drop6p6 5.2.1-a_drop6p7 5.2.1-a_drop6p8
5493  5.2.2-a_drop6p13 5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
5494  5.2.2-a_drop6p13c
5495 
5496  (this was found by grepping for "mysql," in all historical
5497  versions of configure.in in the trees listed above).
5498 
5499  There are 5.1.1-alpha versions that use the new event id's, so we
5500  do not test that version string. So replication from 5.1.1-alpha
5501  with the other event id's to a new version does not work.
5502  Moreover, we can safely ignore the part after drop[56]. This
5503  allows us to simplify the big list above to the following regexes:
5504 
5505  5\.1\.[1-5]-a_drop5.*
5506  5\.1\.4-a_drop6.*
5507  5\.2\.[0-2]-a_drop6.*
5508 
5509  This is what we test for in the 'if' below.
5510  */
5511  if (post_header_len &&
5512  server_version[0] == '5' && server_version[1] == '.' &&
5513  server_version[3] == '.' &&
5514  strncmp(server_version + 5, "-a_drop", 7) == 0 &&
5515  ((server_version[2] == '1' &&
5516  server_version[4] >= '1' && server_version[4] <= '5' &&
5517  server_version[12] == '5') ||
5518  (server_version[2] == '1' &&
5519  server_version[4] == '4' &&
5520  server_version[12] == '6') ||
5521  (server_version[2] == '2' &&
5522  server_version[4] >= '0' && server_version[4] <= '2' &&
5523  server_version[12] == '6')))
5524  {
5525  if (number_of_event_types != 22)
5526  {
5527  DBUG_PRINT("info", (" number_of_event_types=%d",
5528  number_of_event_types));
5529  /* this makes is_valid() return false. */
5530  my_free(post_header_len);
5531  post_header_len= NULL;
5532  DBUG_VOID_RETURN;
5533  }
5534  static const uint8 perm[23]=
5535  {
5536  UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
5537  INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
5538  APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
5539  NEW_LOAD_EVENT,
5540  RAND_EVENT, USER_VAR_EVENT,
5541  FORMAT_DESCRIPTION_EVENT,
5542  TABLE_MAP_EVENT,
5543  PRE_GA_WRITE_ROWS_EVENT,
5544  PRE_GA_UPDATE_ROWS_EVENT,
5545  PRE_GA_DELETE_ROWS_EVENT,
5546  XID_EVENT,
5547  BEGIN_LOAD_QUERY_EVENT,
5548  EXECUTE_LOAD_QUERY_EVENT,
5549  };
5550  event_type_permutation= perm;
5551  /*
5552  Since we use (permuted) event id's to index the post_header_len
5553  array, we need to permute the post_header_len array too.
5554  */
5555  uint8 post_header_len_temp[23];
5556  for (int i= 1; i < 23; i++)
5557  post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
5558  for (int i= 0; i < 22; i++)
5559  post_header_len[i] = post_header_len_temp[i];
5560  }
5561  DBUG_VOID_RETURN;
5562 }
5563 
5564 #ifndef MYSQL_CLIENT
5565 bool Format_description_log_event::write(IO_CACHE* file)
5566 {
5567  bool ret;
5568  bool no_checksum;
5569  /*
5570  We don't call Start_log_event_v3::write() because this would make 2
5571  my_b_safe_write().
5572  */
5573  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN + BINLOG_CHECKSUM_ALG_DESC_LEN];
5574  size_t rec_size= sizeof(buff);
5575  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
5576  memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
5577  if (!dont_set_created)
5578  created= get_time();
5579  int4store(buff + ST_CREATED_OFFSET,created);
5580  buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
5581  memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET + 1, (uchar*) post_header_len,
5582  LOG_EVENT_TYPES);
5583  /*
5584  if checksum is requested
5585  record the checksum-algorithm descriptor next to
5586  post_header_len vector which will be followed by the checksum value.
5587  Master is supposed to trigger checksum computing by binlog_checksum_options,
5588  slave does it via marking the event according to
5589  FD_queue checksum_alg value.
5590  */
5591  compile_time_assert(sizeof(BINLOG_CHECKSUM_ALG_DESC_LEN == 1));
5592 #ifndef DBUG_OFF
5593  data_written= 0; // to prepare for need_checksum assert
5594 #endif
5595  buff[FORMAT_DESCRIPTION_HEADER_LEN]= need_checksum() ?
5596  checksum_alg : (uint8) BINLOG_CHECKSUM_ALG_OFF;
5597  /*
5598  FD of checksum-aware server is always checksum-equipped, (V) is in,
5599  regardless of @@global.binlog_checksum policy.
5600  Thereby a combination of (A) == 0, (V) != 0 means
5601  it's the checksum-aware server's FD event that heads checksum-free binlog
5602  file.
5603  Here 0 stands for checksumming OFF to evaluate (V) as 0 is that case.
5604  A combination of (A) != 0, (V) != 0 denotes FD of the checksum-aware server
5605  heading the checksummed binlog.
5606  (A), (V) presence in FD of the checksum-aware server makes the event
5607  1 + 4 bytes bigger comparing to the former FD.
5608  */
5609 
5610  if ((no_checksum= (checksum_alg == BINLOG_CHECKSUM_ALG_OFF)))
5611  {
5612  checksum_alg= BINLOG_CHECKSUM_ALG_CRC32; // Forcing (V) room to fill anyway
5613  }
5614  ret= (write_header(file, rec_size) ||
5615  wrapper_my_b_safe_write(file, buff, rec_size) ||
5616  write_footer(file));
5617  if (no_checksum)
5618  checksum_alg= BINLOG_CHECKSUM_ALG_OFF;
5619  return ret;
5620 }
5621 #endif
5622 
5623 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5624 int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
5625 {
5626  int ret= 0;
5627  DBUG_ENTER("Format_description_log_event::do_apply_event");
5628 
5629  /*
5630  As a transaction NEVER spans on 2 or more binlogs:
5631  if we have an active transaction at this point, the master died
5632  while writing the transaction to the binary log, i.e. while
5633  flushing the binlog cache to the binlog. XA guarantees that master has
5634  rolled back. So we roll back.
5635  Note: this event could be sent by the master to inform us of the
5636  format of its binlog; in other words maybe it is not at its
5637  original place when it comes to us; we'll know this by checking
5638  log_pos ("artificial" events have log_pos == 0).
5639  */
5640  if (!is_artificial_event() && created && thd->transaction.all.ha_list)
5641  {
5642  /* This is not an error (XA is safe), just an information */
5643  rli->report(INFORMATION_LEVEL, 0,
5644  "Rolling back unfinished transaction (no COMMIT "
5645  "or ROLLBACK in relay log). A probable cause is that "
5646  "the master died while writing the transaction to "
5647  "its binary log, thus rolled back too.");
5648  const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
5649  }
5650 
5651  /*
5652  If this event comes from ourselves, there is no cleaning task to
5653  perform, we don't call Start_log_event_v3::do_apply_event()
5654  (this was just to update the log's description event).
5655  */
5656  if (server_id != (uint32) ::server_id)
5657  {
5658  /*
5659  If the event was not requested by the slave i.e. the master sent
5660  it while the slave asked for a position >4, the event will make
5661  rli->group_master_log_pos advance. Say that the slave asked for
5662  position 1000, and the Format_desc event's end is 96. Then in
5663  the beginning of replication rli->group_master_log_pos will be
5664  0, then 96, then jump to first really asked event (which is
5665  >96). So this is ok.
5666  */
5667  ret= Start_log_event_v3::do_apply_event(rli);
5668  }
5669 
5670  if (!ret)
5671  {
5672  /* Save the information describing this binlog */
5673  const_cast<Relay_log_info *>(rli)->set_rli_description_event(this);
5674  }
5675 
5676  DBUG_RETURN(ret);
5677 }
5678 
5679 int Format_description_log_event::do_update_pos(Relay_log_info *rli)
5680 {
5681  if (server_id == (uint32) ::server_id)
5682  {
5683  /*
5684  We only increase the relay log position if we are skipping
5685  events and do not touch any group_* variables, nor flush the
5686  relay log info. If there is a crash, we will have to re-skip
5687  the events again, but that is a minor issue.
5688 
5689  If we do not skip stepping the group log position (and the
5690  server id was changed when restarting the server), it might well
5691  be that we start executing at a position that is invalid, e.g.,
5692  at a Rows_log_event or a Query_log_event preceeded by a
5693  Intvar_log_event instead of starting at a Table_map_log_event or
5694  the Intvar_log_event respectively.
5695  */
5696  rli->inc_event_relay_log_pos();
5697  return 0;
5698  }
5699  else
5700  {
5701  return Log_event::do_update_pos(rli);
5702  }
5703 }
5704 
5706 Format_description_log_event::do_shall_skip(Relay_log_info *rli)
5707 {
5709 }
5710 
5711 #endif
5712 
5713 
5719 {
5720  do_server_version_split(server_version, server_version_split);
5721 
5722  DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
5723  " '%s' %d %d %d", server_version,
5724  server_version_split[0],
5725  server_version_split[1], server_version_split[2]));
5726 }
5727 
5733 {
5734  return version_product(server_version_split);
5735 }
5736 
5742 {
5743  return get_version_product() < checksum_version_product;
5744 }
5745 
5755 uint8 get_checksum_alg(const char* buf, ulong len)
5756 {
5757  uint8 ret;
5758  char version[ST_SERVER_VER_LEN];
5759  uchar version_split[3];
5760 
5761  DBUG_ENTER("get_checksum_alg");
5762  DBUG_ASSERT(buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT);
5763 
5764  memcpy(version, buf +
5765  buf[LOG_EVENT_MINIMAL_HEADER_LEN + ST_COMMON_HEADER_LEN_OFFSET]
5766  + ST_SERVER_VER_OFFSET, ST_SERVER_VER_LEN);
5767  version[ST_SERVER_VER_LEN - 1]= 0;
5768 
5769  do_server_version_split(version, version_split);
5770  ret= (version_product(version_split) < checksum_version_product) ?
5771  (uint8) BINLOG_CHECKSUM_ALG_UNDEF :
5772  * (uint8*) (buf + len - BINLOG_CHECKSUM_LEN - BINLOG_CHECKSUM_ALG_DESC_LEN);
5773  DBUG_ASSERT(ret == BINLOG_CHECKSUM_ALG_OFF ||
5774  ret == BINLOG_CHECKSUM_ALG_UNDEF ||
5775  ret == BINLOG_CHECKSUM_ALG_CRC32);
5776  DBUG_RETURN(ret);
5777 }
5778 
5779 
5780  /**************************************************************************
5781  Load_log_event methods
5782  General note about Load_log_event: the binlogging of LOAD DATA INFILE is
5783  going to be changed in 5.0 (or maybe in 5.1; not decided yet).
5784  However, the 5.0 slave could still have to read such events (from a 4.x
5785  master), convert them (which just means maybe expand the header, when 5.0
5786  servers have a UID in events) (remember that whatever is after the header
5787  will be like in 4.x, as this event's format is not modified in 5.0 as we
5788  will use new types of events to log the new LOAD DATA INFILE features).
5789  To be able to read/convert, we just need to not assume that the common
5790  header is of length LOG_EVENT_HEADER_LEN (we must use the description
5791  event).
5792  Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
5793  between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
5794  positions displayed in SHOW SLAVE STATUS then are fine too).
5795  **************************************************************************/
5796 
5797 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5798 uint Load_log_event::get_query_buffer_length()
5799 {
5800  return
5801  //the DB name may double if we escape the quote character
5802  5 + 2*db_len + 3 +
5803  18 + fname_len + 2 + // "LOAD DATA INFILE 'file''"
5804  11 + // "CONCURRENT "
5805  7 + // LOCAL
5806  9 + // " REPLACE or IGNORE "
5807  13 + table_name_len*2 + // "INTO TABLE `table`"
5808  21 + sql_ex.field_term_len*4 + 2 + // " FIELDS TERMINATED BY 'str'"
5809  23 + sql_ex.enclosed_len*4 + 2 + // " OPTIONALLY ENCLOSED BY 'str'"
5810  12 + sql_ex.escaped_len*4 + 2 + // " ESCAPED BY 'str'"
5811  21 + sql_ex.line_term_len*4 + 2 + // " LINES TERMINATED BY 'str'"
5812  19 + sql_ex.line_start_len*4 + 2 + // " LINES STARTING BY 'str'"
5813  15 + 22 + // " IGNORE xxx LINES"
5814  3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
5815 }
5816 
5817 
5818 void Load_log_event::print_query(bool need_db, const char *cs, char *buf,
5819  char **end, char **fn_start, char **fn_end)
5820 {
5821  char quoted_id[1 + NAME_LEN * 2 + 2];//quoted length
5822  int quoted_id_len= 0;
5823  char *pos= buf;
5824 
5825  if (need_db && db && db_len)
5826  {
5827  pos= strmov(pos, "use ");
5828 #ifdef MYSQL_SERVER
5829  quoted_id_len= my_strmov_quoted_identifier(this->thd, (char *) quoted_id,
5830  db, 0);
5831 #else
5832  quoted_id_len= my_strmov_quoted_identifier((char *) quoted_id, db);
5833 #endif
5834  quoted_id[quoted_id_len]= '\0';
5835  pos= strmov(pos, quoted_id);
5836  pos= strmov(pos, "; ");
5837  }
5838 
5839  pos= strmov(pos, "LOAD DATA ");
5840 
5841  if (is_concurrent)
5842  pos= strmov(pos, "CONCURRENT ");
5843 
5844  if (fn_start)
5845  *fn_start= pos;
5846 
5847  if (check_fname_outside_temp_buf())
5848  pos= strmov(pos, "LOCAL ");
5849  pos= strmov(pos, "INFILE '");
5850  memcpy(pos, fname, fname_len);
5851  pos= strmov(pos+fname_len, "' ");
5852 
5853  if (sql_ex.opt_flags & REPLACE_FLAG)
5854  pos= strmov(pos, "REPLACE ");
5855  else if (sql_ex.opt_flags & IGNORE_FLAG)
5856  pos= strmov(pos, "IGNORE ");
5857 
5858  pos= strmov(pos ,"INTO");
5859 
5860  if (fn_end)
5861  *fn_end= pos;
5862 
5863  pos= strmov(pos ," TABLE ");
5864  memcpy(pos, table_name, table_name_len);
5865  pos+= table_name_len;
5866 
5867  if (cs != NULL)
5868  {
5869  pos= strmov(pos ," CHARACTER SET ");
5870  pos= strmov(pos , cs);
5871  }
5872 
5873  /* We have to create all optional fields as the default is not empty */
5874  pos= strmov(pos, " FIELDS TERMINATED BY ");
5875  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
5876  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
5877  pos= strmov(pos, " OPTIONALLY ");
5878  pos= strmov(pos, " ENCLOSED BY ");
5879  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
5880 
5881  pos= strmov(pos, " ESCAPED BY ");
5882  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
5883 
5884  pos= strmov(pos, " LINES TERMINATED BY ");
5885  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
5886  if (sql_ex.line_start_len)
5887  {
5888  pos= strmov(pos, " STARTING BY ");
5889  pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
5890  }
5891 
5892  if ((long) skip_lines > 0)
5893  {
5894  pos= strmov(pos, " IGNORE ");
5895  pos= longlong10_to_str((longlong) skip_lines, pos, 10);
5896  pos= strmov(pos," LINES ");
5897  }
5898 
5899  if (num_fields)
5900  {
5901  uint i;
5902  const char *field= fields;
5903  pos= strmov(pos, " (");
5904  for (i = 0; i < num_fields; i++)
5905  {
5906  if (i)
5907  {
5908  *pos++= ' ';
5909  *pos++= ',';
5910  }
5911  quoted_id_len= my_strmov_quoted_identifier(this->thd, quoted_id, field,
5912  0);
5913  memcpy(pos, quoted_id, quoted_id_len-1);
5914  }
5915  *pos++= ')';
5916  }
5917 
5918  *end= pos;
5919 }
5920 
5921 
5922 int Load_log_event::pack_info(Protocol *protocol)
5923 {
5924  char *buf, *end;
5925 
5926  if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
5927  return 1;
5928  print_query(TRUE, NULL, buf, &end, 0, 0);
5929  protocol->store(buf, end-buf, &my_charset_bin);
5930  my_free(buf);
5931  return 0;
5932 }
5933 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
5934 
5935 
5936 #ifndef MYSQL_CLIENT
5937 
5938 /*
5939  Load_log_event::write_data_header()
5940 */
5941 
5942 bool Load_log_event::write_data_header(IO_CACHE* file)
5943 {
5944  char buf[LOAD_HEADER_LEN];
5945  int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
5946  int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
5947  int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
5948  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
5949  buf[L_DB_LEN_OFFSET] = (char)db_len;
5950  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
5951  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
5952 }
5953 
5954 
5955 /*
5956  Load_log_event::write_data_body()
5957 */
5958 
5959 bool Load_log_event::write_data_body(IO_CACHE* file)
5960 {
5961  if (sql_ex.write_data(file))
5962  return 1;
5963  if (num_fields && fields && field_lens)
5964  {
5965  if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
5966  my_b_safe_write(file, (uchar*)fields, field_block_len))
5967  return 1;
5968  }
5969  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
5970  my_b_safe_write(file, (uchar*)db, db_len + 1) ||
5971  my_b_safe_write(file, (uchar*)fname, fname_len));
5972 }
5973 
5974 
5975 /*
5976  Load_log_event::Load_log_event()
5977 */
5978 
5979 Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
5980  const char *db_arg, const char *table_name_arg,
5981  List<Item> &fields_arg,
5982  bool is_concurrent_arg,
5983  enum enum_duplicates handle_dup,
5984  bool ignore, bool using_trans)
5985  :Log_event(thd_arg,
5986  thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
5987  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
5988  Log_event::EVENT_STMT_CACHE,
5989  Log_event::EVENT_NORMAL_LOGGING),
5990  thread_id(thd_arg->thread_id),
5991  slave_proxy_id(thd_arg->variables.pseudo_thread_id),
5992  num_fields(0),fields(0),
5993  field_lens(0),field_block_len(0),
5994  table_name(table_name_arg ? table_name_arg : ""),
5995  db(db_arg), fname(ex->file_name), local_fname(FALSE),
5996  is_concurrent(is_concurrent_arg)
5997 {
5998  time_t end_time;
5999  time(&end_time);
6000  exec_time = (ulong) (end_time - thd_arg->start_time.tv_sec);
6001  /* db can never be a zero pointer in 4.0 */
6002  db_len = (uint32) strlen(db);
6003  table_name_len = (uint32) strlen(table_name);
6004  fname_len = (fname) ? (uint) strlen(fname) : 0;
6005  sql_ex.field_term = (char*) ex->field_term->ptr();
6006  sql_ex.field_term_len = (uint8) ex->field_term->length();
6007  sql_ex.enclosed = (char*) ex->enclosed->ptr();
6008  sql_ex.enclosed_len = (uint8) ex->enclosed->length();
6009  sql_ex.line_term = (char*) ex->line_term->ptr();
6010  sql_ex.line_term_len = (uint8) ex->line_term->length();
6011  sql_ex.line_start = (char*) ex->line_start->ptr();
6012  sql_ex.line_start_len = (uint8) ex->line_start->length();
6013  sql_ex.escaped = (char*) ex->escaped->ptr();
6014  sql_ex.escaped_len = (uint8) ex->escaped->length();
6015  sql_ex.opt_flags = 0;
6016  sql_ex.cached_new_format = -1;
6017 
6018  if (ex->dumpfile)
6019  sql_ex.opt_flags|= DUMPFILE_FLAG;
6020  if (ex->opt_enclosed)
6021  sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
6022 
6023  sql_ex.empty_flags= 0;
6024 
6025  switch (handle_dup) {
6026  case DUP_REPLACE:
6027  sql_ex.opt_flags|= REPLACE_FLAG;
6028  break;
6029  case DUP_UPDATE: // Impossible here
6030  case DUP_ERROR:
6031  break;
6032  }
6033  if (ignore)
6034  sql_ex.opt_flags|= IGNORE_FLAG;
6035 
6036  if (!ex->field_term->length())
6037  sql_ex.empty_flags |= FIELD_TERM_EMPTY;
6038  if (!ex->enclosed->length())
6039  sql_ex.empty_flags |= ENCLOSED_EMPTY;
6040  if (!ex->line_term->length())
6041  sql_ex.empty_flags |= LINE_TERM_EMPTY;
6042  if (!ex->line_start->length())
6043  sql_ex.empty_flags |= LINE_START_EMPTY;
6044  if (!ex->escaped->length())
6045  sql_ex.empty_flags |= ESCAPED_EMPTY;
6046 
6047  skip_lines = ex->skip_lines;
6048 
6049  List_iterator<Item> li(fields_arg);
6050  field_lens_buf.length(0);
6051  fields_buf.length(0);
6052  Item* item;
6053  while ((item = li++))
6054  {
6055  num_fields++;
6056  uchar len= (uchar) item->item_name.length();
6057  field_block_len += len + 1;
6058  fields_buf.append(item->item_name.ptr(), len + 1);
6059  field_lens_buf.append((char*)&len, 1);
6060  }
6061 
6062  field_lens = (const uchar*)field_lens_buf.ptr();
6063  fields = fields_buf.ptr();
6064 }
6065 #endif /* !MYSQL_CLIENT */
6066 
6067 
6073 Load_log_event::Load_log_event(const char *buf, uint event_len,
6074  const Format_description_log_event *description_event)
6075  :Log_event(buf, description_event), num_fields(0), fields(0),
6076  field_lens(0),field_block_len(0),
6077  table_name(0), db(0), fname(0), local_fname(FALSE),
6078  /*
6079  Load_log_event which comes from the binary log does not contain
6080  information about the type of insert which was used on the master.
6081  Assume that it was an ordinary, non-concurrent LOAD DATA.
6082  */
6083  is_concurrent(FALSE)
6084 {
6085  DBUG_ENTER("Load_log_event");
6086  /*
6087  I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
6088  4.0->5.0 and 5.0->5.0 and it works.
6089  */
6090  if (event_len)
6091  copy_log_event(buf, event_len,
6092  ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
6093  LOAD_HEADER_LEN +
6094  description_event->common_header_len :
6095  LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
6096  description_event);
6097  /* otherwise it's a derived class, will call copy_log_event() itself */
6098  DBUG_VOID_RETURN;
6099 }
6100 
6101 
6102 /*
6103  Load_log_event::copy_log_event()
6104 */
6105 
6106 int Load_log_event::copy_log_event(const char *buf, ulong event_len,
6107  int body_offset,
6108  const Format_description_log_event *description_event)
6109 {
6110  DBUG_ENTER("Load_log_event::copy_log_event");
6111  uint data_len;
6112  char* buf_end = (char*)buf + event_len;
6113  /* this is the beginning of the post-header */
6114  const char* data_head = buf + description_event->common_header_len;
6115  slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
6116  exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
6117  skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
6118  table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
6119  db_len = (uint)data_head[L_DB_LEN_OFFSET];
6120  num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
6121 
6122  if ((int) event_len < body_offset)
6123  DBUG_RETURN(1);
6124  /*
6125  Sql_ex.init() on success returns the pointer to the first byte after
6126  the sql_ex structure, which is the start of field lengths array.
6127  */
6128  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
6129  buf_end,
6130  buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
6131  DBUG_RETURN(1);
6132 
6133  data_len = event_len - body_offset;
6134  if (num_fields > data_len) // simple sanity check against corruption
6135  DBUG_RETURN(1);
6136  for (uint i = 0; i < num_fields; i++)
6137  field_block_len += (uint)field_lens[i] + 1;
6138 
6139  fields = (char*)field_lens + num_fields;
6140  table_name = fields + field_block_len;
6141  db = table_name + table_name_len + 1;
6142  fname = db + db_len + 1;
6143  fname_len = (uint) strlen(fname);
6144  // null termination is accomplished by the caller doing buf[event_len]=0
6145 
6146  DBUG_RETURN(0);
6147 }
6148 
6149 
6150 /*
6151  Load_log_event::print()
6152 */
6153 
6154 #ifdef MYSQL_CLIENT
6155 void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6156 {
6157  print(file, print_event_info, 0);
6158 }
6159 
6160 
6161 void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
6162  bool commented)
6163 {
6164  IO_CACHE *const head= &print_event_info->head_cache;
6165  size_t id_len= 0;
6166  char temp_buf[1 + 2*FN_REFLEN + 2];
6167 
6168  DBUG_ENTER("Load_log_event::print");
6169  if (!print_event_info->short_form)
6170  {
6171  print_header(head, print_event_info, FALSE);
6172  my_b_printf(head, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
6173  thread_id, exec_time);
6174  }
6175 
6176  bool different_db= 1;
6177  if (db)
6178  {
6179  /*
6180  If the database is different from the one of the previous statement, we
6181  need to print the "use" command, and we update the last_db.
6182  But if commented, the "use" is going to be commented so we should not
6183  update the last_db.
6184  */
6185  if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
6186  !commented)
6187  memcpy(print_event_info->db, db, db_len + 1);
6188  }
6189 
6190  if (db && db[0] && different_db)
6191  {
6192 #ifdef MYSQL_SERVER
6193  id_len= my_strmov_quoted_identifier(this->thd, temp_buf, db, 0);
6194 #else
6195  id_len= my_strmov_quoted_identifier(temp_buf, db);
6196 #endif
6197  temp_buf[id_len]= '\0';
6198  my_b_printf(head, "%suse %s%s\n",
6199  commented ? "# " : "", temp_buf, print_event_info->delimiter);
6200  }
6201  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
6202  my_b_printf(head,"%sSET @@session.pseudo_thread_id=%lu%s\n",
6203  commented ? "# " : "", (ulong)thread_id,
6204  print_event_info->delimiter);
6205  my_b_printf(head, "%sLOAD DATA ",
6206  commented ? "# " : "");
6207  if (check_fname_outside_temp_buf())
6208  my_b_printf(head, "LOCAL ");
6209  my_b_printf(head, "INFILE '%-*s' ", fname_len, fname);
6210 
6211  if (sql_ex.opt_flags & REPLACE_FLAG)
6212  my_b_printf(head,"REPLACE ");
6213  else if (sql_ex.opt_flags & IGNORE_FLAG)
6214  my_b_printf(head,"IGNORE ");
6215 
6216 #ifdef MYSQL_SERVER
6217  id_len= my_strmov_quoted_identifier(this->thd, temp_buf, table_name, 0);
6218 #else
6219  id_len= my_strmov_quoted_identifier(temp_buf, table_name);
6220 #endif
6221  temp_buf[id_len]= '\0';
6222  my_b_printf(head, "INTO TABLE %s", temp_buf);
6223 
6224  my_b_printf(head, " FIELDS TERMINATED BY ");
6225  pretty_print_str(head, sql_ex.field_term, sql_ex.field_term_len);
6226 
6227  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
6228  my_b_printf(head," OPTIONALLY ");
6229  my_b_printf(head, " ENCLOSED BY ");
6230  pretty_print_str(head, sql_ex.enclosed, sql_ex.enclosed_len);
6231 
6232  my_b_printf(head, " ESCAPED BY ");
6233  pretty_print_str(head, sql_ex.escaped, sql_ex.escaped_len);
6234 
6235  my_b_printf(head," LINES TERMINATED BY ");
6236  pretty_print_str(head, sql_ex.line_term, sql_ex.line_term_len);
6237 
6238 
6239  if (sql_ex.line_start)
6240  {
6241  my_b_printf(head," STARTING BY ");
6242  pretty_print_str(head, sql_ex.line_start, sql_ex.line_start_len);
6243  }
6244  if ((long) skip_lines > 0)
6245  my_b_printf(head, " IGNORE %ld LINES", (long) skip_lines);
6246 
6247  if (num_fields)
6248  {
6249  uint i;
6250  const char* field = fields;
6251  my_b_printf(head, " (");
6252  for (i = 0; i < num_fields; i++)
6253  {
6254  if (i)
6255  my_b_printf(head, ",");
6256  id_len= my_strmov_quoted_identifier((char *) temp_buf, field);
6257  temp_buf[id_len]= '\0';
6258  my_b_printf(head, "%s", temp_buf);
6259 
6260  field += field_lens[i] + 1;
6261  }
6262  my_b_printf(head, ")");
6263  }
6264 
6265  my_b_printf(head, "%s\n", print_event_info->delimiter);
6266  DBUG_VOID_RETURN;
6267 }
6268 #endif /* MYSQL_CLIENT */
6269 
6270 #ifndef MYSQL_CLIENT
6271 
6282 void Load_log_event::set_fields(const char* affected_db,
6283  List<Item> &field_list,
6284  Name_resolution_context *context)
6285 {
6286  uint i;
6287  const char* field = fields;
6288  for (i= 0; i < num_fields; i++)
6289  {
6290  field_list.push_back(new Item_field(context,
6291  affected_db, table_name, field));
6292  field+= field_lens[i] + 1;
6293  }
6294 }
6295 #endif /* !MYSQL_CLIENT */
6296 
6297 
6298 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6299 
6328 int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
6329  bool use_rli_only_for_errors)
6330 {
6331  DBUG_ASSERT(thd->query() == 0);
6332  thd->reset_query_inner(); // Should not be needed
6333  set_thd_db(thd, db, db_len);
6334  thd->is_slave_error= 0;
6335  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
6336 
6337  /* see Query_log_event::do_apply_event() and BUG#13360 */
6338  DBUG_ASSERT(!rli->m_table_map.count());
6339  /*
6340  Usually lex_start() is called by mysql_parse(), but we need it here
6341  as the present method does not call mysql_parse().
6342  */
6343  lex_start(thd);
6344  thd->lex->local_file= local_fname;
6346 
6347  if (!use_rli_only_for_errors)
6348  {
6349  /*
6350  Saved for InnoDB, see comment in
6351  Query_log_event::do_apply_event()
6352  */
6353  const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
6354  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
6355  }
6356 
6357  /*
6358  We test replicate_*_db rules. Note that we have already prepared
6359  the file to load, even if we are going to ignore and delete it
6360  now. So it is possible that we did a lot of disk writes for
6361  nothing. In other words, a big LOAD DATA INFILE on the master will
6362  still consume a lot of space on the slave (space in the relay log
6363  + space of temp files: twice the space of the file to load...)
6364  even if it will finally be ignored. TODO: fix this; this can be
6365  done by testing rules in Create_file_log_event::do_apply_event()
6366  and then discarding Append_block and al. Another way is do the
6367  filtering in the I/O thread (more efficient: no disk writes at
6368  all).
6369 
6370 
6371  Note: We do not need to execute reset_one_shot_variables() if this
6372  db_ok() test fails.
6373  Reason: The db stored in binlog events is the same for SET and for
6374  its companion query. If the SET is ignored because of
6375  db_ok(), the companion query will also be ignored, and if
6376  the companion query is ignored in the db_ok() test of
6377  ::do_apply_event(), then the companion SET also have so
6378  we don't need to reset_one_shot_variables().
6379  */
6380  if (rpl_filter->db_ok(thd->db))
6381  {
6382  thd->set_time(&when);
6383  thd->set_query_id(next_query_id());
6384  thd->get_stmt_da()->opt_clear_warning_info(thd->query_id);
6385 
6386  TABLE_LIST tables;
6387  char table_buf[NAME_LEN + 1];
6388  strmov(table_buf, table_name);
6389  if (lower_case_table_names == 1)
6390  my_casedn_str(system_charset_info, table_buf);
6391  tables.init_one_table(thd->strmake(thd->db, thd->db_length),
6392  thd->db_length,
6393  table_buf, strlen(table_buf),
6394  table_buf, TL_WRITE);
6395  tables.updating= 1;
6396 
6397  // the table will be opened in mysql_load
6398  if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
6399  {
6400  // TODO: this is a bug - this needs to be moved to the I/O thread
6401  if (net)
6402  skip_load_data_infile(net);
6403  }
6404  else
6405  {
6406  char llbuff[22];
6407  char *end;
6408  enum enum_duplicates handle_dup;
6409  bool ignore= 0;
6410  char *load_data_query;
6411 
6412  /*
6413  Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
6414  and written to slave's binlog if binlogging is on.
6415  */
6416  if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
6417  {
6418  /*
6419  This will set thd->fatal_error in case of OOM. So we surely will notice
6420  that something is wrong.
6421  */
6422  goto error;
6423  }
6424 
6425  print_query(FALSE, NULL, load_data_query, &end, NULL, NULL);
6426  *end= 0;
6427  thd->set_query(load_data_query, (uint) (end - load_data_query));
6428 
6429  if (sql_ex.opt_flags & REPLACE_FLAG)
6430  handle_dup= DUP_REPLACE;
6431  else if (sql_ex.opt_flags & IGNORE_FLAG)
6432  {
6433  ignore= 1;
6434  handle_dup= DUP_ERROR;
6435  }
6436  else
6437  {
6438  /*
6439  When replication is running fine, if it was DUP_ERROR on the
6440  master then we could choose IGNORE here, because if DUP_ERROR
6441  suceeded on master, and data is identical on the master and slave,
6442  then there should be no uniqueness errors on slave, so IGNORE is
6443  the same as DUP_ERROR. But in the unlikely case of uniqueness errors
6444  (because the data on the master and slave happen to be different
6445  (user error or bug), we want LOAD DATA to print an error message on
6446  the slave to discover the problem.
6447 
6448  If reading from net (a 3.23 master), mysql_load() will change this
6449  to IGNORE.
6450  */
6451  handle_dup= DUP_ERROR;
6452  }
6453  /*
6454  We need to set thd->lex->sql_command and thd->lex->duplicates
6455  since InnoDB tests these variables to decide if this is a LOAD
6456  DATA ... REPLACE INTO ... statement even though mysql_parse()
6457  is not called. This is not needed in 5.0 since there the LOAD
6458  DATA ... statement is replicated using mysql_parse(), which
6459  sets the thd->lex fields correctly.
6460  */
6461  thd->lex->sql_command= SQLCOM_LOAD;
6462  thd->lex->duplicates= handle_dup;
6463 
6464  sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
6465  String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
6466  String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
6467  String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
6468  String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
6469  String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
6470  const String empty_str("", 0, log_cs);
6471  ex.field_term= &field_term;
6472  ex.enclosed= &enclosed;
6473  ex.line_term= &line_term;
6474  ex.line_start= &line_start;
6475  ex.escaped= &escaped;
6476 
6477  ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
6478  if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
6479  ex.field_term= &empty_str;
6480 
6481  ex.skip_lines = skip_lines;
6482  List<Item> field_list;
6483  thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
6484  set_fields(tables.db, field_list, &thd->lex->select_lex.context);
6485  thd->variables.pseudo_thread_id= thread_id;
6486  if (net)
6487  {
6488  // mysql_load will use thd->net to read the file
6489  thd->net.vio = net->vio;
6490  // Make sure the client does not get confused about the packet sequence
6491  thd->net.pkt_nr = net->pkt_nr;
6492  }
6493  /*
6494  It is safe to use tmp_list twice because we are not going to
6495  update it inside mysql_load().
6496  */
6497  List<Item> tmp_list;
6498  if (open_temporary_tables(thd, &tables) ||
6499  mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
6500  handle_dup, ignore, net != 0))
6501  thd->is_slave_error= 1;
6502  if (thd->cuted_fields)
6503  {
6504  /* log_pos is the position of the LOAD event in the master log */
6505  sql_print_warning("Slave: load data infile on table '%s' at "
6506  "log position %s in log '%s' produced %ld "
6507  "warning(s). Default database: '%s'",
6508  (char*) table_name,
6509  llstr(log_pos,llbuff),
6510  const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
6511  (ulong) thd->cuted_fields,
6512  print_slave_db_safe(thd->db));
6513  }
6514  if (net)
6515  net->pkt_nr= thd->net.pkt_nr;
6516  }
6517  }
6518  else
6519  {
6520  /*
6521  We will just ask the master to send us /dev/null if we do not
6522  want to load the data.
6523  TODO: this a bug - needs to be done in I/O thread
6524  */
6525  if (net)
6526  skip_load_data_infile(net);
6527  }
6528 
6529 error:
6530  thd->net.vio = 0;
6531  const char *remember_db= thd->db;
6532  thd->catalog= 0;
6533  thd->set_db(NULL, 0); /* will free the current database */
6534  thd->reset_query();
6535  thd->get_stmt_da()->set_overwrite_status(true);
6536  thd->is_error() ? trans_rollback_stmt(thd) : trans_commit_stmt(thd);
6537  thd->get_stmt_da()->set_overwrite_status(false);
6538  close_thread_tables(thd);
6539  /*
6540  - If transaction rollback was requested due to deadlock
6541  perform it and release metadata locks.
6542  - If inside a multi-statement transaction,
6543  defer the release of metadata locks until the current
6544  transaction is either committed or rolled back. This prevents
6545  other statements from modifying the table for the entire
6546  duration of this transaction. This provides commit ordering
6547  and guarantees serializability across multiple transactions.
6548  - If in autocommit mode, or outside a transactional context,
6549  automatically release metadata locks of the current statement.
6550  */
6551  if (thd->transaction_rollback_request)
6552  {
6553  trans_rollback_implicit(thd);
6554  thd->mdl_context.release_transactional_locks();
6555  }
6556  else if (! thd->in_multi_stmt_transaction_mode())
6557  thd->mdl_context.release_transactional_locks();
6558  else
6559  thd->mdl_context.release_statement_locks();
6560 
6561  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
6562  thd->is_slave_error= 0; thd->is_fatal_error= 1;);
6563 
6564  if (thd->is_slave_error)
6565  {
6566  /* this err/sql_errno code is copy-paste from net_send_error() */
6567  const char *err;
6568  int sql_errno;
6569  if (thd->is_error())
6570  {
6571  err= thd->get_stmt_da()->message();
6572  sql_errno= thd->get_stmt_da()->sql_errno();
6573  }
6574  else
6575  {
6576  sql_errno=ER_UNKNOWN_ERROR;
6577  err=ER(sql_errno);
6578  }
6579  rli->report(ERROR_LEVEL, sql_errno,"\
6580 Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
6581  err, (char*)table_name, print_slave_db_safe(remember_db));
6582  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6583  return 1;
6584  }
6585  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
6586 
6587  if (thd->is_fatal_error)
6588  {
6589  char buf[256];
6590  my_snprintf(buf, sizeof(buf),
6591  "Running LOAD DATA INFILE on table '%-.64s'."
6592  " Default database: '%-.64s'",
6593  (char*)table_name,
6594  print_slave_db_safe(remember_db));
6595 
6596  rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
6597  ER(ER_SLAVE_FATAL_ERROR), buf);
6598  return 1;
6599  }
6600 
6601  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
6602 }
6603 #endif
6604 
6605 
6606 /**************************************************************************
6607  Rotate_log_event methods
6608 **************************************************************************/
6609 
6610 /*
6611  Rotate_log_event::pack_info()
6612 */
6613 
6614 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6615 int Rotate_log_event::pack_info(Protocol *protocol)
6616 {
6617  char buf1[256], buf[22];
6618  String tmp(buf1, sizeof(buf1), log_cs);
6619  tmp.length(0);
6620  tmp.append(new_log_ident, ident_len);
6621  tmp.append(STRING_WITH_LEN(";pos="));
6622  tmp.append(llstr(pos,buf));
6623  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
6624  return 0;
6625 }
6626 #endif
6627 
6628 
6629 /*
6630  Rotate_log_event::print()
6631 */
6632 
6633 #ifdef MYSQL_CLIENT
6634 void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6635 {
6636  char buf[22];
6637  IO_CACHE *const head= &print_event_info->head_cache;
6638 
6639  if (print_event_info->short_form)
6640  return;
6641  print_header(head, print_event_info, FALSE);
6642  my_b_printf(head, "\tRotate to ");
6643  if (new_log_ident)
6644  my_b_write(head, (uchar*) new_log_ident, (uint)ident_len);
6645  my_b_printf(head, " pos: %s\n", llstr(pos, buf));
6646 }
6647 #endif /* MYSQL_CLIENT */
6648 
6649 
6650 
6651 /*
6652  Rotate_log_event::Rotate_log_event() (2 constructors)
6653 */
6654 
6655 
6656 #ifndef MYSQL_CLIENT
6657 Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
6658  uint ident_len_arg, ulonglong pos_arg,
6659  uint flags_arg)
6660  :Log_event(Log_event::EVENT_NO_CACHE, Log_event::EVENT_IMMEDIATE_LOGGING),
6661  new_log_ident(new_log_ident_arg), pos(pos_arg),ident_len(ident_len_arg ?
6662  ident_len_arg : (uint) strlen(new_log_ident_arg)), flags(flags_arg)
6663 {
6664 #ifndef DBUG_OFF
6665  char buff[22];
6666  DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
6667  DBUG_PRINT("enter",("new_log_ident: %s pos: %s flags: %lu", new_log_ident_arg,
6668  llstr(pos_arg, buff), (ulong) flags));
6669 #endif
6670  if (flags & DUP_NAME)
6671  new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
6672  if (flags & RELAY_LOG)
6673  set_relay_log_event();
6674  DBUG_VOID_RETURN;
6675 }
6676 #endif
6677 
6678 
6679 Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
6680  const Format_description_log_event* description_event)
6681  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
6682 {
6683  DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
6684  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
6685  uint8 header_size= description_event->common_header_len;
6686  uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
6687  uint ident_offset;
6688  if (event_len < header_size)
6689  DBUG_VOID_RETURN;
6690  buf += header_size;
6691  pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
6692  ident_len = (uint)(event_len -
6693  (header_size+post_header_len));
6694  ident_offset = post_header_len;
6695  set_if_smaller(ident_len,FN_REFLEN-1);
6696  new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
6697  DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
6698  DBUG_VOID_RETURN;
6699 }
6700 
6701 
6702 /*
6703  Rotate_log_event::write()
6704 */
6705 
6706 #ifndef MYSQL_CLIENT
6707 bool Rotate_log_event::write(IO_CACHE* file)
6708 {
6709  char buf[ROTATE_HEADER_LEN];
6710  int8store(buf + R_POS_OFFSET, pos);
6711  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
6712  wrapper_my_b_safe_write(file, (uchar*) buf, ROTATE_HEADER_LEN) ||
6713  wrapper_my_b_safe_write(file, (uchar*) new_log_ident,
6714  (uint) ident_len) ||
6715  write_footer(file));
6716 }
6717 #endif
6718 
6719 
6720 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6721 
6722 /*
6723  Got a rotate log event from the master.
6724 
6725  This is mainly used so that we can later figure out the logname and
6726  position for the master.
6727 
6728  We can't rotate the slave's BINlog as this will cause infinitive rotations
6729  in a A -> B -> A setup.
6730  The NOTES below is a wrong comment which will disappear when 4.1 is merged.
6731 
6732  This must only be called from the Slave SQL thread, since it calls
6733  flush_relay_log_info().
6734 
6735  @retval
6736  0 ok
6737 */
6738 int Rotate_log_event::do_update_pos(Relay_log_info *rli)
6739 {
6740  int error= 0;
6741  DBUG_ENTER("Rotate_log_event::do_update_pos");
6742 #ifndef DBUG_OFF
6743  char buf[32];
6744 #endif
6745 
6746  DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
6747  (ulong) this->server_id, (ulong) ::server_id));
6748  DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
6749  DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
6750 
6751  /*
6752  If we are in a transaction or in a group: the only normal case is
6753  when the I/O thread was copying a big transaction, then it was
6754  stopped and restarted: we have this in the relay log:
6755 
6756  BEGIN
6757  ...
6758  ROTATE (a fake one)
6759  ...
6760  COMMIT or ROLLBACK
6761 
6762  In that case, we don't want to touch the coordinates which
6763  correspond to the beginning of the transaction. Starting from
6764  5.0.0, there also are some rotates from the slave itself, in the
6765  relay log, which shall not change the group positions.
6766  */
6767  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
6768  !is_relay_log_event() &&
6769  ((!rli->is_parallel_exec() && !rli->is_in_group()) ||
6770  rli->mts_group_status != Relay_log_info::MTS_IN_GROUP))
6771  {
6772  if (rli->is_parallel_exec())
6773  {
6774  /*
6775  Rotate events are special events that are handled as a
6776  synchronization point. For that reason, the checkpoint
6777  routine is being called here.
6778  */
6779  if ((error= mts_checkpoint_routine(rli, 0, false,
6780  true/*need_data_lock=true*/)))
6781  goto err;
6782  }
6783 
6784  mysql_mutex_lock(&rli->data_lock);
6785  DBUG_PRINT("info", ("old group_master_log_name: '%s' "
6786  "old group_master_log_pos: %lu",
6787  rli->get_group_master_log_name(),
6788  (ulong) rli->get_group_master_log_pos()));
6789 
6790  memcpy((void *)rli->get_group_master_log_name(),
6791  new_log_ident, ident_len + 1);
6793  if ((error= rli->inc_group_relay_log_pos(pos,
6794  false/*need_data_lock=false*/)))
6795  {
6796  mysql_mutex_unlock(&rli->data_lock);
6797  goto err;
6798  }
6799 
6800  DBUG_PRINT("info", ("new group_master_log_name: '%s' "
6801  "new group_master_log_pos: %lu",
6802  rli->get_group_master_log_name(),
6803  (ulong) rli->get_group_master_log_pos()));
6804  mysql_mutex_unlock(&rli->data_lock);
6805  if (rli->is_parallel_exec())
6806  rli->reset_notified_checkpoint(0, when.tv_sec + (time_t) exec_time,
6807  true/*need_data_lock=true*/);
6808 
6809  /*
6810  Reset thd->variables.option_bits and sql_mode etc, because this could be the signal of
6811  a master's downgrade from 5.0 to 4.0.
6812  However, no need to reset rli_description_event: indeed, if the next
6813  master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
6814  master is 4.0 then the events are in the slave's format (conversion).
6815  */
6816  set_slave_thread_options(thd);
6817  set_slave_thread_default_charset(thd, rli);
6818  thd->variables.sql_mode= global_system_variables.sql_mode;
6819  thd->variables.auto_increment_increment=
6820  thd->variables.auto_increment_offset= 1;
6821  }
6822  else
6823  rli->inc_event_relay_log_pos();
6824 
6825 err:
6826  DBUG_RETURN(error);
6827 }
6828 
6829 
6831 Rotate_log_event::do_shall_skip(Relay_log_info *rli)
6832 {
6833  enum_skip_reason reason= Log_event::do_shall_skip(rli);
6834 
6835  switch (reason) {
6839 
6842  }
6843  DBUG_ASSERT(0);
6844  return Log_event::EVENT_SKIP_NOT; // To keep compiler happy
6845 }
6846 
6847 #endif
6848 
6849 
6850 /**************************************************************************
6851  Intvar_log_event methods
6852 **************************************************************************/
6853 
6854 /*
6855  Intvar_log_event::pack_info()
6856 */
6857 
6858 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6859 int Intvar_log_event::pack_info(Protocol *protocol)
6860 {
6861  char buf[256], *pos;
6862  pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
6863  *pos++= '=';
6864  pos= longlong10_to_str(val, pos, -10);
6865  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
6866  return 0;
6867 }
6868 #endif
6869 
6870 
6871 /*
6872  Intvar_log_event::Intvar_log_event()
6873 */
6874 
6875 Intvar_log_event::Intvar_log_event(const char* buf,
6876  const Format_description_log_event* description_event)
6877  :Log_event(buf, description_event)
6878 {
6879  /* The Post-Header is empty. The Varible Data part begins immediately. */
6880  buf+= description_event->common_header_len +
6881  description_event->post_header_len[INTVAR_EVENT-1];
6882  type= buf[I_TYPE_OFFSET];
6883  val= uint8korr(buf+I_VAL_OFFSET);
6884 }
6885 
6886 
6887 /*
6888  Intvar_log_event::get_var_type_name()
6889 */
6890 
6891 const char* Intvar_log_event::get_var_type_name()
6892 {
6893  switch(type) {
6894  case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
6895  case INSERT_ID_EVENT: return "INSERT_ID";
6896  default: /* impossible */ return "UNKNOWN";
6897  }
6898 }
6899 
6900 
6901 /*
6902  Intvar_log_event::write()
6903 */
6904 
6905 #ifndef MYSQL_CLIENT
6906 bool Intvar_log_event::write(IO_CACHE* file)
6907 {
6908  uchar buf[9];
6909  buf[I_TYPE_OFFSET]= (uchar) type;
6910  int8store(buf + I_VAL_OFFSET, val);
6911  return (write_header(file, sizeof(buf)) ||
6912  wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
6913  write_footer(file));
6914 }
6915 #endif
6916 
6917 
6918 /*
6919  Intvar_log_event::print()
6920 */
6921 
6922 #ifdef MYSQL_CLIENT
6923 void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
6924 {
6925  char llbuff[22];
6926  const char *msg;
6927  LINT_INIT(msg);
6928  IO_CACHE *const head= &print_event_info->head_cache;
6929 
6930  if (!print_event_info->short_form)
6931  {
6932  print_header(head, print_event_info, FALSE);
6933  my_b_printf(head, "\tIntvar\n");
6934  }
6935 
6936  my_b_printf(head, "SET ");
6937  switch (type) {
6938  case LAST_INSERT_ID_EVENT:
6939  msg="LAST_INSERT_ID";
6940  break;
6941  case INSERT_ID_EVENT:
6942  msg="INSERT_ID";
6943  break;
6944  case INVALID_INT_EVENT:
6945  default: // cannot happen
6946  msg="INVALID_INT";
6947  break;
6948  }
6949  my_b_printf(head, "%s=%s%s\n",
6950  msg, llstr(val,llbuff), print_event_info->delimiter);
6951 }
6952 #endif
6953 
6954 
6955 #if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
6956 
6957 /*
6958  Intvar_log_event::do_apply_event()
6959 */
6960 
6961 int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
6962 {
6963  /*
6964  We are now in a statement until the associated query log event has
6965  been processed.
6966  */
6967  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
6968 
6969  if (rli->deferred_events_collecting)
6970  return rli->deferred_events->add(this);
6971 
6972  switch (type) {
6973  case LAST_INSERT_ID_EVENT:
6974  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
6975  thd->first_successful_insert_id_in_prev_stmt= val;
6976  break;
6977  case INSERT_ID_EVENT:
6978  thd->force_one_auto_inc_interval(val);
6979  break;
6980  }
6981  return 0;
6982 }
6983 
6984 int Intvar_log_event::do_update_pos(Relay_log_info *rli)
6985 {
6986  rli->inc_event_relay_log_pos();
6987  return 0;
6988 }
6989 
6990 
6992 Intvar_log_event::do_shall_skip(Relay_log_info *rli)
6993 {
6994  /*
6995  It is a common error to set the slave skip counter to 1 instead of
6996  2 when recovering from an insert which used a auto increment,
6997  rand, or user var. Therefore, if the slave skip counter is 1, we
6998  just say that this event should be skipped by ignoring it, meaning
6999  that we do not change the value of the slave skip counter since it
7000  will be decreased by the following insert event.
7001  */
7002  return continue_group(rli);
7003 }
7004 
7005 #endif
7006 
7007 
7008 /**************************************************************************
7009  Rand_log_event methods
7010 **************************************************************************/
7011 
7012 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7013 int Rand_log_event::pack_info(Protocol *protocol)
7014 {
7015  char buf1[256], *pos;
7016  pos= strmov(buf1,"rand_seed1=");
7017  pos= int10_to_str((long) seed1, pos, 10);
7018  pos= strmov(pos, ",rand_seed2=");
7019  pos= int10_to_str((long) seed2, pos, 10);
7020  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
7021  return 0;
7022 }
7023 #endif
7024 
7025 
7026 Rand_log_event::Rand_log_event(const char* buf,
7027  const Format_description_log_event* description_event)
7028  :Log_event(buf, description_event)
7029 {
7030  /* The Post-Header is empty. The Variable Data part begins immediately. */
7031  buf+= description_event->common_header_len +
7032  description_event->post_header_len[RAND_EVENT-1];
7033  seed1= uint8korr(buf+RAND_SEED1_OFFSET);
7034  seed2= uint8korr(buf+RAND_SEED2_OFFSET);
7035 }
7036 
7037 
7038 #ifndef MYSQL_CLIENT
7039 bool Rand_log_event::write(IO_CACHE* file)
7040 {
7041  uchar buf[16];
7042  int8store(buf + RAND_SEED1_OFFSET, seed1);
7043  int8store(buf + RAND_SEED2_OFFSET, seed2);
7044  return (write_header(file, sizeof(buf)) ||
7045  wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
7046  write_footer(file));
7047 }
7048 #endif
7049 
7050 
7051 #ifdef MYSQL_CLIENT
7052 void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7053 {
7054  IO_CACHE *const head= &print_event_info->head_cache;
7055 
7056  char llbuff[22],llbuff2[22];
7057  if (!print_event_info->short_form)
7058  {
7059  print_header(head, print_event_info, FALSE);
7060  my_b_printf(head, "\tRand\n");
7061  }
7062  my_b_printf(head, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
7063  llstr(seed1, llbuff),llstr(seed2, llbuff2),
7064  print_event_info->delimiter);
7065 }
7066 #endif /* MYSQL_CLIENT */
7067 
7068 
7069 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7070 int Rand_log_event::do_apply_event(Relay_log_info const *rli)
7071 {
7072  /*
7073  We are now in a statement until the associated query log event has
7074  been processed.
7075  */
7076  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7077 
7078  if (rli->deferred_events_collecting)
7079  return rli->deferred_events->add(this);
7080 
7081  thd->rand.seed1= (ulong) seed1;
7082  thd->rand.seed2= (ulong) seed2;
7083  return 0;
7084 }
7085 
7086 int Rand_log_event::do_update_pos(Relay_log_info *rli)
7087 {
7088  rli->inc_event_relay_log_pos();
7089  return 0;
7090 }
7091 
7092 
7094 Rand_log_event::do_shall_skip(Relay_log_info *rli)
7095 {
7096  /*
7097  It is a common error to set the slave skip counter to 1 instead of
7098  2 when recovering from an insert which used a auto increment,
7099  rand, or user var. Therefore, if the slave skip counter is 1, we
7100  just say that this event should be skipped by ignoring it, meaning
7101  that we do not change the value of the slave skip counter since it
7102  will be decreased by the following insert event.
7103  */
7104  return continue_group(rli);
7105 }
7106 
7115 bool slave_execute_deferred_events(THD *thd)
7116 {
7117  bool res= false;
7118  Relay_log_info *rli= thd->rli_slave;
7119 
7120  DBUG_ASSERT(rli && (!rli->deferred_events_collecting || rli->deferred_events));
7121 
7122  if (!rli->deferred_events_collecting || rli->deferred_events->is_empty())
7123  return res;
7124 
7125  res= rli->deferred_events->execute(rli);
7126 
7127  return res;
7128 }
7129 
7130 #endif /* !MYSQL_CLIENT */
7131 
7132 
7133 /**************************************************************************
7134  Xid_log_event methods
7135 **************************************************************************/
7136 
7137 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7138 int Xid_log_event::pack_info(Protocol *protocol)
7139 {
7140  char buf[128], *pos;
7141  pos= strmov(buf, "COMMIT /* xid=");
7142  pos= longlong10_to_str(xid, pos, 10);
7143  pos= strmov(pos, " */");
7144  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
7145  return 0;
7146 }
7147 #endif
7148 
7159 Xid_log_event(const char* buf,
7160  const Format_description_log_event *description_event)
7161  :Log_event(buf, description_event)
7162 {
7163  /* The Post-Header is empty. The Variable Data part begins immediately. */
7164  buf+= description_event->common_header_len +
7165  description_event->post_header_len[XID_EVENT-1];
7166  memcpy((char*) &xid, buf, sizeof(xid));
7167 }
7168 
7169 
7170 #ifndef MYSQL_CLIENT
7171 bool Xid_log_event::write(IO_CACHE* file)
7172 {
7173  DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
7174  return (write_header(file, sizeof(xid)) ||
7175  wrapper_my_b_safe_write(file, (uchar*) &xid, sizeof(xid)) ||
7176  write_footer(file));
7177 }
7178 #endif
7179 
7180 
7181 #ifdef MYSQL_CLIENT
7182 void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7183 {
7184  IO_CACHE *const head= &print_event_info->head_cache;
7185 
7186  if (!print_event_info->short_form)
7187  {
7188  char buf[64];
7189  longlong10_to_str(xid, buf, 10);
7190 
7191  print_header(head, print_event_info, FALSE);
7192  my_b_printf(head, "\tXid = %s\n", buf);
7193  }
7194  my_b_printf(head, "COMMIT%s\n", print_event_info->delimiter);
7195 }
7196 #endif /* MYSQL_CLIENT */
7197 
7198 
7199 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7200 
7209 bool Xid_log_event::do_commit(THD *thd)
7210 {
7211  bool error= trans_commit(thd); /* Automatically rolls back on error. */
7212  DBUG_EXECUTE_IF("crash_after_apply",
7213  sql_print_information("Crashing crash_after_apply.");
7214  DBUG_SUICIDE(););
7215  thd->mdl_context.release_transactional_locks();
7216 
7217  if (thd->variables.gtid_next.type == GTID_GROUP &&
7218  thd->owned_gtid.sidno != 0)
7219  {
7220  // GTID logging and cleanup runs regardless of the current res
7221  error |= gtid_empty_group_log_and_cleanup(thd);
7222  }
7223 
7224  /*
7225  Increment the global status commit count variable
7226  */
7227  if (!error)
7228  status_var_increment(thd->status_var.com_stat[SQLCOM_COMMIT]);
7229 
7230  return error;
7231 }
7232 
7240 int Xid_log_event::do_apply_event_worker(Slave_worker *w)
7241 {
7242  int error= 0;
7243  Slave_committed_queue *coordinator_gaq= w->c_rli->gaq;
7244 
7245  /* For a slave Xid_log_event is COMMIT */
7246  general_log_print(thd, COM_QUERY,
7247  "COMMIT /* implicit, from Xid_log_event */");
7248 
7249  DBUG_PRINT("mts", ("do_apply group master %s %llu group relay %s %llu event %s %llu.",
7250  w->get_group_master_log_name(),
7251  w->get_group_master_log_pos(),
7252  w->get_group_relay_log_name(),
7253  w->get_group_relay_log_pos(),
7254  w->get_event_relay_log_name(),
7255  w->get_event_relay_log_pos()));
7256 
7257  DBUG_EXECUTE_IF("crash_before_update_pos",
7258  sql_print_information("Crashing crash_before_update_pos.");
7259  DBUG_SUICIDE(););
7260 
7261  ulong gaq_idx= mts_group_idx;
7262  Slave_job_group *ptr_group= coordinator_gaq->get_job_group(gaq_idx);
7263 
7264  if ((error= w->commit_positions(this, ptr_group,
7265  w->c_rli->is_transactional())))
7266  goto err;
7267 
7268  DBUG_PRINT("mts", ("do_apply group master %s %llu group relay %s %llu event %s %llu.",
7269  w->get_group_master_log_name(),
7270  w->get_group_master_log_pos(),
7271  w->get_group_relay_log_name(),
7272  w->get_group_relay_log_pos(),
7273  w->get_event_relay_log_name(),
7274  w->get_event_relay_log_pos()));
7275 
7276  DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7277  sql_print_information("Crashing crash_after_update_pos_before_apply.");
7278  DBUG_SUICIDE(););
7279 
7280  error= do_commit(thd);
7281 err:
7282  return error;
7283 }
7284 
7285 int Xid_log_event::do_apply_event(Relay_log_info const *rli)
7286 {
7287  int error= 0;
7288  lex_start(thd);
7290  Relay_log_info *rli_ptr= const_cast<Relay_log_info *>(rli);
7291 
7292  /* For a slave Xid_log_event is COMMIT */
7293  general_log_print(thd, COM_QUERY,
7294  "COMMIT /* implicit, from Xid_log_event */");
7295 
7296  mysql_mutex_lock(&rli_ptr->data_lock);
7297 
7298  DBUG_PRINT("info", ("do_apply group master %s %llu group relay %s %llu event %s %llu\n",
7299  rli_ptr->get_group_master_log_name(),
7300  rli_ptr->get_group_master_log_pos(),
7301  rli_ptr->get_group_relay_log_name(),
7302  rli_ptr->get_group_relay_log_pos(),
7303  rli_ptr->get_event_relay_log_name(),
7304  rli_ptr->get_event_relay_log_pos()));
7305 
7306  DBUG_EXECUTE_IF("crash_before_update_pos",
7307  sql_print_information("Crashing crash_before_update_pos.");
7308  DBUG_SUICIDE(););
7309 
7310  /*
7311  We need to update the positions in here to make it transactional.
7312  */
7313  rli_ptr->inc_event_relay_log_pos();
7314  rli_ptr->set_group_relay_log_pos(rli_ptr->get_event_relay_log_pos());
7315  rli_ptr->set_group_relay_log_name(rli_ptr->get_event_relay_log_name());
7316 
7318 
7319  if (log_pos) // 3.23 binlogs don't have log_posx
7320  rli_ptr->set_group_master_log_pos(log_pos);
7321 
7322  if ((error= rli_ptr->flush_info(rli_ptr->is_transactional())))
7323  goto err;
7324 
7325  DBUG_PRINT("info", ("do_apply group master %s %llu group relay %s %llu event %s %llu\n",
7326  rli_ptr->get_group_master_log_name(),
7327  rli_ptr->get_group_master_log_pos(),
7328  rli_ptr->get_group_relay_log_name(),
7329  rli_ptr->get_group_relay_log_pos(),
7330  rli_ptr->get_event_relay_log_name(),
7331  rli_ptr->get_event_relay_log_pos()));
7332 
7333  DBUG_EXECUTE_IF("crash_after_update_pos_before_apply",
7334  sql_print_information("Crashing crash_after_update_pos_before_apply.");
7335  DBUG_SUICIDE(););
7336 
7343  DBUG_EXECUTE_IF("simulate_commit_failure",
7344  {
7345  thd->transaction.xid_state.xa_state = XA_IDLE;
7346  });
7347  error= do_commit(thd);
7348  if(error)
7349  rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
7350  "Error in Xid_log_event: Commit could not be completed, '%s'",
7351  thd->get_stmt_da()->message());
7352 err:
7353  mysql_cond_broadcast(&rli_ptr->data_cond);
7354  mysql_mutex_unlock(&rli_ptr->data_lock);
7355 
7356  return error;
7357 }
7358 
7360 Xid_log_event::do_shall_skip(Relay_log_info *rli)
7361 {
7362  DBUG_ENTER("Xid_log_event::do_shall_skip");
7363  if (rli->slave_skip_counter > 0) {
7364  thd->variables.option_bits&= ~OPTION_BEGIN;
7365  DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
7366  }
7367  DBUG_RETURN(Log_event::do_shall_skip(rli));
7368 }
7369 #endif /* !MYSQL_CLIENT */
7370 
7371 
7372 /**************************************************************************
7373  User_var_log_event methods
7374 **************************************************************************/
7375 
7376 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7377 int User_var_log_event::pack_info(Protocol* protocol)
7378 {
7379  char *buf= 0;
7380  char quoted_id[1 + FN_REFLEN * 2 + 2];// quoted identifier
7381  int id_len= my_strmov_quoted_identifier(this->thd, quoted_id, name, name_len);
7382  quoted_id[id_len]= '\0';
7383  uint val_offset= 2 + id_len;
7384  uint event_len= val_offset;
7385 
7386  if (is_null)
7387  {
7388  if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
7389  return 1;
7390  strmov(buf + val_offset, "NULL");
7391  event_len= val_offset + 4;
7392  }
7393  else
7394  {
7395  switch (type) {
7396  case REAL_RESULT:
7397  double real_val;
7398  float8get(real_val, val);
7399  if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
7400  MYF(MY_WME))))
7401  return 1;
7402  event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
7403  buf + val_offset, NULL);
7404  break;
7405  case INT_RESULT:
7406  if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
7407  return 1;
7408  event_len= longlong10_to_str(uint8korr(val), buf + val_offset,
7409  ((flags & User_var_log_event::UNSIGNED_F) ?
7410  10 : -10))-buf;
7411  break;
7412  case DECIMAL_RESULT:
7413  {
7414  if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH + 1,
7415  MYF(MY_WME))))
7416  return 1;
7417  String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH + 1, &my_charset_bin);
7418  my_decimal dec;
7419  binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
7420  val[1]);
7421  my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
7422  event_len= str.length() + val_offset;
7423  break;
7424  }
7425  case STRING_RESULT:
7426  /* 15 is for 'COLLATE' and other chars */
7427  buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
7428  MYF(MY_WME));
7429  CHARSET_INFO *cs;
7430  if (!buf)
7431  return 1;
7432  if (!(cs= get_charset(charset_number, MYF(0))))
7433  {
7434  strmov(buf+val_offset, "???");
7435  event_len+= 3;
7436  }
7437  else
7438  {
7439  char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
7440  p= str_to_hex(p, val, val_len);
7441  p= strxmov(p, " COLLATE ", cs->name, NullS);
7442  event_len= p-buf;
7443  }
7444  break;
7445  case ROW_RESULT:
7446  default:
7447  DBUG_ASSERT(1);
7448  return 1;
7449  }
7450  }
7451  buf[0]= '@';
7452  memcpy(buf + 1, quoted_id, id_len);
7453  buf[1 + id_len]= '=';
7454  protocol->store(buf, event_len, &my_charset_bin);
7455  my_free(buf);
7456  return 0;
7457 }
7458 #endif /* !MYSQL_CLIENT */
7459 
7460 
7462 User_var_log_event(const char* buf, uint event_len,
7463  const Format_description_log_event* description_event)
7464  :Log_event(buf, description_event)
7465 #ifndef MYSQL_CLIENT
7466  , deferred(false), query_id(0)
7467 #endif
7468 {
7469  bool error= false;
7470  const char* buf_start= buf;
7471  /* The Post-Header is empty. The Variable Data part begins immediately. */
7472  const char *start= buf;
7473  buf+= description_event->common_header_len +
7474  description_event->post_header_len[USER_VAR_EVENT-1];
7475  name_len= uint4korr(buf);
7476  name= (char *) buf + UV_NAME_LEN_SIZE;
7477 
7478  /*
7479  We don't know yet is_null value, so we must assume that name_len
7480  may have the bigger value possible, is_null= True and there is no
7481  payload for val, or even that name_len is 0.
7482  */
7483  if (!valid_buffer_range<uint>(name_len, buf_start, name,
7484  event_len - UV_VAL_IS_NULL))
7485  {
7486  error= true;
7487  goto err;
7488  }
7489 
7490  buf+= UV_NAME_LEN_SIZE + name_len;
7491  is_null= (bool) *buf;
7492  flags= User_var_log_event::UNDEF_F; // defaults to UNDEF_F
7493  if (is_null)
7494  {
7495  type= STRING_RESULT;
7496  charset_number= my_charset_bin.number;
7497  val_len= 0;
7498  val= 0;
7499  }
7500  else
7501  {
7502  if (!valid_buffer_range<uint>(UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE
7503  + UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE,
7504  buf_start, buf, event_len))
7505  {
7506  error= true;
7507  goto err;
7508  }
7509 
7510  type= (Item_result) buf[UV_VAL_IS_NULL];
7511  charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
7512  val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7513  UV_CHARSET_NUMBER_SIZE);
7514  val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7515  UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
7516 
7517  if (!valid_buffer_range<uint>(val_len, buf_start, val, event_len))
7518  {
7519  error= true;
7520  goto err;
7521  }
7522 
7534  uint bytes_read= ((val + val_len) - start);
7535 #ifndef DBUG_OFF
7536  bool old_pre_checksum_fd= description_event->is_version_before_checksum();
7537 #endif
7538  DBUG_ASSERT((bytes_read == data_written -
7539  (old_pre_checksum_fd ||
7540  (description_event->checksum_alg ==
7541  BINLOG_CHECKSUM_ALG_OFF)) ?
7542  0 : BINLOG_CHECKSUM_LEN)
7543  ||
7544  (bytes_read == data_written -1 -
7545  (old_pre_checksum_fd ||
7546  (description_event->checksum_alg ==
7547  BINLOG_CHECKSUM_ALG_OFF)) ?
7548  0 : BINLOG_CHECKSUM_LEN));
7549  if ((data_written - bytes_read) > 0)
7550  {
7551  flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7552  UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE +
7553  val_len);
7554  }
7555  }
7556 
7557 err:
7558  if (error)
7559  name= 0;
7560 }
7561 
7562 
7563 #ifndef MYSQL_CLIENT
7564 bool User_var_log_event::write(IO_CACHE* file)
7565 {
7566  char buf[UV_NAME_LEN_SIZE];
7567  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
7568  UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
7569  uchar buf2[MY_MAX(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
7570  uint unsigned_len= 0;
7571  uint buf1_length;
7572  ulong event_length;
7573 
7574  int4store(buf, name_len);
7575 
7576  if ((buf1[0]= is_null))
7577  {
7578  buf1_length= 1;
7579  val_len= 0; // Length of 'pos'
7580  }
7581  else
7582  {
7583  buf1[1]= type;
7584  int4store(buf1 + 2, charset_number);
7585 
7586  switch (type) {
7587  case REAL_RESULT:
7588  float8store(buf2, *(double*) val);
7589  break;
7590  case INT_RESULT:
7591  int8store(buf2, *(longlong*) val);
7592  unsigned_len= 1;
7593  break;
7594  case DECIMAL_RESULT:
7595  {
7596  my_decimal *dec= (my_decimal *)val;
7597  dec->fix_buffer_pointer();
7598  buf2[0]= (char)(dec->intg + dec->frac);
7599  buf2[1]= (char)dec->frac;
7600  decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
7601  val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
7602  break;
7603  }
7604  case STRING_RESULT:
7605  pos= (uchar*) val;
7606  break;
7607  case ROW_RESULT:
7608  default:
7609  DBUG_ASSERT(1);
7610  return 0;
7611  }
7612  int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
7613  buf1_length= 10;
7614  }
7615 
7616  /* Length of the whole event */
7617  event_length= sizeof(buf)+ name_len + buf1_length + val_len + unsigned_len;
7618 
7619  return (write_header(file, event_length) ||
7620  wrapper_my_b_safe_write(file, (uchar*) buf, sizeof(buf)) ||
7621  wrapper_my_b_safe_write(file, (uchar*) name, name_len) ||
7622  wrapper_my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
7623  wrapper_my_b_safe_write(file, pos, val_len) ||
7624  wrapper_my_b_safe_write(file, &flags, unsigned_len) ||
7625  write_footer(file));
7626 }
7627 #endif
7628 
7629 
7630 /*
7631  User_var_log_event::print()
7632 */
7633 
7634 #ifdef MYSQL_CLIENT
7635 void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7636 {
7637  IO_CACHE *const head= &print_event_info->head_cache;
7638  char quoted_id[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
7639  char name_id[NAME_LEN];
7640  int quoted_len= 0;
7641 
7642  if (!print_event_info->short_form)
7643  {
7644  print_header(head, print_event_info, FALSE);
7645  my_b_printf(head, "\tUser_var\n");
7646  }
7647  strmov(name_id, name);
7648  name_id[name_len]= '\0';
7649  my_b_printf(head, "SET @");
7650  quoted_len= my_strmov_quoted_identifier((char *) quoted_id,
7651  (const char *) name_id);
7652  quoted_id[quoted_len]= '\0';
7653  my_b_write(head, (uchar*) quoted_id, quoted_len);
7654 
7655  if (is_null)
7656  {
7657  my_b_printf(head, ":=NULL%s\n", print_event_info->delimiter);
7658  }
7659  else
7660  {
7661  switch (type) {
7662  case REAL_RESULT:
7663  double real_val;
7664  char real_buf[FMT_G_BUFSIZE(14)];
7665  float8get(real_val, val);
7666  sprintf(real_buf, "%.14g", real_val);
7667  my_b_printf(head, ":=%s%s\n", real_buf, print_event_info->delimiter);
7668  break;
7669  case INT_RESULT:
7670  char int_buf[22];
7671  longlong10_to_str(uint8korr(val), int_buf,
7672  ((flags & User_var_log_event::UNSIGNED_F) ? 10 : -10));
7673  my_b_printf(head, ":=%s%s\n", int_buf, print_event_info->delimiter);
7674  break;
7675  case DECIMAL_RESULT:
7676  {
7677  char str_buf[200];
7678  int str_len= sizeof(str_buf) - 1;
7679  int precision= (int)val[0];
7680  int scale= (int)val[1];
7681  decimal_digit_t dec_buf[10];
7682  decimal_t dec;
7683  dec.len= 10;
7684  dec.buf= dec_buf;
7685 
7686  bin2decimal((uchar*) val+2, &dec, precision, scale);
7687  decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
7688  str_buf[str_len]= 0;
7689  my_b_printf(head, ":=%s%s\n", str_buf, print_event_info->delimiter);
7690  break;
7691  }
7692  case STRING_RESULT:
7693  {
7694  /*
7695  Let's express the string in hex. That's the most robust way. If we
7696  print it in character form instead, we need to escape it with
7697  character_set_client which we don't know (we will know it in 5.0, but
7698  in 4.1 we don't know it easily when we are printing
7699  User_var_log_event). Explanation why we would need to bother with
7700  character_set_client (quoting Bar):
7701  > Note, the parser doesn't switch to another unescaping mode after
7702  > it has met a character set introducer.
7703  > For example, if an SJIS client says something like:
7704  > SET @a= _ucs2 \0a\0b'
7705  > the string constant is still unescaped according to SJIS, not
7706  > according to UCS2.
7707  */
7708  char *hex_str;
7709  CHARSET_INFO *cs;
7710 
7711  hex_str= (char *)my_malloc(2*val_len+1+2,MYF(MY_WME)); // 2 hex digits / byte
7712  if (!hex_str)
7713  return;
7714  str_to_hex(hex_str, val, val_len);
7715  /*
7716  For proper behaviour when mysqlbinlog|mysql, we need to explicitely
7717  specify the variable's collation. It will however cause problems when
7718  people want to mysqlbinlog|mysql into another server not supporting the
7719  character set. But there's not much to do about this and it's unlikely.
7720  */
7721  if (!(cs= get_charset(charset_number, MYF(0))))
7722  /*
7723  Generate an unusable command (=> syntax error) is probably the best
7724  thing we can do here.
7725  */
7726  my_b_printf(head, ":=???%s\n", print_event_info->delimiter);
7727  else
7728  my_b_printf(head, ":=_%s %s COLLATE `%s`%s\n",
7729  cs->csname, hex_str, cs->name,
7730  print_event_info->delimiter);
7731  my_free(hex_str);
7732  }
7733  break;
7734  case ROW_RESULT:
7735  default:
7736  DBUG_ASSERT(1);
7737  return;
7738  }
7739  }
7740 }
7741 #endif
7742 
7743 
7744 /*
7745  User_var_log_event::do_apply_event()
7746 */
7747 
7748 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
7749 int User_var_log_event::do_apply_event(Relay_log_info const *rli)
7750 {
7751  Item *it= 0;
7752  CHARSET_INFO *charset;
7753  query_id_t sav_query_id= 0; /* memorize orig id when deferred applying */
7754 
7755  if (rli->deferred_events_collecting)
7756  {
7757  set_deferred(current_thd->query_id);
7758  return rli->deferred_events->add(this);
7759  } else if (is_deferred())
7760  {
7761  sav_query_id= current_thd->query_id;
7762  current_thd->query_id= query_id; /* recreating original time context */
7763  }
7764 
7765  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
7766  return 1;
7767  double real_val;
7768  longlong int_val;
7769 
7770  /*
7771  We are now in a statement until the associated query log event has
7772  been processed.
7773  */
7774  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
7775 
7776  if (is_null)
7777  {
7778  it= new Item_null();
7779  }
7780  else
7781  {
7782  switch (type) {
7783  case REAL_RESULT:
7784  float8get(real_val, val);
7785  it= new Item_float(real_val, 0);
7786  val= (char*) &real_val; // Pointer to value in native format
7787  val_len= 8;
7788  break;
7789  case INT_RESULT:
7790  int_val= (longlong) uint8korr(val);
7791  it= new Item_int(int_val);
7792  val= (char*) &int_val; // Pointer to value in native format
7793  val_len= 8;
7794  break;
7795  case DECIMAL_RESULT:
7796  {
7797  Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
7798  it= dec;
7799  val= (char *)dec->val_decimal(NULL);
7800  val_len= sizeof(my_decimal);
7801  break;
7802  }
7803  case STRING_RESULT:
7804  it= new Item_string(val, val_len, charset);
7805  break;
7806  case ROW_RESULT:
7807  default:
7808  DBUG_ASSERT(1);
7809  return 0;
7810  }
7811  }
7813  new Item_func_set_user_var(Name_string(name, name_len, false), it, false);
7814  /*
7815  Item_func_set_user_var can't substitute something else on its place =>
7816  0 can be passed as last argument (reference on item)
7817 
7818  Fix_fields() can fail, in which case a call of update_hash() might
7819  crash the server, so if fix fields fails, we just return with an
7820  error.
7821  */
7822  if (e->fix_fields(thd, 0))
7823  return 1;
7824 
7825  /*
7826  A variable can just be considered as a table with
7827  a single record and with a single column. Thus, like
7828  a column value, it could always have IMPLICIT derivation.
7829  */
7830  e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT,
7831  (flags & User_var_log_event::UNSIGNED_F));
7832  if (!is_deferred())
7833  free_root(thd->mem_root, 0);
7834  else
7835  current_thd->query_id= sav_query_id; /* restore current query's context */
7836 
7837  return 0;
7838 }
7839 
7840 int User_var_log_event::do_update_pos(Relay_log_info *rli)
7841 {
7842  rli->inc_event_relay_log_pos();
7843  return 0;
7844 }
7845 
7847 User_var_log_event::do_shall_skip(Relay_log_info *rli)
7848 {
7849  /*
7850  It is a common error to set the slave skip counter to 1 instead
7851  of 2 when recovering from an insert which used a auto increment,
7852  rand, or user var. Therefore, if the slave skip counter is 1, we
7853  just say that this event should be skipped by ignoring it, meaning
7854  that we do not change the value of the slave skip counter since it
7855  will be decreased by the following insert event.
7856  */
7857  return continue_group(rli);
7858 }
7859 #endif /* !MYSQL_CLIENT */
7860 
7861 
7862 /**************************************************************************
7863  Unknown_log_event methods
7864 **************************************************************************/
7865 
7866 #ifdef HAVE_REPLICATION
7867 #ifdef MYSQL_CLIENT
7868 void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
7869 {
7870  if (print_event_info->short_form)
7871  return;
7872  print_header(&print_event_info->head_cache, print_event_info, FALSE);
7873  my_b_printf(&print_event_info->head_cache, "\n# %s", "Unknown event\n");
7874 }
7875 #endif
7876 
7877 /**************************************************************************
7878  Stop_log_event methods
7879 **************************************************************************/
7880 
7881 /*
7882  Stop_log_event::print()
7883 */
7884 
7885 #ifdef MYSQL_CLIENT
7886 void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
7887 {
7888  if (print_event_info->short_form)
7889  return;
7890 
7891  print_header(&print_event_info->head_cache, print_event_info, FALSE);
7892  my_b_printf(&print_event_info->head_cache, "\tStop\n");
7893 }
7894 #endif /* MYSQL_CLIENT */
7895 
7896 
7897 #ifndef MYSQL_CLIENT
7898 /*
7899  The master stopped. We used to clean up all temporary tables but
7900  this is useless as, as the master has shut down properly, it has
7901  written all DROP TEMPORARY TABLE (prepared statements' deletion is
7902  TODO only when we binlog prep stmts). We used to clean up
7903  slave_load_tmpdir, but this is useless as it has been cleared at the
7904  end of LOAD DATA INFILE. So we have nothing to do here. The place
7905  were we must do this cleaning is in
7906  Start_log_event_v3::do_apply_event(), not here. Because if we come
7907  here, the master was sane.
7908 
7909  This must only be called from the Slave SQL thread, since it calls
7910  flush_relay_log_info().
7911 */
7912 int Stop_log_event::do_update_pos(Relay_log_info *rli)
7913 {
7914  int error_inc= 0;
7915  int error_flush= 0;
7916  /*
7917  We do not want to update master_log pos because we get a rotate event
7918  before stop, so by now group_master_log_name is set to the next log.
7919  If we updated it, we will have incorrect master coordinates and this
7920  could give false triggers in MASTER_POS_WAIT() that we have reached
7921  the target position when in fact we have not.
7922  The group position is always unchanged in MTS mode because the event
7923  is never executed so can't be scheduled to a Worker.
7924  */
7925  if ((thd->variables.option_bits & OPTION_BEGIN) || rli->is_parallel_exec())
7926  rli->inc_event_relay_log_pos();
7927  else
7928  {
7929  error_inc= rli->inc_group_relay_log_pos(0, true/*need_data_lock=true*/);
7930  error_flush= rli->flush_info(TRUE);
7931  }
7932  return (error_inc || error_flush);
7933 }
7934 
7935 #endif /* !MYSQL_CLIENT */
7936 #endif /* HAVE_REPLICATION */
7937 
7938 
7939 /**************************************************************************
7940  Create_file_log_event methods
7941 **************************************************************************/
7942 
7943 /*
7944  Create_file_log_event ctor
7945 */
7946 
7947 #ifndef MYSQL_CLIENT
7948 Create_file_log_event::
7949 Create_file_log_event(THD* thd_arg, sql_exchange* ex,
7950  const char* db_arg, const char* table_name_arg,
7951  List<Item>& fields_arg,
7952  bool is_concurrent_arg,
7953  enum enum_duplicates handle_dup,
7954  bool ignore,
7955  uchar* block_arg, uint block_len_arg, bool using_trans)
7956  :Load_log_event(thd_arg, ex, db_arg, table_name_arg, fields_arg,
7957  is_concurrent_arg,
7958  handle_dup, ignore, using_trans),
7959  fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
7960  file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
7961 {
7962  DBUG_ENTER("Create_file_log_event");
7963  sql_ex.force_new_format();
7964  DBUG_VOID_RETURN;
7965 }
7966 
7967 
7968 /*
7969  Create_file_log_event::write_data_body()
7970 */
7971 
7972 bool Create_file_log_event::write_data_body(IO_CACHE* file)
7973 {
7974  bool res;
7975  if ((res= Load_log_event::write_data_body(file)) || fake_base)
7976  return res;
7977  return (my_b_safe_write(file, (uchar*) "", 1) ||
7978  my_b_safe_write(file, (uchar*) block, block_len));
7979 }
7980 
7981 
7982 /*
7983  Create_file_log_event::write_data_header()
7984 */
7985 
7986 bool Create_file_log_event::write_data_header(IO_CACHE* file)
7987 {
7988  bool res;
7989  uchar buf[CREATE_FILE_HEADER_LEN];
7990  if ((res= Load_log_event::write_data_header(file)) || fake_base)
7991  return res;
7992  int4store(buf + CF_FILE_ID_OFFSET, file_id);
7993  return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
7994 }
7995 
7996 
7997 /*
7998  Create_file_log_event::write_base()
7999 */
8000 
8001 bool Create_file_log_event::write_base(IO_CACHE* file)
8002 {
8003  bool res;
8004  fake_base= 1; // pretend we are Load event
8005  res= write(file);
8006  fake_base= 0;
8007  return res;
8008 }
8009 
8010 #endif /* !MYSQL_CLIENT */
8011 
8012 /*
8013  Create_file_log_event ctor
8014 */
8015 
8016 Create_file_log_event::Create_file_log_event(const char* buf, uint len,
8017  const Format_description_log_event* description_event)
8018  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
8019 {
8020  DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
8021  uint block_offset;
8022  uint header_len= description_event->common_header_len;
8023  uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
8024  uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
8025  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
8026  copy_log_event(event_buf,len,
8027  ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
8028  load_header_len + header_len :
8029  (fake_base ? (header_len+load_header_len) :
8030  (header_len+load_header_len) +
8031  create_file_header_len)),
8032  description_event))
8033  DBUG_VOID_RETURN;
8034  if (description_event->binlog_version!=1)
8035  {
8036  file_id= uint4korr(buf +
8037  header_len +
8038  load_header_len + CF_FILE_ID_OFFSET);
8039  /*
8040  Note that it's ok to use get_data_size() below, because it is computed
8041  with values we have already read from this event (because we called
8042  copy_log_event()); we are not using slave's format info to decode
8043  master's format, we are really using master's format info.
8044  Anyway, both formats should be identical (except the common_header_len)
8045  as these Load events are not changed between 4.0 and 5.0 (as logging of
8046  LOAD DATA INFILE does not use Load_log_event in 5.0).
8047 
8048  The + 1 is for \0 terminating fname
8049  */
8050  block_offset= (description_event->common_header_len +
8051  Load_log_event::get_data_size() +
8052  create_file_header_len + 1);
8053  if (len < block_offset)
8054  DBUG_VOID_RETURN;
8055  block = (uchar*)buf + block_offset;
8056  block_len = len - block_offset;
8057  }
8058  else
8059  {
8060  sql_ex.force_new_format();
8061  inited_from_old = 1;
8062  }
8063  DBUG_VOID_RETURN;
8064 }
8065 
8066 
8067 /*
8068  Create_file_log_event::print()
8069 */
8070 
8071 #ifdef MYSQL_CLIENT
8072 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
8073  bool enable_local)
8074 {
8075  if (print_event_info->short_form)
8076  {
8077  if (enable_local && check_fname_outside_temp_buf())
8078  Load_log_event::print(file, print_event_info);
8079  return;
8080  }
8081 
8082  if (enable_local)
8083  {
8084  Load_log_event::print(file, print_event_info,
8085  !check_fname_outside_temp_buf());
8090  DBUG_EXECUTE_IF ("simulate_create_event_write_error",
8091  {(&print_event_info->head_cache)->write_pos=
8092  (&print_event_info->head_cache)->write_end;
8093  DBUG_SET("+d,simulate_file_write_error");});
8094  /*
8095  That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
8096  SHOW BINLOG EVENTS we don't.
8097  */
8098  my_b_printf(&print_event_info->head_cache, "#");
8099  }
8100 
8101  my_b_printf(&print_event_info->head_cache,
8102  " file_id: %d block_len: %d\n", file_id, block_len);
8103 }
8104 
8105 
8106 void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
8107 {
8108  print(file, print_event_info, 0);
8109 }
8110 #endif /* MYSQL_CLIENT */
8111 
8112 
8113 /*
8114  Create_file_log_event::pack_info()
8115 */
8116 
8117 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8118 int Create_file_log_event::pack_info(Protocol *protocol)
8119 {
8120  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
8121  pos= strmov(buf, "db=");
8122  memcpy(pos, db, db_len);
8123  pos= strmov(pos + db_len, ";table=");
8124  memcpy(pos, table_name, table_name_len);
8125  pos= strmov(pos + table_name_len, ";file_id=");
8126  pos= int10_to_str((long) file_id, pos, 10);
8127  pos= strmov(pos, ";block_len=");
8128  pos= int10_to_str((long) block_len, pos, 10);
8129  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
8130  return 0;
8131 }
8132 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8133 
8134 
8146 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8147 int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
8148 {
8149  char fname_buf[FN_REFLEN+TEMP_FILE_MAX_LEN];
8150  char *ext;
8151  int fd = -1;
8152  IO_CACHE file;
8153  int error = 1;
8154 
8155  lex_start(thd);
8157  THD_STAGE_INFO(thd, stage_making_temp_file_create_before_load_data);
8158  memset(&file, 0, sizeof(file));
8159  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
8160  /* old copy may exist already */
8161  mysql_file_delete(key_file_log_event_info, fname_buf, MYF(0));
8166  DBUG_EXECUTE_IF("simulate_file_create_error_create_log_event",
8167  {
8168  strcat(fname_buf,"/");
8169  });
8170  if ((fd= mysql_file_create(key_file_log_event_info,
8171  fname_buf, CREATE_MODE,
8172  O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8173  MYF(MY_WME))) < 0 ||
8174  init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
8175  MYF(MY_WME|MY_NABP)))
8176  {
8177  rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8178  "Error in Create_file event: could not open file '%s'",
8179  fname_buf);
8180  goto err;
8181  }
8182 
8183  // a trick to avoid allocating another buffer
8184  fname= fname_buf;
8185  fname_len= (uint) (strmov(ext, ".data") - fname);
8186  if (write_base(&file))
8187  {
8188  strmov(ext, ".info"); // to have it right in the error message
8189  rli->report(ERROR_LEVEL, my_errno,
8190  "Error in Create_file event: could not write to file '%s'",
8191  fname_buf);
8192  goto err;
8193  }
8194  end_io_cache(&file);
8195  mysql_file_close(fd, MYF(0));
8196 
8197  // fname_buf now already has .data, not .info, because we did our trick
8198  /* old copy may exist already */
8199  mysql_file_delete(key_file_log_event_data, fname_buf, MYF(0));
8200  if ((fd= mysql_file_create(key_file_log_event_data,
8201  fname_buf, CREATE_MODE,
8202  O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8203  MYF(MY_WME))) < 0)
8204  {
8205  rli->report(ERROR_LEVEL, my_errno,
8206  "Error in Create_file event: could not open file '%s'",
8207  fname_buf);
8208  goto err;
8209  }
8214  DBUG_EXECUTE_IF("simulate_file_write_error_create_log_event",
8215  {
8216  mysql_file_close(fd, MYF(0));
8217  });
8218  if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8219  {
8220  rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8221  "Error in Create_file event: write to '%s' failed",
8222  fname_buf);
8223  goto err;
8224  }
8225  error=0; // Everything is ok
8226 
8227 err:
8228  if (error)
8229  end_io_cache(&file);
8230  if (fd >= 0)
8231  mysql_file_close(fd, MYF(0));
8232  return error != 0;
8233 }
8234 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8235 
8236 
8237 /**************************************************************************
8238  Append_block_log_event methods
8239 **************************************************************************/
8240 
8241 /*
8242  Append_block_log_event ctor
8243 */
8244 
8245 #ifndef MYSQL_CLIENT
8247  const char *db_arg,
8248  uchar *block_arg,
8249  uint block_len_arg,
8250  bool using_trans)
8251  :Log_event(thd_arg, 0,
8252  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8253  Log_event::EVENT_STMT_CACHE,
8254  Log_event::EVENT_NORMAL_LOGGING),
8255  block(block_arg),
8256  block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
8257 {
8258 }
8259 #endif
8260 
8261 
8262 /*
8263  Append_block_log_event ctor
8264 */
8265 
8266 Append_block_log_event::Append_block_log_event(const char* buf, uint len,
8267  const Format_description_log_event* description_event)
8268  :Log_event(buf, description_event),block(0)
8269 {
8270  DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
8271  uint8 common_header_len= description_event->common_header_len;
8272  uint8 append_block_header_len=
8273  description_event->post_header_len[APPEND_BLOCK_EVENT-1];
8274  uint total_header_len= common_header_len+append_block_header_len;
8275  if (len < total_header_len)
8276  DBUG_VOID_RETURN;
8277  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
8278  block= (uchar*)buf + total_header_len;
8279  block_len= len - total_header_len;
8280  DBUG_VOID_RETURN;
8281 }
8282 
8283 
8284 /*
8285  Append_block_log_event::write()
8286 */
8287 
8288 #ifndef MYSQL_CLIENT
8289 bool Append_block_log_event::write(IO_CACHE* file)
8290 {
8291  uchar buf[APPEND_BLOCK_HEADER_LEN];
8292  int4store(buf + AB_FILE_ID_OFFSET, file_id);
8293  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
8294  wrapper_my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
8295  wrapper_my_b_safe_write(file, (uchar*) block, block_len) ||
8296  write_footer(file));
8297 }
8298 #endif
8299 
8300 
8301 /*
8302  Append_block_log_event::print()
8303 */
8304 
8305 #ifdef MYSQL_CLIENT
8306 void Append_block_log_event::print(FILE* file,
8307  PRINT_EVENT_INFO* print_event_info)
8308 {
8309  if (print_event_info->short_form)
8310  return;
8311  print_header(&print_event_info->head_cache, print_event_info, FALSE);
8312  my_b_printf(&print_event_info->head_cache,
8313  "\n#%s: file_id: %d block_len: %d\n",
8314  get_type_str(), file_id, block_len);
8315 }
8316 #endif /* MYSQL_CLIENT */
8317 
8318 
8319 /*
8320  Append_block_log_event::pack_info()
8321 */
8322 
8323 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8324 int Append_block_log_event::pack_info(Protocol *protocol)
8325 {
8326  char buf[256];
8327  size_t length;
8328  length= my_snprintf(buf, sizeof(buf), ";file_id=%u;block_len=%u",
8329  file_id, block_len);
8330  protocol->store(buf, length, &my_charset_bin);
8331  return 0;
8332 }
8333 
8334 
8335 /*
8336  Append_block_log_event::get_create_or_append()
8337 */
8338 
8339 int Append_block_log_event::get_create_or_append() const
8340 {
8341  return 0; /* append to the file, fail if not exists */
8342 }
8343 
8344 /*
8345  Append_block_log_event::do_apply_event()
8346 */
8347 
8348 int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
8349 {
8350  char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8351  int fd;
8352  int error = 1;
8353  DBUG_ENTER("Append_block_log_event::do_apply_event");
8354 
8355  THD_STAGE_INFO(thd, stage_making_temp_file_append_before_load_data);
8356  slave_load_file_stem(fname, file_id, server_id, ".data");
8357  if (get_create_or_append())
8358  {
8359  /*
8360  Usually lex_start() is called by mysql_parse(), but we need it here
8361  as the present method does not call mysql_parse().
8362  */
8363  lex_start(thd);
8365  /* old copy may exist already */
8366  mysql_file_delete(key_file_log_event_data, fname, MYF(0));
8367  if ((fd= mysql_file_create(key_file_log_event_data,
8368  fname, CREATE_MODE,
8369  O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
8370  MYF(MY_WME))) < 0)
8371  {
8372  rli->report(ERROR_LEVEL, my_errno,
8373  "Error in %s event: could not create file '%s'",
8374  get_type_str(), fname);
8375  goto err;
8376  }
8377  }
8378  else if ((fd= mysql_file_open(key_file_log_event_data,
8379  fname,
8380  O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
8381  MYF(MY_WME))) < 0)
8382  {
8383  rli->report(ERROR_LEVEL, my_errno,
8384  "Error in %s event: could not open file '%s'",
8385  get_type_str(), fname);
8386  goto err;
8387  }
8388 
8389  DBUG_EXECUTE_IF("remove_slave_load_file_before_write",
8390  {
8391  my_delete_allow_opened(fname, MYF(0));
8392  });
8393 
8394  if (mysql_file_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
8395  {
8396  rli->report(ERROR_LEVEL, my_errno,
8397  "Error in %s event: write to '%s' failed",
8398  get_type_str(), fname);
8399  goto err;
8400  }
8401  error=0;
8402 
8403 err:
8404  if (fd >= 0)
8405  mysql_file_close(fd, MYF(0));
8406  DBUG_RETURN(error);
8407 }
8408 #endif
8409 
8410 
8411 /**************************************************************************
8412  Delete_file_log_event methods
8413 **************************************************************************/
8414 
8415 /*
8416  Delete_file_log_event ctor
8417 */
8418 
8419 #ifndef MYSQL_CLIENT
8420 Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
8421  bool using_trans)
8422  :Log_event(thd_arg, 0,
8423  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8424  Log_event::EVENT_STMT_CACHE,
8425  Log_event::EVENT_NORMAL_LOGGING),
8426  file_id(thd_arg->file_id), db(db_arg)
8427 {
8428 }
8429 #endif
8430 
8431 /*
8432  Delete_file_log_event ctor
8433 */
8434 
8435 Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
8436  const Format_description_log_event* description_event)
8437  :Log_event(buf, description_event),file_id(0)
8438 {
8439  uint8 common_header_len= description_event->common_header_len;
8440  uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
8441  if (len < (uint)(common_header_len + delete_file_header_len))
8442  return;
8443  file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
8444 }
8445 
8446 
8447 /*
8448  Delete_file_log_event::write()
8449 */
8450 
8451 #ifndef MYSQL_CLIENT
8452 bool Delete_file_log_event::write(IO_CACHE* file)
8453 {
8454  uchar buf[DELETE_FILE_HEADER_LEN];
8455  int4store(buf + DF_FILE_ID_OFFSET, file_id);
8456  return (write_header(file, sizeof(buf)) ||
8457  wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8458  write_footer(file));
8459 }
8460 #endif
8461 
8462 
8463 /*
8464  Delete_file_log_event::print()
8465 */
8466 
8467 #ifdef MYSQL_CLIENT
8468 void Delete_file_log_event::print(FILE* file,
8469  PRINT_EVENT_INFO* print_event_info)
8470 {
8471  if (print_event_info->short_form)
8472  return;
8473  print_header(&print_event_info->head_cache, print_event_info, FALSE);
8474  my_b_printf(&print_event_info->head_cache,
8475  "\n#Delete_file: file_id=%u\n", file_id);
8476 }
8477 #endif /* MYSQL_CLIENT */
8478 
8479 /*
8480  Delete_file_log_event::pack_info()
8481 */
8482 
8483 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8484 int Delete_file_log_event::pack_info(Protocol *protocol)
8485 {
8486  char buf[64];
8487  size_t length;
8488  length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8489  protocol->store(buf, length, &my_charset_bin);
8490  return 0;
8491 }
8492 #endif
8493 
8494 /*
8495  Delete_file_log_event::do_apply_event()
8496 */
8497 
8498 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8499 int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
8500 {
8501  char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8502  lex_start(thd);
8504  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
8505  mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8506  strmov(ext, ".info");
8507  mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8508  return 0;
8509 }
8510 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8511 
8512 
8513 /**************************************************************************
8514  Execute_load_log_event methods
8515 **************************************************************************/
8516 
8517 /*
8518  Execute_load_log_event ctor
8519 */
8520 
8521 #ifndef MYSQL_CLIENT
8522 Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
8523  const char* db_arg,
8524  bool using_trans)
8525  :Log_event(thd_arg, 0,
8526  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
8527  Log_event::EVENT_STMT_CACHE,
8528  Log_event::EVENT_NORMAL_LOGGING),
8529  file_id(thd_arg->file_id), db(db_arg)
8530 {
8531 }
8532 #endif
8533 
8534 
8535 /*
8536  Execute_load_log_event ctor
8537 */
8538 
8539 Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
8540  const Format_description_log_event* description_event)
8541  :Log_event(buf, description_event), file_id(0)
8542 {
8543  uint8 common_header_len= description_event->common_header_len;
8544  uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
8545  if (len < (uint)(common_header_len+exec_load_header_len))
8546  return;
8547  file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
8548 }
8549 
8550 
8551 /*
8552  Execute_load_log_event::write()
8553 */
8554 
8555 #ifndef MYSQL_CLIENT
8556 bool Execute_load_log_event::write(IO_CACHE* file)
8557 {
8558  uchar buf[EXEC_LOAD_HEADER_LEN];
8559  int4store(buf + EL_FILE_ID_OFFSET, file_id);
8560  return (write_header(file, sizeof(buf)) ||
8561  wrapper_my_b_safe_write(file, buf, sizeof(buf)) ||
8562  write_footer(file));
8563 }
8564 #endif
8565 
8566 
8567 /*
8568  Execute_load_log_event::print()
8569 */
8570 
8571 #ifdef MYSQL_CLIENT
8572 void Execute_load_log_event::print(FILE* file,
8573  PRINT_EVENT_INFO* print_event_info)
8574 {
8575  if (print_event_info->short_form)
8576  return;
8577  print_header(&print_event_info->head_cache, print_event_info, FALSE);
8578  my_b_printf(&print_event_info->head_cache, "\n#Exec_load: file_id=%d\n",
8579  file_id);
8580 }
8581 #endif
8582 
8583 /*
8584  Execute_load_log_event::pack_info()
8585 */
8586 
8587 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8588 int Execute_load_log_event::pack_info(Protocol *protocol)
8589 {
8590  char buf[64];
8591  size_t length;
8592  length= my_snprintf(buf, sizeof(buf), ";file_id=%u", (uint) file_id);
8593  protocol->store(buf, length, &my_charset_bin);
8594  return 0;
8595 }
8596 
8597 
8598 /*
8599  Execute_load_log_event::do_apply_event()
8600 */
8601 
8602 int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
8603 {
8604  char fname[FN_REFLEN+TEMP_FILE_MAX_LEN];
8605  char *ext;
8606  int fd;
8607  int error= 1;
8608  IO_CACHE file;
8609  Load_log_event *lev= 0;
8610 
8611  lex_start(thd);
8613  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
8619  DBUG_EXECUTE_IF("simulate_file_open_error_exec_event",
8620  {
8621  strcat(fname,"/");
8622  });
8623  if ((fd= mysql_file_open(key_file_log_event_info,
8624  fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
8625  MYF(MY_WME))) < 0 ||
8626  init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
8627  MYF(MY_WME|MY_NABP)))
8628  {
8629  rli->report(ERROR_LEVEL, thd->get_stmt_da()->sql_errno(),
8630  "Error in Exec_load event: could not open file '%s'",
8631  fname);
8632  goto err;
8633  }
8634  if (!(lev= (Load_log_event*)
8635  Log_event::read_log_event(&file,
8636  (mysql_mutex_t*) 0,
8638  opt_slave_sql_verify_checksum)) ||
8639  lev->get_type_code() != NEW_LOAD_EVENT)
8640  {
8641  rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
8642  "file '%s' appears corrupted", fname);
8643  goto err;
8644  }
8645  lev->thd = thd;
8646  /*
8647  lev->do_apply_event should use rli only for errors i.e. should
8648  not advance rli's position.
8649 
8650  lev->do_apply_event is the place where the table is loaded (it
8651  calls mysql_load()).
8652  */
8653  const_cast<Relay_log_info*>(rli)->set_future_group_master_log_pos(log_pos);
8654  if (lev->do_apply_event(0,rli,1))
8655  {
8656  /*
8657  We want to indicate the name of the file that could not be loaded
8658  (SQL_LOADxxx).
8659  But as we are here we are sure the error is in rli->last_slave_error and
8660  rli->last_slave_errno (example of error: duplicate entry for key), so we
8661  don't want to overwrite it with the filename.
8662  What we want instead is add the filename to the current error message.
8663  */
8664  char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
8665  if (tmp)
8666  {
8667  rli->report(ERROR_LEVEL, rli->last_error().number,
8668  "%s. Failed executing load from '%s'", tmp, fname);
8669  my_free(tmp);
8670  }
8671  goto err;
8672  }
8673  /*
8674  We have an open file descriptor to the .info file; we need to close it
8675  or Windows will refuse to delete the file in mysql_file_delete().
8676  */
8677  if (fd >= 0)
8678  {
8679  mysql_file_close(fd, MYF(0));
8680  end_io_cache(&file);
8681  fd= -1;
8682  }
8683  mysql_file_delete(key_file_log_event_info, fname, MYF(MY_WME));
8684  memcpy(ext, ".data", 6);
8685  mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8686  error = 0;
8687 
8688 err:
8689  delete lev;
8690  if (fd >= 0)
8691  {
8692  mysql_file_close(fd, MYF(0));
8693  end_io_cache(&file);
8694  }
8695  return error;
8696 }
8697 
8698 #endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8699 
8700 
8701 /**************************************************************************
8702  Begin_load_query_log_event methods
8703 **************************************************************************/
8704 
8705 #ifndef MYSQL_CLIENT
8706 Begin_load_query_log_event::
8707 Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
8708  uint block_len_arg, bool using_trans)
8709  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
8710  using_trans)
8711 {
8712  file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
8713 }
8714 #endif
8715 
8716 
8717 Begin_load_query_log_event::
8718 Begin_load_query_log_event(const char* buf, uint len,
8719  const Format_description_log_event* desc_event)
8720  :Append_block_log_event(buf, len, desc_event)
8721 {
8722 }
8723 
8724 
8725 #if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8726 int Begin_load_query_log_event::get_create_or_append() const
8727 {
8728  return 1; /* create the file */
8729 }
8730 #endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
8731 
8732 
8733 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
8735 Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
8736 {
8737  /*
8738  If the slave skip counter is 1, then we should not start executing
8739  on the next event.
8740  */
8741  return continue_group(rli);
8742 }
8743 #endif
8744 
8745 
8746 /**************************************************************************
8747  Execute_load_query_log_event methods
8748 **************************************************************************/
8749 
8750 
8751 #ifndef MYSQL_CLIENT
8752 Execute_load_query_log_event::
8753 Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
8754  ulong query_length_arg, uint fn_pos_start_arg,
8755  uint fn_pos_end_arg,
8756  enum_load_dup_handling dup_handling_arg,
8757  bool using_trans, bool immediate, bool suppress_use,
8758  int errcode):
8759  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans, immediate,
8760  suppress_use, errcode),
8761  file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
8762  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
8763 {
8764 }
8765 #endif /* !MYSQL_CLIENT */
8766 
8767 
8768 Execute_load_query_log_event::
8769 Execute_load_query_log_event(const char* buf, uint event_len,
8770  const Format_description_log_event* desc_event):
8771  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
8772  file_id(0), fn_pos_start(0), fn_pos_end(0)
8773 {
8774  if (!Query_log_event::is_valid())
8775  return;
8776 
8777  buf+= desc_event->common_header_len;
8778 
8779  fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
8780  fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
8781  dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
8782 
8783  if (fn_pos_start > q_len || fn_pos_end > q_len ||
8784  dup_handling > LOAD_DUP_REPLACE)
8785  return;
8786 
8787  file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
8788 }
8789 
8790 
8791 ulong Execute_load_query_log_event::get_post_header_size_for_derived()
8792 {
8793  return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
8794 }
8795 
8796 
8797 #ifndef MYSQL_CLIENT
8798 bool
8799 Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
8800 {
8801  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
8802  int4store(buf, file_id);
8803  int4store(buf + 4, fn_pos_start);
8804  int4store(buf + 4 + 4, fn_pos_end);
8805  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
8806  return wrapper_my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
8807 }
8808 #endif
8809 
8810 
8811 #ifdef MYSQL_CLIENT
8812 void Execute_load_query_log_event::print(FILE* file,
8813  PRINT_EVENT_INFO* print_event_info)
8814 {
8815  print(file, print_event_info, 0);
8816 }
8817 
8821 void Execute_load_query_log_event::print(FILE* file,
8822  PRINT_EVENT_INFO* print_event_info,
8823  const char *local_fname)
8824 {
8825  IO_CACHE *const head= &print_event_info->head_cache;
8826 
8827  print_query_header(head, print_event_info);
8832  DBUG_EXECUTE_IF ("simulate_execute_event_write_error",
8833  {head->write_pos= head->write_end;
8834  DBUG_SET("+d,simulate_file_write_error");});
8835 
8836  if (local_fname)
8837  {
8838  my_b_write(head, (uchar*) query, fn_pos_start);
8839  my_b_printf(head, " LOCAL INFILE \'");
8840  my_b_printf(head, "%s", local_fname);
8841  my_b_printf(head, "\'");
8842  if (dup_handling == LOAD_DUP_REPLACE)
8843  my_b_printf(head, " REPLACE");
8844  my_b_printf(head, " INTO");
8845  my_b_write(head, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
8846  my_b_printf(head, "\n%s\n", print_event_info->delimiter);
8847  }
8848  else
8849  {
8850  my_b_write(head, (uchar*) query, q_len);
8851  my_b_printf(head, "\n%s\n", print_event_info->delimiter);
8852  }
8853 
8854  if (!print_event_info->short_form)
8855  my_b_printf(head, "# file_id: %d \n", file_id);
8856 }
8857 #endif
8858 
8859 
8860 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
8861 int Execute_load_query_log_event::pack_info(Protocol *protocol)
8862 {
8863  char *buf, *pos;
8864  if (!(buf= (char*) my_malloc(9 + (db_len * 2) + 2 + q_len + 10 + 21,
8865  MYF(MY_WME))))
8866  return 1;
8867  pos= buf;
8868  if (db && db_len)
8869  {
8870  /*
8871  Statically allocates room to store '\0' and an identifier
8872  that may have NAME_LEN * 2 due to quoting and there are
8873  two quoting characters that wrap them.
8874  */
8875  char quoted_db[1 + NAME_LEN * 2 + 2];// quoted length of the identifier
8876  size_t size= 0;
8877  size= my_strmov_quoted_identifier(this->thd, quoted_db, db, 0);
8878  pos= strmov(buf, "use ");
8879  memcpy(pos, quoted_db, size);
8880  pos= strmov(pos + size, "; ");
8881  }
8882  if (query && q_len)
8883  {
8884  memcpy(pos, query, q_len);
8885  pos+= q_len;
8886  }
8887  pos= strmov(pos, " ;file_id=");
8888  pos= int10_to_str((long) file_id, pos, 10);
8889  protocol->store(buf, pos-buf, &my_charset_bin);
8890  my_free(buf);
8891  return 0;
8892 }
8893 
8894 
8895 int
8896 Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
8897 {
8898  char *p;
8899  char *buf;
8900  char *fname;
8901  char *fname_end;
8902  int error;
8903 
8904  buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
8905  (FN_REFLEN + TEMP_FILE_MAX_LEN) + 10 + 8 + 5, MYF(MY_WME));
8906 
8907  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf); buf= NULL;);
8908 
8909  /* Replace filename and LOCAL keyword in query before executing it */
8910  if (buf == NULL)
8911  {
8912  rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
8913  ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
8914  return 1;
8915  }
8916 
8917  p= buf;
8918  memcpy(p, query, fn_pos_start);
8919  p+= fn_pos_start;
8920  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
8921  p= slave_load_file_stem(p, file_id, server_id, ".data");
8922  fname_end= p= strend(p); // Safer than p=p+5
8923  *(p++)='\'';
8924  switch (dup_handling) {
8925  case LOAD_DUP_IGNORE:
8926  p= strmake(p, STRING_WITH_LEN(" IGNORE"));
8927  break;
8928  case LOAD_DUP_REPLACE:
8929  p= strmake(p, STRING_WITH_LEN(" REPLACE"));
8930  break;
8931  default:
8932  /* Ordinary load data */
8933  break;
8934  }
8935  p= strmake(p, STRING_WITH_LEN(" INTO "));
8936  p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
8937 
8938  error= Query_log_event::do_apply_event(rli, buf, p-buf);
8939 
8940  /* Forging file name for deletion in same buffer */
8941  *fname_end= 0;
8942 
8943  /*
8944  If there was an error the slave is going to stop, leave the
8945  file so that we can re-execute this event at START SLAVE.
8946  */
8947  if (!error)
8948  mysql_file_delete(key_file_log_event_data, fname, MYF(MY_WME));
8949 
8950  my_free(buf);
8951  return error;
8952 }
8953 #endif
8954 
8955 
8956 /**************************************************************************
8957  sql_ex_info methods
8958 **************************************************************************/
8959 
8960 /*
8961  sql_ex_info::write_data()
8962 */
8963 
8965 {
8966  if (new_format())
8967  {
8968  return (write_str_at_most_255_bytes(file, field_term, (uint) field_term_len) ||
8969  write_str_at_most_255_bytes(file, enclosed, (uint) enclosed_len) ||
8970  write_str_at_most_255_bytes(file, line_term, (uint) line_term_len) ||
8971  write_str_at_most_255_bytes(file, line_start, (uint) line_start_len) ||
8972  write_str_at_most_255_bytes(file, escaped, (uint) escaped_len) ||
8973  my_b_safe_write(file,(uchar*) &opt_flags,1));
8974  }
8975  else
8976  {
8981  old_sql_ex old_ex;
8982  old_ex.field_term= *field_term;
8983  old_ex.enclosed= *enclosed;
8984  old_ex.line_term= *line_term;
8985  old_ex.line_start= *line_start;
8986  old_ex.escaped= *escaped;
8987  old_ex.opt_flags= opt_flags;
8988  old_ex.empty_flags=empty_flags;
8989  return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
8990  }
8991 }
8992 
8993 
8994 /*
8995  sql_ex_info::init()
8996 */
8997 
8998 const char *sql_ex_info::init(const char *buf, const char *buf_end,
8999  bool use_new_format)
9000 {
9001  cached_new_format = use_new_format;
9002  if (use_new_format)
9003  {
9004  empty_flags=0;
9005  /*
9006  The code below assumes that buf will not disappear from
9007  under our feet during the lifetime of the event. This assumption
9008  holds true in the slave thread if the log is in new format, but is not
9009  the case when we have old format because we will be reusing net buffer
9010  to read the actual file before we write out the Create_file event.
9011  */
9012  if (read_str_at_most_255_bytes(&buf, buf_end, &field_term, &field_term_len) ||
9013  read_str_at_most_255_bytes(&buf, buf_end, &enclosed, &enclosed_len) ||
9014  read_str_at_most_255_bytes(&buf, buf_end, &line_term, &line_term_len) ||
9015  read_str_at_most_255_bytes(&buf, buf_end, &line_start, &line_start_len) ||
9016  read_str_at_most_255_bytes(&buf, buf_end, &escaped, &escaped_len))
9017  return 0;
9018  opt_flags = *buf++;
9019  }
9020  else
9021  {
9022  field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
9023  field_term = buf++; // Use first byte in string
9024  enclosed= buf++;
9025  line_term= buf++;
9026  line_start= buf++;
9027  escaped= buf++;
9028  opt_flags = *buf++;
9029  empty_flags= *buf++;
9030  if (empty_flags & FIELD_TERM_EMPTY)
9031  field_term_len=0;
9032  if (empty_flags & ENCLOSED_EMPTY)
9033  enclosed_len=0;
9034  if (empty_flags & LINE_TERM_EMPTY)
9035  line_term_len=0;
9036  if (empty_flags & LINE_START_EMPTY)
9037  line_start_len=0;
9038  if (empty_flags & ESCAPED_EMPTY)
9039  escaped_len=0;
9040  }
9041  return buf;
9042 }
9043 
9044 #ifndef DBUG_OFF
9045 #ifndef MYSQL_CLIENT
9046 static uchar dbug_extra_row_data_val= 0;
9047 
9058 const uchar* set_extra_data(uchar* arr)
9059 {
9060  uchar val= (dbug_extra_row_data_val++) %
9061  (EXTRA_ROW_INFO_MAX_PAYLOAD + 1); /* 0 .. MAX_PAYLOAD + 1 */
9062  arr[EXTRA_ROW_INFO_LEN_OFFSET]= val + EXTRA_ROW_INFO_HDR_BYTES;
9063  arr[EXTRA_ROW_INFO_FORMAT_OFFSET]= val;
9064  for (uchar i=0; i<val; i++)
9065  arr[EXTRA_ROW_INFO_HDR_BYTES+i]= val;
9066 
9067  return arr;
9068 }
9069 
9070 #endif // #ifndef MYSQL_CLIENT
9071 
9084 void check_extra_data(uchar* extra_row_data)
9085 {
9086  assert(extra_row_data);
9087  uint16 len= extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
9088  uint8 val= len - EXTRA_ROW_INFO_HDR_BYTES;
9089  assert(extra_row_data[EXTRA_ROW_INFO_FORMAT_OFFSET] == val);
9090  for (uint16 i= 0; i < val; i++)
9091  {
9092  assert(extra_row_data[EXTRA_ROW_INFO_HDR_BYTES + i] == val);
9093  }
9094 }
9095 
9096 #endif // #ifndef DBUG_OFF
9097 
9098 /**************************************************************************
9099  Rows_log_event member functions
9100 **************************************************************************/
9101 
9102 #ifndef MYSQL_CLIENT
9103 Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, const Table_id& tid,
9104  MY_BITMAP const *cols, bool using_trans,
9105  Log_event_type event_type,
9106  const uchar* extra_row_info)
9107  : Log_event(thd_arg, 0,
9108  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
9109  Log_event::EVENT_STMT_CACHE,
9110  Log_event::EVENT_NORMAL_LOGGING),
9111  m_row_count(0),
9112  m_table(tbl_arg),
9113  m_table_id(tid),
9114  m_width(tbl_arg ? tbl_arg->s->fields : 1),
9115  m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0),
9116  m_type(event_type), m_extra_row_data(0)
9117 #ifdef HAVE_REPLICATION
9118  , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), last_hashed_key(NULL)
9119 #endif
9120 {
9121  DBUG_ASSERT(tbl_arg && tbl_arg->s && tid.is_valid());
9122 
9123  if (thd_arg->variables.option_bits & OPTION_NO_FOREIGN_KEY_CHECKS)
9124  set_flags(NO_FOREIGN_KEY_CHECKS_F);
9125  if (thd_arg->variables.option_bits & OPTION_RELAXED_UNIQUE_CHECKS)
9126  set_flags(RELAXED_UNIQUE_CHECKS_F);
9127 #ifndef DBUG_OFF
9128  uchar extra_data[255];
9129  DBUG_EXECUTE_IF("extra_row_data_set",
9130  /* Set extra row data to a known value */
9131  extra_row_info = set_extra_data(extra_data););
9132 #endif
9133  if (extra_row_info)
9134  {
9135  /* Copy Extra data from thd into new event */
9136  uint8 extra_data_len= extra_row_info[EXTRA_ROW_INFO_LEN_OFFSET];
9137  assert(extra_data_len >= EXTRA_ROW_INFO_HDR_BYTES);
9138 
9139  m_extra_row_data= (uchar*) my_malloc(extra_data_len, MYF(MY_WME));
9140 
9141  if (likely(m_extra_row_data != NULL))
9142  {
9143  memcpy(m_extra_row_data, extra_row_info,
9144  extra_data_len);
9145  }
9146  }
9147 
9148  /* if bitmap_init fails, caught in is_valid() */
9149  if (likely(!bitmap_init(&m_cols,
9150  m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9151  m_width,
9152  false)))
9153  {
9154  /* Cols can be zero if this is a dummy binrows event */
9155  if (likely(cols != NULL))
9156  {
9157  memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
9158  create_last_word_mask(&m_cols);
9159  }
9160  }
9161  else
9162  {
9163  // Needed because bitmap_init() does not set it to null on failure
9164  m_cols.bitmap= 0;
9165  }
9166 }
9167 #endif
9168 
9169 Rows_log_event::Rows_log_event(const char *buf, uint event_len,
9171  *description_event)
9172  : Log_event(buf, description_event),
9173  m_row_count(0),
9174 #ifndef MYSQL_CLIENT
9175  m_table(NULL),
9176 #endif
9177  m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0),
9178  m_extra_row_data(0)
9179 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9180  , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL), last_hashed_key(NULL)
9181 #endif
9182 {
9183  DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
9184  uint8 const common_header_len= description_event->common_header_len;
9185  Log_event_type event_type= (Log_event_type) buf[EVENT_TYPE_OFFSET];
9186  m_type= event_type;
9187 
9188  uint8 const post_header_len= description_event->post_header_len[event_type-1];
9189 
9190  DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
9191  "post_header_len: %d",
9192  event_len, common_header_len,
9193  post_header_len));
9194 
9195  const char *post_start= buf + common_header_len;
9196  post_start+= RW_MAPID_OFFSET;
9197  if (post_header_len == 6)
9198  {
9199  /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
9200  m_table_id= uint4korr(post_start);
9201  post_start+= 4;
9202  }
9203  else
9204  {
9205  m_table_id= uint6korr(post_start);
9206  post_start+= RW_FLAGS_OFFSET;
9207  }
9208 
9209  m_flags= uint2korr(post_start);
9210  post_start+= 2;
9211 
9212  uint16 var_header_len= 0;
9213  if (post_header_len == ROWS_HEADER_LEN_V2)
9214  {
9215  /*
9216  Have variable length header, check length,
9217  which includes length bytes
9218  */
9219  var_header_len= uint2korr(post_start);
9220  assert(var_header_len >= 2);
9221  var_header_len-= 2;
9222 
9223  /* Iterate over var-len header, extracting 'chunks' */
9224  const char* start= post_start + 2;
9225  const char* end= start + var_header_len;
9226  for (const char* pos= start; pos < end;)
9227  {
9228  switch(*pos++)
9229  {
9230  case RW_V_EXTRAINFO_TAG:
9231  {
9232  /* Have an 'extra info' section, read it in */
9233  assert((end - pos) >= EXTRA_ROW_INFO_HDR_BYTES);
9234  uint8 infoLen= pos[EXTRA_ROW_INFO_LEN_OFFSET];
9235  assert((end - pos) >= infoLen);
9236  /* Just store/use the first tag of this type, skip others */
9237  if (likely(!m_extra_row_data))
9238  {
9239  m_extra_row_data= (uchar*) my_malloc(infoLen,
9240  MYF(MY_WME));
9241  if (likely(m_extra_row_data != NULL))
9242  {
9243  memcpy(m_extra_row_data, pos, infoLen);
9244  }
9245  DBUG_EXECUTE_IF("extra_row_data_check",
9246  /* Check extra data has expected value */
9247  check_extra_data(m_extra_row_data););
9248  }
9249  pos+= infoLen;
9250  break;
9251  }
9252  default:
9253  /* Unknown code, we will not understand anything further here */
9254  pos= end; /* Break loop */
9255  }
9256  }
9257  }
9258 
9259  uchar const *const var_start=
9260  (const uchar *)buf + common_header_len + post_header_len + var_header_len;
9261  uchar const *const ptr_width= var_start;
9262  uchar *ptr_after_width= (uchar*) ptr_width;
9263  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9264  m_width = net_field_length(&ptr_after_width);
9265  DBUG_PRINT("debug", ("m_width=%lu", m_width));
9266  /* if bitmap_init fails, catched in is_valid() */
9267  if (likely(!bitmap_init(&m_cols,
9268  m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
9269  m_width,
9270  false)))
9271  {
9272  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9273  memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
9274  create_last_word_mask(&m_cols);
9275  ptr_after_width+= (m_width + 7) / 8;
9276  DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
9277  }
9278  else
9279  {
9280  // Needed because bitmap_init() does not set it to null on failure
9281  m_cols.bitmap= NULL;
9282  DBUG_VOID_RETURN;
9283  }
9284 
9285  m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
9286 
9287  if ((event_type == UPDATE_ROWS_EVENT) ||
9288  (event_type == UPDATE_ROWS_EVENT_V1))
9289  {
9290  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9291 
9292  /* if bitmap_init fails, caught in is_valid() */
9293  if (likely(!bitmap_init(&m_cols_ai,
9294  m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
9295  m_width,
9296  false)))
9297  {
9298  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
9299  memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
9300  create_last_word_mask(&m_cols_ai);
9301  ptr_after_width+= (m_width + 7) / 8;
9302  DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
9303  no_bytes_in_map(&m_cols_ai));
9304  }
9305  else
9306  {
9307  // Needed because bitmap_init() does not set it to null on failure
9308  m_cols_ai.bitmap= 0;
9309  DBUG_VOID_RETURN;
9310  }
9311  }
9312 
9313  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
9314 
9315  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
9316  DBUG_PRINT("info",("m_table_id: %llu m_flags: %d m_width: %lu data_size: %lu",
9317  m_table_id.id(), m_flags, m_width, (ulong) data_size));
9318 
9319  // Allocate one extra byte, in case we have to do uint3korr!
9320  m_rows_buf= (uchar*) my_malloc(data_size + 1, MYF(MY_WME)); // didrik
9321  if (likely((bool)m_rows_buf))
9322  {
9323 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9324  m_curr_row= m_rows_buf;
9325 #endif
9326  m_rows_end= m_rows_buf + data_size;
9327  m_rows_cur= m_rows_end;
9328  memcpy(m_rows_buf, ptr_rows_data, data_size);
9329  }
9330  else
9331  m_cols.bitmap= 0; // to not free it
9332 
9333  DBUG_VOID_RETURN;
9334 }
9335 
9336 Rows_log_event::~Rows_log_event()
9337 {
9338  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
9339  m_cols.bitmap= 0; // so no my_free in bitmap_free
9340  bitmap_free(&m_cols); // To pair with bitmap_init().
9341  my_free(m_rows_buf);
9342  my_free(m_extra_row_data);
9343 }
9344 
9345 int Rows_log_event::get_data_size()
9346 {
9347  int const general_type_code= get_general_type_code();
9348 
9349  uchar buf[sizeof(m_width) + 1];
9350  uchar *end= net_store_length(buf, m_width);
9351 
9352  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
9353  return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
9354  (general_type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
9355  (m_rows_cur - m_rows_buf););
9356 
9357  int data_size= 0;
9358  bool is_v2_event= get_type_code() > DELETE_ROWS_EVENT_V1;
9359  if (is_v2_event)
9360  {
9361  data_size= ROWS_HEADER_LEN_V2 +
9362  (m_extra_row_data ?
9363  RW_V_TAG_LEN + m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET]:
9364  0);
9365  }
9366  else
9367  {
9368  data_size= ROWS_HEADER_LEN_V1;
9369  }
9370  data_size+= no_bytes_in_map(&m_cols);
9371  data_size+= (uint) (end - buf);
9372 
9373  if (general_type_code == UPDATE_ROWS_EVENT)
9374  data_size+= no_bytes_in_map(&m_cols_ai);
9375 
9376  data_size+= (uint) (m_rows_cur - m_rows_buf);
9377  return data_size;
9378 }
9379 
9380 
9381 #ifndef MYSQL_CLIENT
9382 int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
9383 {
9384  /*
9385  When the table has a primary key, we would probably want, by default, to
9386  log only the primary key value instead of the entire "before image". This
9387  would save binlog space. TODO
9388  */
9389  DBUG_ENTER("Rows_log_event::do_add_row_data");
9390  DBUG_PRINT("enter", ("row_data: 0x%lx length: %lu", (ulong) row_data,
9391  (ulong) length));
9392 
9393  /*
9394  If length is zero, there is nothing to write, so we just
9395  return. Note that this is not an optimization, since calling
9396  realloc() with size 0 means free().
9397  */
9398  if (length == 0)
9399  {
9400  m_row_count++;
9401  DBUG_RETURN(0);
9402  }
9403 
9404  /*
9405  Don't print debug messages when running valgrind since they can
9406  trigger false warnings.
9407  */
9408 #ifndef HAVE_purify
9409  DBUG_DUMP("row_data", row_data, min<size_t>(length, 32));
9410 #endif
9411 
9412  DBUG_ASSERT(m_rows_buf <= m_rows_cur);
9413  DBUG_ASSERT(!m_rows_buf || (m_rows_end && m_rows_buf < m_rows_end));
9414  DBUG_ASSERT(m_rows_cur <= m_rows_end);
9415 
9416  /* The cast will always work since m_rows_cur <= m_rows_end */
9417  if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
9418  {
9419  size_t const block_size= 1024;
9420  my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
9421  my_ptrdiff_t const new_alloc=
9422  block_size * ((cur_size + length + block_size - 1) / block_size);
9423 
9424  // Allocate one extra byte, in case we have to do uint3korr!
9425  uchar* const new_buf=
9426  (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc + 1,
9427  MYF(MY_ALLOW_ZERO_PTR|MY_WME));
9428  if (unlikely(!new_buf))
9429  DBUG_RETURN(HA_ERR_OUT_OF_MEM);
9430 
9431  /* If the memory moved, we need to move the pointers */
9432  if (new_buf != m_rows_buf)
9433  {
9434  m_rows_buf= new_buf;
9435  m_rows_cur= m_rows_buf + cur_size;
9436  }
9437 
9438  /*
9439  The end pointer should always be changed to point to the end of
9440  the allocated memory.
9441  */
9442  m_rows_end= m_rows_buf + new_alloc;
9443  }
9444 
9445  DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
9446  memcpy(m_rows_cur, row_data, length);
9447  m_rows_cur+= length;
9448  m_row_count++;
9449  DBUG_RETURN(0);
9450 }
9451 #endif
9452 
9453 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
9454 
9486 static
9487 my_bool is_any_column_signaled_for_table(TABLE *table, MY_BITMAP *cols)
9488 {
9489  DBUG_ENTER("is_any_column_signaled_for_table");
9490 
9491  for (Field **ptr= table->field ;
9492  *ptr && ((*ptr)->field_index < cols->n_bits);
9493  ptr++)
9494  {
9495  if (bitmap_is_set(cols, (*ptr)->field_index))
9496  DBUG_RETURN(TRUE);
9497  }
9498 
9499  DBUG_RETURN (FALSE);
9500 }
9501 
9533 static
9534 my_bool are_all_columns_signaled_for_key(KEY *keyinfo, MY_BITMAP *cols)
9535 {
9536  DBUG_ENTER("are_all_columns_signaled_for_key");
9537 
9538  for (uint i=0 ; i < keyinfo->user_defined_key_parts ;i++)
9539  {
9540  uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
9541  if (fieldnr >= cols->n_bits ||
9542  !bitmap_is_set(cols, fieldnr))
9543  DBUG_RETURN(FALSE);
9544  }
9545 
9546  DBUG_RETURN(TRUE);
9547 }
9548 
9588 static
9589 uint
9590 search_key_in_table(TABLE *table, MY_BITMAP *bi_cols, uint key_type)
9591 {
9592  DBUG_ENTER("search_key_in_table");
9593 
9594  KEY *keyinfo;
9595  uint res= MAX_KEY;
9596  uint key;
9597 
9598  if (key_type & PRI_KEY_FLAG &&
9599  (table->s->primary_key < MAX_KEY))
9600  {
9601  DBUG_PRINT("debug", ("Searching for PK"));
9602  keyinfo= table->s->key_info + (uint) table->s->primary_key;
9603  if (are_all_columns_signaled_for_key(keyinfo, bi_cols))
9604  DBUG_RETURN(table->s->primary_key);
9605  }
9606 
9607  DBUG_PRINT("debug", ("Unique keys count: %u", table->s->uniques));
9608 
9609  if (key_type & UNIQUE_KEY_FLAG && table->s->uniques)
9610  {
9611  DBUG_PRINT("debug", ("Searching for UK"));
9612  for (key=0,keyinfo= table->key_info ;
9613  (key < table->s->keys) && (res == MAX_KEY);
9614  key++,keyinfo++)
9615  {
9616  /*
9617  - Unique keys cannot be disabled, thence we skip the check.
9618  - Skip unique keys with nullable parts
9619  - Skip primary keys
9620  */
9621  if (!((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
9622  (key == table->s->primary_key))
9623  continue;
9624  res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
9625  key : MAX_KEY;
9626 
9627  if (res < MAX_KEY)
9628  DBUG_RETURN(res);
9629  }
9630  DBUG_PRINT("debug", ("UK has NULLABLE parts or not all columns signaled."));
9631  }
9632 
9633  if (key_type & MULTIPLE_KEY_FLAG && table->s->keys)
9634  {
9635  DBUG_PRINT("debug", ("Searching for K."));
9636  for (key=0,keyinfo= table->key_info ;
9637  (key < table->s->keys) && (res == MAX_KEY);
9638  key++,keyinfo++)
9639  {
9640  /*
9641  - Skip innactive keys
9642  - Skip unique keys without nullable parts
9643  - Skip indices that do not support ha_index_next() e.g. full-text
9644  - Skip primary keys
9645  */
9646  if (!(table->s->keys_in_use.is_set(key)) ||
9647  ((keyinfo->flags & (HA_NOSAME | HA_NULL_PART_KEY)) == HA_NOSAME) ||
9648  !(table->file->index_flags(key, 0, true) & HA_READ_NEXT) ||
9649  (key == table->s->primary_key))
9650  continue;
9651 
9652  res= are_all_columns_signaled_for_key(keyinfo, bi_cols) ?
9653  key : MAX_KEY;
9654 
9655  if (res < MAX_KEY)
9656  DBUG_RETURN(res);
9657  }
9658  DBUG_PRINT("debug", ("Not all columns signaled for K."));
9659  }
9660 
9661  DBUG_RETURN(res);
9662 }
9663 
9664 void
9665 Rows_log_event::decide_row_lookup_algorithm_and_key()
9666 {
9667 
9668  DBUG_ENTER("decide_row_lookup_algorithm_and_key");
9669 
9670  /*
9671  Decision table:
9672  - I --> Index scan / search
9673  - T --> Table scan
9674  - Hi --> Hash over index
9675  - Ht --> Hash over the entire table
9676 
9677  |--------------+-----------+------+------+------|
9678  | Index\Option | I , T , H | I, T | I, H | T, H |
9679  |--------------+-----------+------+------+------|
9680  | PK / UK | I | I | I | Hi |
9681  | K | Hi | I | Hi | Hi |
9682  | No Index | Ht | T | Ht | Ht |
9683  |--------------+-----------+------+------+------|
9684 
9685  */
9686 
9687  TABLE *table= this->m_table;
9688  uint event_type= this->get_general_type_code();
9689  MY_BITMAP *cols= &this->m_cols;
9690  this->m_rows_lookup_algorithm= ROW_LOOKUP_NOT_NEEDED;
9691  this->m_key_index= MAX_KEY;
9692 
9693  if (event_type == WRITE_ROWS_EVENT) // row lookup not needed
9694  DBUG_VOID_RETURN;
9695 
9696  if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN))
9697  goto TABLE_OR_INDEX_HASH_SCAN;
9698 
9699  /* PK or UK => use LOOKUP_INDEX_SCAN */
9700  this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG));
9701  if (this->m_key_index != MAX_KEY)
9702  {
9703  DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
9704  this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
9705  goto end;
9706  }
9707 
9708 TABLE_OR_INDEX_HASH_SCAN:
9709 
9710  /*
9711  NOTE: Engines like Blackhole cannot use HASH_SCAN, because
9712  they do not syncronize reads .
9713  */
9714  if (!(slave_rows_search_algorithms_options & SLAVE_ROWS_HASH_SCAN) ||
9715  (table->file->ha_table_flags() & HA_READ_OUT_OF_SYNC))
9716  goto TABLE_OR_INDEX_FULL_SCAN;
9717 
9718  /* search for a key to see if we can narrow the lookup domain further. */
9719  this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
9720  this->m_rows_lookup_algorithm= ROW_LOOKUP_HASH_SCAN;
9721  DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - HASH_SCAN"));
9722  goto end;
9723 
9724 TABLE_OR_INDEX_FULL_SCAN:
9725 
9726  this->m_key_index= MAX_KEY;
9727 
9728  /* If we can use an index, try to narrow the scan a bit further. */
9729  if (slave_rows_search_algorithms_options & SLAVE_ROWS_INDEX_SCAN)
9730  this->m_key_index= search_key_in_table(table, cols, (PRI_KEY_FLAG | UNIQUE_KEY_FLAG | MULTIPLE_KEY_FLAG));
9731 
9732  if (this->m_key_index != MAX_KEY)
9733  {
9734  DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - INDEX_SCAN"));
9735  this->m_rows_lookup_algorithm= ROW_LOOKUP_INDEX_SCAN;
9736  }
9737  else
9738  {
9739  DBUG_PRINT("info", ("decide_row_lookup_algorithm_and_key: decided - TABLE_SCAN"));
9740  this->m_rows_lookup_algorithm= ROW_LOOKUP_TABLE_SCAN;
9741  }
9742 
9743 end:
9744 #ifndef DBUG_OFF
9745  const char* s= ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_TABLE_SCAN) ? "TABLE_SCAN" :
9746  ((m_rows_lookup_algorithm == Rows_log_event::ROW_LOOKUP_HASH_SCAN) ? "HASH_SCAN" :
9747  "INDEX_SCAN"));
9748 
9749  // only for testing purposes
9750  slave_rows_last_search_algorithm_used= m_rows_lookup_algorithm;
9751  DBUG_PRINT("debug", ("Row lookup method: %s", s));
9752 #endif
9753 
9754  DBUG_VOID_RETURN;
9755 }
9756 
9757 /*
9758  Encapsulates the operations to be done before applying
9759  row events for update and delete.
9760 
9761  @ret value error code
9762  0 success
9763 */
9764 int
9765 Rows_log_event::row_operations_scan_and_key_setup()
9766 {
9767  int error= 0;
9768  DBUG_ENTER("Row_log_event::row_operations_scan_and_key_setup");
9769 
9770  /*
9771  Prepare memory structures for search operations. If
9772  search is performed:
9773 
9774  1. using hash search => initialize the hash
9775  2. using key => decide on key to use and allocate mem structures
9776  3. using table scan => do nothing
9777  */
9778  decide_row_lookup_algorithm_and_key();
9779 
9780  switch (m_rows_lookup_algorithm)
9781  {
9782  case ROW_LOOKUP_HASH_SCAN:
9783  {
9784  if (m_hash.init())
9785  error= HA_ERR_OUT_OF_MEM;
9786  goto err;
9787  }
9788  case ROW_LOOKUP_INDEX_SCAN:
9789  {
9790  DBUG_ASSERT (m_key_index < MAX_KEY);
9791  // Allocate buffer for key searches
9792  m_key= (uchar*)my_malloc(MAX_KEY_LENGTH, MYF(MY_WME));
9793  if (!m_key)
9794  error= HA_ERR_OUT_OF_MEM;
9795  goto err;
9796  }
9797  case ROW_LOOKUP_TABLE_SCAN:
9798  default: break;
9799  }
9800 err:
9801  DBUG_RETURN(error);
9802 }
9803 
9804 /*
9805  Encapsulates the operations to be done after applying
9806  row events for update and delete.
9807 
9808  @ret value error code
9809  0 success
9810 */
9811 
9812 int
9813 Rows_log_event::row_operations_scan_and_key_teardown(int error)
9814 {
9815  DBUG_ENTER("Rows_log_event::row_operations_scan_and_key_teardown");
9816 
9817  DBUG_ASSERT(!m_table->file->inited);
9818  switch (m_rows_lookup_algorithm)
9819  {
9820  case ROW_LOOKUP_HASH_SCAN:
9821  {
9822  m_hash.deinit(); // we don't need the hash anymore.
9823  goto err;
9824  }
9825 
9826  case ROW_LOOKUP_INDEX_SCAN:
9827  {
9828  if (m_table->s->keys > 0)
9829  {
9830  my_free(m_key); // Free for multi_malloc
9831  m_key= NULL;
9832  m_key_index= MAX_KEY;
9833  }
9834  goto err;
9835  }
9836 
9837  case ROW_LOOKUP_TABLE_SCAN:
9838  default: break;
9839  }
9840 
9841 err:
9842  m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
9843  DBUG_RETURN(error);
9844 }
9845 
9846 /*
9847  Compares table->record[0] and table->record[1]
9848 
9849  Returns TRUE if different.
9850 */
9851 static bool record_compare(TABLE *table, MY_BITMAP *cols)
9852 {
9853  DBUG_ENTER("record_compare");
9854 
9855  /*
9856  Need to set the X bit and the filler bits in both records since
9857  there are engines that do not set it correctly.
9858 
9859  In addition, since MyISAM checks that one hasn't tampered with the
9860  record, it is necessary to restore the old bytes into the record
9861  after doing the comparison.
9862 
9863  TODO[record format ndb]: Remove it once NDB returns correct
9864  records. Check that the other engines also return correct records.
9865  */
9866 
9867  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
9868  DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
9869 
9870  bool result= false;
9871  uchar saved_x[2]= {0, 0}, saved_filler[2]= {0, 0};
9872 
9873  if (table->s->null_bytes > 0)
9874  {
9875  for (int i = 0 ; i < 2 ; ++i)
9876  {
9877  /*
9878  If we have an X bit then we need to take care of it.
9879  */
9880  if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
9881  {
9882  saved_x[i]= table->record[i][0];
9883  table->record[i][0]|= 1U;
9884  }
9885 
9886  /*
9887  If (last_null_bit_pos == 0 && null_bytes > 1), then:
9888 
9889  X bit (if any) + N nullable fields + M Field_bit fields = 8 bits
9890 
9891  Ie, the entire byte is used.
9892  */
9893  if (table->s->last_null_bit_pos > 0)
9894  {
9895  saved_filler[i]= table->record[i][table->s->null_bytes - 1];
9896  table->record[i][table->s->null_bytes - 1]|=
9897  256U - (1U << table->s->last_null_bit_pos);
9898  }
9899  }
9900  }
9901 
9913  if ((table->s->blob_fields +
9914  table->s->varchar_fields +
9915  table->s->null_fields) == 0 &&
9916  bitmap_is_set_all(cols))
9917  {
9918  result= cmp_record(table,record[1]);
9919  }
9920 
9921  /*
9922  Fallback to field-by-field comparison:
9923  1. start by checking if the field is signaled:
9924  2. if it is, first compare the null bit if the field is nullable
9925  3. then compare the contents of the field, if it is not
9926  set to null
9927  */
9928  else
9929  {
9930  for (Field **ptr=table->field ;
9931  *ptr && ((*ptr)->field_index < cols->n_bits) && !result;
9932  ptr++)
9933  {
9934  Field *field= *ptr;
9935  if (bitmap_is_set(cols, field->field_index))
9936  {
9937  /* compare null bit */
9938  if (field->is_null() != field->is_null_in_record(table->record[1]))
9939  result= true;
9940 
9941  /* compare content, only if fields are not set to NULL */
9942  else if (!field->is_null())
9943  result= field->cmp_binary_offset(table->s->rec_buff_length);
9944  }
9945  }
9946  }
9947 
9948  /*
9949  Restore the saved bytes.
9950 
9951  TODO[record format ndb]: Remove this code once NDB returns the
9952  correct record format.
9953  */
9954  if (table->s->null_bytes > 0)
9955  {
9956  for (int i = 0 ; i < 2 ; ++i)
9957  {
9958  if (!(table->s->db_options_in_use & HA_OPTION_PACK_RECORD))
9959  table->record[i][0]= saved_x[i];
9960 
9961  if (table->s->last_null_bit_pos)
9962  table->record[i][table->s->null_bytes - 1]= saved_filler[i];
9963  }
9964  }
9965 
9966  DBUG_RETURN(result);
9967 }
9968 
9969 void Rows_log_event::do_post_row_operations(Relay_log_info const *rli, int error)
9970 {
9971 
9972  /*
9973  If m_curr_row_end was not set during event execution (e.g., because
9974  of errors) we can't proceed to the next row. If the error is transient
9975  (i.e., error==0 at this point) we must call unpack_current_row() to set
9976  m_curr_row_end.
9977  */
9978 
9979  DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
9980  (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
9981 
9982  if (!m_curr_row_end && !error)
9983  {
9984  error= unpack_current_row(rli, &m_cols);
9985  }
9986 
9987  // at this moment m_curr_row_end should be set
9988  DBUG_ASSERT(error || m_curr_row_end != NULL);
9989  DBUG_ASSERT(error || m_curr_row <= m_curr_row_end);
9990  DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
9991 
9992  m_curr_row= m_curr_row_end;
9993 
9994  if (error == 0 && !m_table->file->has_transactions())
9995  {
9996  thd->transaction.all.set_unsafe_rollback_flags(TRUE);
9997  thd->transaction.stmt.set_unsafe_rollback_flags(TRUE);
9998  }
9999 }
10000 
10001 int Rows_log_event::handle_idempotent_and_ignored_errors(Relay_log_info const *rli, int *err)
10002 {
10003  int error= *err;
10004  if (error)
10005  {
10006  int actual_error= convert_handler_error(error, thd, m_table);
10007  bool idempotent_error= (idempotent_error_code(error) &&
10008  (slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT));
10009  bool ignored_error= (idempotent_error == 0 ?
10010  ignored_error_code(actual_error) : 0);
10011 
10012  if (idempotent_error || ignored_error)
10013  {
10014  if ( (idempotent_error && log_warnings) ||
10015  (ignored_error && log_warnings > 1) )
10016  slave_rows_error_report(WARNING_LEVEL, error, rli, thd, m_table,
10017  get_type_str(),
10018  const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
10019  (ulong) log_pos);
10020  thd->get_stmt_da()->clear_warning_info(thd->query_id);
10021  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
10022  *err= 0;
10023  if (idempotent_error == 0)
10024  return ignored_error;
10025  }
10026  }
10027 
10028  return *err;
10029 }
10030 
10031 int Rows_log_event::do_apply_row(Relay_log_info const *rli)
10032 {
10033  DBUG_ENTER("Rows_log_event::do_apply_row");
10034 
10035  int error= 0;
10036 
10037  /* in_use can have been set to NULL in close_tables_for_reopen */
10038  THD* old_thd= m_table->in_use;
10039  if (!m_table->in_use)
10040  m_table->in_use= thd;
10041 
10042  error= do_exec_row(rli);
10043 
10044  if(error)
10045  {
10046  DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10047  DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10048  }
10049 
10050  m_table->in_use = old_thd;
10051 
10052  DBUG_RETURN(error);
10053 }
10054 
10061 int
10062 Rows_log_event::close_record_scan()
10063 {
10064  DBUG_ENTER("Rows_log_event::close_record_scan");
10065  int error= 0;
10066 
10067  // if there is something to actually close
10068  if (m_key_index < MAX_KEY)
10069  {
10070  if (m_table->file->inited)
10071  error= m_table->file->ha_index_end();
10072 
10073  if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10074  {
10075  uchar *key_val;
10076  /* free the allocated memory for each key values */
10077  List_iterator_fast<uchar> it(m_distinct_key_list);
10078  while((key_val= it++) && (key_val))
10079  my_free(key_val);
10080  }
10081  }
10082  else if (m_table->file->inited)
10083  error= m_table->file->ha_rnd_end();
10084 
10085  DBUG_RETURN(error);
10086 }
10087 
10100 int
10101 Rows_log_event::next_record_scan(bool first_read)
10102 {
10103  DBUG_ENTER("Rows_log_event::next_record_scan");
10104  DBUG_ASSERT(m_table->file->inited);
10105  TABLE *table= m_table;
10106  int error= 0;
10107 
10108  if (m_key_index >= MAX_KEY)
10109  error= table->file->ha_rnd_next(table->record[0]);
10110  else
10111  {
10112  KEY *keyinfo= m_table->key_info + m_key_index;
10113  /*
10114  We need to set the null bytes to ensure that the filler bit are
10115  all set when returning. There are storage engines that just set
10116  the necessary bits on the bytes and don't set the filler bits
10117  correctly.
10118  */
10119  if (table->s->null_bytes > 0)
10120  table->record[0][table->s->null_bytes - 1]|=
10121  256U - (1U << table->s->last_null_bit_pos);
10122 
10123  if (!first_read)
10124  {
10125  /*
10126  if we fail to fetch next record corresponding to an index value, we
10127  move to the next key value. If we are out of key values as well an error
10128  will be returned.
10129  */
10130  error= table->file->ha_index_next(table->record[0]);
10131  if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10132  /*
10133  if we are out of rows for this particular key value
10134  or we have jumped to the next key value, we reposition the
10135  marker according to the next key value that we have in the
10136  list.
10137  */
10138  if ((error) ||
10139  (key_cmp(keyinfo->key_part, m_key, keyinfo->key_length) != 0))
10140  {
10141  if ((m_key= m_itr++))
10142  first_read= true;
10143  else
10144  error= HA_ERR_KEY_NOT_FOUND;
10145  }
10146  }
10147 
10148  if (first_read)
10149  if ((error= table->file->ha_index_read_map(table->record[0], m_key,
10150  HA_WHOLE_KEY,
10151  HA_READ_KEY_EXACT)))
10152  {
10153  DBUG_PRINT("info",("no record matching the key found in the table"));
10154  if (error == HA_ERR_RECORD_DELETED)
10155  error= HA_ERR_KEY_NOT_FOUND;
10156  }
10157  }
10158 
10159  DBUG_RETURN(error);
10160 }
10161 
10167 int
10168 Rows_log_event::open_record_scan()
10169 {
10170  int error= 0;
10171  TABLE *table= m_table;
10172  DBUG_ENTER("Rows_log_event::open_record_scan");
10173 
10174  if (m_key_index < MAX_KEY )
10175  {
10176  KEY *keyinfo= m_table->key_info + m_key_index;
10177  if(m_rows_lookup_algorithm == ROW_LOOKUP_HASH_SCAN)
10178  {
10179  /* initialize the iterator over the list of distinct keys that we have */
10180  m_itr.init(m_distinct_key_list);
10181 
10182  /* get the first element from the list of keys and increment the
10183  iterator
10184  */
10185  m_key= m_itr++;
10186  }
10187  else {
10188  /* this is an INDEX_SCAN we need to store the key in m_key */
10189  DBUG_ASSERT((m_rows_lookup_algorithm == ROW_LOOKUP_INDEX_SCAN) && m_key);
10190  key_copy(m_key, m_table->record[0], keyinfo, 0);
10191  }
10192 
10193  /*
10194  Save copy of the record in table->record[1]. It might be needed
10195  later if linear search is used to find exact match.
10196  */
10197  store_record(table,record[1]);
10198 
10199  DBUG_PRINT("info",("locating record using a key (index_read)"));
10200 
10201  /* The m_key_index'th key is active and usable: search the table using the index */
10202  if (!table->file->inited && (error= table->file->ha_index_init(m_key_index, FALSE)))
10203  {
10204  DBUG_PRINT("info",("ha_index_init returns error %d",error));
10205  goto end;
10206  }
10207 
10208  /*
10209  Don't print debug messages when running valgrind since they can
10210  trigger false warnings.
10211  */
10212 #ifndef HAVE_purify
10213  DBUG_DUMP("key data", m_key, keyinfo->key_length);
10214 #endif
10215  }
10216  else
10217  {
10218  if ((error= table->file->ha_rnd_init(1)))
10219  {
10220  DBUG_PRINT("info",("error initializing table scan"
10221  " (ha_rnd_init returns %d)",error));
10222  table->file->print_error(error, MYF(0));
10223  }
10224  }
10225 
10226 end:
10227  DBUG_RETURN(error);
10228 }
10229 
10236 int
10237 Rows_log_event::add_key_to_distinct_keyset()
10238 {
10239  int error= 0;
10240  bool distinct= true;
10241  DBUG_ENTER("Rows_log_event::add_key_to_distinct_keyset");
10242  DBUG_ASSERT(m_key_index < MAX_KEY);
10243  KEY *cur_key_info= m_table->key_info + m_key_index;
10244 
10245  if ((last_hashed_key))
10246  distinct= key_cmp(cur_key_info->key_part, last_hashed_key,
10247  cur_key_info->key_length);
10248 
10249  if (distinct)
10250  {
10251  uchar *cur_key= (uchar *)my_malloc(cur_key_info->key_length,
10252  MYF(MY_WME));
10253  if (!cur_key )
10254  {
10255  error= HA_ERR_OUT_OF_MEM;
10256  goto err;
10257  }
10258  m_distinct_key_list.push_back(cur_key);
10259  last_hashed_key= cur_key;
10260  key_copy(cur_key, m_table->record[0], cur_key_info, 0);
10261  }
10262 
10263 err:
10264  DBUG_RETURN(error);
10265 }
10266 
10267 
10268 int Rows_log_event::do_index_scan_and_update(Relay_log_info const *rli)
10269 {
10270  DBUG_ENTER("Rows_log_event::do_index_scan_and_update");
10271  DBUG_ASSERT(m_table && m_table->in_use != NULL);
10272 
10273  KEY *keyinfo= NULL;
10274  TABLE *table= m_table;
10275  int error= 0;
10276  const uchar *saved_m_curr_row= m_curr_row;
10277 
10278  /*
10279  rpl_row_tabledefs.test specifies that
10280  if the extra field on the slave does not have a default value
10281  and this is okay with Delete or Update events.
10282  Todo: fix wl3228 hld that requires defaults for all types of events
10283  */
10284 
10285  prepare_record(table, &m_cols, FALSE);
10286  if ((error= unpack_current_row(rli, &m_cols)))
10287  goto end;
10288 
10289  // Temporary fix to find out why it fails [/Matz]
10290  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
10291 
10292  /*
10293  Trying to do an index scan without a usable key
10294  This is a valid state because we allow the user
10295  to set Slave_rows_search_algorithm= 'INDEX_SCAN'.
10296 
10297  Therefore on tables with no indexes we will end
10298  up here.
10299  */
10300  if (m_key_index >= MAX_KEY)
10301  {
10302  error= HA_ERR_END_OF_FILE;
10303  goto end;
10304  }
10305 
10306 #ifndef DBUG_OFF
10307  DBUG_PRINT("info",("looking for the following record"));
10308  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10309 #endif
10310 
10311  if (m_key_index != m_table->s->primary_key)
10312  /* we dont have a PK, or PK is not usable */
10313  goto INDEX_SCAN;
10314 
10315  if ((table->file->ha_table_flags() & HA_READ_BEFORE_WRITE_REMOVAL))
10316  {
10317  /*
10318  Read removal is possible since the engine supports write without
10319  previous read using full primary key
10320  */
10321  DBUG_PRINT("info", ("using read before write removal"));
10322  DBUG_ASSERT(m_key_index == m_table->s->primary_key);
10323 
10324  /*
10325  Tell the handler to ignore if key exists or not, since it's
10326  not yet known if the key does exist(when using rbwr)
10327  */
10328  table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
10329 
10330  goto end;
10331  }
10332 
10333  if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION))
10334  {
10335  /*
10336  Use a more efficient method to fetch the record given by
10337  table->record[0] if the engine allows it. We first compute a
10338  row reference using the position() member function (it will be
10339  stored in table->file->ref) and then use rnd_pos() to position
10340  the "cursor" (i.e., record[0] in this case) at the correct row.
10341 
10342  TODO: Check that the correct record has been fetched by
10343  comparing it with the original record. Take into account that the
10344  record on the master and slave can be of different
10345  length. Something along these lines should work:
10346 
10347  ADD>>> store_record(table,record[1]);
10348  int error= table->file->rnd_pos(table->record[0], table->file->ref);
10349  ADD>>> DBUG_ASSERT(memcmp(table->record[1], table->record[0],
10350  table->s->reclength) == 0);
10351 
10352  */
10353 
10354  DBUG_PRINT("info",("locating record using primary key (position)"));
10355  if (table->file->inited && (error= table->file->ha_index_end()))
10356  goto end;
10357 
10358  if ((error= table->file->ha_rnd_init(FALSE)))
10359  goto end;
10360 
10361  error= table->file->rnd_pos_by_record(table->record[0]);
10362 
10363  table->file->ha_rnd_end();
10364  if (error)
10365  {
10366  DBUG_PRINT("info",("rnd_pos returns error %d",error));
10367  if (error == HA_ERR_RECORD_DELETED)
10368  error= HA_ERR_KEY_NOT_FOUND;
10369  }
10370 
10371  goto end;
10372  }
10373 
10374  // We can't use position() - try other methods.
10375 
10376 INDEX_SCAN:
10377 
10378  /* Use the m_key_index'th key */
10379  keyinfo= table->key_info + m_key_index;
10380 
10381  if ((error= open_record_scan()))
10382  goto end;
10383 
10384  error= next_record_scan(true);
10385  if (error)
10386  {
10387  DBUG_PRINT("info",("no record matching the key found in the table"));
10388  if (error == HA_ERR_RECORD_DELETED)
10389  error= HA_ERR_KEY_NOT_FOUND;
10390  goto end;
10391  }
10392 
10393 
10394  /*
10395  Don't print debug messages when running valgrind since they can
10396  trigger false warnings.
10397  */
10398 #ifndef HAVE_purify
10399  DBUG_PRINT("info",("found first matching record"));
10400  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
10401 #endif
10402  /*
10403  Below is a minor "optimization". If the key (i.e., key number
10404  0) has the HA_NOSAME flag set, we know that we have found the
10405  correct record (since there can be no duplicates); otherwise, we
10406  have to compare the record with the one found to see if it is
10407  the correct one.
10408 
10409  CAVEAT! This behaviour is essential for the replication of,
10410  e.g., the mysql.proc table since the correct record *shall* be
10411  found using the primary key *only*. There shall be no
10412  comparison of non-PK columns to decide if the correct record is
10413  found. I can see no scenario where it would be incorrect to
10414  chose the row to change only using a PK or an UNNI.
10415  */
10416  if (keyinfo->flags & HA_NOSAME || m_key_index == table->s->primary_key)
10417  {
10418  /* Unique does not have non nullable part */
10419  if (!(keyinfo->flags & (HA_NULL_PART_KEY)))
10420  goto end; // record found
10421  else
10422  {
10423  /*
10424  Unique has nullable part. We need to check if there is any field in the
10425  BI image that is null and part of UNNI.
10426  */
10427  bool null_found= FALSE;
10428  for (uint i=0; i < keyinfo->user_defined_key_parts && !null_found; i++)
10429  {
10430  uint fieldnr= keyinfo->key_part[i].fieldnr - 1;
10431  Field **f= table->field+fieldnr;
10432  null_found= (*f)->is_null();
10433  }
10434 
10435  if (!null_found)
10436  goto end; // record found
10437 
10438  /* else fall through to index scan */
10439  }
10440  }
10441 
10442  /*
10443  In case key is not unique, we still have to iterate over records found
10444  and find the one which is identical to the row given. A copy of the
10445  record we are looking for is stored in record[1].
10446  */
10447  DBUG_PRINT("info",("non-unique index, scanning it to find matching record"));
10448 
10449  while (record_compare(table, &m_cols))
10450  {
10451  while((error= next_record_scan(false)))
10452  {
10453  /* We just skip records that has already been deleted */
10454  if (error == HA_ERR_RECORD_DELETED)
10455  continue;
10456  DBUG_PRINT("info",("no record matching the given row found"));
10457  goto end;
10458  }
10459  }
10460 
10461 end:
10462 
10463  DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10464 
10465  if (error && error != HA_ERR_RECORD_DELETED)
10466  table->file->print_error(error, MYF(0));
10467  else
10468  error= do_apply_row(rli);
10469 
10470  if (!error)
10471  error= close_record_scan();
10472  else
10473  /*
10474  we are already with errors. Keep the error code and
10475  try to close the scan anyway.
10476  */
10477  (void) close_record_scan();
10478 
10479  if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
10480  (saved_m_curr_row == m_curr_row))
10481  {
10482  /* we need to unpack the AI so that positions get updated */
10483  m_curr_row= m_curr_row_end;
10484  unpack_current_row(rli, &m_cols);
10485  }
10486  table->default_column_bitmaps();
10487  DBUG_RETURN(error);
10488 
10489 }
10490 
10491 int Rows_log_event::do_hash_row(Relay_log_info const *rli)
10492 {
10493  DBUG_ENTER("Rows_log_event::do_hash_row");
10494  DBUG_ASSERT(m_table && m_table->in_use != NULL);
10495  int error= 0;
10496 
10497  /* create an empty entry to add to the hash table */
10499 
10500  /* Prepare the record, unpack and save positions. */
10501  entry->positions->bi_start= m_curr_row; // save the bi start pos
10502  prepare_record(m_table, &m_cols, false);
10503  if ((error= unpack_current_row(rli, &m_cols)))
10504  goto end;
10505  entry->positions->bi_ends= m_curr_row_end; // save the bi end pos
10506 
10507  /*
10508  Now that m_table->record[0] is filled in, we can add the entry
10509  to the hash table. Note that the put operation calculates the
10510  key based on record[0] contents (including BLOB fields).
10511  */
10512  m_hash.put(m_table, &m_cols, entry);
10513 
10514  if (m_key_index < MAX_KEY)
10515  add_key_to_distinct_keyset();
10516 
10517  /*
10518  We need to unpack the AI to advance the positions, so we
10519  know when we have reached m_rows_end and that we do not
10520  unpack the AI in the next iteration as if it was a BI.
10521  */
10522  if (get_general_type_code() == UPDATE_ROWS_EVENT)
10523  {
10524  /* Save a copy of the BI. */
10525  store_record(m_table, record[1]);
10526 
10527  /*
10528  This is the situation after hashing the BI:
10529 
10530  ===|=== before image ====|=== after image ===|===
10531  ^ ^
10532  m_curr_row m_curr_row_end
10533  */
10534 
10535  /* Set the position to the start of the record to be unpacked. */
10536  m_curr_row= m_curr_row_end;
10537 
10538  /* We shouldn't need this, but lets not leave loose ends */
10539  prepare_record(m_table, &m_cols, false);
10540  error= unpack_current_row(rli, &m_cols_ai);
10541 
10542  /*
10543  This is the situation after unpacking the AI:
10544 
10545  ===|=== before image ====|=== after image ===|===
10546  ^ ^
10547  m_curr_row m_curr_row_end
10548  */
10549 
10550  /* Restore back the copy of the BI. */
10551  restore_record(m_table, record[1]);
10552  }
10553 
10554 end:
10555  DBUG_RETURN(error);
10556 }
10557 
10558 int Rows_log_event::do_scan_and_update(Relay_log_info const *rli)
10559 {
10560  DBUG_ENTER("Rows_log_event::do_scan_and_update");
10561  DBUG_ASSERT(m_table && m_table->in_use != NULL);
10562  DBUG_ASSERT(m_hash.is_empty() == false);
10563  TABLE *table= m_table;
10564  int error= 0;
10565  const uchar *saved_last_m_curr_row= NULL;
10566  const uchar *saved_last_m_curr_row_end= NULL;
10567  /* create an empty entry to add to the hash table */
10568  HASH_ROW_ENTRY* entry= NULL;
10569  int idempotent_errors= 0;
10570  int i= 0;
10571 
10572  saved_last_m_curr_row=m_curr_row;
10573  saved_last_m_curr_row_end=m_curr_row_end;
10574 
10575  DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
10576 
10577  /* open table or index depending on whether we have set m_key_index or not. */
10578  if ((error= open_record_scan()))
10579  goto err;
10580 
10581  /*
10582  Scan the table only once and compare against entries in hash.
10583  When a match is found, apply the changes.
10584  */
10585  do
10586  {
10587  /* get the next record from the table */
10588  error= next_record_scan(i == 0);
10589  i++;
10590 
10591  if(error)
10592  DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10593  switch (error) {
10594  case 0:
10595  {
10596  entry= m_hash.get(table, &m_cols);
10597  store_record(table, record[1]);
10598 
10605  while(entry)
10606  {
10607  m_curr_row= entry->positions->bi_start;
10608  m_curr_row_end= entry->positions->bi_ends;
10609 
10610  prepare_record(table, &m_cols, false);
10611  if ((error= unpack_current_row(rli, &m_cols)))
10612  goto close_table;
10613 
10614  if (record_compare(table, &m_cols))
10615  m_hash.next(&entry);
10616  else
10617  break; // we found a match
10618  }
10619 
10623  if (entry)
10624  {
10625  // just to be safe, copy the record from the SE to table->record[0]
10626  restore_record(table, record[1]);
10627 
10639  m_curr_row= entry->positions->bi_start;
10640  m_curr_row_end= entry->positions->bi_ends;
10641 
10642  /* we don't need this entry anymore, just delete it */
10643  if ((error= m_hash.del(entry)))
10644  goto err;
10645 
10646  if ((error= do_apply_row(rli)))
10647  {
10648  if (handle_idempotent_and_ignored_errors(rli, &error))
10649  goto close_table;
10650 
10651  do_post_row_operations(rli, error);
10652  }
10653  }
10654  }
10655  break;
10656 
10657  case HA_ERR_RECORD_DELETED:
10658  // get next
10659  continue;
10660 
10661  case HA_ERR_KEY_NOT_FOUND:
10662  /* If the slave exec mode is idempotent or the error is
10663  skipped error, then don't break */
10664  if (handle_idempotent_and_ignored_errors(rli, &error))
10665  goto close_table;
10666  idempotent_errors++;
10667  continue;
10668 
10669  case HA_ERR_END_OF_FILE:
10670  default:
10671  // exception (hash is not empty and we have reached EOF or
10672  // other error happened)
10673  goto close_table;
10674  }
10675  }
10681  while (((idempotent_errors < m_hash.size()) && !m_hash.is_empty()) &&
10682  (!error || (error == HA_ERR_RECORD_DELETED)));
10683 
10684 close_table:
10685  if (error == HA_ERR_RECORD_DELETED)
10686  error= 0;
10687 
10688  if (error)
10689  {
10690  table->file->print_error(error, MYF(0));
10691  DBUG_PRINT("info", ("Failed to get next record"
10692  " (ha_rnd_next returns %d)",error));
10693  /*
10694  we are already with errors. Keep the error code and
10695  try to close the scan anyway.
10696  */
10697  (void) close_record_scan();
10698  }
10699  else
10700  error= close_record_scan();
10701 
10702  DBUG_ASSERT((m_hash.is_empty() && !error) ||
10703  (!m_hash.is_empty() &&
10704  ((error) || (idempotent_errors >= m_hash.size()))));
10705 
10706 err:
10707 
10708  if ((m_hash.is_empty() && !error) || (idempotent_errors >= m_hash.size()))
10709  {
10714  m_curr_row= saved_last_m_curr_row;
10715  m_curr_row_end= saved_last_m_curr_row_end;
10716  }
10717 
10718  DBUG_RETURN(error);
10719 }
10720 
10721 int Rows_log_event::do_hash_scan_and_update(Relay_log_info const *rli)
10722 {
10723  DBUG_ENTER("Rows_log_event::do_hash_scan_and_update");
10724  DBUG_ASSERT(m_table && m_table->in_use != NULL);
10725 
10726  // HASHING PART
10727 
10728  /* unpack the BI (and AI, if it exists) and add it to the hash map. */
10729  if (int error= this->do_hash_row(rli))
10730  DBUG_RETURN(error);
10731 
10732  /* We have not yet hashed all rows in the buffer. Do not proceed to the SCAN part. */
10733  if (m_curr_row_end < m_rows_end)
10734  DBUG_RETURN (0);
10735 
10736  DBUG_PRINT("info",("Hash was populated with %d records!", m_hash.size()));
10737  DBUG_ASSERT(m_curr_row_end == m_rows_end);
10738 
10739  // SCANNING & UPDATE PART
10740 
10741  DBUG_RETURN(this->do_scan_and_update(rli));
10742 }
10743 
10744 int Rows_log_event::do_table_scan_and_update(Relay_log_info const *rli)
10745 {
10746  int error= 0;
10747  const uchar* saved_m_curr_row= m_curr_row;
10748  TABLE* table= m_table;
10749 
10750  DBUG_ENTER("Rows_log_event::do_table_scan_and_update");
10751  DBUG_ASSERT(m_curr_row != m_rows_end);
10752  DBUG_PRINT("info",("locating record using table scan (ha_rnd_next)"));
10753 
10754  saved_m_curr_row= m_curr_row;
10755 
10757  prepare_record(table, &m_cols, FALSE);
10758  if (!(error= unpack_current_row(rli, &m_cols)))
10759  {
10760  // Temporary fix to find out why it fails [/Matz]
10761  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
10762 
10764  store_record(m_table, record[1]);
10765 
10766  int restart_count= 0; // Number of times scanning has restarted from top
10767 
10768  if ((error= m_table->file->ha_rnd_init(1)))
10769  {
10770  DBUG_PRINT("info",("error initializing table scan"
10771  " (ha_rnd_init returns %d)",error));
10772  goto end;
10773  }
10774 
10775  /* Continue until we find the right record or have made a full loop */
10776  do
10777  {
10778  error= m_table->file->ha_rnd_next(m_table->record[0]);
10779  if (error)
10780  DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
10781  switch (error) {
10782  case HA_ERR_END_OF_FILE:
10783  // restart scan from top
10784  if (++restart_count < 2)
10785  error= m_table->file->ha_rnd_init(1);
10786  break;
10787 
10788  case HA_ERR_RECORD_DELETED:
10789  // fetch next
10790  case 0:
10791  // we're good, check if record matches
10792  break;
10793 
10794  default:
10795  // exception
10796  goto end;
10797  }
10798  }
10799  while ((error == HA_ERR_END_OF_FILE && restart_count < 2) ||
10800  (error == HA_ERR_RECORD_DELETED) ||
10801  (!error && record_compare(m_table, &m_cols)));
10802  }
10803 
10804 end:
10805 
10806  DBUG_ASSERT(error != HA_ERR_RECORD_DELETED);
10807 
10808  /* either we report error or apply the changes */
10809  if (error && error != HA_ERR_RECORD_DELETED)
10810  {
10811  DBUG_PRINT("info", ("Failed to get next record"
10812  " (ha_rnd_next returns %d)",error));
10813  m_table->file->print_error(error, MYF(0));
10814  }
10815  else
10816  error= do_apply_row(rli);
10817 
10818 
10819  if (!error)
10820  error= close_record_scan();
10821  else
10822  /*
10823  we are already with errors. Keep the error code and
10824  try to close the scan anyway.
10825  */
10826  (void) close_record_scan();
10827 
10828  if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
10829  (saved_m_curr_row == m_curr_row)) // we need to unpack the AI
10830  {
10831  m_curr_row= m_curr_row_end;
10832  unpack_current_row(rli, &m_cols);
10833  }
10834 
10835  table->default_column_bitmaps();
10836  DBUG_RETURN(error);
10837 }
10838 
10839 int Rows_log_event::do_apply_event(Relay_log_info const *rli)
10840 {
10841  DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
10842  int error= 0;
10843 
10844  if (opt_bin_log)
10845  {
10846  enum_gtid_statement_status state= gtid_pre_statement_checks(thd);
10847  if (state == GTID_STATEMENT_CANCEL)
10848  // error has already been printed; don't print anything more here
10849  DBUG_RETURN(-1);
10850  else if (state == GTID_STATEMENT_SKIP)
10851  DBUG_RETURN(0);
10852  }
10853 
10854  /*
10855  'thd' has been set by exec_relay_log_event(), just before calling
10856  do_apply_event(). We still check here to prevent future coding
10857  errors.
10858  */
10859  DBUG_ASSERT(rli->info_thd == thd);
10860 
10861  /*
10862  If there is no locks taken, this is the first binrow event seen
10863  after the table map events. We should then lock all the tables
10864  used in the transaction and proceed with execution of the actual
10865  event.
10866  */
10867  if (!thd->lock)
10868  {
10869  /*
10870  Lock_tables() reads the contents of thd->lex, so they must be
10871  initialized.
10872 
10873  We also call the mysql_reset_thd_for_next_command(), since this
10874  is the logical start of the next "statement". Note that this
10875  call might reset the value of current_stmt_binlog_format, so
10876  we need to do any changes to that value after this function.
10877  */
10878  lex_start(thd);
10880  /*
10881  The current statement is just about to begin and
10882  has not yet modified anything. Note, all.modified is reset
10883  by mysql_reset_thd_for_next_command.
10884  */
10885  thd->transaction.stmt.reset_unsafe_rollback_flags();
10886  /*
10887  This is a row injection, so we flag the "statement" as
10888  such. Note that this code is called both when the slave does row
10889  injections and when the BINLOG statement is used to do row
10890  injections.
10891  */
10892  thd->lex->set_stmt_row_injection();
10893 
10894  /*
10895  There are a few flags that are replicated with each row event.
10896  Make sure to set/clear them before executing the main body of
10897  the event.
10898  */
10899  if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
10900  thd->variables.option_bits|= OPTION_NO_FOREIGN_KEY_CHECKS;
10901  else
10902  thd->variables.option_bits&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
10903 
10904  if (get_flags(RELAXED_UNIQUE_CHECKS_F))
10905  thd->variables.option_bits|= OPTION_RELAXED_UNIQUE_CHECKS;
10906  else
10907  thd->variables.option_bits&= ~OPTION_RELAXED_UNIQUE_CHECKS;
10908 
10909  thd->binlog_row_event_extra_data = m_extra_row_data;
10910 
10911  /* A small test to verify that objects have consistent types */
10912  DBUG_ASSERT(sizeof(thd->variables.option_bits) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
10913 
10914  if (open_and_lock_tables(thd, rli->tables_to_lock, FALSE, 0))
10915  {
10916  uint actual_error= thd->get_stmt_da()->sql_errno();
10917  if (thd->is_slave_error || thd->is_fatal_error)
10918  {
10919  /*
10920  Error reporting borrowed from Query_log_event with many excessive
10921  simplifications.
10922  We should not honour --slave-skip-errors at this point as we are
10923  having severe errors which should not be skiped.
10924  */
10925  rli->report(ERROR_LEVEL, actual_error,
10926  "Error executing row event: '%s'",
10927  (actual_error ? thd->get_stmt_da()->message() :
10928  "unexpected success or fatal error"));
10929  thd->is_slave_error= 1;
10930  }
10931  const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
10932  DBUG_RETURN(actual_error);
10933  }
10934 
10935  /*
10936  When the open and locking succeeded, we check all tables to
10937  ensure that they still have the correct type.
10938 
10939  We can use a down cast here since we know that every table added
10940  to the tables_to_lock is a RPL_TABLE_LIST.
10941  */
10942 
10943  {
10944  DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
10945  rli->tables_to_lock));
10946 
10959  RPL_TABLE_LIST *ptr= rli->tables_to_lock;
10960  for (uint i= 0 ; ptr && (i < rli->tables_to_lock_count);
10961  ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global), i++)
10962  {
10963  DBUG_ASSERT(ptr->m_tabledef_valid);
10964  TABLE *conv_table;
10965  if (!ptr->m_tabledef.compatible_with(thd, const_cast<Relay_log_info*>(rli),
10966  ptr->table, &conv_table))
10967  {
10968  DBUG_PRINT("debug", ("Table: %s.%s is not compatible with master",
10969  ptr->table->s->db.str,
10970  ptr->table->s->table_name.str));
10971  /*
10972  We should not honour --slave-skip-errors at this point as we are
10973  having severe errors which should not be skiped.
10974  */
10975  thd->is_slave_error= 1;
10976  const_cast<Relay_log_info*>(rli)->slave_close_thread_tables(thd);
10977  DBUG_RETURN(ERR_BAD_TABLE_DEF);
10978  }
10979  DBUG_PRINT("debug", ("Table: %s.%s is compatible with master"
10980  " - conv_table: %p",
10981  ptr->table->s->db.str,
10982  ptr->table->s->table_name.str, conv_table));
10983  ptr->m_conv_table= conv_table;
10984  }
10985  }
10986 
10987  /*
10988  ... and then we add all the tables to the table map and but keep
10989  them in the tables to lock list.
10990 
10991  We also invalidate the query cache for all the tables, since
10992  they will now be changed.
10993 
10994  TODO [/Matz]: Maybe the query cache should not be invalidated
10995  here? It might be that a table is not changed, even though it
10996  was locked for the statement. We do know that each
10997  Rows_log_event contain at least one row, so after processing one
10998  Rows_log_event, we can invalidate the query cache for the
10999  associated table.
11000  */
11001  TABLE_LIST *ptr= rli->tables_to_lock;
11002  for (uint i=0 ; ptr && (i < rli->tables_to_lock_count); ptr= ptr->next_global, i++)
11003  const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
11004 
11005 #ifdef HAVE_QUERY_CACHE
11006  query_cache.invalidate_locked_for_write(rli->tables_to_lock);
11007 #endif
11008  }
11009 
11010  TABLE*
11011  table=
11012  m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
11013 
11014  DBUG_PRINT("debug", ("m_table: 0x%lx, m_table_id: %llu", (ulong) m_table,
11015  m_table_id.id()));
11016 
11017  if (table)
11018  {
11019  /*
11020  table == NULL means that this table should not be replicated
11021  (this was set up by Table_map_log_event::do_apply_event()
11022  which tested replicate-* rules).
11023  */
11024 
11025  /*
11026  It's not needed to set_time() but
11027  1) it continues the property that "Time" in SHOW PROCESSLIST shows how
11028  much slave is behind
11029  2) it will be needed when we allow replication from a table with no
11030  TIMESTAMP column to a table with one.
11031  So we call set_time(), like in SBR. Presently it changes nothing.
11032  */
11033  thd->set_time(&when);
11034 
11035  thd->binlog_row_event_extra_data = m_extra_row_data;
11036 
11037  /*
11038  Now we are in a statement and will stay in a statement until we
11039  see a STMT_END_F.
11040 
11041  We set this flag here, before actually applying any rows, in
11042  case the SQL thread is stopped and we need to detect that we're
11043  inside a statement and halting abruptly might cause problems
11044  when restarting.
11045  */
11046  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
11047 
11048  if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
11049  set_flags(COMPLETE_ROWS_F);
11050 
11051  /*
11052  Set tables write and read sets.
11053 
11054  Read_set contains all slave columns (in case we are going to fetch
11055  a complete record from slave)
11056 
11057  Write_set equals the m_cols bitmap sent from master but it can be
11058  longer if slave has extra columns.
11059  */
11060 
11061  DBUG_PRINT_BITSET("debug", "Setting table's read_set from: %s", &m_cols);
11062 
11063  bitmap_set_all(table->read_set);
11064  if (get_general_type_code() == DELETE_ROWS_EVENT ||
11065  get_general_type_code() == UPDATE_ROWS_EVENT)
11066  bitmap_intersect(table->read_set,&m_cols);
11067 
11068  bitmap_set_all(table->write_set);
11069 
11070  /* WRITE ROWS EVENTS store the bitmap in m_cols instead of m_cols_ai */
11071  MY_BITMAP *after_image= ((get_general_type_code() == UPDATE_ROWS_EVENT) ?
11072  &m_cols_ai : &m_cols);
11073  bitmap_intersect(table->write_set, after_image);
11074 
11075  this->slave_exec_mode= slave_exec_mode_options; // fix the mode
11076 
11077  // Do event specific preparations
11078  error= do_before_row_operations(rli);
11079 
11080  /*
11081  Bug#56662 Assertion failed: next_insert_id == 0, file handler.cc
11082  Don't allow generation of auto_increment value when processing
11083  rows event by setting 'MODE_NO_AUTO_VALUE_ON_ZERO'.
11084  */
11085  ulong saved_sql_mode= thd->variables.sql_mode;
11086  thd->variables.sql_mode= MODE_NO_AUTO_VALUE_ON_ZERO;
11087 
11088  // row processing loop
11089 
11090  /*
11091  set the initial time of this ROWS statement if it was not done
11092  before in some other ROWS event.
11093  */
11094  const_cast<Relay_log_info*>(rli)->set_row_stmt_start_timestamp();
11095 
11096  const uchar *saved_m_curr_row= m_curr_row;
11097 
11098  int (Rows_log_event::*do_apply_row_ptr)(Relay_log_info const *)= NULL;
11099 
11104  if ((get_general_type_code() == UPDATE_ROWS_EVENT) &&
11105  !is_any_column_signaled_for_table(table, &m_cols_ai))
11106  goto AFTER_MAIN_EXEC_ROW_LOOP;
11107 
11115  if ((m_rows_lookup_algorithm != ROW_LOOKUP_NOT_NEEDED) &&
11116  !is_any_column_signaled_for_table(table, &m_cols))
11117  {
11118  error= HA_ERR_END_OF_FILE;
11119  goto AFTER_MAIN_EXEC_ROW_LOOP;
11120  }
11121  switch (m_rows_lookup_algorithm)
11122  {
11123  case ROW_LOOKUP_HASH_SCAN:
11124  do_apply_row_ptr= &Rows_log_event::do_hash_scan_and_update;
11125  break;
11126 
11127  case ROW_LOOKUP_INDEX_SCAN:
11128  do_apply_row_ptr= &Rows_log_event::do_index_scan_and_update;
11129  break;
11130 
11131  case ROW_LOOKUP_TABLE_SCAN:
11132  do_apply_row_ptr= &Rows_log_event::do_table_scan_and_update;
11133  break;
11134 
11135  case ROW_LOOKUP_NOT_NEEDED:
11136  DBUG_ASSERT(get_general_type_code() == WRITE_ROWS_EVENT);
11137 
11138  /* No need to scan for rows, just apply it */
11139  do_apply_row_ptr= &Rows_log_event::do_apply_row;
11140  break;
11141 
11142  default:
11143  DBUG_ASSERT(0);
11144  error= 1;
11145  goto AFTER_MAIN_EXEC_ROW_LOOP;
11146  break;
11147  }
11148 
11149  do {
11150 
11151  error= (this->*do_apply_row_ptr)(rli);
11152 
11153  if (handle_idempotent_and_ignored_errors(rli, &error))
11154  break;
11155 
11156  /* this advances m_curr_row */
11157  do_post_row_operations(rli, error);
11158 
11159  } while (!error && (m_curr_row != m_rows_end));
11160 
11161 AFTER_MAIN_EXEC_ROW_LOOP:
11162 
11163  if (saved_m_curr_row != m_curr_row && !table->file->has_transactions())
11164  {
11165  /*
11166  Usually, the trans_commit_stmt() propagates unsafe_rollback_flags
11167  from statement to transaction level. However, we cannot rely on
11168  this when row format is in use as several events can be processed
11169  before calling this function. This happens because it is called
11170  only when the latest event generated by a statement is processed.
11171 
11172  There are however upper level functions that execute per event
11173  and check transaction's status. So if the unsafe_rollback_flags
11174  are not propagated here, this can lead to errors.
11175 
11176  For example, a transaction that updates non-transactional tables
11177  may be stopped in the middle thus leading to inconsistencies
11178  after a restart.
11179  */
11180  thd->transaction.stmt.mark_modified_non_trans_table();
11181  thd->transaction.merge_unsafe_rollback_flags();
11182  }
11183 
11184  /*
11185  Restore the sql_mode after the rows event is processed.
11186  */
11187  thd->variables.sql_mode= saved_sql_mode;
11188 
11189  {/*
11190  The following failure injecion works in cooperation with tests
11191  setting @@global.debug= 'd,stop_slave_middle_group'.
11192  The sql thread receives the killed status and will proceed
11193  to shutdown trying to finish incomplete events group.
11194  */
11195  DBUG_EXECUTE_IF("stop_slave_middle_group",
11196  if (thd->transaction.all.cannot_safely_rollback())
11197  const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
11198  }
11199 
11200  if ((error= do_after_row_operations(rli, error)) &&
11201  ignored_error_code(convert_handler_error(error, thd, table)))
11202  {
11203 
11204  if (log_warnings > 1)
11205  slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
11206  get_type_str(),
11207  const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11208  (ulong) log_pos);
11209  thd->get_stmt_da()->clear_warning_info(thd->query_id);
11210  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
11211  error= 0;
11212  }
11213  } // if (table)
11214 
11215  if (error)
11216  {
11217  slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
11218  get_type_str(),
11219  const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11220  (ulong) log_pos);
11221  /*
11222  @todo We should probably not call
11223  reset_current_stmt_binlog_format_row() from here.
11224 
11225  Note: this applies to log_event_old.cc too.
11226  /Sven
11227  */
11228  thd->reset_current_stmt_binlog_format_row();
11229  thd->is_slave_error= 1;
11230  DBUG_RETURN(error);
11231  }
11232 
11233  if (get_flags(STMT_END_F) && (error= rows_event_stmt_cleanup(rli, thd)))
11234  slave_rows_error_report(ERROR_LEVEL,
11235  thd->is_error() ? 0 : error,
11236  rli, thd, table,
11237  get_type_str(),
11238  const_cast<Relay_log_info*>(rli)->get_rpl_log_name(),
11239  (ulong) log_pos);
11240  DBUG_RETURN(error);
11241 }
11242 
11244 Rows_log_event::do_shall_skip(Relay_log_info *rli)
11245 {
11246  /*
11247  If the slave skip counter is 1 and this event does not end a
11248  statement, then we should not start executing on the next event.
11249  Otherwise, we defer the decision to the normal skipping logic.
11250  */
11251  if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
11253  else
11254  return Log_event::do_shall_skip(rli);
11255 }
11256 
11268 static int rows_event_stmt_cleanup(Relay_log_info const *rli, THD * thd)
11269 {
11270  int error;
11271  {
11272  /*
11273  This is the end of a statement or transaction, so close (and
11274  unlock) the tables we opened when processing the
11275  Table_map_log_event starting the statement.
11276 
11277  OBSERVER. This will clear *all* mappings, not only those that
11278  are open for the table. There is not good handle for on-close
11279  actions for tables.
11280 
11281  NOTE. Even if we have no table ('table' == 0) we still need to be
11282  here, so that we increase the group relay log position. If we didn't, we
11283  could have a group relay log position which lags behind "forever"
11284  (assume the last master's transaction is ignored by the slave because of
11285  replicate-ignore rules).
11286  */
11287  error= thd->binlog_flush_pending_rows_event(TRUE);
11288 
11289  /*
11290  If this event is not in a transaction, the call below will, if some
11291  transactional storage engines are involved, commit the statement into
11292  them and flush the pending event to binlog.
11293  If this event is in a transaction, the call will do nothing, but a
11294  Xid_log_event will come next which will, if some transactional engines
11295  are involved, commit the transaction and flush the pending event to the
11296  binlog.
11297  If there was a deadlock the transaction should have been rolled back
11298  already. So there should be no need to rollback the transaction.
11299  */
11300  DBUG_ASSERT(! thd->transaction_rollback_request);
11301  error|= (error ? trans_rollback_stmt(thd) : trans_commit_stmt(thd));
11302 
11303  /*
11304  Now what if this is not a transactional engine? we still need to
11305  flush the pending event to the binlog; we did it with
11306  thd->binlog_flush_pending_rows_event(). Note that we imitate
11307  what is done for real queries: a call to
11308  ha_autocommit_or_rollback() (sometimes only if involves a
11309  transactional engine), and a call to be sure to have the pending
11310  event flushed.
11311  */
11312 
11313  /*
11314  @todo We should probably not call
11315  reset_current_stmt_binlog_format_row() from here.
11316 
11317  Note: this applies to log_event_old.cc too
11318 
11319  Btw, the previous comment about transactional engines does not
11320  seem related to anything that happens here.
11321  /Sven
11322  */
11323  thd->reset_current_stmt_binlog_format_row();
11324 
11325  const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 0);
11326  }
11327  return error;
11328 }
11329 
11340 int
11341 Rows_log_event::do_update_pos(Relay_log_info *rli)
11342 {
11343  DBUG_ENTER("Rows_log_event::do_update_pos");
11344  int error= 0;
11345 
11346  DBUG_PRINT("info", ("flags: %s",
11347  get_flags(STMT_END_F) ? "STMT_END_F " : ""));
11348 
11349  /* Worker does not execute binlog update position logics */
11350  DBUG_ASSERT(!is_mts_worker(rli->info_thd));
11351 
11352  if (get_flags(STMT_END_F))
11353  {
11354  /*
11355  Indicate that a statement is finished.
11356  Step the group log position if we are not in a transaction,
11357  otherwise increase the event log position.
11358  */
11359  error= rli->stmt_done(log_pos);
11360  }
11361  else
11362  {
11363  rli->inc_event_relay_log_pos();
11364  }
11365 
11366  DBUG_RETURN(error);
11367 }
11368 
11369 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
11370 
11371 #ifndef MYSQL_CLIENT
11372 bool Rows_log_event::write_data_header(IO_CACHE *file)
11373 {
11374  uchar buf[ROWS_HEADER_LEN_V2]; // No need to init the buffer
11375  DBUG_ASSERT(m_table_id.is_valid());
11376  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
11377  {
11378  int4store(buf + 0, (ulong) m_table_id.id());
11379  int2store(buf + 4, m_flags);
11380  return (wrapper_my_b_safe_write(file, buf, 6));
11381  });
11382  int6store(buf + RW_MAPID_OFFSET, m_table_id.id());
11383  int2store(buf + RW_FLAGS_OFFSET, m_flags);
11384  int rc = 0;
11385  if (likely(!log_bin_use_v1_row_events))
11386  {
11387  /*
11388  v2 event, with variable header portion.
11389  Determine length of variable header payload
11390  */
11391  uint16 vhlen= 2;
11392  uint16 vhpayloadlen= 0;
11393  uint16 extra_data_len= 0;
11394  if (m_extra_row_data)
11395  {
11396  extra_data_len= m_extra_row_data[EXTRA_ROW_INFO_LEN_OFFSET];
11397  vhpayloadlen= RW_V_TAG_LEN + extra_data_len;
11398  }
11399 
11400  /* Var-size header len includes len itself */
11401  int2store(buf + RW_VHLEN_OFFSET, vhlen + vhpayloadlen);
11402  rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V2);
11403 
11404  /* Write var-sized payload, if any */
11405  if ((vhpayloadlen > 0) &&
11406  (rc == 0))
11407  {
11408  /* Add tag and extra row info */
11409  uchar type_code= RW_V_EXTRAINFO_TAG;
11410  rc= wrapper_my_b_safe_write(file, &type_code, RW_V_TAG_LEN);
11411  if (rc==0)
11412  rc= wrapper_my_b_safe_write(file, m_extra_row_data, extra_data_len);
11413  }
11414  }
11415  else
11416  {
11417  rc= wrapper_my_b_safe_write(file, buf, ROWS_HEADER_LEN_V1);
11418  }
11419 
11420  return (rc != 0);
11421 }
11422 
11423 bool Rows_log_event::write_data_body(IO_CACHE*file)
11424 {
11425  /*
11426  Note that this should be the number of *bits*, not the number of
11427  bytes.
11428  */
11429  uchar sbuf[sizeof(m_width) + 1];
11430  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
11431  bool res= false;
11432  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
11433  DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
11434 
11435  DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
11436  res= res || wrapper_my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
11437 
11438  DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
11439  res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols.bitmap,
11440  no_bytes_in_map(&m_cols));
11441  /*
11442  TODO[refactor write]: Remove the "down cast" here (and elsewhere).
11443  */
11444  if (get_general_type_code() == UPDATE_ROWS_EVENT)
11445  {
11446  DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
11447  no_bytes_in_map(&m_cols_ai));
11448  res= res || wrapper_my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
11449  no_bytes_in_map(&m_cols_ai));
11450  }
11451  DBUG_DUMP("rows", m_rows_buf, data_size);
11452  res= res || wrapper_my_b_safe_write(file, m_rows_buf, (size_t) data_size);
11453 
11454  return res;
11455 
11456 }
11457 #endif
11458 
11459 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
11460 int Rows_log_event::pack_info(Protocol *protocol)
11461 {
11462  char buf[256];
11463  char const *const flagstr=
11464  get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
11465  size_t bytes= my_snprintf(buf, sizeof(buf),
11466  "table_id: %llu%s", m_table_id.id(), flagstr);
11467  protocol->store(buf, bytes, &my_charset_bin);
11468  return 0;
11469 }
11470 #endif
11471 
11472 #ifdef MYSQL_CLIENT
11473 void Rows_log_event::print_helper(FILE *file,
11474  PRINT_EVENT_INFO *print_event_info,
11475  char const *const name)
11476 {
11477  IO_CACHE *const head= &print_event_info->head_cache;
11478  IO_CACHE *const body= &print_event_info->body_cache;
11479  if (!print_event_info->short_form)
11480  {
11481  bool const last_stmt_event= get_flags(STMT_END_F);
11482  print_header(head, print_event_info, !last_stmt_event);
11483  my_b_printf(head, "\t%s: table id %llu%s\n",
11484  name, m_table_id.id(),
11485  last_stmt_event ? " flags: STMT_END_F" : "");
11486  print_base64(body, print_event_info, !last_stmt_event);
11487  }
11488 }
11489 #endif
11490 
11491 /**************************************************************************
11492  Table_map_log_event member functions and support functions
11493 **************************************************************************/
11494 
11527 #if !defined(MYSQL_CLIENT)
11528 
11552 int Table_map_log_event::save_field_metadata()
11553 {
11554  DBUG_ENTER("Table_map_log_event::save_field_metadata");
11555  int index= 0;
11556  for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
11557  {
11558  DBUG_PRINT("debug", ("field_type: %d", m_coltype[i]));
11559  index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
11560  }
11561  DBUG_RETURN(index);
11562 }
11563 #endif /* !defined(MYSQL_CLIENT) */
11564 
11565 /*
11566  Constructor used to build an event for writing to the binary log.
11567  Mats says tbl->s lives longer than this event so it's ok to copy pointers
11568  (tbl->s->db etc) and not pointer content.
11569  */
11570 #if !defined(MYSQL_CLIENT)
11571 Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl,
11572  const Table_id& tid,
11573  bool using_trans)
11574  : Log_event(thd, 0,
11575  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
11576  Log_event::EVENT_STMT_CACHE,
11577  Log_event::EVENT_NORMAL_LOGGING),
11578  m_table(tbl),
11579  m_dbnam(tbl->s->db.str),
11580  m_dblen(m_dbnam ? tbl->s->db.length : 0),
11581  m_tblnam(tbl->s->table_name.str),
11582  m_tbllen(tbl->s->table_name.length),
11583  m_colcnt(tbl->s->fields),
11584  m_memory(NULL),
11585  m_table_id(tid),
11586  m_flags(TM_BIT_LEN_EXACT_F),
11587  m_data_size(0),
11588  m_field_metadata(0),
11589  m_field_metadata_size(0),
11590  m_null_bits(0),
11591  m_meta_memory(NULL)
11592 {
11593  uchar cbuf[sizeof(m_colcnt) + 1];
11594  uchar *cbuf_end;
11595  DBUG_ASSERT(m_table_id.is_valid());
11596  /*
11597  In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
11598  table.cc / alloc_table_share():
11599  Use the fact the key is db/0/table_name/0
11600  As we rely on this let's assert it.
11601  */
11602  DBUG_ASSERT((tbl->s->db.str == 0) ||
11603  (tbl->s->db.str[tbl->s->db.length] == 0));
11604  DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
11605 
11606 
11607  m_data_size= TABLE_MAP_HEADER_LEN;
11608  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
11609  m_data_size+= m_dblen + 2; // Include length and terminating \0
11610  m_data_size+= m_tbllen + 2; // Include length and terminating \0
11611  cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
11612  DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
11613  m_data_size+= (cbuf_end - cbuf) + m_colcnt; // COLCNT and column types
11614 
11615  /* If malloc fails, caught in is_valid() */
11616  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
11617  {
11618  m_coltype= reinterpret_cast<uchar*>(m_memory);
11619  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
11620  m_coltype[i]= m_table->field[i]->binlog_type();
11621  }
11622 
11623  /*
11624  Calculate a bitmap for the results of maybe_null() for all columns.
11625  The bitmap is used to determine when there is a column from the master
11626  that is not on the slave and is null and thus not in the row data during
11627  replication.
11628  */
11629  uint num_null_bytes= (m_table->s->fields + 7) / 8;
11630  m_data_size+= num_null_bytes;
11631  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
11632  &m_null_bits, num_null_bytes,
11633  &m_field_metadata, (m_colcnt * 2),
11634  NULL);
11635 
11636  memset(m_field_metadata, 0, (m_colcnt * 2));
11637 
11638  /*
11639  Create an array for the field metadata and store it.
11640  */
11641  m_field_metadata_size= save_field_metadata();
11642  DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
11643 
11644  /*
11645  Now set the size of the data to the size of the field metadata array
11646  plus one or three bytes (see pack.c:net_store_length) for number of
11647  elements in the field metadata array.
11648  */
11649  if (m_field_metadata_size < 251)
11650  m_data_size+= m_field_metadata_size + 1;
11651  else
11652  m_data_size+= m_field_metadata_size + 3;
11653 
11654  memset(m_null_bits, 0, num_null_bytes);
11655  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
11656  if (m_table->field[i]->maybe_null())
11657  m_null_bits[(i / 8)]+= 1 << (i % 8);
11658  /*
11659  Marking event to require sequential execution in MTS
11660  if the query might have updated FK-referenced db.
11661  Unlike Query_log_event where this fact is encoded through
11662  the accessed db list in the Table_map case m_flags is exploited.
11663  */
11664  uchar dbs= thd->get_binlog_accessed_db_names() ?
11665  thd->get_binlog_accessed_db_names()->elements : 0;
11666  if (dbs == 1)
11667  {
11668  char *db_name= thd->get_binlog_accessed_db_names()->head();
11669  if (!strcmp(db_name, ""))
11670  m_flags |= TM_REFERRED_FK_DB_F;
11671  }
11672 }
11673 #endif /* !defined(MYSQL_CLIENT) */
11674 
11675 /*
11676  Constructor used by slave to read the event from the binary log.
11677  */
11678 #if defined(HAVE_REPLICATION)
11679 Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
11681  *description_event)
11682 
11683  : Log_event(buf, description_event),
11684 #ifndef MYSQL_CLIENT
11685  m_table(NULL),
11686 #endif
11687  m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
11688  m_colcnt(0), m_coltype(0),
11689  m_memory(NULL), m_table_id(ULONGLONG_MAX), m_flags(0),
11690  m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
11691  m_null_bits(0), m_meta_memory(NULL)
11692 {
11693  unsigned int bytes_read= 0;
11694  DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
11695 
11696  uint8 common_header_len= description_event->common_header_len;
11697  uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
11698  DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
11699  event_len, common_header_len, post_header_len));
11700 
11701  /*
11702  Don't print debug messages when running valgrind since they can
11703  trigger false warnings.
11704  */
11705 #ifndef HAVE_purify
11706  DBUG_DUMP("event buffer", (uchar*) buf, event_len);
11707 #endif
11708 
11709  /* Read the post-header */
11710  const char *post_start= buf + common_header_len;
11711 
11712  post_start+= TM_MAPID_OFFSET;
11713  if (post_header_len == 6)
11714  {
11715  /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
11716  m_table_id= uint4korr(post_start);
11717  post_start+= 4;
11718  }
11719  else
11720  {
11721  DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
11722  m_table_id= uint6korr(post_start);
11723  post_start+= TM_FLAGS_OFFSET;
11724  }
11725 
11726  m_flags= uint2korr(post_start);
11727 
11728  /* Read the variable part of the event */
11729  const char *const vpart= buf + common_header_len + post_header_len;
11730 
11731  /* Extract the length of the various parts from the buffer */
11732  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
11733  m_dblen= *(uchar*) ptr_dblen;
11734 
11735  /* Length of database name + counter + terminating null */
11736  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
11737  m_tbllen= *(uchar*) ptr_tbllen;
11738 
11739  /* Length of table name + counter + terminating null */
11740  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
11741  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
11742  m_colcnt= net_field_length(&ptr_after_colcnt);
11743 
11744  DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
11745  (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart),
11746  (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
11747  m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
11748 
11749  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
11750  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
11751  &m_dbnam, (uint) m_dblen + 1,
11752  &m_tblnam, (uint) m_tbllen + 1,
11753  &m_coltype, (uint) m_colcnt,
11754  NullS);
11755 
11756  if (m_memory)
11757  {
11758  /* Copy the different parts into their memory */
11759  strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen + 1, m_dblen + 1);
11760  strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
11761  memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
11762 
11763  ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
11764  bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
11765  DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
11766  if (bytes_read < event_len)
11767  {
11768  m_field_metadata_size= net_field_length(&ptr_after_colcnt);
11769  DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
11770  uint num_null_bytes= (m_colcnt + 7) / 8;
11771  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
11772  &m_null_bits, num_null_bytes,
11773  &m_field_metadata, m_field_metadata_size,
11774  NULL);
11775  memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
11776  ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
11777  memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
11778  }
11779  }
11780 
11781  DBUG_VOID_RETURN;
11782 }
11783 #endif
11784 
11785 Table_map_log_event::~Table_map_log_event()
11786 {
11787  my_free(m_meta_memory);
11788  my_free(m_memory);
11789 }
11790 
11791 /*
11792  Return value is an error code, one of:
11793 
11794  -1 Failure to open table [from open_tables()]
11795  0 Success
11796  1 No room for more tables [from set_table()]
11797  2 Out of memory [from set_table()]
11798  3 Wrong table definition
11799  4 Daisy-chaining RBR with SBR not possible
11800  */
11801 
11802 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
11803 
11804 enum enum_tbl_map_status
11805 {
11806  /* no duplicate identifier found */
11807  OK_TO_PROCESS= 0,
11808 
11809  /* this table map must be filtered out */
11810  FILTERED_OUT= 1,
11811 
11812  /* identifier mapping table with different properties */
11813  SAME_ID_MAPPING_DIFFERENT_TABLE= 2,
11814 
11815  /* a duplicate identifier was found mapping the same table */
11816  SAME_ID_MAPPING_SAME_TABLE= 3
11817 };
11818 
11819 /*
11820  Checks if this table map event should be processed or not. First
11821  it checks the filtering rules, and then looks for duplicate identifiers
11822  in the existing list of rli->tables_to_lock.
11823 
11824  It checks that there hasn't been any corruption by verifying that there
11825  are no duplicate entries with different properties.
11826 
11827  In some cases, some binary logs could get corrupted, showing several
11828  tables mapped to the same table_id, 0 (see: BUG#56226). Thus we do this
11829  early sanity check for such cases and avoid that the server crashes
11830  later.
11831 
11832  In some corner cases, the master logs duplicate table map events, i.e.,
11833  same id, same database name, same table name (see: BUG#37137). This is
11834  different from the above as it's the same table that is mapped again
11835  to the same identifier. Thus we cannot just check for same ids and
11836  assume that the event is corrupted we need to check every property.
11837 
11838  NOTE: in the event that BUG#37137 ever gets fixed, this extra check
11839  will still be valid because we would need to support old binary
11840  logs anyway.
11841 
11842  @param rli The relay log info reference.
11843  @param table_list A list element containing the table to check against.
11844  @return OK_TO_PROCESS
11845  if there was no identifier already in rli->tables_to_lock
11846 
11847  FILTERED_OUT
11848  if the event is filtered according to the filtering rules
11849 
11850  SAME_ID_MAPPING_DIFFERENT_TABLE
11851  if the same identifier already maps a different table in
11852  rli->tables_to_lock
11853 
11854  SAME_ID_MAPPING_SAME_TABLE
11855  if the same identifier already maps the same table in
11856  rli->tables_to_lock.
11857 */
11858 static enum_tbl_map_status
11859 check_table_map(Relay_log_info const *rli, RPL_TABLE_LIST *table_list)
11860 {
11861  DBUG_ENTER("check_table_map");
11862  enum_tbl_map_status res= OK_TO_PROCESS;
11863 
11864  if (rli->info_thd->slave_thread /* filtering is for slave only */ &&
11865  (!rpl_filter->db_ok(table_list->db) ||
11866  (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list))))
11867  res= FILTERED_OUT;
11868  else
11869  {
11870  RPL_TABLE_LIST *ptr= static_cast<RPL_TABLE_LIST*>(rli->tables_to_lock);
11871  for(uint i=0 ; ptr && (i< rli->tables_to_lock_count);
11872  ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_local), i++)
11873  {
11874  if (ptr->table_id == table_list->table_id)
11875  {
11876 
11877  if (strcmp(ptr->db, table_list->db) ||
11878  strcmp(ptr->alias, table_list->table_name) ||
11879  ptr->lock_type != TL_WRITE) // the ::do_apply_event always sets TL_WRITE
11880  res= SAME_ID_MAPPING_DIFFERENT_TABLE;
11881  else
11882  res= SAME_ID_MAPPING_SAME_TABLE;
11883 
11884  break;
11885  }
11886  }
11887  }
11888 
11889  DBUG_PRINT("debug", ("check of table map ended up with: %u", res));
11890 
11891  DBUG_RETURN(res);
11892 }
11893 
11894 int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
11895 {
11896  RPL_TABLE_LIST *table_list;
11897  char *db_mem, *tname_mem, *ptr;
11898  size_t dummy_len;
11899  void *memory;
11900  DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
11901  DBUG_ASSERT(rli->info_thd == thd);
11902 
11903  /* Step the query id to mark what columns that are actually used. */
11904  thd->set_query_id(next_query_id());
11905 
11906  if (!(memory= my_multi_malloc(MYF(MY_WME),
11907  &table_list, (uint) sizeof(RPL_TABLE_LIST),
11908  &db_mem, (uint) NAME_LEN + 1,
11909  &tname_mem, (uint) NAME_LEN + 1,
11910  NullS)))
11911  DBUG_RETURN(HA_ERR_OUT_OF_MEM);
11912 
11913  strmov(db_mem, m_dbnam);
11914  strmov(tname_mem, m_tblnam);
11915 
11916  if (lower_case_table_names == 1)
11917  {
11918  my_casedn_str(system_charset_info, db_mem);
11919  my_casedn_str(system_charset_info, tname_mem);
11920  }
11921 
11922  /* rewrite rules changed the database */
11923  if (((ptr= (char*) rpl_filter->get_rewrite_db(db_mem, &dummy_len)) != db_mem))
11924  strmov(db_mem, ptr);
11925 
11926  table_list->init_one_table(db_mem, strlen(db_mem),
11927  tname_mem, strlen(tname_mem),
11928  tname_mem, TL_WRITE);
11929 
11930  table_list->table_id=
11931  DBUG_EVALUATE_IF("inject_tblmap_same_id_maps_diff_table", 0, m_table_id.id());
11932  table_list->updating= 1;
11933  table_list->required_type= FRMTYPE_TABLE;
11934  DBUG_PRINT("debug", ("table: %s is mapped to %llu", table_list->table_name,
11935  table_list->table_id.id()));
11936 
11937  enum_tbl_map_status tblmap_status= check_table_map(rli, table_list);
11938  if (tblmap_status == OK_TO_PROCESS)
11939  {
11940  DBUG_ASSERT(thd->lex->query_tables != table_list);
11941 
11942  /*
11943  Use placement new to construct the table_def instance in the
11944  memory allocated for it inside table_list.
11945 
11946  The memory allocated by the table_def structure (i.e., not the
11947  memory allocated *for* the table_def structure) is released
11948  inside Relay_log_info::clear_tables_to_lock() by calling the
11949  table_def destructor explicitly.
11950  */
11951  new (&table_list->m_tabledef)
11952  table_def(m_coltype, m_colcnt,
11953  m_field_metadata, m_field_metadata_size,
11954  m_null_bits, m_flags);
11955  table_list->m_tabledef_valid= TRUE;
11956  table_list->m_conv_table= NULL;
11957  table_list->open_type= OT_BASE_ONLY;
11958 
11959  /*
11960  We record in the slave's information that the table should be
11961  locked by linking the table into the list of tables to lock.
11962  */
11963  table_list->next_global= table_list->next_local= rli->tables_to_lock;
11964  const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
11965  const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
11966  /* 'memory' is freed in clear_tables_to_lock */
11967  }
11968  else // FILTERED_OUT, SAME_ID_MAPPING_*
11969  {
11970  /*
11971  If mapped already but with different properties, we raise an
11972  error.
11973  If mapped already but with same properties we skip the event.
11974  If filtered out we skip the event.
11975 
11976  In all three cases, we need to free the memory previously
11977  allocated.
11978  */
11979  if (tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE)
11980  {
11981  /*
11982  Something bad has happened. We need to stop the slave as strange things
11983  could happen if we proceed: slave crash, wrong table being updated, ...
11984  As a consequence we push an error in this case.
11985  */
11986 
11987  char buf[256];
11988 
11989  my_snprintf(buf, sizeof(buf),
11990  "Found table map event mapping table id %llu which "
11991  "was already mapped but with different settings.",
11992  table_list->table_id.id());
11993 
11994  if (thd->slave_thread)
11995  rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
11996  ER(ER_SLAVE_FATAL_ERROR), buf);
11997  else
11998  /*
11999  For the cases in which a 'BINLOG' statement is set to
12000  execute in a user session
12001  */
12002  my_printf_error(ER_SLAVE_FATAL_ERROR, ER(ER_SLAVE_FATAL_ERROR),
12003  MYF(0), buf);
12004  }
12005 
12006  my_free(memory);
12007  }
12008 
12009  DBUG_RETURN(tblmap_status == SAME_ID_MAPPING_DIFFERENT_TABLE);
12010 }
12011 
12013 Table_map_log_event::do_shall_skip(Relay_log_info *rli)
12014 {
12015  /*
12016  If the slave skip counter is 1, then we should not start executing
12017  on the next event.
12018  */
12019  return continue_group(rli);
12020 }
12021 
12022 int Table_map_log_event::do_update_pos(Relay_log_info *rli)
12023 {
12024  rli->inc_event_relay_log_pos();
12025  return 0;
12026 }
12027 
12028 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12029 
12030 #ifndef MYSQL_CLIENT
12031 bool Table_map_log_event::write_data_header(IO_CACHE *file)
12032 {
12033  DBUG_ASSERT(m_table_id.is_valid());
12034  uchar buf[TABLE_MAP_HEADER_LEN];
12035  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
12036  {
12037  int4store(buf + 0, m_table_id.id());
12038  int2store(buf + 4, m_flags);
12039  return (wrapper_my_b_safe_write(file, buf, 6));
12040  });
12041  int6store(buf + TM_MAPID_OFFSET, m_table_id.id());
12042  int2store(buf + TM_FLAGS_OFFSET, m_flags);
12043  return (wrapper_my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
12044 }
12045 
12046 bool Table_map_log_event::write_data_body(IO_CACHE *file)
12047 {
12048  DBUG_ASSERT(m_dbnam != NULL);
12049  DBUG_ASSERT(m_tblnam != NULL);
12050  /* We use only one byte per length for storage in event: */
12051  DBUG_ASSERT(m_dblen < 128);
12052  DBUG_ASSERT(m_tbllen < 128);
12053 
12054  uchar const dbuf[]= { (uchar) m_dblen };
12055  uchar const tbuf[]= { (uchar) m_tbllen };
12056 
12057  uchar cbuf[sizeof(m_colcnt) + 1];
12058  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
12059  DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
12060 
12061  /*
12062  Store the size of the field metadata.
12063  */
12064  uchar mbuf[sizeof(m_field_metadata_size)];
12065  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
12066 
12067  return (wrapper_my_b_safe_write(file, dbuf, sizeof(dbuf)) ||
12068  wrapper_my_b_safe_write(file, (const uchar*)m_dbnam, m_dblen+1) ||
12069  wrapper_my_b_safe_write(file, tbuf, sizeof(tbuf)) ||
12070  wrapper_my_b_safe_write(file, (const uchar*)m_tblnam, m_tbllen+1) ||
12071  wrapper_my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
12072  wrapper_my_b_safe_write(file, m_coltype, m_colcnt) ||
12073  wrapper_my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
12074  wrapper_my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
12075  wrapper_my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
12076  }
12077 #endif
12078 
12079 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12080 
12081 /*
12082  Print some useful information for the SHOW BINARY LOG information
12083  field.
12084  */
12085 
12086 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12087 int Table_map_log_event::pack_info(Protocol *protocol)
12088 {
12089  char buf[256];
12090  size_t bytes= my_snprintf(buf, sizeof(buf),
12091  "table_id: %llu (%s.%s)",
12092  m_table_id.id(), m_dbnam, m_tblnam);
12093  protocol->store(buf, bytes, &my_charset_bin);
12094  return 0;
12095 }
12096 #endif
12097 
12098 
12099 #endif
12100 
12101 
12102 #ifdef MYSQL_CLIENT
12103 void Table_map_log_event::print(FILE *, PRINT_EVENT_INFO *print_event_info)
12104 {
12105  if (!print_event_info->short_form)
12106  {
12107  print_header(&print_event_info->head_cache, print_event_info, TRUE);
12108  my_b_printf(&print_event_info->head_cache,
12109  "\tTable_map: `%s`.`%s` mapped to number %llu\n",
12110  m_dbnam, m_tblnam, m_table_id.id());
12111  print_base64(&print_event_info->body_cache, print_event_info, TRUE);
12112  }
12113 }
12114 #endif
12115 
12116 /**************************************************************************
12117  Write_rows_log_event member functions
12118 **************************************************************************/
12119 
12120 /*
12121  Constructor used to build an event for writing to the binary log.
12122  */
12123 #if !defined(MYSQL_CLIENT)
12124 Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12125  const Table_id& tid_arg,
12126  bool is_transactional,
12127  const uchar* extra_row_info)
12128  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional,
12129  log_bin_use_v1_row_events?
12130  WRITE_ROWS_EVENT_V1:
12131  WRITE_ROWS_EVENT,
12132  extra_row_info)
12133 {
12134 }
12135 #endif
12136 
12137 /*
12138  Constructor used by slave to read the event from the binary log.
12139  */
12140 #ifdef HAVE_REPLICATION
12141 Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
12143  *description_event)
12144 : Rows_log_event(buf, event_len, description_event)
12145 {
12146 }
12147 #endif
12148 
12149 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12150 int
12151 Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12152 {
12153  int error= 0;
12154 
12155  /*
12156  Increment the global status insert count variable
12157  */
12158  if (get_flags(STMT_END_F))
12159  status_var_increment(thd->status_var.com_stat[SQLCOM_INSERT]);
12160 
12165  if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12166  (m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER))
12167  {
12168  /*
12169  We are using REPLACE semantics and not INSERT IGNORE semantics
12170  when writing rows, that is: new rows replace old rows. We need to
12171  inform the storage engine that it should use this behaviour.
12172  */
12173 
12174  /* Tell the storage engine that we are using REPLACE semantics. */
12175  thd->lex->duplicates= DUP_REPLACE;
12176 
12177  /*
12178  Pretend we're executing a REPLACE command: this is needed for
12179  InnoDB and NDB Cluster since they are not (properly) checking the
12180  lex->duplicates flag.
12181  */
12182  thd->lex->sql_command= SQLCOM_REPLACE;
12183  /*
12184  Do not raise the error flag in case of hitting to an unique attribute
12185  */
12186  m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
12187  /*
12188  NDB specific: update from ndb master wrapped as Write_rows
12189  so that the event should be applied to replace slave's row
12190  */
12191  m_table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
12192  /*
12193  NDB specific: if update from ndb master wrapped as Write_rows
12194  does not find the row it's assumed idempotent binlog applying
12195  is taking place; don't raise the error.
12196  */
12197  m_table->file->extra(HA_EXTRA_IGNORE_NO_KEY);
12198  /*
12199  TODO: the cluster team (Tomas?) says that it's better if the engine knows
12200  how many rows are going to be inserted, then it can allocate needed memory
12201  from the start.
12202  */
12203  }
12204 
12205 
12206  /* Honor next number column if present */
12207  m_table->next_number_field= m_table->found_next_number_field;
12208  /*
12209  * Fixed Bug#45999, In RBR, Store engine of Slave auto-generates new
12210  * sequence numbers for auto_increment fields if the values of them are 0.
12211  * If generateing a sequence number is decided by the values of
12212  * table->auto_increment_field_not_null and SQL_MODE(if includes
12213  * MODE_NO_AUTO_VALUE_ON_ZERO) in update_auto_increment function.
12214  * SQL_MODE of slave sql thread is always consistency with master's.
12215  * In RBR, auto_increment fields never are NULL.
12216  */
12217  m_table->auto_increment_field_not_null= TRUE;
12218 
12222  decide_row_lookup_algorithm_and_key();
12223  DBUG_ASSERT(m_rows_lookup_algorithm==ROW_LOOKUP_NOT_NEEDED);
12224  return error;
12225 }
12226 
12227 int
12228 Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12229  int error)
12230 {
12231  int local_error= 0;
12232  m_table->next_number_field=0;
12233  m_table->auto_increment_field_not_null= FALSE;
12234  if ((slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT) ||
12235  m_table->s->db_type()->db_type == DB_TYPE_NDBCLUSTER)
12236  {
12237  m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
12238  m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
12239  /*
12240  resetting the extra with
12241  table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
12242  fires bug#27077
12243  explanation: file->reset() performs this duty
12244  ultimately. Still todo: fix
12245  */
12246  }
12247  if ((local_error= m_table->file->ha_end_bulk_insert()))
12248  {
12249  m_table->file->print_error(local_error, MYF(0));
12250  }
12251 
12252  m_rows_lookup_algorithm= ROW_LOOKUP_UNDEFINED;
12253 
12254  return error? error : local_error;
12255 }
12256 
12257 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12258 
12259 /*
12260  Check if there are more UNIQUE keys after the given key.
12261 */
12262 static int
12263 last_uniq_key(TABLE *table, uint keyno)
12264 {
12265  while (++keyno < table->s->keys)
12266  if (table->key_info[keyno].flags & HA_NOSAME)
12267  return 0;
12268  return 1;
12269 }
12270 
12284 bool
12285 is_duplicate_key_error(int errcode)
12286 {
12287  switch (errcode)
12288  {
12289  case HA_ERR_FOUND_DUPP_KEY:
12290  case HA_ERR_FOUND_DUPP_UNIQUE:
12291  return true;
12292  }
12293  return false;
12294 }
12295 
12331 int
12332 Write_rows_log_event::write_row(const Relay_log_info *const rli,
12333  const bool overwrite)
12334 {
12335  DBUG_ENTER("write_row");
12336  DBUG_ASSERT(m_table != NULL && thd != NULL);
12337 
12338  TABLE *table= m_table; // pointer to event's table
12339  int error;
12340  int UNINIT_VAR(keynum);
12341  auto_afree_ptr<char> key(NULL);
12342 
12343  prepare_record(table, &m_cols,
12344  table->file->ht->db_type != DB_TYPE_NDBCLUSTER);
12345 
12346  /* unpack row into table->record[0] */
12347  if ((error= unpack_current_row(rli, &m_cols)))
12348  DBUG_RETURN(error);
12349 
12350  if (m_curr_row == m_rows_buf)
12351  {
12352  /* this is the first row to be inserted, we estimate the rows with
12353  the size of the first row and use that value to initialize
12354  storage engine for bulk insertion */
12355  DBUG_ASSERT(!(m_curr_row > m_curr_row_end));
12356  ulong estimated_rows= 0;
12357  if (m_curr_row < m_curr_row_end)
12358  estimated_rows= (m_rows_end - m_curr_row) / (m_curr_row_end - m_curr_row);
12359  else if (m_curr_row == m_curr_row_end)
12360  estimated_rows= 1;
12361 
12362  m_table->file->ha_start_bulk_insert(estimated_rows);
12363  }
12364 
12365 
12366 #ifndef DBUG_OFF
12367  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
12368  DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
12369  DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
12370 #endif
12371 
12372  /*
12373  Try to write record. If a corresponding record already exists in the table,
12374  we try to change it using ha_update_row() if possible. Otherwise we delete
12375  it and repeat the whole process again.
12376 
12377  TODO: Add safety measures against infinite looping.
12378  */
12379 
12380  m_table->mark_columns_per_binlog_row_image();
12381 
12382  while ((error= table->file->ha_write_row(table->record[0])))
12383  {
12384  if (error == HA_ERR_LOCK_DEADLOCK ||
12385  error == HA_ERR_LOCK_WAIT_TIMEOUT ||
12386  (keynum= table->file->get_dup_key(error)) < 0 ||
12387  !overwrite)
12388  {
12389  DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
12390  /*
12391  Deadlock, waiting for lock or just an error from the handler
12392  such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
12393  Retrieval of the duplicate key number may fail
12394  - either because the error was not "duplicate key" error
12395  - or because the information which key is not available
12396  */
12397  table->file->print_error(error, MYF(0));
12398  goto error;
12399  }
12400  /*
12401  We need to retrieve the old row into record[1] to be able to
12402  either update or delete the offending record. We either:
12403 
12404  - use ha_rnd_pos() with a row-id (available as dupp_row) to the
12405  offending row, if that is possible (MyISAM and Blackhole), or else
12406 
12407  - use ha_index_read_idx_map() with the key that is duplicated, to
12408  retrieve the offending row.
12409  */
12410  if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
12411  {
12412  DBUG_PRINT("info",("Locating offending record using ha_rnd_pos()"));
12413 
12414  if (table->file->inited && (error= table->file->ha_index_end()))
12415  {
12416  table->file->print_error(error, MYF(0));
12417  goto error;
12418  }
12419  if ((error= table->file->ha_rnd_init(FALSE)))
12420  {
12421  table->file->print_error(error, MYF(0));
12422  goto error;
12423  }
12424 
12425  error= table->file->ha_rnd_pos(table->record[1], table->file->dup_ref);
12426 
12427  table->file->ha_rnd_end();
12428  if (error)
12429  {
12430  DBUG_PRINT("info",("ha_rnd_pos() returns error %d",error));
12431  if (error == HA_ERR_RECORD_DELETED)
12432  error= HA_ERR_KEY_NOT_FOUND;
12433  table->file->print_error(error, MYF(0));
12434  goto error;
12435  }
12436  }
12437  else
12438  {
12439  DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
12440 
12441  if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
12442  {
12443  DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
12444  error= my_errno;
12445  goto error;
12446  }
12447 
12448  if (key.get() == NULL)
12449  {
12450  key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
12451  if (key.get() == NULL)
12452  {
12453  DBUG_PRINT("info",("Can't allocate key buffer"));
12454  error= ENOMEM;
12455  goto error;
12456  }
12457  }
12458 
12459  key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
12460  0);
12461  error= table->file->ha_index_read_idx_map(table->record[1], keynum,
12462  (const uchar*)key.get(),
12463  HA_WHOLE_KEY,
12464  HA_READ_KEY_EXACT);
12465  if (error)
12466  {
12467  DBUG_PRINT("info",("ha_index_read_idx_map() returns %s", HA_ERR(error)));
12468  if (error == HA_ERR_RECORD_DELETED)
12469  error= HA_ERR_KEY_NOT_FOUND;
12470  table->file->print_error(error, MYF(0));
12471  goto error;
12472  }
12473  }
12474 
12475  /*
12476  Now, record[1] should contain the offending row. That
12477  will enable us to update it or, alternatively, delete it (so
12478  that we can insert the new row afterwards).
12479  */
12480 
12481  /*
12482  If row is incomplete we will use the record found to fill
12483  missing columns.
12484  */
12485  if (!get_flags(COMPLETE_ROWS_F))
12486  {
12487  restore_record(table,record[1]);
12488  error= unpack_current_row(rli, &m_cols);
12489  }
12490 
12491 #ifndef DBUG_OFF
12492  DBUG_PRINT("debug",("preparing for update: before and after image"));
12493  DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
12494  DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
12495 #endif
12496 
12497  /*
12498  REPLACE is defined as either INSERT or DELETE + INSERT. If
12499  possible, we can replace it with an UPDATE, but that will not
12500  work on InnoDB if FOREIGN KEY checks are necessary.
12501 
12502  I (Matz) am not sure of the reason for the last_uniq_key()
12503  check as, but I'm guessing that it's something along the
12504  following lines.
12505 
12506  Suppose that we got the duplicate key to be a key that is not
12507  the last unique key for the table and we perform an update:
12508  then there might be another key for which the unique check will
12509  fail, so we're better off just deleting the row and inserting
12510  the correct row.
12511  */
12512  if (last_uniq_key(table, keynum) &&
12513  !table->file->referenced_by_foreign_key())
12514  {
12515  DBUG_PRINT("info",("Updating row using ha_update_row()"));
12516  error=table->file->ha_update_row(table->record[1],
12517  table->record[0]);
12518  switch (error) {
12519 
12520  case HA_ERR_RECORD_IS_THE_SAME:
12521  DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
12522  " ha_update_row()"));
12523  error= 0;
12524 
12525  case 0:
12526  break;
12527 
12528  default:
12529  DBUG_PRINT("info",("ha_update_row() returns error %d",error));
12530  table->file->print_error(error, MYF(0));
12531  }
12532 
12533  goto error;
12534  }
12535  else
12536  {
12537  DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
12538  if ((error= table->file->ha_delete_row(table->record[1])))
12539  {
12540  DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
12541  table->file->print_error(error, MYF(0));
12542  goto error;
12543  }
12544  /* Will retry ha_write_row() with the offending row removed. */
12545  }
12546  }
12547 
12548 error:
12549  m_table->default_column_bitmaps();
12550  DBUG_RETURN(error);
12551 }
12552 
12553 #endif
12554 
12555 int
12556 Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
12557 {
12558  DBUG_ASSERT(m_table != NULL);
12559  int error= write_row(rli, slave_exec_mode == SLAVE_EXEC_MODE_IDEMPOTENT);
12560 
12561  if (error && !thd->is_error())
12562  {
12563  DBUG_ASSERT(0);
12564  my_error(ER_UNKNOWN_ERROR, MYF(0));
12565  }
12566 
12567  return error;
12568 }
12569 
12570 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12571 
12572 #ifdef MYSQL_CLIENT
12573 void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
12574 {
12575  DBUG_EXECUTE_IF("simulate_cache_read_error",
12576  {DBUG_SET("+d,simulate_my_b_fill_error");});
12577  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
12578 }
12579 #endif
12580 
12581 /**************************************************************************
12582  Delete_rows_log_event member functions
12583 **************************************************************************/
12584 
12585 /*
12586  Constructor used to build an event for writing to the binary log.
12587  */
12588 
12589 #ifndef MYSQL_CLIENT
12590 Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12591  const Table_id& tid,
12592  bool is_transactional,
12593  const uchar* extra_row_info)
12594  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
12595  log_bin_use_v1_row_events?
12596  DELETE_ROWS_EVENT_V1:
12597  DELETE_ROWS_EVENT,
12598  extra_row_info)
12599 {
12600 }
12601 #endif /* #if !defined(MYSQL_CLIENT) */
12602 
12603 /*
12604  Constructor used by slave to read the event from the binary log.
12605  */
12606 #ifdef HAVE_REPLICATION
12607 Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
12609  *description_event)
12610  : Rows_log_event(buf, event_len, description_event)
12611 {
12612 }
12613 #endif
12614 
12615 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12616 
12617 int
12618 Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12619 {
12620  int error= 0;
12621  DBUG_ENTER("Delete_rows_log_event::do_before_row_operations");
12622  /*
12623  Increment the global status delete count variable
12624  */
12625  if (get_flags(STMT_END_F))
12626  status_var_increment(thd->status_var.com_stat[SQLCOM_DELETE]);
12627  error= row_operations_scan_and_key_setup();
12628  DBUG_RETURN(error);
12629 
12630 }
12631 
12632 int
12633 Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12634  int error)
12635 {
12636  DBUG_ENTER("Delete_rows_log_event::do_after_row_operations");
12637  error= row_operations_scan_and_key_teardown(error);
12638  DBUG_RETURN(error);
12639 }
12640 
12641 int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
12642 {
12643  int error;
12644  DBUG_ASSERT(m_table != NULL);
12645  /* m_table->record[0] contains the BI */
12646  m_table->mark_columns_per_binlog_row_image();
12647  error= m_table->file->ha_delete_row(m_table->record[0]);
12648  m_table->default_column_bitmaps();
12649  return error;
12650 }
12651 
12652 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12653 
12654 #ifdef MYSQL_CLIENT
12655 void Delete_rows_log_event::print(FILE *file,
12656  PRINT_EVENT_INFO* print_event_info)
12657 {
12658  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
12659 }
12660 #endif
12661 
12662 
12663 /**************************************************************************
12664  Update_rows_log_event member functions
12665 **************************************************************************/
12666 
12667 /*
12668  Constructor used to build an event for writing to the binary log.
12669  */
12670 #if !defined(MYSQL_CLIENT)
12671 Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
12672  const Table_id& tid,
12673  bool is_transactional,
12674  const uchar* extra_row_info)
12675 : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional,
12676  log_bin_use_v1_row_events?
12677  UPDATE_ROWS_EVENT_V1:
12678  UPDATE_ROWS_EVENT,
12679  extra_row_info)
12680 {
12681  init(tbl_arg->write_set);
12682 }
12683 
12684 void Update_rows_log_event::init(MY_BITMAP const *cols)
12685 {
12686  /* if bitmap_init fails, caught in is_valid() */
12687  if (likely(!bitmap_init(&m_cols_ai,
12688  m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
12689  m_width,
12690  false)))
12691  {
12692  /* Cols can be zero if this is a dummy binrows event */
12693  if (likely(cols != NULL))
12694  {
12695  memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
12696  create_last_word_mask(&m_cols_ai);
12697  }
12698  }
12699 }
12700 #endif /* !defined(MYSQL_CLIENT) */
12701 
12702 
12703 Update_rows_log_event::~Update_rows_log_event()
12704 {
12705  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
12706  m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
12707  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
12708 }
12709 
12710 
12711 /*
12712  Constructor used by slave to read the event from the binary log.
12713  */
12714 #ifdef HAVE_REPLICATION
12715 Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
12716  const
12718  *description_event)
12719  : Rows_log_event(buf, event_len, description_event)
12720 {
12721 }
12722 #endif
12723 
12724 #if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
12725 
12726 int
12727 Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
12728 {
12729  int error= 0;
12730  DBUG_ENTER("Update_rows_log_event::do_before_row_operations");
12731  /*
12732  Increment the global status update count variable
12733  */
12734  if (get_flags(STMT_END_F))
12735  status_var_increment(thd->status_var.com_stat[SQLCOM_UPDATE]);
12736  error= row_operations_scan_and_key_setup();
12737  DBUG_RETURN(error);
12738 
12739 }
12740 
12741 int
12742 Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
12743  int error)
12744 {
12745  DBUG_ENTER("Update_rows_log_event::do_after_row_operations");
12746  error= row_operations_scan_and_key_teardown(error);
12747  DBUG_RETURN(error);
12748 }
12749 
12750 int
12751 Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
12752 {
12753  DBUG_ASSERT(m_table != NULL);
12754  int error= 0;
12755 
12756  /*
12757  This is the situation after locating BI:
12758 
12759  ===|=== before image ====|=== after image ===|===
12760  ^ ^
12761  m_curr_row m_curr_row_end
12762 
12763  BI found in the table is stored in record[0]. We copy it to record[1]
12764  and unpack AI to record[0].
12765  */
12766 
12767  store_record(m_table,record[1]);
12768 
12769  m_curr_row= m_curr_row_end;
12770  /* this also updates m_curr_row_end */
12771  if ((error= unpack_current_row(rli, &m_cols_ai)))
12772  return error;
12773 
12774  /*
12775  Now we have the right row to update. The old row (the one we're
12776  looking for) is in record[1] and the new row is in record[0].
12777  */
12778 #ifndef HAVE_purify
12779  /*
12780  Don't print debug messages when running valgrind since they can
12781  trigger false warnings.
12782  */
12783  DBUG_PRINT("info",("Updating row in table"));
12784  DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
12785  DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
12786 #endif
12787 
12788  // Temporary fix to find out why it fails [/Matz]
12789  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
12790  memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
12791 
12792  m_table->mark_columns_per_binlog_row_image();
12793  error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
12794  if (error == HA_ERR_RECORD_IS_THE_SAME)
12795  error= 0;
12796  m_table->default_column_bitmaps();
12797 
12798  return error;
12799 }
12800 
12801 #endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
12802 
12803 #ifdef MYSQL_CLIENT
12804 void Update_rows_log_event::print(FILE *file,
12805  PRINT_EVENT_INFO* print_event_info)
12806 {
12807  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
12808 }
12809 #endif
12810 
12811 
12812 Incident_log_event::Incident_log_event(const char *buf, uint event_len,
12813  const Format_description_log_event *descr_event)
12814  : Log_event(buf, descr_event)
12815 {
12816  DBUG_ENTER("Incident_log_event::Incident_log_event");
12817  uint8 const common_header_len=
12818  descr_event->common_header_len;
12819  uint8 const post_header_len=
12820  descr_event->post_header_len[INCIDENT_EVENT-1];
12821 
12822  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
12823  event_len, common_header_len, post_header_len));
12824 
12825  m_message.str= NULL;
12826  m_message.length= 0;
12827  int incident_number= uint2korr(buf + common_header_len);
12828  if (incident_number >= INCIDENT_COUNT ||
12829  incident_number <= INCIDENT_NONE)
12830  {
12831  // If the incident is not recognized, this binlog event is
12832  // invalid. If we set incident_number to INCIDENT_NONE, the
12833  // invalidity will be detected by is_valid().
12834  m_incident= INCIDENT_NONE;
12835  DBUG_VOID_RETURN;
12836  }
12837  m_incident= static_cast<Incident>(incident_number);
12838  char const *ptr= buf + common_header_len + post_header_len;
12839  char const *const str_end= buf + event_len;
12840  uint8 len= 0; // Assignment to keep compiler happy
12841  const char *str= NULL; // Assignment to keep compiler happy
12842  read_str_at_most_255_bytes(&ptr, str_end, &str, &len);
12843  if (!(m_message.str= (char*) my_malloc(len+1, MYF(MY_WME))))
12844  {
12845  /* Mark this event invalid */
12846  m_incident= INCIDENT_NONE;
12847  DBUG_VOID_RETURN;
12848  }
12849  strmake(m_message.str, str, len);
12850  m_message.length= len;
12851  DBUG_PRINT("info", ("m_incident: %d", m_incident));
12852  DBUG_VOID_RETURN;
12853 }
12854 
12855 
12856 Incident_log_event::~Incident_log_event()
12857 {
12858  if (m_message.str)
12859  my_free(m_message.str);
12860 }
12861 
12862 
12863 const char *
12864 Incident_log_event::description() const
12865 {
12866  static const char *const description[]= {
12867  "NOTHING", // Not used
12868  "LOST_EVENTS"
12869  };
12870 
12871  DBUG_PRINT("info", ("m_incident: %d", m_incident));
12872 
12873  return description[m_incident];
12874 }
12875 
12876 
12877 #ifndef MYSQL_CLIENT
12878 int Incident_log_event::pack_info(Protocol *protocol)
12879 {
12880  char buf[256];
12881  size_t bytes;
12882  if (m_message.length > 0)
12883  bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
12884  m_incident, description());
12885  else
12886  bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
12887  m_incident, description(), m_message.str);
12888  protocol->store(buf, bytes, &my_charset_bin);
12889  return 0;
12890 }
12891 #endif
12892 
12893 
12894 #ifdef MYSQL_CLIENT
12895 void
12896 Incident_log_event::print(FILE *file,
12897  PRINT_EVENT_INFO *print_event_info)
12898 {
12899  if (print_event_info->short_form)
12900  return;
12901 
12902  print_header(&print_event_info->head_cache, print_event_info, FALSE);
12903  my_b_printf(&print_event_info->head_cache,
12904  "\n# Incident: %s\nRELOAD DATABASE; # Shall generate syntax error\n",
12905  description());
12906 }
12907 #endif
12908 
12909 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
12910 int
12911 Incident_log_event::do_apply_event(Relay_log_info const *rli)
12912 {
12913  DBUG_ENTER("Incident_log_event::do_apply_event");
12914 
12915  if (ignored_error_code(ER_SLAVE_INCIDENT))
12916  {
12917  DBUG_PRINT("info", ("Ignoring Incident"));
12918  DBUG_RETURN(0);
12919  }
12920 
12921  rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
12922  ER(ER_SLAVE_INCIDENT),
12923  description(),
12924  m_message.length > 0 ? m_message.str : "<none>");
12925  DBUG_RETURN(1);
12926 }
12927 #endif
12928 
12929 bool
12930 Incident_log_event::write_data_header(IO_CACHE *file)
12931 {
12932  DBUG_ENTER("Incident_log_event::write_data_header");
12933  DBUG_PRINT("enter", ("m_incident: %d", m_incident));
12934  uchar buf[sizeof(int16)];
12935  int2store(buf, (int16) m_incident);
12936 #ifndef MYSQL_CLIENT
12937  DBUG_RETURN(wrapper_my_b_safe_write(file, buf, sizeof(buf)));
12938 #else
12939  DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
12940 #endif
12941 }
12942 
12943 bool
12944 Incident_log_event::write_data_body(IO_CACHE *file)
12945 {
12946  uchar tmp[1];
12947  DBUG_ENTER("Incident_log_event::write_data_body");
12948  tmp[0]= (uchar) m_message.length;
12949  crc= my_checksum(crc, (uchar*) tmp, 1);
12950  if (m_message.length > 0)
12951  {
12952  crc= my_checksum(crc, (uchar*) m_message.str, m_message.length);
12953  // todo: report a bug on write_str accepts uint but treats it as uchar
12954  }
12955  DBUG_RETURN(write_str_at_most_255_bytes(file, m_message.str, (uint) m_message.length));
12956 }
12957 
12958 
12959 Ignorable_log_event::Ignorable_log_event(const char *buf,
12960  const Format_description_log_event *descr_event)
12961  : Log_event(buf, descr_event)
12962 {
12963  DBUG_ENTER("Ignorable_log_event::Ignorable_log_event");
12964  DBUG_VOID_RETURN;
12965 }
12966 
12967 Ignorable_log_event::~Ignorable_log_event()
12968 {
12969 }
12970 
12971 #ifndef MYSQL_CLIENT
12972 /* Pack info for its unrecognized ignorable event */
12973 int Ignorable_log_event::pack_info(Protocol *protocol)
12974 {
12975  char buf[256];
12976  size_t bytes;
12977  bytes= my_snprintf(buf, sizeof(buf), "# Unrecognized ignorable event");
12978  protocol->store(buf, bytes, &my_charset_bin);
12979  return 0;
12980 }
12981 #endif
12982 
12983 #ifdef MYSQL_CLIENT
12984 /* Print for its unrecognized ignorable event */
12985 void
12986 Ignorable_log_event::print(FILE *file,
12987  PRINT_EVENT_INFO *print_event_info)
12988 {
12989  if (print_event_info->short_form)
12990  return;
12991 
12992  print_header(&print_event_info->head_cache, print_event_info, FALSE);
12993  my_b_printf(&print_event_info->head_cache, "\tIgnorable\n");
12994  my_b_printf(&print_event_info->head_cache,
12995  "# Unrecognized ignorable event\n");
12996 }
12997 #endif
12998 
12999 
13000 Rows_query_log_event::Rows_query_log_event(const char *buf, uint event_len,
13001  const Format_description_log_event *descr_event)
13002  : Ignorable_log_event(buf, descr_event)
13003 {
13004  DBUG_ENTER("Rows_query_log_event::Rows_query_log_event");
13005  uint8 const common_header_len=
13006  descr_event->common_header_len;
13007  uint8 const post_header_len=
13008  descr_event->post_header_len[ROWS_QUERY_LOG_EVENT-1];
13009 
13010  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13011  event_len, common_header_len, post_header_len));
13012 
13013  /*
13014  m_rows_query length is stored using only one byte, but that length is
13015  ignored and the complete query is read.
13016  */
13017  int offset= common_header_len + post_header_len + 1;
13018  int len= event_len - offset;
13019  if (!(m_rows_query= (char*) my_malloc(len+1, MYF(MY_WME))))
13020  return;
13021  strmake(m_rows_query, buf + offset, len);
13022  DBUG_PRINT("info", ("m_rows_query: %s", m_rows_query));
13023  DBUG_VOID_RETURN;
13024 }
13025 
13026 Rows_query_log_event::~Rows_query_log_event()
13027 {
13028  my_free(m_rows_query);
13029 }
13030 
13031 #ifndef MYSQL_CLIENT
13032 int Rows_query_log_event::pack_info(Protocol *protocol)
13033 {
13034  char *buf;
13035  size_t bytes;
13036  ulong len= sizeof("# ") + (ulong) strlen(m_rows_query);
13037  if (!(buf= (char*) my_malloc(len, MYF(MY_WME))))
13038  return 1;
13039  bytes= my_snprintf(buf, len, "# %s", m_rows_query);
13040  protocol->store(buf, bytes, &my_charset_bin);
13041  my_free(buf);
13042  return 0;
13043 }
13044 #endif
13045 
13046 #ifdef MYSQL_CLIENT
13047 void
13048 Rows_query_log_event::print(FILE *file,
13049  PRINT_EVENT_INFO *print_event_info)
13050 {
13051  if (!print_event_info->short_form && print_event_info->verbose > 1)
13052  {
13053  IO_CACHE *const head= &print_event_info->head_cache;
13054  IO_CACHE *const body= &print_event_info->body_cache;
13055  char *token= NULL, *saveptr= NULL;
13056  char *rows_query_copy= NULL;
13057  if (!(rows_query_copy= my_strdup(m_rows_query, MYF(MY_WME))))
13058  return;
13059 
13060  print_header(head, print_event_info, FALSE);
13061  my_b_printf(head, "\tRows_query\n");
13062  /*
13063  Prefix every line of a multi-line query with '#' to prevent the
13064  statement from being executed when binary log will be processed
13065  using 'mysqlbinlog --verbose --verbose'.
13066  */
13067  for (token= strtok_r(rows_query_copy, "\n", &saveptr); token;
13068  token= strtok_r(NULL, "\n", &saveptr))
13069  my_b_printf(head, "# %s\n", token);
13070  my_free(rows_query_copy);
13071  print_base64(body, print_event_info, true);
13072  }
13073 }
13074 #endif
13075 
13076 bool
13077 Rows_query_log_event::write_data_body(IO_CACHE *file)
13078 {
13079  DBUG_ENTER("Rows_query_log_event::write_data_body");
13080  /*
13081  m_rows_query length will be stored using only one byte, but on read
13082  that length will be ignored and the complete query will be read.
13083  */
13084  DBUG_RETURN(write_str_at_most_255_bytes(file, m_rows_query,
13085  (uint) strlen(m_rows_query)));
13086 }
13087 
13088 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
13089 int Rows_query_log_event::do_apply_event(Relay_log_info const *rli)
13090 {
13091  DBUG_ENTER("Rows_query_log_event::do_apply_event");
13092  DBUG_ASSERT(rli->info_thd == thd);
13093  /* Set query for writing Rows_query log event into binlog later.*/
13094  thd->set_query(m_rows_query, (uint32) strlen(m_rows_query));
13095 
13096  DBUG_ASSERT(rli->rows_query_ev == NULL);
13097 
13098  const_cast<Relay_log_info*>(rli)->rows_query_ev= this;
13099 
13100  DBUG_RETURN(0);
13101 }
13102 #endif
13103 
13104 
13105 const char *Gtid_log_event::SET_STRING_PREFIX= "SET @@SESSION.GTID_NEXT= '";
13106 
13107 
13108 Gtid_log_event::Gtid_log_event(const char *buffer, uint event_len,
13109  const Format_description_log_event *descr_event)
13110  : Log_event(buffer, descr_event)
13111 {
13112  DBUG_ENTER("Gtid_log_event::Gtid_log_event(const char *, uint, const Format_description_log_event *");
13113  uint8 const common_header_len=
13114  descr_event->common_header_len;
13115 
13116 #ifndef DBUG_OFF
13117  uint8 const post_header_len=
13118  buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13119  descr_event->post_header_len[ANONYMOUS_GTID_LOG_EVENT - 1] :
13120  descr_event->post_header_len[GTID_LOG_EVENT - 1];
13121  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13122  event_len, common_header_len, post_header_len));
13123 #endif
13124 
13125  char const *ptr_buffer= buffer + common_header_len;
13126 
13127  spec.type= buffer[EVENT_TYPE_OFFSET] == ANONYMOUS_GTID_LOG_EVENT ?
13128  ANONYMOUS_GROUP : GTID_GROUP;
13129 
13130  commit_flag= *ptr_buffer != 0;
13131  ptr_buffer+= ENCODED_FLAG_LENGTH;
13132 
13133  sid.copy_from((uchar *)ptr_buffer);
13134  ptr_buffer+= ENCODED_SID_LENGTH;
13135 
13136  // SIDNO is only generated if needed, in get_sidno().
13137  spec.gtid.sidno= -1;
13138 
13139  spec.gtid.gno= uint8korr(ptr_buffer);
13140  ptr_buffer+= ENCODED_GNO_LENGTH;
13141 
13142  DBUG_VOID_RETURN;
13143 }
13144 
13145 #ifndef MYSQL_CLIENT
13146 Gtid_log_event::Gtid_log_event(THD* thd_arg, bool using_trans,
13147  const Gtid_specification *spec_arg)
13148 : Log_event(thd_arg, thd_arg->variables.gtid_next.type == ANONYMOUS_GROUP ?
13150  using_trans ? Log_event::EVENT_TRANSACTIONAL_CACHE :
13151  Log_event::EVENT_STMT_CACHE, Log_event::EVENT_NORMAL_LOGGING),
13152  commit_flag(true)
13153 {
13154  DBUG_ENTER("Gtid_log_event::Gtid_log_event(THD *)");
13155  spec= spec_arg ? *spec_arg : thd_arg->variables.gtid_next;
13156  if (spec.type == GTID_GROUP)
13157  {
13158  global_sid_lock->rdlock();
13159  sid= global_sid_map->sidno_to_sid(spec.gtid.sidno);
13160  global_sid_lock->unlock();
13161  }
13162  else
13163  sid.clear();
13164 #ifndef DBUG_OFF
13165  char buf[MAX_SET_STRING_LENGTH + 1];
13166  to_string(buf);
13167  DBUG_PRINT("info", ("%s", buf));
13168 #endif
13169  DBUG_VOID_RETURN;
13170 }
13171 #endif
13172 
13173 #ifndef MYSQL_CLIENT
13174 int Gtid_log_event::pack_info(Protocol *protocol)
13175 {
13176  char buffer[MAX_SET_STRING_LENGTH + 1];
13177  size_t len= to_string(buffer);
13178  protocol->store(buffer, len, &my_charset_bin);
13179  return 0;
13180 }
13181 #endif
13182 
13183 size_t Gtid_log_event::to_string(char *buf) const
13184 {
13185  char *p= buf;
13186  DBUG_ASSERT(strlen(SET_STRING_PREFIX) == SET_STRING_PREFIX_LENGTH);
13187  strcpy(p, SET_STRING_PREFIX);
13188  p+= SET_STRING_PREFIX_LENGTH;
13189  p+= spec.to_string(&sid, p);
13190  *p++= '\'';
13191  *p= '\0';
13192  return p - buf;
13193 }
13194 
13195 #ifdef MYSQL_CLIENT
13196 void
13197 Gtid_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
13198 {
13199  char buffer[MAX_SET_STRING_LENGTH + 1];
13200  IO_CACHE *const head= &print_event_info->head_cache;
13201  if (!print_event_info->short_form)
13202  {
13203  print_header(head, print_event_info, FALSE);
13204  my_b_printf(head, "\tGTID [commit=%s]\n", commit_flag ? "yes" : "no");
13205  }
13206  to_string(buffer);
13207  my_b_printf(head, "%s%s\n", buffer, print_event_info->delimiter);
13208 }
13209 #endif
13210 
13211 #ifdef MYSQL_SERVER
13212 bool Gtid_log_event::write_data_header(IO_CACHE *file)
13213 {
13214  DBUG_ENTER("Gtid_log_event::write_data_header");
13215  char buffer[POST_HEADER_LENGTH];
13216  char* ptr_buffer= buffer;
13217 
13218  *ptr_buffer= commit_flag ? 1 : 0;
13219  ptr_buffer+= ENCODED_FLAG_LENGTH;
13220 
13221 #ifndef DBUG_OFF
13222  char buf[rpl_sid::TEXT_LENGTH + 1];
13223  sid.to_string(buf);
13224  DBUG_PRINT("info", ("sid=%s sidno=%d gno=%lld",
13225  buf, spec.gtid.sidno, spec.gtid.gno));
13226 #endif
13227 
13228  sid.copy_to((uchar *)ptr_buffer);
13229  ptr_buffer+= ENCODED_SID_LENGTH;
13230 
13231  int8store(ptr_buffer, spec.gtid.gno);
13232  ptr_buffer+= ENCODED_GNO_LENGTH;
13233 
13234  DBUG_ASSERT(ptr_buffer == (buffer + sizeof(buffer)));
13235  DBUG_RETURN(wrapper_my_b_safe_write(file, (uchar *) buffer, sizeof(buffer)));
13236 }
13237 #endif // MYSQL_SERVER
13238 
13239 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
13240 int Gtid_log_event::do_apply_event(Relay_log_info const *rli)
13241 {
13242  DBUG_ENTER("Gtid_log_event::do_apply_event");
13243  DBUG_ASSERT(rli->info_thd == thd);
13244 
13245  // Gtid_log_events should be filtered out at earlier stages if gtid_mode == 0
13246  DBUG_ASSERT(gtid_mode > 0);
13247 
13248  rpl_sidno sidno= get_sidno(true);
13249  if (sidno < 0)
13250  DBUG_RETURN(1); // out of memory
13251  if (thd->owned_gtid.sidno)
13252  {
13253  gtid_rollback(thd);
13254  }
13255  thd->variables.gtid_next.set(sidno, spec.gtid.gno);
13256  DBUG_PRINT("info", ("setting gtid_next=%d:%lld",
13257  sidno, spec.gtid.gno));
13258 
13259  if (gtid_acquire_ownership_single(thd))
13260  DBUG_RETURN(1);
13261 
13262  DBUG_RETURN(0);
13263 }
13264 
13265 int Gtid_log_event::do_update_pos(Relay_log_info *rli)
13266 {
13267  /*
13268  This event does not increment group positions. This means
13269  that if there is a failure after it has been processed,
13270  it will be automatically re-executed.
13271  */
13272  rli->inc_event_relay_log_pos();
13273  DBUG_EXECUTE_IF("crash_after_update_pos_gtid",
13274  sql_print_information("Crashing crash_after_update_pos_gtid.");
13275  DBUG_SUICIDE(););
13276  return 0;
13277 }
13278 #endif
13279 
13280 Previous_gtids_log_event::Previous_gtids_log_event(
13281  const char *buffer, uint event_len,
13282  const Format_description_log_event *descr_event)
13283  : Log_event(buffer, descr_event)
13284 {
13285  DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event");
13286  uint8 const common_header_len=
13287  descr_event->common_header_len;
13288  uint8 const post_header_len=
13289  descr_event->post_header_len[PREVIOUS_GTIDS_LOG_EVENT - 1];
13290 
13291  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
13292  event_len, common_header_len, post_header_len));
13293 
13294  buf= (const uchar *)buffer + common_header_len + post_header_len;
13295  buf_size= (const uchar *)buffer + event_len - buf;
13296  DBUG_PRINT("info", ("data size of the event: %d", buf_size));
13297  DBUG_VOID_RETURN;
13298 }
13299 
13300 #ifndef MYSQL_CLIENT
13301 Previous_gtids_log_event::Previous_gtids_log_event(const Gtid_set *set)
13302 : Log_event(Log_event::EVENT_NO_CACHE,
13303  Log_event::EVENT_IMMEDIATE_LOGGING)
13304 {
13305  DBUG_ENTER("Previous_gtids_log_event::Previous_gtids_log_event(THD *, const Gtid_set *)");
13306  global_sid_lock->assert_some_lock();
13307  buf_size= set->get_encoded_length();
13308  uchar *buffer= (uchar *) my_malloc(buf_size, MYF(MY_WME));
13309  if (buffer != NULL)
13310  {
13311  set->encode(buffer);
13312  register_temp_buf((char *)buffer);
13313  }
13314  this->buf= buffer;
13315  // if buf == NULL, is_valid will return false
13316  DBUG_VOID_RETURN;
13317 }
13318 #endif
13319 
13320 #ifndef MYSQL_CLIENT
13321 int Previous_gtids_log_event::pack_info(Protocol *protocol)
13322 {
13323  size_t length= 0;
13324  global_sid_lock->rdlock();
13325  char *str= get_str(&length, &Gtid_set::default_string_format);
13326  global_sid_lock->unlock();
13327  if (str == NULL)
13328  return 1;
13329  protocol->store(str, length, &my_charset_bin);
13330  my_free(str);
13331  return 0;
13332 }
13333 #endif
13334 
13335 #ifdef MYSQL_CLIENT
13336 void Previous_gtids_log_event::print(FILE *file,
13337  PRINT_EVENT_INFO *print_event_info)
13338 {
13339  IO_CACHE *const head= &print_event_info->head_cache;
13340 
13341  global_sid_lock->rdlock();
13342  char *str= get_str(NULL, &Gtid_set::commented_string_format);
13343  global_sid_lock->unlock();
13344  if (str != NULL)
13345  {
13346  if (!print_event_info->short_form)
13347  {
13348  print_header(head, print_event_info, FALSE);
13349  my_b_printf(head, "\tPrevious-GTIDs\n");
13350  }
13351  my_b_printf(head, "%s\n", str);
13352  my_free(str);
13353  }
13354 }
13355 #endif
13356 
13358 {
13359  DBUG_ENTER("Previous_gtids_log_event::add_to_set(Gtid_set *)");
13360  size_t end_pos= 0;
13361  size_t add_size= DBUG_EVALUATE_IF("gtid_has_extra_data", 10, 0);
13362  /* Silently ignore additional unknown data at the end of the encoding */
13363  PROPAGATE_REPORTED_ERROR_INT(target->add_gtid_encoding(buf,
13364  buf_size + add_size,
13365  &end_pos));
13366  DBUG_ASSERT(end_pos <= (size_t) buf_size);
13367  DBUG_RETURN(0);
13368 }
13369 
13371  size_t *length_p, const Gtid_set::String_format *string_format) const
13372 {
13373  DBUG_ENTER("Previous_gtids_log_event::get_str(size_t *)");
13374  Sid_map sid_map(NULL);
13375  Gtid_set set(&sid_map, NULL);
13376  DBUG_PRINT("info", ("temp_buf=%p buf=%p", temp_buf, buf));
13377  if (set.add_gtid_encoding(buf, buf_size) != RETURN_STATUS_OK)
13378  DBUG_RETURN(NULL);
13379  set.dbug_print("set");
13380  size_t length= set.get_string_length(string_format);
13381  DBUG_PRINT("info", ("string length= %lu", (ulong) length));
13382  char* str= (char *)my_malloc(length + 1, MYF(MY_WME));
13383  if (str != NULL)
13384  {
13385  set.to_string(str, string_format);
13386  if (length_p != NULL)
13387  *length_p= length;
13388  }
13389  DBUG_RETURN(str);
13390 }
13391 
13392 #ifndef MYSQL_CLIENT
13393 bool Previous_gtids_log_event::write_data_body(IO_CACHE *file)
13394 {
13395  DBUG_ENTER("Previous_gtids_log_event::write_data_body");
13396  DBUG_PRINT("info", ("size=%d", buf_size));
13397  bool ret= wrapper_my_b_safe_write(file, buf, buf_size);
13398  DBUG_RETURN(ret);
13399 }
13400 #endif
13401 
13402 #if defined(MYSQL_SERVER) && defined(HAVE_REPLICATION)
13403 int Previous_gtids_log_event::do_update_pos(Relay_log_info *rli)
13404 {
13405  rli->inc_event_relay_log_pos();
13406  return 0;
13407 }
13408 #endif
13409 
13410 
13411 #ifdef MYSQL_CLIENT
13412 
13417 st_print_event_info::st_print_event_info()
13418  :flags2_inited(0), sql_mode_inited(0), sql_mode(0),
13419  auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
13420  lc_time_names_number(~0),
13421  charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
13422  thread_id(0), thread_id_printed(false),
13423  base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE),
13424  have_unflushed_events(FALSE), skipped_event_in_transaction(false)
13425 {
13426  /*
13427  Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
13428  program's startup, but these explicit memset() is for the day someone
13429  creates dynamic instances.
13430  */
13431  memset(db, 0, sizeof(db));
13432  memset(charset, 0, sizeof(charset));
13433  memset(time_zone_str, 0, sizeof(time_zone_str));
13434  delimiter[0]= ';';
13435  delimiter[1]= 0;
13436  myf const flags = MYF(MY_WME | MY_NABP);
13437  open_cached_file(&head_cache, NULL, NULL, 0, flags);
13438  open_cached_file(&body_cache, NULL, NULL, 0, flags);
13439 }
13440 #endif
13441 
13442 
13443 #if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
13444 Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
13445  const Format_description_log_event* description_event)
13446  :Log_event(buf, description_event)
13447 {
13448  uint8 header_size= description_event->common_header_len;
13449  ident_len = event_len - header_size;
13450  set_if_smaller(ident_len,FN_REFLEN-1);
13451  log_ident= buf + header_size;
13452 }
13453 #endif
13454 
13455 #ifdef MYSQL_SERVER
13456 /*
13457  This is a utility function that adds a quoted identifier into the a buffer.
13458  This also escapes any existance of the quote string inside the identifier.
13459 
13460  SYNOPSIS
13461  my_strmov_quoted_identifier
13462  thd thread handler
13463  buffer target buffer
13464  identifier the identifier to be quoted
13465  length length of the identifier
13466 */
13467 size_t my_strmov_quoted_identifier(THD* thd, char *buffer,
13468  const char* identifier,
13469  uint length)
13470 {
13471  int q= thd ? get_quote_char_for_identifier(thd, identifier, length) : '`';
13472  return my_strmov_quoted_identifier_helper(q, buffer, identifier, length);
13473 }
13474 #else
13475 size_t my_strmov_quoted_identifier(char *buffer, const char* identifier)
13476 {
13477  int q= '`';
13478  return my_strmov_quoted_identifier_helper(q, buffer, identifier, 0);
13479 }
13480 
13481 #endif
13482 
13483 size_t my_strmov_quoted_identifier_helper(int q, char *buffer,
13484  const char* identifier,
13485  uint length)
13486 {
13487  size_t written= 0;
13488  char quote_char;
13489  uint id_length= (length) ? length : strlen(identifier);
13490 
13491  if (q == EOF)
13492  {
13493  (void) strncpy(buffer, identifier, id_length);
13494  return id_length;
13495  }
13496  quote_char= (char) q;
13497  *buffer++= quote_char;
13498  written++;
13499  while (id_length--)
13500  {
13501  if (*identifier == quote_char)
13502  {
13503  *buffer++= quote_char;
13504  written++;
13505  }
13506  *buffer++= *identifier++;
13507  written++;
13508  }
13509  *buffer++= quote_char;
13510  return ++written;
13511 }
13512