~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/log_event.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000-2004 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
#ifdef MYSQL_CLIENT
 
18
 
 
19
#include "mysql_priv.h"
 
20
 
 
21
#else
 
22
 
 
23
#ifdef USE_PRAGMA_IMPLEMENTATION
 
24
#pragma implementation                          // gcc: Class implementation
 
25
#endif
 
26
 
 
27
#include "mysql_priv.h"
 
28
#include "slave.h"
 
29
#include "rpl_rli.h"
 
30
#include "rpl_mi.h"
 
31
#include "rpl_filter.h"
 
32
#include "rpl_utility.h"
 
33
#include "rpl_record.h"
 
34
#include <my_dir.h>
 
35
 
 
36
#endif /* MYSQL_CLIENT */
 
37
 
 
38
#include <base64.h>
 
39
#include <my_bitmap.h>
 
40
 
 
41
#define log_cs  &my_charset_latin1
 
42
 
 
43
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
44
 
 
45
 
 
46
/*
 
47
  Size of buffer for printing a double in format %.<PREC>g
 
48
 
 
49
  optional '-' + optional zero + '.'  + PREC digits + 'e' + sign +
 
50
  exponent digits + '\0'
 
51
*/
 
52
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
 
53
 
 
54
 
 
55
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
56
static const char *HA_ERR(int i)
 
57
{
 
58
  switch (i) {
 
59
  case HA_ERR_KEY_NOT_FOUND: return "HA_ERR_KEY_NOT_FOUND";
 
60
  case HA_ERR_FOUND_DUPP_KEY: return "HA_ERR_FOUND_DUPP_KEY";
 
61
  case HA_ERR_RECORD_CHANGED: return "HA_ERR_RECORD_CHANGED";
 
62
  case HA_ERR_WRONG_INDEX: return "HA_ERR_WRONG_INDEX";
 
63
  case HA_ERR_CRASHED: return "HA_ERR_CRASHED";
 
64
  case HA_ERR_WRONG_IN_RECORD: return "HA_ERR_WRONG_IN_RECORD";
 
65
  case HA_ERR_OUT_OF_MEM: return "HA_ERR_OUT_OF_MEM";
 
66
  case HA_ERR_NOT_A_TABLE: return "HA_ERR_NOT_A_TABLE";
 
67
  case HA_ERR_WRONG_COMMAND: return "HA_ERR_WRONG_COMMAND";
 
68
  case HA_ERR_OLD_FILE: return "HA_ERR_OLD_FILE";
 
69
  case HA_ERR_NO_ACTIVE_RECORD: return "HA_ERR_NO_ACTIVE_RECORD";
 
70
  case HA_ERR_RECORD_DELETED: return "HA_ERR_RECORD_DELETED";
 
71
  case HA_ERR_RECORD_FILE_FULL: return "HA_ERR_RECORD_FILE_FULL";
 
72
  case HA_ERR_INDEX_FILE_FULL: return "HA_ERR_INDEX_FILE_FULL";
 
73
  case HA_ERR_END_OF_FILE: return "HA_ERR_END_OF_FILE";
 
74
  case HA_ERR_UNSUPPORTED: return "HA_ERR_UNSUPPORTED";
 
75
  case HA_ERR_TO_BIG_ROW: return "HA_ERR_TO_BIG_ROW";
 
76
  case HA_WRONG_CREATE_OPTION: return "HA_WRONG_CREATE_OPTION";
 
77
  case HA_ERR_FOUND_DUPP_UNIQUE: return "HA_ERR_FOUND_DUPP_UNIQUE";
 
78
  case HA_ERR_UNKNOWN_CHARSET: return "HA_ERR_UNKNOWN_CHARSET";
 
79
  case HA_ERR_WRONG_MRG_TABLE_DEF: return "HA_ERR_WRONG_MRG_TABLE_DEF";
 
80
  case HA_ERR_CRASHED_ON_REPAIR: return "HA_ERR_CRASHED_ON_REPAIR";
 
81
  case HA_ERR_CRASHED_ON_USAGE: return "HA_ERR_CRASHED_ON_USAGE";
 
82
  case HA_ERR_LOCK_WAIT_TIMEOUT: return "HA_ERR_LOCK_WAIT_TIMEOUT";
 
83
  case HA_ERR_LOCK_TABLE_FULL: return "HA_ERR_LOCK_TABLE_FULL";
 
84
  case HA_ERR_READ_ONLY_TRANSACTION: return "HA_ERR_READ_ONLY_TRANSACTION";
 
85
  case HA_ERR_LOCK_DEADLOCK: return "HA_ERR_LOCK_DEADLOCK";
 
86
  case HA_ERR_CANNOT_ADD_FOREIGN: return "HA_ERR_CANNOT_ADD_FOREIGN";
 
87
  case HA_ERR_NO_REFERENCED_ROW: return "HA_ERR_NO_REFERENCED_ROW";
 
88
  case HA_ERR_ROW_IS_REFERENCED: return "HA_ERR_ROW_IS_REFERENCED";
 
89
  case HA_ERR_NO_SAVEPOINT: return "HA_ERR_NO_SAVEPOINT";
 
90
  case HA_ERR_NON_UNIQUE_BLOCK_SIZE: return "HA_ERR_NON_UNIQUE_BLOCK_SIZE";
 
91
  case HA_ERR_NO_SUCH_TABLE: return "HA_ERR_NO_SUCH_TABLE";
 
92
  case HA_ERR_TABLE_EXIST: return "HA_ERR_TABLE_EXIST";
 
93
  case HA_ERR_NO_CONNECTION: return "HA_ERR_NO_CONNECTION";
 
94
  case HA_ERR_NULL_IN_SPATIAL: return "HA_ERR_NULL_IN_SPATIAL";
 
95
  case HA_ERR_TABLE_DEF_CHANGED: return "HA_ERR_TABLE_DEF_CHANGED";
 
96
  case HA_ERR_NO_PARTITION_FOUND: return "HA_ERR_NO_PARTITION_FOUND";
 
97
  case HA_ERR_RBR_LOGGING_FAILED: return "HA_ERR_RBR_LOGGING_FAILED";
 
98
  case HA_ERR_DROP_INDEX_FK: return "HA_ERR_DROP_INDEX_FK";
 
99
  case HA_ERR_FOREIGN_DUPLICATE_KEY: return "HA_ERR_FOREIGN_DUPLICATE_KEY";
 
100
  case HA_ERR_TABLE_NEEDS_UPGRADE: return "HA_ERR_TABLE_NEEDS_UPGRADE";
 
101
  case HA_ERR_TABLE_READONLY: return "HA_ERR_TABLE_READONLY";
 
102
  case HA_ERR_AUTOINC_READ_FAILED: return "HA_ERR_AUTOINC_READ_FAILED";
 
103
  case HA_ERR_AUTOINC_ERANGE: return "HA_ERR_AUTOINC_ERANGE";
 
104
  case HA_ERR_GENERIC: return "HA_ERR_GENERIC";
 
105
  case HA_ERR_RECORD_IS_THE_SAME: return "HA_ERR_RECORD_IS_THE_SAME";
 
106
  case HA_ERR_LOGGING_IMPOSSIBLE: return "HA_ERR_LOGGING_IMPOSSIBLE";
 
107
  case HA_ERR_CORRUPT_EVENT: return "HA_ERR_CORRUPT_EVENT";
 
108
  case HA_ERR_ROWS_EVENT_APPLY : return "HA_ERR_ROWS_EVENT_APPLY";
 
109
  }
 
110
  return 0;
 
111
}
 
112
 
 
113
/**
 
114
   Error reporting facility for Rows_log_event::do_apply_event
 
115
 
 
116
   @param level     error, warning or info
 
117
   @param ha_error  HA_ERR_ code
 
118
   @param rli       pointer to the active Relay_log_info instance
 
119
   @param thd       pointer to the slave thread's thd
 
120
   @param table     pointer to the event's table object
 
121
   @param type      the type of the event
 
122
   @param log_name  the master binlog file name
 
123
   @param pos       the master binlog file pos (the next after the event)
 
124
 
 
125
*/
 
126
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
 
127
                                           Relay_log_info const *rli, THD *thd,
 
128
                                           TABLE *table, const char * type,
 
129
                                           const char *log_name, ulong pos)
 
130
{
 
131
  const char *handler_error= HA_ERR(ha_error);
 
132
  char buff[MAX_SLAVE_ERRMSG], *slider;
 
133
  const char *buff_end= buff + sizeof(buff);
 
134
  uint len;
 
135
  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
136
  MYSQL_ERROR *err;
 
137
  buff[0]= 0;
 
138
 
 
139
  for (err= it++, slider= buff; err && slider < buff_end - 1;
 
140
       slider += len, err= it++)
 
141
  {
 
142
    len= my_snprintf(slider, buff_end - slider,
 
143
                     " %s, Error_code: %d;", err->msg, err->code);
 
144
  }
 
145
  
 
146
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
 
147
              "Could not execute %s event on table %s.%s;"
 
148
              "%s handler error %s; "
 
149
              "the event's master log %s, end_log_pos %lu",
 
150
              type, table->s->db.str,
 
151
              table->s->table_name.str,
 
152
              buff,
 
153
              handler_error == NULL? "<unknown>" : handler_error,
 
154
              log_name, pos);
 
155
}
 
156
#endif
 
157
 
 
158
/*
 
159
  Cache that will automatically be written to a dedicated file on
 
160
  destruction.
 
161
 
 
162
  DESCRIPTION
 
163
 
 
164
 */
 
165
class Write_on_release_cache
 
166
{
 
167
public:
 
168
  enum flag
 
169
  {
 
170
    FLUSH_F
 
171
  };
 
172
 
 
173
  typedef unsigned short flag_set;
 
174
 
 
175
  /*
 
176
    Constructor.
 
177
 
 
178
    SYNOPSIS
 
179
      Write_on_release_cache
 
180
      cache  Pointer to cache to use
 
181
      file   File to write cache to upon destruction
 
182
      flags  Flags for the cache
 
183
 
 
184
    DESCRIPTION
 
185
 
 
186
      Class used to guarantee copy of cache to file before exiting the
 
187
      current block.  On successful copy of the cache, the cache will
 
188
      be reinited as a WRITE_CACHE.
 
189
 
 
190
      Currently, a pointer to the cache is provided in the
 
191
      constructor, but it would be possible to create a subclass
 
192
      holding the IO_CACHE itself.
 
193
   */
 
194
  Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
 
195
    : m_cache(cache), m_file(file), m_flags(flags)
 
196
  {
 
197
    reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
 
198
  }
 
199
 
 
200
  ~Write_on_release_cache()
 
201
  {
 
202
    copy_event_cache_to_file_and_reinit(m_cache, m_file);
 
203
    if (m_flags | FLUSH_F)
 
204
      fflush(m_file);
 
205
  }
 
206
 
 
207
  /*
 
208
    Return a pointer to the internal IO_CACHE.
 
209
 
 
210
    SYNOPSIS
 
211
      operator&()
 
212
 
 
213
    DESCRIPTION
 
214
 
 
215
      Function to return a pointer to the internal cache, so that the
 
216
      object can be treated as a IO_CACHE and used with the my_b_*
 
217
      IO_CACHE functions
 
218
 
 
219
    RETURN VALUE
 
220
      A pointer to the internal IO_CACHE.
 
221
   */
 
222
  IO_CACHE *operator&()
 
223
  {
 
224
    return m_cache;
 
225
  }
 
226
 
 
227
private:
 
228
  // Hidden, to prevent usage.
 
229
  Write_on_release_cache(Write_on_release_cache const&);
 
230
 
 
231
  IO_CACHE *m_cache;
 
232
  FILE *m_file;
 
233
  flag_set m_flags;
 
234
};
 
235
 
 
236
#ifndef DBUG_OFF
 
237
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
238
#endif
 
239
 
 
240
/*
 
241
  pretty_print_str()
 
242
*/
 
243
 
 
244
#ifdef MYSQL_CLIENT
 
245
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
 
246
{
 
247
  const char* end = str + len;
 
248
  my_b_printf(cache, "\'");
 
249
  while (str < end)
 
250
  {
 
251
    char c;
 
252
    switch ((c=*str++)) {
 
253
    case '\n': my_b_printf(cache, "\\n"); break;
 
254
    case '\r': my_b_printf(cache, "\\r"); break;
 
255
    case '\\': my_b_printf(cache, "\\\\"); break;
 
256
    case '\b': my_b_printf(cache, "\\b"); break;
 
257
    case '\t': my_b_printf(cache, "\\t"); break;
 
258
    case '\'': my_b_printf(cache, "\\'"); break;
 
259
    case 0   : my_b_printf(cache, "\\0"); break;
 
260
    default:
 
261
      my_b_printf(cache, "%c", c);
 
262
      break;
 
263
    }
 
264
  }
 
265
  my_b_printf(cache, "\'");
 
266
}
 
267
#endif /* MYSQL_CLIENT */
 
268
 
 
269
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
270
 
 
271
static void clear_all_errors(THD *thd, Relay_log_info *rli)
 
272
{
 
273
  thd->is_slave_error = 0;
 
274
  thd->clear_error();
 
275
  rli->clear_error();
 
276
}
 
277
 
 
278
 
 
279
/**
 
280
  Ignore error code specified on command line.
 
281
*/
 
282
 
 
283
inline int ignored_error_code(int err_code)
 
284
{
 
285
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
 
286
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
 
287
}
 
288
#endif
 
289
 
 
290
 
 
291
/*
 
292
  pretty_print_str()
 
293
*/
 
294
 
 
295
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
296
static char *pretty_print_str(char *packet, const char *str, int len)
 
297
{
 
298
  const char *end= str + len;
 
299
  char *pos= packet;
 
300
  *pos++= '\'';
 
301
  while (str < end)
 
302
  {
 
303
    char c;
 
304
    switch ((c=*str++)) {
 
305
    case '\n': *pos++= '\\'; *pos++= 'n'; break;
 
306
    case '\r': *pos++= '\\'; *pos++= 'r'; break;
 
307
    case '\\': *pos++= '\\'; *pos++= '\\'; break;
 
308
    case '\b': *pos++= '\\'; *pos++= 'b'; break;
 
309
    case '\t': *pos++= '\\'; *pos++= 't'; break;
 
310
    case '\'': *pos++= '\\'; *pos++= '\''; break;
 
311
    case 0   : *pos++= '\\'; *pos++= '0'; break;
 
312
    default:
 
313
      *pos++= c;
 
314
      break;
 
315
    }
 
316
  }
 
317
  *pos++= '\'';
 
318
  return pos;
 
319
}
 
320
#endif /* !MYSQL_CLIENT */
 
321
 
 
322
 
 
323
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
324
 
 
325
/**
 
326
  Creates a temporary name for load data infile:.
 
327
 
 
328
  @param buf                  Store new filename here
 
329
  @param file_id              File_id (part of file name)
 
330
  @param event_server_id     Event_id (part of file name)
 
331
  @param ext                  Extension for file name
 
332
 
 
333
  @return
 
334
    Pointer to start of extension
 
335
*/
 
336
 
 
337
static char *slave_load_file_stem(char *buf, uint file_id,
 
338
                                  int event_server_id, const char *ext)
 
339
{
 
340
  char *res;
 
341
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
 
342
  to_unix_path(buf);
 
343
 
 
344
  buf = strend(buf);
 
345
  buf = int10_to_str(::server_id, buf, 10);
 
346
  *buf++ = '-';
 
347
  buf = int10_to_str(event_server_id, buf, 10);
 
348
  *buf++ = '-';
 
349
  res= int10_to_str(file_id, buf, 10);
 
350
  strmov(res, ext);                             // Add extension last
 
351
  return res;                                   // Pointer to extension
 
352
}
 
353
#endif
 
354
 
 
355
 
 
356
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
357
 
 
358
/**
 
359
  Delete all temporary files used for SQL_LOAD.
 
360
*/
 
361
 
 
362
static void cleanup_load_tmpdir()
 
363
{
 
364
  MY_DIR *dirp;
 
365
  FILEINFO *file;
 
366
  uint i;
 
367
  char fname[FN_REFLEN], prefbuf[31], *p;
 
368
 
 
369
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
 
370
    return;
 
371
 
 
372
  /* 
 
373
     When we are deleting temporary files, we should only remove
 
374
     the files associated with the server id of our server.
 
375
     We don't use event_server_id here because since we've disabled
 
376
     direct binlogging of Create_file/Append_file/Exec_load events
 
377
     we cannot meet Start_log event in the middle of events from one 
 
378
     LOAD DATA.
 
379
  */
 
380
  p= strmake(prefbuf, STRING_WITH_LEN("SQL_LOAD-"));
 
381
  p= int10_to_str(::server_id, p, 10);
 
382
  *(p++)= '-';
 
383
  *p= 0;
 
384
 
 
385
  for (i=0 ; i < (uint)dirp->number_off_files; i++)
 
386
  {
 
387
    file=dirp->dir_entry+i;
 
388
    if (is_prefix(file->name, prefbuf))
 
389
    {
 
390
      fn_format(fname,file->name,slave_load_tmpdir,"",MY_UNPACK_FILENAME);
 
391
      my_delete(fname, MYF(0));
 
392
    }
 
393
  }
 
394
 
 
395
  my_dirend(dirp);
 
396
}
 
397
#endif
 
398
 
 
399
 
 
400
/*
 
401
  write_str()
 
402
*/
 
403
 
 
404
static bool write_str(IO_CACHE *file, const char *str, uint length)
 
405
{
 
406
  uchar tmp[1];
 
407
  tmp[0]= (uchar) length;
 
408
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
 
409
          my_b_safe_write(file, (uchar*) str, length));
 
410
}
 
411
 
 
412
 
 
413
/*
 
414
  read_str()
 
415
*/
 
416
 
 
417
static inline int read_str(const char **buf, const char *buf_end,
 
418
                           const char **str, uint8 *len)
 
419
{
 
420
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
 
421
    return 1;
 
422
  *len= (uint8) **buf;
 
423
  *str= (*buf)+1;
 
424
  (*buf)+= (uint) *len+1;
 
425
  return 0;
 
426
}
 
427
 
 
428
 
 
429
/**
 
430
  Transforms a string into "" or its expression in 0x... form.
 
431
*/
 
432
 
 
433
char *str_to_hex(char *to, const char *from, uint len)
 
434
{
 
435
  if (len)
 
436
  {
 
437
    *to++= '0';
 
438
    *to++= 'x';
 
439
    to= octet2hex(to, from, len);
 
440
  }
 
441
  else
 
442
    to= strmov(to, "\"\"");
 
443
  return to;                               // pointer to end 0 of 'to'
 
444
}
 
445
 
 
446
#ifndef MYSQL_CLIENT
 
447
 
 
448
/**
 
449
  Append a version of the 'from' string suitable for use in a query to
 
450
  the 'to' string.  To generate a correct escaping, the character set
 
451
  information in 'csinfo' is used.
 
452
*/
 
453
 
 
454
int
 
455
append_query_string(CHARSET_INFO *csinfo,
 
456
                    String const *from, String *to)
 
457
{
 
458
  char *beg, *ptr;
 
459
  uint32 const orig_len= to->length();
 
460
  if (to->reserve(orig_len + from->length()*2+3))
 
461
    return 1;
 
462
 
 
463
  beg= to->c_ptr_quick() + to->length();
 
464
  ptr= beg;
 
465
  if (csinfo->escape_with_backslash_is_dangerous)
 
466
    ptr= str_to_hex(ptr, from->ptr(), from->length());
 
467
  else
 
468
  {
 
469
    *ptr++= '\'';
 
470
    ptr+= escape_string_for_mysql(csinfo, ptr, 0,
 
471
                                  from->ptr(), from->length());
 
472
    *ptr++='\'';
 
473
  }
 
474
  to->length(orig_len + ptr - beg);
 
475
  return 0;
 
476
}
 
477
#endif
 
478
 
 
479
 
 
480
/**
 
481
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
 
482
  commands just before it prints a query.
 
483
*/
 
484
 
 
485
#ifdef MYSQL_CLIENT
 
486
 
 
487
static void print_set_option(IO_CACHE* file, uint32 bits_changed,
 
488
                             uint32 option, uint32 flags, const char* name,
 
489
                             bool* need_comma)
 
490
{
 
491
  if (bits_changed & option)
 
492
  {
 
493
    if (*need_comma)
 
494
      my_b_printf(file,", ");
 
495
    my_b_printf(file,"%s=%d", name, test(flags & option));
 
496
    *need_comma= 1;
 
497
  }
 
498
}
 
499
#endif
 
500
 
 
501
/**************************************************************************
 
502
        Log_event methods (= the parent class of all events)
 
503
**************************************************************************/
 
504
 
 
505
/**
 
506
  @return
 
507
  returns the human readable name of the event's type
 
508
*/
 
509
 
 
510
const char* Log_event::get_type_str(Log_event_type type)
 
511
{
 
512
  switch(type) {
 
513
  case START_EVENT_V3:  return "Start_v3";
 
514
  case STOP_EVENT:   return "Stop";
 
515
  case QUERY_EVENT:  return "Query";
 
516
  case ROTATE_EVENT: return "Rotate";
 
517
  case INTVAR_EVENT: return "Intvar";
 
518
  case LOAD_EVENT:   return "Load";
 
519
  case NEW_LOAD_EVENT:   return "New_load";
 
520
  case SLAVE_EVENT:  return "Slave";
 
521
  case CREATE_FILE_EVENT: return "Create_file";
 
522
  case APPEND_BLOCK_EVENT: return "Append_block";
 
523
  case DELETE_FILE_EVENT: return "Delete_file";
 
524
  case EXEC_LOAD_EVENT: return "Exec_load";
 
525
  case RAND_EVENT: return "RAND";
 
526
  case XID_EVENT: return "Xid";
 
527
  case USER_VAR_EVENT: return "User var";
 
528
  case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
 
529
  case TABLE_MAP_EVENT: return "Table_map";
 
530
  case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
 
531
  case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
 
532
  case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
 
533
  case WRITE_ROWS_EVENT: return "Write_rows";
 
534
  case UPDATE_ROWS_EVENT: return "Update_rows";
 
535
  case DELETE_ROWS_EVENT: return "Delete_rows";
 
536
  case BEGIN_LOAD_QUERY_EVENT: return "Begin_load_query";
 
537
  case EXECUTE_LOAD_QUERY_EVENT: return "Execute_load_query";
 
538
  case INCIDENT_EVENT: return "Incident";
 
539
  default: return "Unknown";                            /* impossible */
 
540
  }
 
541
}
 
542
 
 
543
const char* Log_event::get_type_str()
 
544
{
 
545
  return get_type_str(get_type_code());
 
546
}
 
547
 
 
548
 
 
549
/*
 
550
  Log_event::Log_event()
 
551
*/
 
552
 
 
553
#ifndef MYSQL_CLIENT
 
554
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
 
555
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
 
556
{
 
557
  server_id=    thd->server_id;
 
558
  when=         thd->start_time;
 
559
  cache_stmt=   using_trans;
 
560
}
 
561
 
 
562
 
 
563
/**
 
564
  This minimal constructor is for when you are not even sure that there
 
565
  is a valid THD. For example in the server when we are shutting down or
 
566
  flushing logs after receiving a SIGHUP (then we must write a Rotate to
 
567
  the binlog but we have no THD, so we need this minimal constructor).
 
568
*/
 
569
 
 
570
Log_event::Log_event()
 
571
  :temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
 
572
   thd(0)
 
573
{
 
574
  server_id=    ::server_id;
 
575
  /*
 
576
    We can't call my_time() here as this would cause a call before
 
577
    my_init() is called
 
578
  */
 
579
  when=         0;
 
580
  log_pos=      0;
 
581
}
 
582
#endif /* !MYSQL_CLIENT */
 
583
 
 
584
 
 
585
/*
 
586
  Log_event::Log_event()
 
587
*/
 
588
 
 
589
Log_event::Log_event(const char* buf,
 
590
                     const Format_description_log_event* description_event)
 
591
  :temp_buf(0), cache_stmt(0)
 
592
{
 
593
#ifndef MYSQL_CLIENT
 
594
  thd = 0;
 
595
#endif
 
596
  when = uint4korr(buf);
 
597
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
 
598
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
 
599
  if (description_event->binlog_version==1)
 
600
  {
 
601
    log_pos= 0;
 
602
    flags= 0;
 
603
    return;
 
604
  }
 
605
  /* 4.0 or newer */
 
606
  log_pos= uint4korr(buf + LOG_POS_OFFSET);
 
607
  /*
 
608
    If the log is 4.0 (so here it can only be a 4.0 relay log read by
 
609
    the SQL thread or a 4.0 master binlog read by the I/O thread),
 
610
    log_pos is the beginning of the event: we transform it into the end
 
611
    of the event, which is more useful.
 
612
    But how do you know that the log is 4.0: you know it if
 
613
    description_event is version 3 *and* you are not reading a
 
614
    Format_desc (remember that mysqlbinlog starts by assuming that 5.0
 
615
    logs are in 4.0 format, until it finds a Format_desc).
 
616
  */
 
617
  if (description_event->binlog_version==3 &&
 
618
      buf[EVENT_TYPE_OFFSET]<FORMAT_DESCRIPTION_EVENT && log_pos)
 
619
  {
 
620
      /*
 
621
        If log_pos=0, don't change it. log_pos==0 is a marker to mean
 
622
        "don't change rli->group_master_log_pos" (see
 
623
        inc_group_relay_log_pos()). As it is unreal log_pos, adding the
 
624
        event len's is nonsense. For example, a fake Rotate event should
 
625
        not have its log_pos (which is 0) changed or it will modify
 
626
        Exec_master_log_pos in SHOW SLAVE STATUS, displaying a nonsense
 
627
        value of (a non-zero offset which does not exist in the master's
 
628
        binlog, so which will cause problems if the user uses this value
 
629
        in CHANGE MASTER).
 
630
      */
 
631
    log_pos+= data_written; /* purecov: inspected */
 
632
  }
 
633
  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
 
634
 
 
635
  flags= uint2korr(buf + FLAGS_OFFSET);
 
636
  if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
 
637
      (buf[EVENT_TYPE_OFFSET] == ROTATE_EVENT))
 
638
  {
 
639
    /*
 
640
      These events always have a header which stops here (i.e. their
 
641
      header is FROZEN).
 
642
    */
 
643
    /*
 
644
      Initialization to zero of all other Log_event members as they're
 
645
      not specified. Currently there are no such members; in the future
 
646
      there will be an event UID (but Format_description and Rotate
 
647
      don't need this UID, as they are not propagated through
 
648
      --log-slave-updates (remember the UID is used to not play a query
 
649
      twice when you have two masters which are slaves of a 3rd master).
 
650
      Then we are done.
 
651
    */
 
652
    return;
 
653
  }
 
654
  /* otherwise, go on with reading the header from buf (nothing now) */
 
655
}
 
656
 
 
657
#ifndef MYSQL_CLIENT
 
658
#ifdef HAVE_REPLICATION
 
659
 
 
660
int Log_event::do_update_pos(Relay_log_info *rli)
 
661
{
 
662
  /*
 
663
    rli is null when (as far as I (Guilhem) know) the caller is
 
664
    Load_log_event::do_apply_event *and* that one is called from
 
665
    Execute_load_log_event::do_apply_event.  In this case, we don't
 
666
    do anything here ; Execute_load_log_event::do_apply_event will
 
667
    call Log_event::do_apply_event again later with the proper rli.
 
668
    Strictly speaking, if we were sure that rli is null only in the
 
669
    case discussed above, 'if (rli)' is useless here.  But as we are
 
670
    not 100% sure, keep it for now.
 
671
 
 
672
    Matz: I don't think we will need this check with this refactoring.
 
673
  */
 
674
  if (rli)
 
675
  {
 
676
    /*
 
677
      bug#29309 simulation: resetting the flag to force
 
678
      wrong behaviour of artificial event to update
 
679
      rli->last_master_timestamp for only one time -
 
680
      the first FLUSH LOGS in the test.
 
681
    */
 
682
    DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
 
683
                    if (debug_not_change_ts_if_art_event == 1
 
684
                        && is_artificial_event())
 
685
                    {
 
686
                      debug_not_change_ts_if_art_event= 0;
 
687
                    });
 
688
#ifndef DBUG_OFF
 
689
    rli->stmt_done(log_pos, 
 
690
                   is_artificial_event() &&
 
691
                   debug_not_change_ts_if_art_event > 0 ? 0 : when);
 
692
#else
 
693
    rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
 
694
#endif
 
695
    DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
 
696
                    if (debug_not_change_ts_if_art_event == 0)
 
697
                    {
 
698
                      debug_not_change_ts_if_art_event= 2;
 
699
                    });
 
700
  }
 
701
  return 0;                                   // Cannot fail currently
 
702
}
 
703
 
 
704
 
 
705
Log_event::enum_skip_reason
 
706
Log_event::do_shall_skip(Relay_log_info *rli)
 
707
{
 
708
  DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
 
709
                      " rli->replicate_same_server_id=%d,"
 
710
                      " rli->slave_skip_counter=%d",
 
711
                      (ulong) server_id, (ulong) ::server_id,
 
712
                      rli->replicate_same_server_id,
 
713
                      rli->slave_skip_counter));
 
714
  if ((server_id == ::server_id && !rli->replicate_same_server_id) || (rli->slave_skip_counter == 1 && rli->is_in_group()))
 
715
    return EVENT_SKIP_IGNORE;
 
716
  else if (rli->slave_skip_counter > 0)
 
717
    return EVENT_SKIP_COUNT;
 
718
  else
 
719
    return EVENT_SKIP_NOT;
 
720
}
 
721
 
 
722
 
 
723
/*
 
724
  Log_event::pack_info()
 
725
*/
 
726
 
 
727
void Log_event::pack_info(Protocol *protocol)
 
728
{
 
729
  protocol->store("", &my_charset_bin);
 
730
}
 
731
 
 
732
 
 
733
/**
 
734
  Only called by SHOW BINLOG EVENTS
 
735
*/
 
736
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
 
737
{
 
738
  const char *p= strrchr(log_name, FN_LIBCHAR);
 
739
  const char *event_type;
 
740
  if (p)
 
741
    log_name = p + 1;
 
742
 
 
743
  protocol->prepare_for_resend();
 
744
  protocol->store(log_name, &my_charset_bin);
 
745
  protocol->store((ulonglong) pos);
 
746
  event_type = get_type_str();
 
747
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
 
748
  protocol->store((uint32) server_id);
 
749
  protocol->store((ulonglong) log_pos);
 
750
  pack_info(protocol);
 
751
  return protocol->write();
 
752
}
 
753
#endif /* HAVE_REPLICATION */
 
754
 
 
755
 
 
756
/**
 
757
  init_show_field_list() prepares the column names and types for the
 
758
  output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
 
759
  EVENTS.
 
760
*/
 
761
 
 
762
void Log_event::init_show_field_list(List<Item>* field_list)
 
763
{
 
764
  field_list->push_back(new Item_empty_string("Log_name", 20));
 
765
  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
 
766
                                            MYSQL_TYPE_LONGLONG));
 
767
  field_list->push_back(new Item_empty_string("Event_type", 20));
 
768
  field_list->push_back(new Item_return_int("Server_id", 10,
 
769
                                            MYSQL_TYPE_LONG));
 
770
  field_list->push_back(new Item_return_int("End_log_pos",
 
771
                                            MY_INT32_NUM_DECIMAL_DIGITS,
 
772
                                            MYSQL_TYPE_LONGLONG));
 
773
  field_list->push_back(new Item_empty_string("Info", 20));
 
774
}
 
775
 
 
776
 
 
777
/*
 
778
  Log_event::write()
 
779
*/
 
780
 
 
781
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
 
782
{
 
783
  uchar header[LOG_EVENT_HEADER_LEN];
 
784
  ulong now;
 
785
  DBUG_ENTER("Log_event::write_header");
 
786
 
 
787
  /* Store number of bytes that will be written by this event */
 
788
  data_written= event_data_length + sizeof(header);
 
789
 
 
790
  /*
 
791
    log_pos != 0 if this is relay-log event. In this case we should not
 
792
    change the position
 
793
  */
 
794
 
 
795
  if (is_artificial_event())
 
796
  {
 
797
    /*
 
798
      We should not do any cleanup on slave when reading this. We
 
799
      mark this by setting log_pos to 0.  Start_log_event_v3() will
 
800
      detect this on reading and set artificial_event=1 for the event.
 
801
    */
 
802
    log_pos= 0;
 
803
  }
 
804
  else  if (!log_pos)
 
805
  {
 
806
    /*
 
807
      Calculate position of end of event
 
808
 
 
809
      Note that with a SEQ_READ_APPEND cache, my_b_tell() does not
 
810
      work well.  So this will give slightly wrong positions for the
 
811
      Format_desc/Rotate/Stop events which the slave writes to its
 
812
      relay log. For example, the initial Format_desc will have
 
813
      end_log_pos=91 instead of 95. Because after writing the first 4
 
814
      bytes of the relay log, my_b_tell() still reports 0. Because
 
815
      my_b_append() does not update the counter which my_b_tell()
 
816
      later uses (one should probably use my_b_append_tell() to work
 
817
      around this).  To get right positions even when writing to the
 
818
      relay log, we use the (new) my_b_safe_tell().
 
819
 
 
820
      Note that this raises a question on the correctness of all these
 
821
      DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
 
822
 
 
823
      If in a transaction, the log_pos which we calculate below is not
 
824
      very good (because then my_b_safe_tell() returns start position
 
825
      of the BEGIN, so it's like the statement was at the BEGIN's
 
826
      place), but it's not a very serious problem (as the slave, when
 
827
      it is in a transaction, does not take those end_log_pos into
 
828
      account (as it calls inc_event_relay_log_pos()). To be fixed
 
829
      later, so that it looks less strange. But not bug.
 
830
    */
 
831
 
 
832
    log_pos= my_b_safe_tell(file)+data_written;
 
833
  }
 
834
 
 
835
  now= (ulong) get_time();                              // Query start time
 
836
 
 
837
  /*
 
838
    Header will be of size LOG_EVENT_HEADER_LEN for all events, except for
 
839
    FORMAT_DESCRIPTION_EVENT and ROTATE_EVENT, where it will be
 
840
    LOG_EVENT_MINIMAL_HEADER_LEN (remember these 2 have a frozen header,
 
841
    because we read them before knowing the format).
 
842
  */
 
843
 
 
844
  int4store(header, now);              // timestamp
 
845
  header[EVENT_TYPE_OFFSET]= get_type_code();
 
846
  int4store(header+ SERVER_ID_OFFSET, server_id);
 
847
  int4store(header+ EVENT_LEN_OFFSET, data_written);
 
848
  int4store(header+ LOG_POS_OFFSET, log_pos);
 
849
  int2store(header+ FLAGS_OFFSET, flags);
 
850
 
 
851
  DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0);
 
852
}
 
853
 
 
854
 
 
855
/**
 
856
  This needn't be format-tolerant, because we only read
 
857
  LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
 
858
*/
 
859
 
 
860
int Log_event::read_log_event(IO_CACHE* file, String* packet,
 
861
                              pthread_mutex_t* log_lock)
 
862
{
 
863
  ulong data_len;
 
864
  int result=0;
 
865
  char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
 
866
  DBUG_ENTER("Log_event::read_log_event");
 
867
 
 
868
  if (log_lock)
 
869
    pthread_mutex_lock(log_lock);
 
870
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
 
871
  {
 
872
    /*
 
873
      If the read hits eof, we must report it as eof so the caller
 
874
      will know it can go into cond_wait to be woken up on the next
 
875
      update to the log.
 
876
    */
 
877
    DBUG_PRINT("error",("file->error: %d", file->error));
 
878
    if (!file->error)
 
879
      result= LOG_READ_EOF;
 
880
    else
 
881
      result= (file->error > 0 ? LOG_READ_TRUNC : LOG_READ_IO);
 
882
    goto end;
 
883
  }
 
884
  data_len= uint4korr(buf + EVENT_LEN_OFFSET);
 
885
  if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
 
886
      data_len > current_thd->variables.max_allowed_packet)
 
887
  {
 
888
    DBUG_PRINT("error",("data_len: %ld", data_len));
 
889
    result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
 
890
             LOG_READ_TOO_LARGE);
 
891
    goto end;
 
892
  }
 
893
 
 
894
  /* Append the log event header to packet */
 
895
  if (packet->append(buf, sizeof(buf)))
 
896
  {
 
897
    /* Failed to allocate packet */
 
898
    result= LOG_READ_MEM;
 
899
    goto end;
 
900
  }
 
901
  data_len-= LOG_EVENT_MINIMAL_HEADER_LEN;
 
902
  if (data_len)
 
903
  {
 
904
    /* Append rest of event, read directly from file into packet */
 
905
    if (packet->append(file, data_len))
 
906
    {
 
907
      /*
 
908
        Fatal error occured when appending rest of the event
 
909
        to packet, possible failures:
 
910
        1. EOF occured when reading from file, it's really an error
 
911
           as data_len is >=0 there's supposed to be more bytes available.
 
912
           file->error will have been set to number of bytes left to read
 
913
        2. Read was interrupted, file->error would normally be set to -1
 
914
        3. Failed to allocate memory for packet, my_errno
 
915
           will be ENOMEM(file->error shuold be 0, but since the
 
916
           memory allocation occurs before the call to read it might
 
917
           be uninitialized)
 
918
      */
 
919
      result= (my_errno == ENOMEM ? LOG_READ_MEM :
 
920
               (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO));
 
921
      /* Implicit goto end; */
 
922
    }
 
923
  }
 
924
 
 
925
end:
 
926
  if (log_lock)
 
927
    pthread_mutex_unlock(log_lock);
 
928
  DBUG_RETURN(result);
 
929
}
 
930
#endif /* !MYSQL_CLIENT */
 
931
 
 
932
#ifndef MYSQL_CLIENT
 
933
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
 
934
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
 
935
#else
 
936
#define UNLOCK_MUTEX
 
937
#define LOCK_MUTEX
 
938
#endif
 
939
 
 
940
#ifndef MYSQL_CLIENT
 
941
/**
 
942
  @note
 
943
    Allocates memory;  The caller is responsible for clean-up.
 
944
*/
 
945
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
946
                                     pthread_mutex_t* log_lock,
 
947
                                     const Format_description_log_event
 
948
                                     *description_event)
 
949
#else
 
950
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
951
                                     const Format_description_log_event
 
952
                                     *description_event)
 
953
#endif
 
954
{
 
955
  DBUG_ENTER("Log_event::read_log_event");
 
956
  DBUG_ASSERT(description_event != 0);
 
957
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
 
958
  /*
 
959
    First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
 
960
    check the event for sanity and to know its length; no need to really parse
 
961
    it. We say "at most" because this could be a 3.23 master, which has header
 
962
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
 
963
    "minimal" over the set {MySQL >=4.0}).
 
964
  */
 
965
  uint header_size= min(description_event->common_header_len,
 
966
                        LOG_EVENT_MINIMAL_HEADER_LEN);
 
967
 
 
968
  LOCK_MUTEX;
 
969
  DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
 
970
  if (my_b_read(file, (uchar *) head, header_size))
 
971
  {
 
972
    DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
 
973
failed my_b_read"));
 
974
    UNLOCK_MUTEX;
 
975
    /*
 
976
      No error here; it could be that we are at the file's end. However
 
977
      if the next my_b_read() fails (below), it will be an error as we
 
978
      were able to read the first bytes.
 
979
    */
 
980
    DBUG_RETURN(0);
 
981
  }
 
982
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
983
  char *buf= 0;
 
984
  const char *error= 0;
 
985
  Log_event *res=  0;
 
986
#ifndef max_allowed_packet
 
987
  THD *thd=current_thd;
 
988
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
 
989
#endif
 
990
 
 
991
  if (data_len > max_allowed_packet)
 
992
  {
 
993
    error = "Event too big";
 
994
    goto err;
 
995
  }
 
996
 
 
997
  if (data_len < header_size)
 
998
  {
 
999
    error = "Event too small";
 
1000
    goto err;
 
1001
  }
 
1002
 
 
1003
  // some events use the extra byte to null-terminate strings
 
1004
  if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
 
1005
  {
 
1006
    error = "Out of memory";
 
1007
    goto err;
 
1008
  }
 
1009
  buf[data_len] = 0;
 
1010
  memcpy(buf, head, header_size);
 
1011
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
 
1012
  {
 
1013
    error = "read error";
 
1014
    goto err;
 
1015
  }
 
1016
  if ((res= read_log_event(buf, data_len, &error, description_event)))
 
1017
    res->register_temp_buf(buf);
 
1018
 
 
1019
err:
 
1020
  UNLOCK_MUTEX;
 
1021
  if (!res)
 
1022
  {
 
1023
    DBUG_ASSERT(error != 0);
 
1024
    sql_print_error("Error in Log_event::read_log_event(): "
 
1025
                    "'%s', data_len: %d, event_type: %d",
 
1026
                    error,data_len,head[EVENT_TYPE_OFFSET]);
 
1027
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
1028
    /*
 
1029
      The SQL slave thread will check if file->error<0 to know
 
1030
      if there was an I/O error. Even if there is no "low-level" I/O errors
 
1031
      with 'file', any of the high-level above errors is worrying
 
1032
      enough to stop the SQL thread now ; as we are skipping the current event,
 
1033
      going on with reading and successfully executing other events can
 
1034
      only corrupt the slave's databases. So stop.
 
1035
    */
 
1036
    file->error= -1;
 
1037
  }
 
1038
  DBUG_RETURN(res);
 
1039
}
 
1040
 
 
1041
 
 
1042
/**
 
1043
  Binlog format tolerance is in (buf, event_len, description_event)
 
1044
  constructors.
 
1045
*/
 
1046
 
 
1047
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
 
1048
                                     const char **error,
 
1049
                                     const Format_description_log_event *description_event)
 
1050
{
 
1051
  Log_event* ev;
 
1052
  DBUG_ENTER("Log_event::read_log_event(char*,...)");
 
1053
  DBUG_ASSERT(description_event != 0);
 
1054
  DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
 
1055
  DBUG_DUMP("data", (unsigned char*) buf, event_len);
 
1056
 
 
1057
  /* Check the integrity */
 
1058
  if (event_len < EVENT_LEN_OFFSET ||
 
1059
      buf[EVENT_TYPE_OFFSET] >= ENUM_END_EVENT ||
 
1060
      (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
 
1061
  {
 
1062
    *error="Sanity check failed";               // Needed to free buffer
 
1063
    DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
 
1064
  }
 
1065
 
 
1066
  uint event_type= buf[EVENT_TYPE_OFFSET];
 
1067
  if (event_type > description_event->number_of_event_types &&
 
1068
      event_type != FORMAT_DESCRIPTION_EVENT)
 
1069
  {
 
1070
    /*
 
1071
      It is unsafe to use the description_event if its post_header_len
 
1072
      array does not include the event type.
 
1073
    */
 
1074
    DBUG_PRINT("error", ("event type %d found, but the current "
 
1075
                         "Format_description_log_event supports only %d event "
 
1076
                         "types", event_type,
 
1077
                         description_event->number_of_event_types));
 
1078
    ev= NULL;
 
1079
  }
 
1080
  else
 
1081
  {
 
1082
    /*
 
1083
      In some previuos versions (see comment in
 
1084
      Format_description_log_event::Format_description_log_event(char*,...)),
 
1085
      event types were assigned different id numbers than in the
 
1086
      present version. In order to replicate from such versions to the
 
1087
      present version, we must map those event type id's to our event
 
1088
      type id's.  The mapping is done with the event_type_permutation
 
1089
      array, which was set up when the Format_description_log_event
 
1090
      was read.
 
1091
    */
 
1092
    if (description_event->event_type_permutation)
 
1093
    {
 
1094
      IF_DBUG({
 
1095
          int new_event_type=
 
1096
            description_event->event_type_permutation[event_type];
 
1097
          DBUG_PRINT("info",
 
1098
                     ("converting event type %d to %d (%s)",
 
1099
                      event_type, new_event_type,
 
1100
                      get_type_str((Log_event_type)new_event_type)));
 
1101
        });
 
1102
      event_type= description_event->event_type_permutation[event_type];
 
1103
    }
 
1104
 
 
1105
    switch(event_type) {
 
1106
    case QUERY_EVENT:
 
1107
      ev  = new Query_log_event(buf, event_len, description_event, QUERY_EVENT);
 
1108
      break;
 
1109
    case LOAD_EVENT:
 
1110
      ev = new Load_log_event(buf, event_len, description_event);
 
1111
      break;
 
1112
    case NEW_LOAD_EVENT:
 
1113
      ev = new Load_log_event(buf, event_len, description_event);
 
1114
      break;
 
1115
    case ROTATE_EVENT:
 
1116
      ev = new Rotate_log_event(buf, event_len, description_event);
 
1117
      break;
 
1118
#ifdef HAVE_REPLICATION
 
1119
    case SLAVE_EVENT: /* can never happen (unused event) */
 
1120
      ev = new Slave_log_event(buf, event_len);
 
1121
      break;
 
1122
#endif /* HAVE_REPLICATION */
 
1123
    case CREATE_FILE_EVENT:
 
1124
      ev = new Create_file_log_event(buf, event_len, description_event);
 
1125
      break;
 
1126
    case APPEND_BLOCK_EVENT:
 
1127
      ev = new Append_block_log_event(buf, event_len, description_event);
 
1128
      break;
 
1129
    case DELETE_FILE_EVENT:
 
1130
      ev = new Delete_file_log_event(buf, event_len, description_event);
 
1131
      break;
 
1132
    case EXEC_LOAD_EVENT:
 
1133
      ev = new Execute_load_log_event(buf, event_len, description_event);
 
1134
      break;
 
1135
    case START_EVENT_V3: /* this is sent only by MySQL <=4.x */
 
1136
      ev = new Start_log_event_v3(buf, description_event);
 
1137
      break;
 
1138
    case STOP_EVENT:
 
1139
      ev = new Stop_log_event(buf, description_event);
 
1140
      break;
 
1141
    case INTVAR_EVENT:
 
1142
      ev = new Intvar_log_event(buf, description_event);
 
1143
      break;
 
1144
    case XID_EVENT:
 
1145
      ev = new Xid_log_event(buf, description_event);
 
1146
      break;
 
1147
    case RAND_EVENT:
 
1148
      ev = new Rand_log_event(buf, description_event);
 
1149
      break;
 
1150
    case USER_VAR_EVENT:
 
1151
      ev = new User_var_log_event(buf, description_event);
 
1152
      break;
 
1153
    case FORMAT_DESCRIPTION_EVENT:
 
1154
      ev = new Format_description_log_event(buf, event_len, description_event);
 
1155
      break;
 
1156
#if defined(HAVE_REPLICATION) 
 
1157
    case WRITE_ROWS_EVENT:
 
1158
      ev = new Write_rows_log_event(buf, event_len, description_event);
 
1159
      break;
 
1160
    case UPDATE_ROWS_EVENT:
 
1161
      ev = new Update_rows_log_event(buf, event_len, description_event);
 
1162
      break;
 
1163
    case DELETE_ROWS_EVENT:
 
1164
      ev = new Delete_rows_log_event(buf, event_len, description_event);
 
1165
      break;
 
1166
    case TABLE_MAP_EVENT:
 
1167
      ev = new Table_map_log_event(buf, event_len, description_event);
 
1168
      break;
 
1169
#endif
 
1170
    case BEGIN_LOAD_QUERY_EVENT:
 
1171
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
 
1172
      break;
 
1173
    case EXECUTE_LOAD_QUERY_EVENT:
 
1174
      ev= new Execute_load_query_log_event(buf, event_len, description_event);
 
1175
      break;
 
1176
    case INCIDENT_EVENT:
 
1177
      ev = new Incident_log_event(buf, event_len, description_event);
 
1178
      break;
 
1179
    default:
 
1180
      DBUG_PRINT("error",("Unknown event code: %d",
 
1181
                          (int) buf[EVENT_TYPE_OFFSET]));
 
1182
      ev= NULL;
 
1183
      break;
 
1184
    }
 
1185
  }
 
1186
 
 
1187
  DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
 
1188
                            ev ? ev->get_type_str() : "<unknown>",
 
1189
                            buf[EVENT_TYPE_OFFSET],
 
1190
                            event_len));
 
1191
  /*
 
1192
    is_valid() are small event-specific sanity tests which are
 
1193
    important; for example there are some my_malloc() in constructors
 
1194
    (e.g. Query_log_event::Query_log_event(char*...)); when these
 
1195
    my_malloc() fail we can't return an error out of the constructor
 
1196
    (because constructor is "void") ; so instead we leave the pointer we
 
1197
    wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
 
1198
    Same for Format_description_log_event, member 'post_header_len'.
 
1199
  */
 
1200
  if (!ev || !ev->is_valid())
 
1201
  {
 
1202
    DBUG_PRINT("error",("Found invalid event in binary log"));
 
1203
 
 
1204
    delete ev;
 
1205
#ifdef MYSQL_CLIENT
 
1206
    if (!force_opt) /* then mysqlbinlog dies */
 
1207
    {
 
1208
      *error= "Found invalid event in binary log";
 
1209
      DBUG_RETURN(0);
 
1210
    }
 
1211
    ev= new Unknown_log_event(buf, description_event);
 
1212
#else
 
1213
    *error= "Found invalid event in binary log";
 
1214
    DBUG_RETURN(0);
 
1215
#endif
 
1216
  }
 
1217
  DBUG_RETURN(ev);  
 
1218
}
 
1219
 
 
1220
#ifdef MYSQL_CLIENT
 
1221
 
 
1222
/*
 
1223
  Log_event::print_header()
 
1224
*/
 
1225
 
 
1226
void Log_event::print_header(IO_CACHE* file,
 
1227
                             PRINT_EVENT_INFO* print_event_info,
 
1228
                             bool is_more __attribute__((unused)))
 
1229
{
 
1230
  char llbuff[22];
 
1231
  my_off_t hexdump_from= print_event_info->hexdump_from;
 
1232
  DBUG_ENTER("Log_event::print_header");
 
1233
 
 
1234
  my_b_printf(file, "#");
 
1235
  print_timestamp(file);
 
1236
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
 
1237
              llstr(log_pos,llbuff));
 
1238
 
 
1239
  /* mysqlbinlog --hexdump */
 
1240
  if (print_event_info->hexdump_from)
 
1241
  {
 
1242
    my_b_printf(file, "\n");
 
1243
    uchar *ptr= (uchar*)temp_buf;
 
1244
    my_off_t size=
 
1245
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
 
1246
    my_off_t i;
 
1247
 
 
1248
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
 
1249
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
 
1250
    char *c, char_string[16+1]= {0};
 
1251
 
 
1252
    /* Pretty-print event common header if header is exactly 19 bytes */
 
1253
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
 
1254
    {
 
1255
      char emit_buf[256];               // Enough for storing one line
 
1256
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
 
1257
                  "Size      Master Pos    Flags \n");
 
1258
      int const bytes_written=
 
1259
        my_snprintf(emit_buf, sizeof(emit_buf),
 
1260
                    "# %8.8lx %02x %02x %02x %02x   %02x   "
 
1261
                    "%02x %02x %02x %02x   %02x %02x %02x %02x   "
 
1262
                    "%02x %02x %02x %02x   %02x %02x\n",
 
1263
                    (unsigned long) hexdump_from,
 
1264
                    ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
 
1265
                    ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
 
1266
                    ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
 
1267
      DBUG_ASSERT(bytes_written >= 0);
 
1268
      DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1269
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1270
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1271
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1272
    }
 
1273
 
 
1274
    /* Rest of event (without common header) */
 
1275
    for (i= 0, c= char_string, h=hex_string;
 
1276
         i < size;
 
1277
         i++, ptr++)
 
1278
    {
 
1279
      my_snprintf(h, 4, "%02x ", *ptr);
 
1280
      h += 3;
 
1281
 
 
1282
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
 
1283
 
 
1284
      if (i % 16 == 15)
 
1285
      {
 
1286
        /*
 
1287
          my_b_printf() does not support full printf() formats, so we
 
1288
          have to do it this way.
 
1289
 
 
1290
          TODO: Rewrite my_b_printf() to support full printf() syntax.
 
1291
         */
 
1292
        char emit_buf[256];
 
1293
        int const bytes_written=
 
1294
          my_snprintf(emit_buf, sizeof(emit_buf),
 
1295
                      "# %8.8lx %-48.48s |%16s|\n",
 
1296
                      (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1297
                      hex_string, char_string);
 
1298
        DBUG_ASSERT(bytes_written >= 0);
 
1299
        DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1300
        my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1301
        hex_string[0]= 0;
 
1302
        char_string[0]= 0;
 
1303
        c= char_string;
 
1304
        h= hex_string;
 
1305
      }
 
1306
      else if (i % 8 == 7) *h++ = ' ';
 
1307
    }
 
1308
    *c= '\0';
 
1309
 
 
1310
    if (hex_string[0])
 
1311
    {
 
1312
      char emit_buf[256];
 
1313
      int const bytes_written=
 
1314
        my_snprintf(emit_buf, sizeof(emit_buf),
 
1315
                    "# %8.8lx %-48.48s |%s|\n",
 
1316
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1317
                    hex_string, char_string);
 
1318
      DBUG_ASSERT(bytes_written >= 0);
 
1319
      DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1320
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1321
    }
 
1322
    /*
 
1323
      need a # to prefix the rest of printouts for example those of
 
1324
      Rows_log_event::print_helper().
 
1325
    */
 
1326
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
 
1327
  }
 
1328
  DBUG_VOID_RETURN;
 
1329
}
 
1330
 
 
1331
 
 
1332
void Log_event::print_base64(IO_CACHE* file,
 
1333
                             PRINT_EVENT_INFO* print_event_info,
 
1334
                             bool more)
 
1335
{
 
1336
  const uchar *ptr= (const uchar *)temp_buf;
 
1337
  uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
 
1338
  DBUG_ENTER("Log_event::print_base64");
 
1339
 
 
1340
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
 
1341
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
 
1342
  if (!tmp_str) {
 
1343
    fprintf(stderr, "\nError: Out of memory. "
 
1344
            "Could not print correct binlog event.\n");
 
1345
    DBUG_VOID_RETURN;
 
1346
  }
 
1347
 
 
1348
  if (base64_encode(ptr, (size_t) size, tmp_str))
 
1349
  {
 
1350
    DBUG_ASSERT(0);
 
1351
  }
 
1352
 
 
1353
  if (my_b_tell(file) == 0)
 
1354
    my_b_printf(file, "\nBINLOG '\n");
 
1355
 
 
1356
  my_b_printf(file, "%s\n", tmp_str);
 
1357
 
 
1358
  if (!more)
 
1359
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
 
1360
 
 
1361
  my_free(tmp_str, MYF(0));
 
1362
  DBUG_VOID_RETURN;
 
1363
}
 
1364
 
 
1365
 
 
1366
/*
 
1367
  Log_event::print_timestamp()
 
1368
*/
 
1369
 
 
1370
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
 
1371
{
 
1372
  struct tm *res;
 
1373
  DBUG_ENTER("Log_event::print_timestamp");
 
1374
  if (!ts)
 
1375
    ts = &when;
 
1376
#ifdef MYSQL_SERVER                             // This is always false
 
1377
  struct tm tm_tmp;
 
1378
  localtime_r(ts,(res= &tm_tmp));
 
1379
#else
 
1380
  res=localtime(ts);
 
1381
#endif
 
1382
 
 
1383
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
 
1384
              res->tm_year % 100,
 
1385
              res->tm_mon+1,
 
1386
              res->tm_mday,
 
1387
              res->tm_hour,
 
1388
              res->tm_min,
 
1389
              res->tm_sec);
 
1390
  DBUG_VOID_RETURN;
 
1391
}
 
1392
 
 
1393
#endif /* MYSQL_CLIENT */
 
1394
 
 
1395
 
 
1396
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
1397
inline Log_event::enum_skip_reason
 
1398
Log_event::continue_group(Relay_log_info *rli)
 
1399
{
 
1400
  if (rli->slave_skip_counter == 1)
 
1401
    return Log_event::EVENT_SKIP_IGNORE;
 
1402
  return Log_event::do_shall_skip(rli);
 
1403
}
 
1404
#endif
 
1405
 
 
1406
/**************************************************************************
 
1407
        Query_log_event methods
 
1408
**************************************************************************/
 
1409
 
 
1410
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
1411
 
 
1412
/**
 
1413
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
 
1414
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
 
1415
  only an information, it does not produce suitable queries to replay (for
 
1416
  example it does not print LOAD DATA INFILE).
 
1417
  @todo
 
1418
    show the catalog ??
 
1419
*/
 
1420
 
 
1421
void Query_log_event::pack_info(Protocol *protocol)
 
1422
{
 
1423
  // TODO: show the catalog ??
 
1424
  char *buf, *pos;
 
1425
  if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
 
1426
    return;
 
1427
  pos= buf;
 
1428
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
 
1429
      && db && db_len)
 
1430
  {
 
1431
    pos= strmov(buf, "use `");
 
1432
    memcpy(pos, db, db_len);
 
1433
    pos= strmov(pos+db_len, "`; ");
 
1434
  }
 
1435
  if (query && q_len)
 
1436
  {
 
1437
    memcpy(pos, query, q_len);
 
1438
    pos+= q_len;
 
1439
  }
 
1440
  protocol->store(buf, pos-buf, &my_charset_bin);
 
1441
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
1442
}
 
1443
#endif
 
1444
 
 
1445
#ifndef MYSQL_CLIENT
 
1446
 
 
1447
/**
 
1448
  Utility function for the next method (Query_log_event::write()) .
 
1449
*/
 
1450
static void write_str_with_code_and_len(char **dst, const char *src,
 
1451
                                        int len, uint code)
 
1452
{
 
1453
  DBUG_ASSERT(src);
 
1454
  *((*dst)++)= code;
 
1455
  *((*dst)++)= (uchar) len;
 
1456
  bmove(*dst, src, len);
 
1457
  (*dst)+= len;
 
1458
}
 
1459
 
 
1460
 
 
1461
/**
 
1462
  Query_log_event::write().
 
1463
 
 
1464
  @note
 
1465
    In this event we have to modify the header to have the correct
 
1466
    EVENT_LEN_OFFSET as we don't yet know how many status variables we
 
1467
    will print!
 
1468
*/
 
1469
 
 
1470
bool Query_log_event::write(IO_CACHE* file)
 
1471
{
 
1472
  /**
 
1473
    @todo if catalog can be of length FN_REFLEN==512, then we are not
 
1474
    replicating it correctly, since the length is stored in a byte
 
1475
    /sven
 
1476
  */
 
1477
  uchar buf[QUERY_HEADER_LEN+
 
1478
            1+4+           // code of flags2 and flags2
 
1479
            1+8+           // code of sql_mode and sql_mode
 
1480
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
 
1481
            1+4+           // code of autoinc and the 2 autoinc variables
 
1482
            1+6+           // code of charset and charset
 
1483
            1+1+MAX_TIME_ZONE_NAME_LENGTH+ // code of tz and tz length and tz name
 
1484
            1+2+           // code of lc_time_names and lc_time_names_number
 
1485
            1+2            // code of charset_database and charset_database_number
 
1486
            ], *start, *start_of_status;
 
1487
  ulong event_length;
 
1488
 
 
1489
  if (!query)
 
1490
    return 1;                                   // Something wrong with event
 
1491
 
 
1492
  /*
 
1493
    We want to store the thread id:
 
1494
    (- as an information for the user when he reads the binlog)
 
1495
    - if the query uses temporary table: for the slave SQL thread to know to
 
1496
    which master connection the temp table belongs.
 
1497
    Now imagine we (write()) are called by the slave SQL thread (we are
 
1498
    logging a query executed by this thread; the slave runs with
 
1499
    --log-slave-updates). Then this query will be logged with
 
1500
    thread_id=the_thread_id_of_the_SQL_thread. Imagine that 2 temp tables of
 
1501
    the same name were created simultaneously on the master (in the master
 
1502
    binlog you have
 
1503
    CREATE TEMPORARY TABLE t; (thread 1)
 
1504
    CREATE TEMPORARY TABLE t; (thread 2)
 
1505
    ...)
 
1506
    then in the slave's binlog there will be
 
1507
    CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
 
1508
    CREATE TEMPORARY TABLE t; (thread_id_of_the_slave_SQL_thread)
 
1509
    which is bad (same thread id!).
 
1510
 
 
1511
    To avoid this, we log the thread's thread id EXCEPT for the SQL
 
1512
    slave thread for which we log the original (master's) thread id.
 
1513
    Now this moves the bug: what happens if the thread id on the
 
1514
    master was 10 and when the slave replicates the query, a
 
1515
    connection number 10 is opened by a normal client on the slave,
 
1516
    and updates a temp table of the same name? We get a problem
 
1517
    again. To avoid this, in the handling of temp tables (sql_base.cc)
 
1518
    we use thread_id AND server_id.  TODO when this is merged into
 
1519
    4.1: in 4.1, slave_proxy_id has been renamed to pseudo_thread_id
 
1520
    and is a session variable: that's to make mysqlbinlog work with
 
1521
    temp tables. We probably need to introduce
 
1522
 
 
1523
    SET PSEUDO_SERVER_ID
 
1524
    for mysqlbinlog in 4.1. mysqlbinlog would print:
 
1525
    SET PSEUDO_SERVER_ID=
 
1526
    SET PSEUDO_THREAD_ID=
 
1527
    for each query using temp tables.
 
1528
  */
 
1529
  int4store(buf + Q_THREAD_ID_OFFSET, slave_proxy_id);
 
1530
  int4store(buf + Q_EXEC_TIME_OFFSET, exec_time);
 
1531
  buf[Q_DB_LEN_OFFSET] = (char) db_len;
 
1532
  int2store(buf + Q_ERR_CODE_OFFSET, error_code);
 
1533
 
 
1534
  /*
 
1535
    You MUST always write status vars in increasing order of code. This
 
1536
    guarantees that a slightly older slave will be able to parse those he
 
1537
    knows.
 
1538
  */
 
1539
  start_of_status= start= buf+QUERY_HEADER_LEN;
 
1540
  if (flags2_inited)
 
1541
  {
 
1542
    *start++= Q_FLAGS2_CODE;
 
1543
    int4store(start, flags2);
 
1544
    start+= 4;
 
1545
  }
 
1546
  if (sql_mode_inited)
 
1547
  {
 
1548
    *start++= Q_SQL_MODE_CODE;
 
1549
    int8store(start, (ulonglong)sql_mode);
 
1550
    start+= 8;
 
1551
  }
 
1552
  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
 
1553
  {
 
1554
    write_str_with_code_and_len((char **)(&start),
 
1555
                                catalog, catalog_len, Q_CATALOG_NZ_CODE);
 
1556
    /*
 
1557
      In 5.0.x where x<4 masters we used to store the end zero here. This was
 
1558
      a waste of one byte so we don't do it in x>=4 masters. We change code to
 
1559
      Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
 
1560
      of this x>=4 master segfault (expecting a zero when there is
 
1561
      none). Remaining compatibility problems are: the older slave will not
 
1562
      find the catalog; but it is will not crash, and it's not an issue
 
1563
      that it does not find the catalog as catalogs were not used in these
 
1564
      older MySQL versions (we store it in binlog and read it from relay log
 
1565
      but do nothing useful with it). What is an issue is that the older slave
 
1566
      will stop processing the Q_* blocks (and jumps to the db/query) as soon
 
1567
      as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
 
1568
      Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
 
1569
      various ways. Documented that you should not mix alpha/beta versions if
 
1570
      they are not exactly the same version, with example of 5.0.3->5.0.2 and
 
1571
      5.0.4->5.0.3. If replication is from older to new, the new will
 
1572
      recognize Q_CATALOG_CODE and have no problem.
 
1573
    */
 
1574
  }
 
1575
  if (auto_increment_increment != 1 || auto_increment_offset != 1)
 
1576
  {
 
1577
    *start++= Q_AUTO_INCREMENT;
 
1578
    int2store(start, auto_increment_increment);
 
1579
    int2store(start+2, auto_increment_offset);
 
1580
    start+= 4;
 
1581
  }
 
1582
  if (charset_inited)
 
1583
  {
 
1584
    *start++= Q_CHARSET_CODE;
 
1585
    memcpy(start, charset, 6);
 
1586
    start+= 6;
 
1587
  }
 
1588
  if (time_zone_len)
 
1589
  {
 
1590
    /* In the TZ sys table, column Name is of length 64 so this should be ok */
 
1591
    DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
 
1592
    *start++= Q_TIME_ZONE_CODE;
 
1593
    *start++= time_zone_len;
 
1594
    memcpy(start, time_zone_str, time_zone_len);
 
1595
    start+= time_zone_len;
 
1596
  }
 
1597
  if (lc_time_names_number)
 
1598
  {
 
1599
    DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
 
1600
    *start++= Q_LC_TIME_NAMES_CODE;
 
1601
    int2store(start, lc_time_names_number);
 
1602
    start+= 2;
 
1603
  }
 
1604
  if (charset_database_number)
 
1605
  {
 
1606
    DBUG_ASSERT(charset_database_number <= 0xFFFF);
 
1607
    *start++= Q_CHARSET_DATABASE_CODE;
 
1608
    int2store(start, charset_database_number);
 
1609
    start+= 2;
 
1610
  }
 
1611
  /*
 
1612
    Here there could be code like
 
1613
    if (command-line-option-which-says-"log_this_variable" && inited)
 
1614
    {
 
1615
    *start++= Q_THIS_VARIABLE_CODE;
 
1616
    int4store(start, this_variable);
 
1617
    start+= 4;
 
1618
    }
 
1619
  */
 
1620
  
 
1621
  /* Store length of status variables */
 
1622
  status_vars_len= (uint) (start-start_of_status);
 
1623
  DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
 
1624
  int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
 
1625
 
 
1626
  /*
 
1627
    Calculate length of whole event
 
1628
    The "1" below is the \0 in the db's length
 
1629
  */
 
1630
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
 
1631
 
 
1632
  return (write_header(file, event_length) ||
 
1633
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
 
1634
          write_post_header_for_derived(file) ||
 
1635
          my_b_safe_write(file, (uchar*) start_of_status,
 
1636
                          (uint) (start-start_of_status)) ||
 
1637
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
 
1638
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
 
1639
}
 
1640
 
 
1641
/**
 
1642
  The simplest constructor that could possibly work.  This is used for
 
1643
  creating static objects that have a special meaning and are invisible
 
1644
  to the log.  
 
1645
*/
 
1646
Query_log_event::Query_log_event()
 
1647
  :Log_event(), data_buf(0)
 
1648
{
 
1649
}
 
1650
 
 
1651
 
 
1652
/*
 
1653
  SYNOPSIS
 
1654
    Query_log_event::Query_log_event()
 
1655
      thd_arg           - thread handle
 
1656
      query_arg         - array of char representing the query
 
1657
      query_length      - size of the  `query_arg' array
 
1658
      using_trans       - there is a modified transactional table
 
1659
      suppress_use      - suppress the generation of 'USE' statements
 
1660
      killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
 
1661
                          if the value is different from the default, the arg
 
1662
                          is set to the current thd->killed value.
 
1663
                          A caller might need to masquerade thd->killed with
 
1664
                          THD::NOT_KILLED.
 
1665
  DESCRIPTION
 
1666
  Creates an event for binlogging
 
1667
  The value for local `killed_status' can be supplied by caller.
 
1668
*/
 
1669
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
 
1670
                                 ulong query_length, bool using_trans,
 
1671
                                 bool suppress_use,
 
1672
                                 THD::killed_state killed_status_arg)
 
1673
  :Log_event(thd_arg,
 
1674
             (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
 
1675
              0) |
 
1676
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
 
1677
             using_trans),
 
1678
   data_buf(0), query(query_arg), catalog(thd_arg->catalog),
 
1679
   db(thd_arg->db), q_len((uint32) query_length),
 
1680
   thread_id(thd_arg->thread_id),
 
1681
   /* save the original thread id; we already know the server id */
 
1682
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
 
1683
   flags2_inited(1), sql_mode_inited(1), charset_inited(1),
 
1684
   sql_mode(0),
 
1685
   auto_increment_increment(thd_arg->variables.auto_increment_increment),
 
1686
   auto_increment_offset(thd_arg->variables.auto_increment_offset),
 
1687
   lc_time_names_number(thd_arg->variables.lc_time_names->number),
 
1688
   charset_database_number(0)
 
1689
{
 
1690
  time_t end_time;
 
1691
 
 
1692
  if (killed_status_arg == THD::KILLED_NO_VALUE)
 
1693
    killed_status_arg= thd_arg->killed;
 
1694
  error_code=
 
1695
    (killed_status_arg == THD::NOT_KILLED) ?
 
1696
    (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
 
1697
    ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
 
1698
     thd_arg->killed_errno());
 
1699
  
 
1700
  time(&end_time);
 
1701
  exec_time = (ulong) (end_time  - thd_arg->start_time);
 
1702
  /**
 
1703
    @todo this means that if we have no catalog, then it is replicated
 
1704
    as an existing catalog of length zero. is that safe? /sven
 
1705
  */
 
1706
  catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
 
1707
  /* status_vars_len is set just before writing the event */
 
1708
  db_len = (db) ? (uint32) strlen(db) : 0;
 
1709
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
 
1710
    charset_database_number= thd_arg->variables.collation_database->number;
 
1711
  
 
1712
  /*
 
1713
    If we don't use flags2 for anything else than options contained in
 
1714
    thd_arg->options, it would be more efficient to flags2=thd_arg->options
 
1715
    (OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
 
1716
    But it's likely that we don't want to use 32 bits for 3 bits; in the future
 
1717
    we will probably want to reclaim the 29 bits. So we need the &.
 
1718
  */
 
1719
  flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
 
1720
  DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
 
1721
  DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
 
1722
  DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
 
1723
  DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
 
1724
  int2store(charset, thd_arg->variables.character_set_client->number);
 
1725
  int2store(charset+2, thd_arg->variables.collation_connection->number);
 
1726
  int2store(charset+4, thd_arg->variables.collation_server->number);
 
1727
  if (thd_arg->time_zone_used)
 
1728
  {
 
1729
    /*
 
1730
      Note that our event becomes dependent on the Time_zone object
 
1731
      representing the time zone. Fortunately such objects are never deleted
 
1732
      or changed during mysqld's lifetime.
 
1733
    */
 
1734
    time_zone_len= thd_arg->variables.time_zone->get_name()->length();
 
1735
    time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
 
1736
  }
 
1737
  else
 
1738
    time_zone_len= 0;
 
1739
  DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %lu",
 
1740
                     (ulong) flags2, sql_mode));
 
1741
}
 
1742
#endif /* MYSQL_CLIENT */
 
1743
 
 
1744
 
 
1745
/* 2 utility functions for the next method */
 
1746
 
 
1747
/**
 
1748
   Read a string with length from memory.
 
1749
 
 
1750
   This function reads the string-with-length stored at
 
1751
   <code>src</code> and extract the length into <code>*len</code> and
 
1752
   a pointer to the start of the string into <code>*dst</code>. The
 
1753
   string can then be copied using <code>memcpy()</code> with the
 
1754
   number of bytes given in <code>*len</code>.
 
1755
 
 
1756
   @param src Pointer to variable holding a pointer to the memory to
 
1757
              read the string from.
 
1758
   @param dst Pointer to variable holding a pointer where the actual
 
1759
              string starts. Starting from this position, the string
 
1760
              can be copied using @c memcpy().
 
1761
   @param len Pointer to variable where the length will be stored.
 
1762
   @param end One-past-the-end of the memory where the string is
 
1763
              stored.
 
1764
 
 
1765
   @return    Zero if the entire string can be copied successfully,
 
1766
              @c UINT_MAX if the length could not be read from memory
 
1767
              (that is, if <code>*src >= end</code>), otherwise the
 
1768
              number of bytes that are missing to read the full
 
1769
              string, which happends <code>*dst + *len >= end</code>.
 
1770
*/
 
1771
static int
 
1772
get_str_len_and_pointer(const Log_event::Byte **src,
 
1773
                        const char **dst,
 
1774
                        uint *len,
 
1775
                        const Log_event::Byte *end)
 
1776
{
 
1777
  if (*src >= end)
 
1778
    return -1;       // Will be UINT_MAX in two-complement arithmetics
 
1779
  uint length= **src;
 
1780
  if (length > 0)
 
1781
  {
 
1782
    if (*src + length >= end)
 
1783
      return *src + length - end + 1;       // Number of bytes missing
 
1784
    *dst= (char *)*src + 1;                    // Will be copied later
 
1785
  }
 
1786
  *len= length;
 
1787
  *src+= length + 1;
 
1788
  return 0;
 
1789
}
 
1790
 
 
1791
static void copy_str_and_move(const char **src, 
 
1792
                              Log_event::Byte **dst, 
 
1793
                              uint len)
 
1794
{
 
1795
  memcpy(*dst, *src, len);
 
1796
  *src= (const char *)*dst;
 
1797
  (*dst)+= len;
 
1798
  *(*dst)++= 0;
 
1799
}
 
1800
 
 
1801
 
 
1802
#ifndef DBUG_OFF
 
1803
static char const *
 
1804
code_name(int code)
 
1805
{
 
1806
  static char buf[255];
 
1807
  switch (code) {
 
1808
  case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
 
1809
  case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
 
1810
  case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
 
1811
  case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
 
1812
  case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
 
1813
  case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
 
1814
  case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
 
1815
  case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
 
1816
  case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
 
1817
  }
 
1818
  sprintf(buf, "CODE#%d", code);
 
1819
  return buf;
 
1820
}
 
1821
#endif
 
1822
 
 
1823
/**
 
1824
   Macro to check that there is enough space to read from memory.
 
1825
 
 
1826
   @param PTR Pointer to memory
 
1827
   @param END End of memory
 
1828
   @param CNT Number of bytes that should be read.
 
1829
 */
 
1830
#define CHECK_SPACE(PTR,END,CNT)                      \
 
1831
  do {                                                \
 
1832
    DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
 
1833
    DBUG_ASSERT((PTR) + (CNT) <= (END));              \
 
1834
    if ((PTR) + (CNT) > (END)) {                      \
 
1835
      DBUG_PRINT("info", ("query= 0"));               \
 
1836
      query= 0;                                       \
 
1837
      DBUG_VOID_RETURN;                               \
 
1838
    }                                                 \
 
1839
  } while (0)
 
1840
 
 
1841
 
 
1842
/**
 
1843
  This is used by the SQL slave thread to prepare the event before execution.
 
1844
*/
 
1845
Query_log_event::Query_log_event(const char* buf, uint event_len,
 
1846
                                 const Format_description_log_event
 
1847
                                 *description_event,
 
1848
                                 Log_event_type event_type)
 
1849
  :Log_event(buf, description_event), data_buf(0), query(NullS),
 
1850
   db(NullS), catalog_len(0), status_vars_len(0),
 
1851
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
 
1852
   auto_increment_increment(1), auto_increment_offset(1),
 
1853
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
 
1854
{
 
1855
  ulong data_len;
 
1856
  uint32 tmp;
 
1857
  uint8 common_header_len, post_header_len;
 
1858
  Log_event::Byte *start;
 
1859
  const Log_event::Byte *end;
 
1860
  bool catalog_nz= 1;
 
1861
  DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
 
1862
 
 
1863
  common_header_len= description_event->common_header_len;
 
1864
  post_header_len= description_event->post_header_len[event_type-1];
 
1865
  DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
 
1866
                     event_len, common_header_len, post_header_len));
 
1867
  
 
1868
  /*
 
1869
    We test if the event's length is sensible, and if so we compute data_len.
 
1870
    We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
 
1871
    We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
 
1872
  */
 
1873
  if (event_len < (uint)(common_header_len + post_header_len))
 
1874
    DBUG_VOID_RETURN;                           
 
1875
  data_len = event_len - (common_header_len + post_header_len);
 
1876
  buf+= common_header_len;
 
1877
  
 
1878
  slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
 
1879
  exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
 
1880
  db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
 
1881
  error_code = uint2korr(buf + Q_ERR_CODE_OFFSET);
 
1882
 
 
1883
  /*
 
1884
    5.0 format starts here.
 
1885
    Depending on the format, we may or not have affected/warnings etc
 
1886
    The remnent post-header to be parsed has length:
 
1887
  */
 
1888
  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN; 
 
1889
  if (tmp)
 
1890
  {
 
1891
    status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
 
1892
    /*
 
1893
      Check if status variable length is corrupt and will lead to very
 
1894
      wrong data. We could be even more strict and require data_len to
 
1895
      be even bigger, but this will suffice to catch most corruption
 
1896
      errors that can lead to a crash.
 
1897
    */
 
1898
    if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
 
1899
    {
 
1900
      DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
 
1901
                          status_vars_len, data_len));
 
1902
      query= 0;
 
1903
      DBUG_VOID_RETURN;
 
1904
    }
 
1905
    data_len-= status_vars_len;
 
1906
    DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
 
1907
                        (uint) status_vars_len));
 
1908
    tmp-= 2;
 
1909
  }
 
1910
  /*
 
1911
    We have parsed everything we know in the post header for QUERY_EVENT,
 
1912
    the rest of post header is either comes from older version MySQL or
 
1913
    dedicated to derived events (e.g. Execute_load_query...)
 
1914
  */
 
1915
 
 
1916
  /* variable-part: the status vars; only in MySQL 5.0  */
 
1917
  
 
1918
  start= (Log_event::Byte*) (buf+post_header_len);
 
1919
  end= (const Log_event::Byte*) (start+status_vars_len);
 
1920
  for (const Log_event::Byte* pos= start; pos < end;)
 
1921
  {
 
1922
    switch (*pos++) {
 
1923
    case Q_FLAGS2_CODE:
 
1924
      CHECK_SPACE(pos, end, 4);
 
1925
      flags2_inited= 1;
 
1926
      flags2= uint4korr(pos);
 
1927
      DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
 
1928
      pos+= 4;
 
1929
      break;
 
1930
    case Q_SQL_MODE_CODE:
 
1931
    {
 
1932
#ifndef DBUG_OFF
 
1933
      char buff[22];
 
1934
#endif
 
1935
      CHECK_SPACE(pos, end, 8);
 
1936
      sql_mode_inited= 1;
 
1937
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong
 
1938
      DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
 
1939
                         llstr(sql_mode, buff)));
 
1940
      pos+= 8;
 
1941
      break;
 
1942
    }
 
1943
    case Q_CATALOG_NZ_CODE:
 
1944
      DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
 
1945
                          (ulong) pos, (ulong) end));
 
1946
      if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
 
1947
      {
 
1948
        DBUG_PRINT("info", ("query= 0"));
 
1949
        query= 0;
 
1950
        DBUG_VOID_RETURN;
 
1951
      }
 
1952
      break;
 
1953
    case Q_AUTO_INCREMENT:
 
1954
      CHECK_SPACE(pos, end, 4);
 
1955
      auto_increment_increment= uint2korr(pos);
 
1956
      auto_increment_offset=    uint2korr(pos+2);
 
1957
      pos+= 4;
 
1958
      break;
 
1959
    case Q_CHARSET_CODE:
 
1960
    {
 
1961
      CHECK_SPACE(pos, end, 6);
 
1962
      charset_inited= 1;
 
1963
      memcpy(charset, pos, 6);
 
1964
      pos+= 6;
 
1965
      break;
 
1966
    }
 
1967
    case Q_TIME_ZONE_CODE:
 
1968
    {
 
1969
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
 
1970
      {
 
1971
        DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
 
1972
        query= 0;
 
1973
        DBUG_VOID_RETURN;
 
1974
      }
 
1975
      break;
 
1976
    }
 
1977
    case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
 
1978
      CHECK_SPACE(pos, end, 1);
 
1979
      if ((catalog_len= *pos))
 
1980
        catalog= (char*) pos+1;                           // Will be copied later
 
1981
      CHECK_SPACE(pos, end, catalog_len + 2);
 
1982
      pos+= catalog_len+2; // leap over end 0
 
1983
      catalog_nz= 0; // catalog has end 0 in event
 
1984
      break;
 
1985
    case Q_LC_TIME_NAMES_CODE:
 
1986
      CHECK_SPACE(pos, end, 2);
 
1987
      lc_time_names_number= uint2korr(pos);
 
1988
      pos+= 2;
 
1989
      break;
 
1990
    case Q_CHARSET_DATABASE_CODE:
 
1991
      CHECK_SPACE(pos, end, 2);
 
1992
      charset_database_number= uint2korr(pos);
 
1993
      pos+= 2;
 
1994
      break;
 
1995
    default:
 
1996
      /* That's why you must write status vars in growing order of code */
 
1997
      DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
 
1998
 code: %u), skipping the rest of them", (uint) *(pos-1)));
 
1999
      pos= (const uchar*) end;                         // Break loop
 
2000
    }
 
2001
  }
 
2002
  
 
2003
  if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
 
2004
                                             time_zone_len + 1 +
 
2005
                                             data_len + 1,
 
2006
                                             MYF(MY_WME))))
 
2007
      DBUG_VOID_RETURN;
 
2008
  if (catalog_len)                                  // If catalog is given
 
2009
  {
 
2010
    /**
 
2011
      @todo we should clean up and do only copy_str_and_move; it
 
2012
      works for both cases.  Then we can remove the catalog_nz
 
2013
      flag. /sven
 
2014
    */
 
2015
    if (likely(catalog_nz)) // true except if event comes from 5.0.0|1|2|3.
 
2016
      copy_str_and_move(&catalog, &start, catalog_len);
 
2017
    else
 
2018
    {
 
2019
      memcpy(start, catalog, catalog_len+1); // copy end 0
 
2020
      catalog= (const char *)start;
 
2021
      start+= catalog_len+1;
 
2022
    }
 
2023
  }
 
2024
  if (time_zone_len)
 
2025
    copy_str_and_move(&time_zone_str, &start, time_zone_len);
 
2026
 
 
2027
  /**
 
2028
    if time_zone_len or catalog_len are 0, then time_zone and catalog
 
2029
    are uninitialized at this point.  shouldn't they point to the
 
2030
    zero-length null-terminated strings we allocated space for in the
 
2031
    my_alloc call above? /sven
 
2032
  */
 
2033
 
 
2034
  /* A 2nd variable part; this is common to all versions */ 
 
2035
  memcpy((char*) start, end, data_len);          // Copy db and query
 
2036
  start[data_len]= '\0';              // End query with \0 (For safetly)
 
2037
  db= (char *)start;
 
2038
  query= (char *)(start + db_len + 1);
 
2039
  q_len= data_len - db_len -1;
 
2040
  DBUG_VOID_RETURN;
 
2041
}
 
2042
 
 
2043
 
 
2044
#ifdef MYSQL_CLIENT
 
2045
/**
 
2046
  Query_log_event::print().
 
2047
 
 
2048
  @todo
 
2049
    print the catalog ??
 
2050
*/
 
2051
void Query_log_event::print_query_header(IO_CACHE* file,
 
2052
                                         PRINT_EVENT_INFO* print_event_info)
 
2053
{
 
2054
  // TODO: print the catalog ??
 
2055
  char buff[40],*end;                           // Enough for SET TIMESTAMP
 
2056
  bool different_db= 1;
 
2057
  uint32 tmp;
 
2058
 
 
2059
  if (!print_event_info->short_form)
 
2060
  {
 
2061
    print_header(file, print_event_info, FALSE);
 
2062
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 
2063
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
 
2064
                error_code);
 
2065
  }
 
2066
 
 
2067
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
 
2068
  {
 
2069
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
 
2070
      memcpy(print_event_info->db, db, db_len + 1);
 
2071
    if (db[0] && different_db) 
 
2072
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
 
2073
  }
 
2074
 
 
2075
  end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
 
2076
  end= strmov(end, print_event_info->delimiter);
 
2077
  *end++='\n';
 
2078
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
 
2079
  if ((!print_event_info->thread_id_printed ||
 
2080
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
 
2081
        thread_id != print_event_info->thread_id)))
 
2082
  {
 
2083
    // If --short-form, print deterministic value instead of pseudo_thread_id.
 
2084
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
 
2085
                short_form ? 999999999 : (ulong)thread_id,
 
2086
                print_event_info->delimiter);
 
2087
    print_event_info->thread_id= thread_id;
 
2088
    print_event_info->thread_id_printed= 1;
 
2089
  }
 
2090
 
 
2091
  /*
 
2092
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
 
2093
    print (remember we don't produce mixed relay logs so there cannot be
 
2094
    5.0 events before that one so there is nothing to reset).
 
2095
  */
 
2096
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
 
2097
  {
 
2098
    /* tmp is a bitmask of bits which have changed. */
 
2099
    if (likely(print_event_info->flags2_inited)) 
 
2100
      /* All bits which have changed */
 
2101
      tmp= (print_event_info->flags2) ^ flags2;
 
2102
    else /* that's the first Query event we read */
 
2103
    {
 
2104
      print_event_info->flags2_inited= 1;
 
2105
      tmp= ~((uint32)0); /* all bits have changed */
 
2106
    }
 
2107
 
 
2108
    if (unlikely(tmp)) /* some bits have changed */
 
2109
    {
 
2110
      bool need_comma= 0;
 
2111
      my_b_printf(file, "SET ");
 
2112
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
 
2113
                   "@@session.foreign_key_checks", &need_comma);
 
2114
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
 
2115
                   "@@session.sql_auto_is_null", &need_comma);
 
2116
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
 
2117
                   "@@session.unique_checks", &need_comma);
 
2118
      my_b_printf(file,"%s\n", print_event_info->delimiter);
 
2119
      print_event_info->flags2= flags2;
 
2120
    }
 
2121
  }
 
2122
 
 
2123
  /*
 
2124
    Now the session variables;
 
2125
    it's more efficient to pass SQL_MODE as a number instead of a
 
2126
    comma-separated list.
 
2127
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
 
2128
    variables (they have no global version; they're not listed in
 
2129
    sql_class.h), The tests below work for pure binlogs or pure relay
 
2130
    logs. Won't work for mixed relay logs but we don't create mixed
 
2131
    relay logs (that is, there is no relay log with a format change
 
2132
    except within the 3 first events, which mysqlbinlog handles
 
2133
    gracefully). So this code should always be good.
 
2134
  */
 
2135
 
 
2136
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
 
2137
      print_event_info->auto_increment_offset != auto_increment_offset)
 
2138
  {
 
2139
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
 
2140
                auto_increment_increment,auto_increment_offset,
 
2141
                print_event_info->delimiter);
 
2142
    print_event_info->auto_increment_increment= auto_increment_increment;
 
2143
    print_event_info->auto_increment_offset=    auto_increment_offset;
 
2144
  }
 
2145
 
 
2146
  /* TODO: print the catalog when we feature SET CATALOG */
 
2147
 
 
2148
  if (likely(charset_inited) &&
 
2149
      (unlikely(!print_event_info->charset_inited ||
 
2150
                bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
 
2151
  {
 
2152
    CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
 
2153
    if (cs_info)
 
2154
    {
 
2155
      /* for mysql client */
 
2156
      my_b_printf(file, "/*!\\C %s */%s\n",
 
2157
                  cs_info->csname, print_event_info->delimiter);
 
2158
    }
 
2159
    my_b_printf(file,"SET "
 
2160
                "@@session.character_set_client=%d,"
 
2161
                "@@session.collation_connection=%d,"
 
2162
                "@@session.collation_server=%d"
 
2163
                "%s\n",
 
2164
                uint2korr(charset),
 
2165
                uint2korr(charset+2),
 
2166
                uint2korr(charset+4),
 
2167
                print_event_info->delimiter);
 
2168
    memcpy(print_event_info->charset, charset, 6);
 
2169
    print_event_info->charset_inited= 1;
 
2170
  }
 
2171
  if (time_zone_len)
 
2172
  {
 
2173
    if (bcmp((uchar*) print_event_info->time_zone_str,
 
2174
             (uchar*) time_zone_str, time_zone_len+1))
 
2175
    {
 
2176
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
 
2177
                  time_zone_str, print_event_info->delimiter);
 
2178
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
 
2179
    }
 
2180
  }
 
2181
  if (lc_time_names_number != print_event_info->lc_time_names_number)
 
2182
  {
 
2183
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
 
2184
                lc_time_names_number, print_event_info->delimiter);
 
2185
    print_event_info->lc_time_names_number= lc_time_names_number;
 
2186
  }
 
2187
  if (charset_database_number != print_event_info->charset_database_number)
 
2188
  {
 
2189
    if (charset_database_number)
 
2190
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
 
2191
                  charset_database_number, print_event_info->delimiter);
 
2192
    else
 
2193
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
2194
                  print_event_info->delimiter);
 
2195
    print_event_info->charset_database_number= charset_database_number;
 
2196
  }
 
2197
}
 
2198
 
 
2199
 
 
2200
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2201
{
 
2202
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
2203
 
 
2204
  print_query_header(&cache, print_event_info);
 
2205
  my_b_write(&cache, (uchar*) query, q_len);
 
2206
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
2207
}
 
2208
#endif /* MYSQL_CLIENT */
 
2209
 
 
2210
 
 
2211
/*
 
2212
  Query_log_event::do_apply_event()
 
2213
*/
 
2214
 
 
2215
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2216
 
 
2217
int Query_log_event::do_apply_event(Relay_log_info const *rli)
 
2218
{
 
2219
  return do_apply_event(rli, query, q_len);
 
2220
}
 
2221
 
 
2222
 
 
2223
/**
 
2224
  @todo
 
2225
  Compare the values of "affected rows" around here. Something
 
2226
  like:
 
2227
  @code
 
2228
     if ((uint32) affected_in_event != (uint32) affected_on_slave)
 
2229
     {
 
2230
     sql_print_error("Slave: did not get the expected number of affected \
 
2231
     rows running query from master - expected %d, got %d (this numbers \
 
2232
     should have matched modulo 4294967296).", 0, ...);
 
2233
     thd->query_error = 1;
 
2234
     }
 
2235
  @endcode
 
2236
  We may also want an option to tell the slave to ignore "affected"
 
2237
  mismatch. This mismatch could be implemented with a new ER_ code, and
 
2238
  to ignore it you would use --slave-skip-errors...
 
2239
*/
 
2240
int Query_log_event::do_apply_event(Relay_log_info const *rli,
 
2241
                                      const char *query_arg, uint32 q_len_arg)
 
2242
{
 
2243
  LEX_STRING new_db;
 
2244
  int expected_error,actual_error= 0;
 
2245
  /*
 
2246
    Colleagues: please never free(thd->catalog) in MySQL. This would
 
2247
    lead to bugs as here thd->catalog is a part of an alloced block,
 
2248
    not an entire alloced block (see
 
2249
    Query_log_event::do_apply_event()). Same for thd->db.  Thank
 
2250
    you.
 
2251
  */
 
2252
  thd->catalog= catalog_len ? (char *) catalog : (char *)"";
 
2253
  new_db.length= db_len;
 
2254
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
 
2255
  thd->set_db(new_db.str, new_db.length);       /* allocates a copy of 'db' */
 
2256
  thd->variables.auto_increment_increment= auto_increment_increment;
 
2257
  thd->variables.auto_increment_offset=    auto_increment_offset;
 
2258
 
 
2259
  /*
 
2260
    InnoDB internally stores the master log position it has executed so far,
 
2261
    i.e. the position just after the COMMIT event.
 
2262
    When InnoDB will want to store, the positions in rli won't have
 
2263
    been updated yet, so group_master_log_* will point to old BEGIN
 
2264
    and event_master_log* will point to the beginning of current COMMIT.
 
2265
    But log_pos of the COMMIT Query event is what we want, i.e. the pos of the
 
2266
    END of the current log event (COMMIT). We save it in rli so that InnoDB can
 
2267
    access it.
 
2268
  */
 
2269
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
 
2270
  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
 
2271
 
 
2272
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
2273
  const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
2274
 
 
2275
  /*
 
2276
    Note:   We do not need to execute reset_one_shot_variables() if this
 
2277
            db_ok() test fails.
 
2278
    Reason: The db stored in binlog events is the same for SET and for
 
2279
            its companion query.  If the SET is ignored because of
 
2280
            db_ok(), the companion query will also be ignored, and if
 
2281
            the companion query is ignored in the db_ok() test of
 
2282
            ::do_apply_event(), then the companion SET also have so
 
2283
            we don't need to reset_one_shot_variables().
 
2284
  */
 
2285
  if (rpl_filter->db_ok(thd->db))
 
2286
  {
 
2287
    thd->set_time((time_t)when);
 
2288
    thd->query_length= q_len_arg;
 
2289
    thd->query= (char*)query_arg;
 
2290
    VOID(pthread_mutex_lock(&LOCK_thread_count));
 
2291
    thd->query_id = next_query_id();
 
2292
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2293
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
 
2294
    DBUG_PRINT("query",("%s",thd->query));
 
2295
 
 
2296
    if (ignored_error_code((expected_error= error_code)) ||
 
2297
        !check_expected_error(thd,rli,expected_error))
 
2298
    {
 
2299
      if (flags2_inited)
 
2300
        /*
 
2301
          all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
 
2302
          must take their value from flags2.
 
2303
        */
 
2304
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2305
      /*
 
2306
        else, we are in a 3.23/4.0 binlog; we previously received a
 
2307
        Rotate_log_event which reset thd->options and sql_mode etc, so
 
2308
        nothing to do.
 
2309
      */
 
2310
      if (charset_inited)
 
2311
      {
 
2312
        if (rli->cached_charset_compare(charset))
 
2313
        {
 
2314
          /* Verify that we support the charsets found in the event. */
 
2315
          if (!(thd->variables.character_set_client=
 
2316
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
 
2317
              !(thd->variables.collation_connection=
 
2318
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
 
2319
              !(thd->variables.collation_server=
 
2320
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
 
2321
          {
 
2322
            /*
 
2323
              We updated the thd->variables with nonsensical values (0). Let's
 
2324
              set them to something safe (i.e. which avoids crash), and we'll
 
2325
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
 
2326
              ignore this error).
 
2327
            */
 
2328
            set_slave_thread_default_charset(thd, rli);
 
2329
            goto compare_errors;
 
2330
          }
 
2331
          thd->update_charset(); // for the charset change to take effect
 
2332
        }
 
2333
      }
 
2334
      if (time_zone_len)
 
2335
      {
 
2336
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
 
2337
        if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
 
2338
        {
 
2339
          my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
 
2340
          thd->variables.time_zone= global_system_variables.time_zone;
 
2341
          goto compare_errors;
 
2342
        }
 
2343
      }
 
2344
      if (lc_time_names_number)
 
2345
      {
 
2346
        if (!(thd->variables.lc_time_names=
 
2347
              my_locale_by_number(lc_time_names_number)))
 
2348
        {
 
2349
          my_printf_error(ER_UNKNOWN_ERROR,
 
2350
                      "Unknown locale: '%d'", MYF(0), lc_time_names_number);
 
2351
          thd->variables.lc_time_names= &my_locale_en_US;
 
2352
          goto compare_errors;
 
2353
        }
 
2354
      }
 
2355
      else
 
2356
        thd->variables.lc_time_names= &my_locale_en_US;
 
2357
      if (charset_database_number)
 
2358
      {
 
2359
        CHARSET_INFO *cs;
 
2360
        if (!(cs= get_charset(charset_database_number, MYF(0))))
 
2361
        {
 
2362
          char buf[20];
 
2363
          int10_to_str((int) charset_database_number, buf, -10);
 
2364
          my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
 
2365
          goto compare_errors;
 
2366
        }
 
2367
        thd->variables.collation_database= cs;
 
2368
      }
 
2369
      else
 
2370
        thd->variables.collation_database= thd->db_charset;
 
2371
      
 
2372
      /* Execute the query (note that we bypass dispatch_command()) */
 
2373
      const char* found_semicolon= NULL;
 
2374
      mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
 
2375
      log_slow_statement(thd);
 
2376
    }
 
2377
    else
 
2378
    {
 
2379
      /*
 
2380
        The query got a really bad error on the master (thread killed etc),
 
2381
        which could be inconsistent. Parse it to test the table names: if the
 
2382
        replicate-*-do|ignore-table rules say "this query must be ignored" then
 
2383
        we exit gracefully; otherwise we warn about the bad error and tell DBA
 
2384
        to check/fix it.
 
2385
      */
 
2386
      if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
 
2387
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
 
2388
      else
 
2389
      {
 
2390
        rli->report(ERROR_LEVEL, expected_error, 
 
2391
                          "\
 
2392
Query partially completed on the master (error on master: %d) \
 
2393
and was aborted. There is a chance that your master is inconsistent at this \
 
2394
point. If you are sure that your master is ok, run this query manually on the \
 
2395
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
 
2396
START SLAVE; . Query: '%s'", expected_error, thd->query);
 
2397
        thd->is_slave_error= 1;
 
2398
      }
 
2399
      goto end;
 
2400
    }
 
2401
 
 
2402
    /* If the query was not ignored, it is printed to the general log */
 
2403
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
 
2404
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
 
2405
 
 
2406
compare_errors:
 
2407
 
 
2408
     /*
 
2409
      If we expected a non-zero error code, and we don't get the same error
 
2410
      code, and none of them should be ignored.
 
2411
    */
 
2412
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
 
2413
    DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
 
2414
                       expected_error, actual_error));
 
2415
    if ((expected_error != actual_error) &&
 
2416
        expected_error &&
 
2417
        !ignored_error_code(actual_error) &&
 
2418
        !ignored_error_code(expected_error))
 
2419
    {
 
2420
      rli->report(ERROR_LEVEL, 0,
 
2421
                      "\
 
2422
Query caused different errors on master and slave.     \
 
2423
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
 
2424
Default database: '%s'. Query: '%s'",
 
2425
                      ER_SAFE(expected_error),
 
2426
                      expected_error,
 
2427
                      actual_error ? thd->main_da.message() : "no error",
 
2428
                      actual_error,
 
2429
                      print_slave_db_safe(db), query_arg);
 
2430
      thd->is_slave_error= 1;
 
2431
    }
 
2432
    /*
 
2433
      If we get the same error code as expected, or they should be ignored. 
 
2434
    */
 
2435
    else if (expected_error == actual_error ||
 
2436
             ignored_error_code(actual_error))
 
2437
    {
 
2438
      DBUG_PRINT("info",("error ignored"));
 
2439
      clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
2440
      thd->killed= THD::NOT_KILLED;
 
2441
    }
 
2442
    /*
 
2443
      Other cases: mostly we expected no error and get one.
 
2444
    */
 
2445
    else if (thd->is_slave_error || thd->is_fatal_error)
 
2446
    {
 
2447
      rli->report(ERROR_LEVEL, actual_error,
 
2448
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
 
2449
                      (actual_error ? thd->main_da.message() :
 
2450
                       "unexpected success or fatal error"),
 
2451
                      print_slave_db_safe(thd->db), query_arg);
 
2452
      thd->is_slave_error= 1;
 
2453
    }
 
2454
 
 
2455
    /*
 
2456
      TODO: compare the values of "affected rows" around here. Something
 
2457
      like:
 
2458
      if ((uint32) affected_in_event != (uint32) affected_on_slave)
 
2459
      {
 
2460
      sql_print_error("Slave: did not get the expected number of affected \
 
2461
      rows running query from master - expected %d, got %d (this numbers \
 
2462
      should have matched modulo 4294967296).", 0, ...);
 
2463
      thd->is_slave_error = 1;
 
2464
      }
 
2465
      We may also want an option to tell the slave to ignore "affected"
 
2466
      mismatch. This mismatch could be implemented with a new ER_ code, and
 
2467
      to ignore it you would use --slave-skip-errors...
 
2468
 
 
2469
      To do the comparison we need to know the value of "affected" which the
 
2470
      above mysql_parse() computed. And we need to know the value of
 
2471
      "affected" in the master's binlog. Both will be implemented later. The
 
2472
      important thing is that we now have the format ready to log the values
 
2473
      of "affected" in the binlog. So we can release 5.0.0 before effectively
 
2474
      logging "affected" and effectively comparing it.
 
2475
    */
 
2476
  } /* End of if (db_ok(... */
 
2477
 
 
2478
end:
 
2479
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
2480
  /*
 
2481
    Probably we have set thd->query, thd->db, thd->catalog to point to places
 
2482
    in the data_buf of this event. Now the event is going to be deleted
 
2483
    probably, so data_buf will be freed, so the thd->... listed above will be
 
2484
    pointers to freed memory. 
 
2485
    So we must set them to 0, so that those bad pointers values are not later
 
2486
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
 
2487
    don't suffer from these assignments to 0 as DROP TEMPORARY
 
2488
    TABLE uses the db.table syntax.
 
2489
  */
 
2490
  thd->catalog= 0;
 
2491
  thd->set_db(NULL, 0);                 /* will free the current database */
 
2492
  DBUG_PRINT("info", ("end: query= 0"));
 
2493
  thd->query= 0;                        // just to be sure
 
2494
  thd->query_length= 0;
 
2495
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2496
  close_thread_tables(thd);      
 
2497
  /*
 
2498
    As a disk space optimization, future masters will not log an event for
 
2499
    LAST_INSERT_ID() if that function returned 0 (and thus they will be able
 
2500
    to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
 
2501
    variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
 
2502
    resetting below we are ready to support that.
 
2503
  */
 
2504
  thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
 
2505
  thd->first_successful_insert_id_in_prev_stmt= 0;
 
2506
  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
 
2507
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
2508
  return thd->is_slave_error;
 
2509
}
 
2510
 
 
2511
int Query_log_event::do_update_pos(Relay_log_info *rli)
 
2512
{
 
2513
  /*
 
2514
    Note that we will not increment group* positions if we are just
 
2515
    after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
 
2516
    from its following updating query.
 
2517
  */
 
2518
  if (thd->one_shot_set)
 
2519
  {
 
2520
    rli->inc_event_relay_log_pos();
 
2521
    return 0;
 
2522
  }
 
2523
  else
 
2524
    return Log_event::do_update_pos(rli);
 
2525
}
 
2526
 
 
2527
 
 
2528
Log_event::enum_skip_reason
 
2529
Query_log_event::do_shall_skip(Relay_log_info *rli)
 
2530
{
 
2531
  DBUG_ENTER("Query_log_event::do_shall_skip");
 
2532
  DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
 
2533
  DBUG_ASSERT(query && q_len > 0);
 
2534
 
 
2535
  if (rli->slave_skip_counter > 0)
 
2536
  {
 
2537
    if (strcmp("BEGIN", query) == 0)
 
2538
    {
 
2539
      thd->options|= OPTION_BEGIN;
 
2540
      DBUG_RETURN(Log_event::continue_group(rli));
 
2541
    }
 
2542
 
 
2543
    if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
 
2544
    {
 
2545
      thd->options&= ~OPTION_BEGIN;
 
2546
      DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
 
2547
    }
 
2548
  }
 
2549
  DBUG_RETURN(Log_event::do_shall_skip(rli));
 
2550
}
 
2551
 
 
2552
#endif
 
2553
 
 
2554
 
 
2555
/**************************************************************************
 
2556
        Start_log_event_v3 methods
 
2557
**************************************************************************/
 
2558
 
 
2559
#ifndef MYSQL_CLIENT
 
2560
Start_log_event_v3::Start_log_event_v3()
 
2561
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
 
2562
   artificial_event(0), dont_set_created(0)
 
2563
{
 
2564
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
 
2565
}
 
2566
#endif
 
2567
 
 
2568
/*
 
2569
  Start_log_event_v3::pack_info()
 
2570
*/
 
2571
 
 
2572
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2573
void Start_log_event_v3::pack_info(Protocol *protocol)
 
2574
{
 
2575
  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
 
2576
  pos= strmov(buf, "Server ver: ");
 
2577
  pos= strmov(pos, server_version);
 
2578
  pos= strmov(pos, ", Binlog ver: ");
 
2579
  pos= int10_to_str(binlog_version, pos, 10);
 
2580
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
 
2581
}
 
2582
#endif
 
2583
 
 
2584
 
 
2585
/*
 
2586
  Start_log_event_v3::print()
 
2587
*/
 
2588
 
 
2589
#ifdef MYSQL_CLIENT
 
2590
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2591
{
 
2592
  DBUG_ENTER("Start_log_event_v3::print");
 
2593
 
 
2594
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
2595
                               Write_on_release_cache::FLUSH_F);
 
2596
 
 
2597
  if (!print_event_info->short_form)
 
2598
  {
 
2599
    print_header(&cache, print_event_info, FALSE);
 
2600
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
 
2601
                binlog_version, server_version);
 
2602
    print_timestamp(&cache);
 
2603
    if (created)
 
2604
      my_b_printf(&cache," at startup");
 
2605
    my_b_printf(&cache, "\n");
 
2606
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
 
2607
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
 
2608
                  "Most probably mysqld crashed writing it.\n");
 
2609
  }
 
2610
  if (!artificial_event && created)
 
2611
  {
 
2612
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
 
2613
    /*
 
2614
      This is for mysqlbinlog: like in replication, we want to delete the stale
 
2615
      tmp files left by an unclean shutdown of mysqld (temporary tables)
 
2616
      and rollback unfinished transaction.
 
2617
      Probably this can be done with RESET CONNECTION (syntax to be defined).
 
2618
    */
 
2619
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
 
2620
#else
 
2621
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
 
2622
#endif
 
2623
  }
 
2624
  if (temp_buf &&
 
2625
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
 
2626
      !print_event_info->short_form)
 
2627
  {
 
2628
    my_b_printf(&cache, "BINLOG '\n");
 
2629
    print_base64(&cache, print_event_info, FALSE);
 
2630
    print_event_info->printed_fd_event= TRUE;
 
2631
  }
 
2632
  DBUG_VOID_RETURN;
 
2633
}
 
2634
#endif /* MYSQL_CLIENT */
 
2635
 
 
2636
/*
 
2637
  Start_log_event_v3::Start_log_event_v3()
 
2638
*/
 
2639
 
 
2640
Start_log_event_v3::Start_log_event_v3(const char* buf,
 
2641
                                       const Format_description_log_event
 
2642
                                       *description_event)
 
2643
  :Log_event(buf, description_event)
 
2644
{
 
2645
  buf+= description_event->common_header_len;
 
2646
  binlog_version= uint2korr(buf+ST_BINLOG_VER_OFFSET);
 
2647
  memcpy(server_version, buf+ST_SERVER_VER_OFFSET,
 
2648
         ST_SERVER_VER_LEN);
 
2649
  // prevent overrun if log is corrupted on disk
 
2650
  server_version[ST_SERVER_VER_LEN-1]= 0;
 
2651
  created= uint4korr(buf+ST_CREATED_OFFSET);
 
2652
  /* We use log_pos to mark if this was an artificial event or not */
 
2653
  artificial_event= (log_pos == 0);
 
2654
  dont_set_created= 1;
 
2655
}
 
2656
 
 
2657
 
 
2658
/*
 
2659
  Start_log_event_v3::write()
 
2660
*/
 
2661
 
 
2662
#ifndef MYSQL_CLIENT
 
2663
bool Start_log_event_v3::write(IO_CACHE* file)
 
2664
{
 
2665
  char buff[START_V3_HEADER_LEN];
 
2666
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
 
2667
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
 
2668
  if (!dont_set_created)
 
2669
    created= when= get_time();
 
2670
  int4store(buff + ST_CREATED_OFFSET,created);
 
2671
  return (write_header(file, sizeof(buff)) ||
 
2672
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
 
2673
}
 
2674
#endif
 
2675
 
 
2676
 
 
2677
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2678
 
 
2679
/**
 
2680
  Start_log_event_v3::do_apply_event() .
 
2681
  The master started
 
2682
 
 
2683
    IMPLEMENTATION
 
2684
    - To handle the case where the master died without having time to write
 
2685
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
 
2686
    TODO), we clean up all temporary tables that we got, if we are sure we
 
2687
    can (see below).
 
2688
 
 
2689
  @todo
 
2690
    - Remove all active user locks.
 
2691
    Guilhem 2003-06: this is true but not urgent: the worst it can cause is
 
2692
    the use of a bit of memory for a user lock which will not be used
 
2693
    anymore. If the user lock is later used, the old one will be released. In
 
2694
    other words, no deadlock problem.
 
2695
*/
 
2696
 
 
2697
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
 
2698
{
 
2699
  DBUG_ENTER("Start_log_event_v3::do_apply_event");
 
2700
  switch (binlog_version)
 
2701
  {
 
2702
  case 3:
 
2703
  case 4:
 
2704
    /*
 
2705
      This can either be 4.x (then a Start_log_event_v3 is only at master
 
2706
      startup so we are sure the master has restarted and cleared his temp
 
2707
      tables; the event always has 'created'>0) or 5.0 (then we have to test
 
2708
      'created').
 
2709
    */
 
2710
    if (created)
 
2711
    {
 
2712
      close_temporary_tables(thd);
 
2713
      cleanup_load_tmpdir();
 
2714
    }
 
2715
    break;
 
2716
 
 
2717
    /*
 
2718
       Now the older formats; in that case load_tmpdir is cleaned up by the I/O
 
2719
       thread.
 
2720
    */
 
2721
  case 1:
 
2722
    if (strncmp(rli->relay_log.description_event_for_exec->server_version,
 
2723
                "3.23.57",7) >= 0 && created)
 
2724
    {
 
2725
      /*
 
2726
        Can distinguish, based on the value of 'created': this event was
 
2727
        generated at master startup.
 
2728
      */
 
2729
      close_temporary_tables(thd);
 
2730
    }
 
2731
    /*
 
2732
      Otherwise, can't distinguish a Start_log_event generated at
 
2733
      master startup and one generated by master FLUSH LOGS, so cannot
 
2734
      be sure temp tables have to be dropped. So do nothing.
 
2735
    */
 
2736
    break;
 
2737
  default:
 
2738
    /* this case is impossible */
 
2739
    DBUG_RETURN(1);
 
2740
  }
 
2741
  DBUG_RETURN(0);
 
2742
}
 
2743
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
2744
 
 
2745
/***************************************************************************
 
2746
       Format_description_log_event methods
 
2747
****************************************************************************/
 
2748
 
 
2749
/**
 
2750
  Format_description_log_event 1st ctor.
 
2751
 
 
2752
    Ctor. Can be used to create the event to write to the binary log (when the
 
2753
    server starts or when FLUSH LOGS), or to create artificial events to parse
 
2754
    binlogs from MySQL 3.23 or 4.x.
 
2755
    When in a client, only the 2nd use is possible.
 
2756
 
 
2757
  @param binlog_version         the binlog version for which we want to build
 
2758
                                an event. Can be 1 (=MySQL 3.23), 3 (=4.0.x
 
2759
                                x>=2 and 4.1) or 4 (MySQL 5.0). Note that the
 
2760
                                old 4.0 (binlog version 2) is not supported;
 
2761
                                it should not be used for replication with
 
2762
                                5.0.
 
2763
*/
 
2764
 
 
2765
Format_description_log_event::
 
2766
Format_description_log_event(uint8 binlog_ver, const char* server_ver)
 
2767
  :Start_log_event_v3(), event_type_permutation(0)
 
2768
{
 
2769
  binlog_version= binlog_ver;
 
2770
  switch (binlog_ver) {
 
2771
  case 4: /* MySQL 5.0 */
 
2772
    memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
 
2773
    DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
 
2774
                    strmov(server_version, "5.0.34"););
 
2775
    common_header_len= LOG_EVENT_HEADER_LEN;
 
2776
    number_of_event_types= LOG_EVENT_TYPES;
 
2777
    /* we'll catch my_malloc() error in is_valid() */
 
2778
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
 
2779
                                       MYF(MY_ZEROFILL));
 
2780
    /*
 
2781
      This long list of assignments is not beautiful, but I see no way to
 
2782
      make it nicer, as the right members are #defines, not array members, so
 
2783
      it's impossible to write a loop.
 
2784
    */
 
2785
    if (post_header_len)
 
2786
    {
 
2787
      post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
 
2788
      post_header_len[QUERY_EVENT-1]= QUERY_HEADER_LEN;
 
2789
      post_header_len[ROTATE_EVENT-1]= ROTATE_HEADER_LEN;
 
2790
      post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
 
2791
      post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
 
2792
      post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
 
2793
      post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
 
2794
      post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
 
2795
      post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
 
2796
      post_header_len[FORMAT_DESCRIPTION_EVENT-1]= FORMAT_DESCRIPTION_HEADER_LEN;
 
2797
      post_header_len[TABLE_MAP_EVENT-1]=    TABLE_MAP_HEADER_LEN;
 
2798
      post_header_len[WRITE_ROWS_EVENT-1]=   ROWS_HEADER_LEN;
 
2799
      post_header_len[UPDATE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
 
2800
      post_header_len[DELETE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
 
2801
      /*
 
2802
        We here have the possibility to simulate a master of before we changed
 
2803
        the table map id to be stored in 6 bytes: when it was stored in 4
 
2804
        bytes (=> post_header_len was 6). This is used to test backward
 
2805
        compatibility.
 
2806
        This code can be removed after a few months (today is Dec 21st 2005),
 
2807
        when we know that the 4-byte masters are not deployed anymore (check
 
2808
        with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
 
2809
        too.
 
2810
      */
 
2811
      DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
2812
                      post_header_len[TABLE_MAP_EVENT-1]=
 
2813
                      post_header_len[WRITE_ROWS_EVENT-1]=
 
2814
                      post_header_len[UPDATE_ROWS_EVENT-1]=
 
2815
                      post_header_len[DELETE_ROWS_EVENT-1]= 6;);
 
2816
      post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
 
2817
      post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
 
2818
      post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
 
2819
      post_header_len[HEARTBEAT_LOG_EVENT-1]= 0;
 
2820
    }
 
2821
    break;
 
2822
 
 
2823
  case 1: /* 3.23 */
 
2824
  case 3: /* 4.0.x x>=2 */
 
2825
    /*
 
2826
      We build an artificial (i.e. not sent by the master) event, which
 
2827
      describes what those old master versions send.
 
2828
    */
 
2829
    if (binlog_ver==1)
 
2830
      strmov(server_version, server_ver ? server_ver : "3.23");
 
2831
    else
 
2832
      strmov(server_version, server_ver ? server_ver : "4.0");
 
2833
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
 
2834
      LOG_EVENT_MINIMAL_HEADER_LEN;
 
2835
    /*
 
2836
      The first new event in binlog version 4 is Format_desc. So any event type
 
2837
      after that does not exist in older versions. We use the events known by
 
2838
      version 3, even if version 1 had only a subset of them (this is not a
 
2839
      problem: it uses a few bytes for nothing but unifies code; it does not
 
2840
      make the slave detect less corruptions).
 
2841
    */
 
2842
    number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
 
2843
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
 
2844
                                       MYF(0));
 
2845
    if (post_header_len)
 
2846
    {
 
2847
      post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
 
2848
      post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
 
2849
      post_header_len[STOP_EVENT-1]= 0;
 
2850
      post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
 
2851
      post_header_len[INTVAR_EVENT-1]= 0;
 
2852
      post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
 
2853
      post_header_len[SLAVE_EVENT-1]= 0;
 
2854
      post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
 
2855
      post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
 
2856
      post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
 
2857
      post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
 
2858
      post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
 
2859
      post_header_len[RAND_EVENT-1]= 0;
 
2860
      post_header_len[USER_VAR_EVENT-1]= 0;
 
2861
    }
 
2862
    break;
 
2863
  default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
 
2864
    post_header_len= 0; /* will make is_valid() fail */
 
2865
    break;
 
2866
  }
 
2867
  calc_server_version_split();
 
2868
}
 
2869
 
 
2870
 
 
2871
/**
 
2872
  The problem with this constructor is that the fixed header may have a
 
2873
  length different from this version, but we don't know this length as we
 
2874
  have not read the Format_description_log_event which says it, yet. This
 
2875
  length is in the post-header of the event, but we don't know where the
 
2876
  post-header starts.
 
2877
 
 
2878
  So this type of event HAS to:
 
2879
  - either have the header's length at the beginning (in the header, at a
 
2880
  fixed position which will never be changed), not in the post-header. That
 
2881
  would make the header be "shifted" compared to other events.
 
2882
  - or have a header of size LOG_EVENT_MINIMAL_HEADER_LEN (19), in all future
 
2883
  versions, so that we know for sure.
 
2884
 
 
2885
  I (Guilhem) chose the 2nd solution. Rotate has the same constraint (because
 
2886
  it is sent before Format_description_log_event).
 
2887
*/
 
2888
 
 
2889
Format_description_log_event::
 
2890
Format_description_log_event(const char* buf,
 
2891
                             uint event_len,
 
2892
                             const
 
2893
                             Format_description_log_event*
 
2894
                             description_event)
 
2895
  :Start_log_event_v3(buf, description_event), event_type_permutation(0)
 
2896
{
 
2897
  DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
 
2898
  buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
 
2899
  if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
 
2900
    DBUG_VOID_RETURN; /* sanity check */
 
2901
  number_of_event_types=
 
2902
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
 
2903
  DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
 
2904
                      common_header_len, number_of_event_types));
 
2905
  /* If alloc fails, we'll detect it in is_valid() */
 
2906
  post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
 
2907
                                      number_of_event_types*
 
2908
                                      sizeof(*post_header_len), MYF(0));
 
2909
  calc_server_version_split();
 
2910
 
 
2911
  /*
 
2912
    In some previous versions, the events were given other event type
 
2913
    id numbers than in the present version. When replicating from such
 
2914
    a version, we therefore set up an array that maps those id numbers
 
2915
    to the id numbers of the present server.
 
2916
 
 
2917
    If post_header_len is null, it means malloc failed, and is_valid
 
2918
    will fail, so there is no need to do anything.
 
2919
 
 
2920
    The trees in which events have wrong id's are:
 
2921
 
 
2922
    mysql-5.1-wl1012.old mysql-5.1-wl2325-5.0-drop6p13-alpha
 
2923
    mysql-5.1-wl2325-5.0-drop6 mysql-5.1-wl2325-5.0
 
2924
    mysql-5.1-wl2325-no-dd
 
2925
 
 
2926
    (this was found by grepping for two lines in sequence where the
 
2927
    first matches "FORMAT_DESCRIPTION_EVENT," and the second matches
 
2928
    "TABLE_MAP_EVENT," in log_event.h in all trees)
 
2929
 
 
2930
    In these trees, the following server_versions existed since
 
2931
    TABLE_MAP_EVENT was introduced:
 
2932
 
 
2933
    5.1.1-a_drop5p3   5.1.1-a_drop5p4        5.1.1-alpha
 
2934
    5.1.2-a_drop5p10  5.1.2-a_drop5p11       5.1.2-a_drop5p12
 
2935
    5.1.2-a_drop5p13  5.1.2-a_drop5p14       5.1.2-a_drop5p15
 
2936
    5.1.2-a_drop5p16  5.1.2-a_drop5p16b      5.1.2-a_drop5p16c
 
2937
    5.1.2-a_drop5p17  5.1.2-a_drop5p4        5.1.2-a_drop5p5
 
2938
    5.1.2-a_drop5p6   5.1.2-a_drop5p7        5.1.2-a_drop5p8
 
2939
    5.1.2-a_drop5p9   5.1.3-a_drop5p17       5.1.3-a_drop5p17b
 
2940
    5.1.3-a_drop5p17c 5.1.4-a_drop5p18       5.1.4-a_drop5p19
 
2941
    5.1.4-a_drop5p20  5.1.4-a_drop6p0        5.1.4-a_drop6p1
 
2942
    5.1.4-a_drop6p2   5.1.5-a_drop5p20       5.2.0-a_drop6p3
 
2943
    5.2.0-a_drop6p4   5.2.0-a_drop6p5        5.2.0-a_drop6p6
 
2944
    5.2.1-a_drop6p10  5.2.1-a_drop6p11       5.2.1-a_drop6p12
 
2945
    5.2.1-a_drop6p6   5.2.1-a_drop6p7        5.2.1-a_drop6p8
 
2946
    5.2.2-a_drop6p13  5.2.2-a_drop6p13-alpha 5.2.2-a_drop6p13b
 
2947
    5.2.2-a_drop6p13c
 
2948
 
 
2949
    (this was found by grepping for "mysql," in all historical
 
2950
    versions of configure.in in the trees listed above).
 
2951
 
 
2952
    There are 5.1.1-alpha versions that use the new event id's, so we
 
2953
    do not test that version string.  So replication from 5.1.1-alpha
 
2954
    with the other event id's to a new version does not work.
 
2955
    Moreover, we can safely ignore the part after drop[56].  This
 
2956
    allows us to simplify the big list above to the following regexes:
 
2957
 
 
2958
    5\.1\.[1-5]-a_drop5.*
 
2959
    5\.1\.4-a_drop6.*
 
2960
    5\.2\.[0-2]-a_drop6.*
 
2961
 
 
2962
    This is what we test for in the 'if' below.
 
2963
  */
 
2964
  if (post_header_len &&
 
2965
      server_version[0] == '5' && server_version[1] == '.' &&
 
2966
      server_version[3] == '.' &&
 
2967
      strncmp(server_version + 5, "-a_drop", 7) == 0 &&
 
2968
      ((server_version[2] == '1' &&
 
2969
        server_version[4] >= '1' && server_version[4] <= '5' &&
 
2970
        server_version[12] == '5') ||
 
2971
       (server_version[2] == '1' &&
 
2972
        server_version[4] == '4' &&
 
2973
        server_version[12] == '6') ||
 
2974
       (server_version[2] == '2' &&
 
2975
        server_version[4] >= '0' && server_version[4] <= '2' &&
 
2976
        server_version[12] == '6')))
 
2977
  {
 
2978
    if (number_of_event_types != 22)
 
2979
    {
 
2980
      DBUG_PRINT("info", (" number_of_event_types=%d",
 
2981
                          number_of_event_types));
 
2982
      /* this makes is_valid() return false. */
 
2983
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
 
2984
      post_header_len= NULL;
 
2985
      DBUG_VOID_RETURN;
 
2986
    }
 
2987
    static const uint8 perm[23]=
 
2988
      {
 
2989
        UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
 
2990
        INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
 
2991
        APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
 
2992
        NEW_LOAD_EVENT,
 
2993
        RAND_EVENT, USER_VAR_EVENT,
 
2994
        FORMAT_DESCRIPTION_EVENT,
 
2995
        TABLE_MAP_EVENT,
 
2996
        PRE_GA_WRITE_ROWS_EVENT,
 
2997
        PRE_GA_UPDATE_ROWS_EVENT,
 
2998
        PRE_GA_DELETE_ROWS_EVENT,
 
2999
        XID_EVENT,
 
3000
        BEGIN_LOAD_QUERY_EVENT,
 
3001
        EXECUTE_LOAD_QUERY_EVENT,
 
3002
      };
 
3003
    event_type_permutation= perm;
 
3004
    /*
 
3005
      Since we use (permuted) event id's to index the post_header_len
 
3006
      array, we need to permute the post_header_len array too.
 
3007
    */
 
3008
    uint8 post_header_len_temp[23];
 
3009
    for (int i= 1; i < 23; i++)
 
3010
      post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
 
3011
    for (int i= 0; i < 22; i++)
 
3012
      post_header_len[i] = post_header_len_temp[i];
 
3013
  }
 
3014
  DBUG_VOID_RETURN;
 
3015
}
 
3016
 
 
3017
#ifndef MYSQL_CLIENT
 
3018
bool Format_description_log_event::write(IO_CACHE* file)
 
3019
{
 
3020
  /*
 
3021
    We don't call Start_log_event_v3::write() because this would make 2
 
3022
    my_b_safe_write().
 
3023
  */
 
3024
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
3025
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
 
3026
  memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
 
3027
  if (!dont_set_created)
 
3028
    created= when= get_time();
 
3029
  int4store(buff + ST_CREATED_OFFSET,created);
 
3030
  buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
 
3031
  memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
 
3032
         LOG_EVENT_TYPES);
 
3033
  return (write_header(file, sizeof(buff)) ||
 
3034
          my_b_safe_write(file, buff, sizeof(buff)));
 
3035
}
 
3036
#endif
 
3037
 
 
3038
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3039
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
 
3040
{
 
3041
  DBUG_ENTER("Format_description_log_event::do_apply_event");
 
3042
 
 
3043
  /*
 
3044
    As a transaction NEVER spans on 2 or more binlogs:
 
3045
    if we have an active transaction at this point, the master died
 
3046
    while writing the transaction to the binary log, i.e. while
 
3047
    flushing the binlog cache to the binlog. XA guarantees that master has
 
3048
    rolled back. So we roll back.
 
3049
    Note: this event could be sent by the master to inform us of the
 
3050
    format of its binlog; in other words maybe it is not at its
 
3051
    original place when it comes to us; we'll know this by checking
 
3052
    log_pos ("artificial" events have log_pos == 0).
 
3053
  */
 
3054
  if (!artificial_event && created && thd->transaction.all.ha_list)
 
3055
  {
 
3056
    /* This is not an error (XA is safe), just an information */
 
3057
    rli->report(INFORMATION_LEVEL, 0,
 
3058
                "Rolling back unfinished transaction (no COMMIT "
 
3059
                "or ROLLBACK in relay log). A probable cause is that "
 
3060
                "the master died while writing the transaction to "
 
3061
                "its binary log, thus rolled back too."); 
 
3062
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
 
3063
  }
 
3064
  /*
 
3065
    If this event comes from ourselves, there is no cleaning task to
 
3066
    perform, we don't call Start_log_event_v3::do_apply_event()
 
3067
    (this was just to update the log's description event).
 
3068
  */
 
3069
  if (server_id != (uint32) ::server_id)
 
3070
  {
 
3071
    /*
 
3072
      If the event was not requested by the slave i.e. the master sent
 
3073
      it while the slave asked for a position >4, the event will make
 
3074
      rli->group_master_log_pos advance. Say that the slave asked for
 
3075
      position 1000, and the Format_desc event's end is 96. Then in
 
3076
      the beginning of replication rli->group_master_log_pos will be
 
3077
      0, then 96, then jump to first really asked event (which is
 
3078
      >96). So this is ok.
 
3079
    */
 
3080
    DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
 
3081
  }
 
3082
  DBUG_RETURN(0);
 
3083
}
 
3084
 
 
3085
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
 
3086
{
 
3087
  /* save the information describing this binlog */
 
3088
  delete rli->relay_log.description_event_for_exec;
 
3089
  rli->relay_log.description_event_for_exec= this;
 
3090
 
 
3091
  if (server_id == (uint32) ::server_id)
 
3092
  {
 
3093
    /*
 
3094
      We only increase the relay log position if we are skipping
 
3095
      events and do not touch any group_* variables, nor flush the
 
3096
      relay log info.  If there is a crash, we will have to re-skip
 
3097
      the events again, but that is a minor issue.
 
3098
 
 
3099
      If we do not skip stepping the group log position (and the
 
3100
      server id was changed when restarting the server), it might well
 
3101
      be that we start executing at a position that is invalid, e.g.,
 
3102
      at a Rows_log_event or a Query_log_event preceeded by a
 
3103
      Intvar_log_event instead of starting at a Table_map_log_event or
 
3104
      the Intvar_log_event respectively.
 
3105
     */
 
3106
    rli->inc_event_relay_log_pos();
 
3107
    return 0;
 
3108
  }
 
3109
  else
 
3110
  {
 
3111
    return Log_event::do_update_pos(rli);
 
3112
  }
 
3113
}
 
3114
 
 
3115
Log_event::enum_skip_reason
 
3116
Format_description_log_event::do_shall_skip(Relay_log_info *rli)
 
3117
{
 
3118
  return Log_event::EVENT_SKIP_NOT;
 
3119
}
 
3120
 
 
3121
#endif
 
3122
 
 
3123
 
 
3124
/**
 
3125
   Splits the event's 'server_version' string into three numeric pieces stored
 
3126
   into 'server_version_split':
 
3127
   X.Y.Zabc (X,Y,Z numbers, a not a digit) -> {X,Y,Z}
 
3128
   X.Yabc -> {X,Y,0}
 
3129
   Xabc -> {X,0,0}
 
3130
   'server_version_split' is then used for lookups to find if the server which
 
3131
   created this event has some known bug.
 
3132
*/
 
3133
void Format_description_log_event::calc_server_version_split()
 
3134
{
 
3135
  char *p= server_version, *r;
 
3136
  ulong number;
 
3137
  for (uint i= 0; i<=2; i++)
 
3138
  {
 
3139
    number= strtoul(p, &r, 10);
 
3140
    server_version_split[i]= (uchar)number;
 
3141
    DBUG_ASSERT(number < 256); // fit in uchar
 
3142
    p= r;
 
3143
    DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
 
3144
    if (*r == '.')
 
3145
      p++; // skip the dot
 
3146
  }
 
3147
  DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
 
3148
                     " '%s' %d %d %d", server_version,
 
3149
                     server_version_split[0],
 
3150
                     server_version_split[1], server_version_split[2]));
 
3151
}
 
3152
 
 
3153
 
 
3154
  /**************************************************************************
 
3155
        Load_log_event methods
 
3156
   General note about Load_log_event: the binlogging of LOAD DATA INFILE is
 
3157
   going to be changed in 5.0 (or maybe in 5.1; not decided yet).
 
3158
   However, the 5.0 slave could still have to read such events (from a 4.x
 
3159
   master), convert them (which just means maybe expand the header, when 5.0
 
3160
   servers have a UID in events) (remember that whatever is after the header
 
3161
   will be like in 4.x, as this event's format is not modified in 5.0 as we
 
3162
   will use new types of events to log the new LOAD DATA INFILE features).
 
3163
   To be able to read/convert, we just need to not assume that the common
 
3164
   header is of length LOG_EVENT_HEADER_LEN (we must use the description
 
3165
   event).
 
3166
   Note that I (Guilhem) manually tested replication of a big LOAD DATA INFILE
 
3167
   between 3.23 and 5.0, and between 4.0 and 5.0, and it works fine (and the
 
3168
   positions displayed in SHOW SLAVE STATUS then are fine too).
 
3169
  **************************************************************************/
 
3170
 
 
3171
/*
 
3172
  Load_log_event::pack_info()
 
3173
*/
 
3174
 
 
3175
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3176
uint Load_log_event::get_query_buffer_length()
 
3177
{
 
3178
  return
 
3179
    5 + db_len + 3 +                        // "use DB; "
 
3180
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
 
3181
    7 +                                     // LOCAL
 
3182
    9 +                                     // " REPLACE or IGNORE "
 
3183
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
 
3184
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
 
3185
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
 
3186
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
 
3187
    21 + sql_ex.line_term_len*4 + 2 +       // " LINES TERMINATED BY 'str'"
 
3188
    19 + sql_ex.line_start_len*4 + 2 +      // " LINES STARTING BY 'str'"
 
3189
    15 + 22 +                               // " IGNORE xxx  LINES"
 
3190
    3 + (num_fields-1)*2 + field_block_len; // " (field1, field2, ...)"
 
3191
}
 
3192
 
 
3193
 
 
3194
void Load_log_event::print_query(bool need_db, char *buf,
 
3195
                                 char **end, char **fn_start, char **fn_end)
 
3196
{
 
3197
  char *pos= buf;
 
3198
 
 
3199
  if (need_db && db && db_len)
 
3200
  {
 
3201
    pos= strmov(pos, "use `");
 
3202
    memcpy(pos, db, db_len);
 
3203
    pos= strmov(pos+db_len, "`; ");
 
3204
  }
 
3205
 
 
3206
  pos= strmov(pos, "LOAD DATA ");
 
3207
 
 
3208
  if (fn_start)
 
3209
    *fn_start= pos;
 
3210
 
 
3211
  if (check_fname_outside_temp_buf())
 
3212
    pos= strmov(pos, "LOCAL ");
 
3213
  pos= strmov(pos, "INFILE '");
 
3214
  memcpy(pos, fname, fname_len);
 
3215
  pos= strmov(pos+fname_len, "' ");
 
3216
 
 
3217
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3218
    pos= strmov(pos, " REPLACE ");
 
3219
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3220
    pos= strmov(pos, " IGNORE ");
 
3221
 
 
3222
  pos= strmov(pos ,"INTO");
 
3223
 
 
3224
  if (fn_end)
 
3225
    *fn_end= pos;
 
3226
 
 
3227
  pos= strmov(pos ," TABLE `");
 
3228
  memcpy(pos, table_name, table_name_len);
 
3229
  pos+= table_name_len;
 
3230
 
 
3231
  /* We have to create all optinal fields as the default is not empty */
 
3232
  pos= strmov(pos, "` FIELDS TERMINATED BY ");
 
3233
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
 
3234
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3235
    pos= strmov(pos, " OPTIONALLY ");
 
3236
  pos= strmov(pos, " ENCLOSED BY ");
 
3237
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
 
3238
 
 
3239
  pos= strmov(pos, " ESCAPED BY ");
 
3240
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
 
3241
 
 
3242
  pos= strmov(pos, " LINES TERMINATED BY ");
 
3243
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
 
3244
  if (sql_ex.line_start_len)
 
3245
  {
 
3246
    pos= strmov(pos, " STARTING BY ");
 
3247
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
 
3248
  }
 
3249
 
 
3250
  if ((long) skip_lines > 0)
 
3251
  {
 
3252
    pos= strmov(pos, " IGNORE ");
 
3253
    pos= longlong10_to_str((longlong) skip_lines, pos, 10);
 
3254
    pos= strmov(pos," LINES ");    
 
3255
  }
 
3256
 
 
3257
  if (num_fields)
 
3258
  {
 
3259
    uint i;
 
3260
    const char *field= fields;
 
3261
    pos= strmov(pos, " (");
 
3262
    for (i = 0; i < num_fields; i++)
 
3263
    {
 
3264
      if (i)
 
3265
      {
 
3266
        *pos++= ' ';
 
3267
        *pos++= ',';
 
3268
      }
 
3269
      memcpy(pos, field, field_lens[i]);
 
3270
      pos+=   field_lens[i];
 
3271
      field+= field_lens[i]  + 1;
 
3272
    }
 
3273
    *pos++= ')';
 
3274
  }
 
3275
 
 
3276
  *end= pos;
 
3277
}
 
3278
 
 
3279
 
 
3280
void Load_log_event::pack_info(Protocol *protocol)
 
3281
{
 
3282
  char *buf, *end;
 
3283
 
 
3284
  if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
 
3285
    return;
 
3286
  print_query(TRUE, buf, &end, 0, 0);
 
3287
  protocol->store(buf, end-buf, &my_charset_bin);
 
3288
  my_free(buf, MYF(0));
 
3289
}
 
3290
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
3291
 
 
3292
 
 
3293
#ifndef MYSQL_CLIENT
 
3294
 
 
3295
/*
 
3296
  Load_log_event::write_data_header()
 
3297
*/
 
3298
 
 
3299
bool Load_log_event::write_data_header(IO_CACHE* file)
 
3300
{
 
3301
  char buf[LOAD_HEADER_LEN];
 
3302
  int4store(buf + L_THREAD_ID_OFFSET, slave_proxy_id);
 
3303
  int4store(buf + L_EXEC_TIME_OFFSET, exec_time);
 
3304
  int4store(buf + L_SKIP_LINES_OFFSET, skip_lines);
 
3305
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
 
3306
  buf[L_DB_LEN_OFFSET] = (char)db_len;
 
3307
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
 
3308
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
 
3309
}
 
3310
 
 
3311
 
 
3312
/*
 
3313
  Load_log_event::write_data_body()
 
3314
*/
 
3315
 
 
3316
bool Load_log_event::write_data_body(IO_CACHE* file)
 
3317
{
 
3318
  if (sql_ex.write_data(file))
 
3319
    return 1;
 
3320
  if (num_fields && fields && field_lens)
 
3321
  {
 
3322
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
 
3323
        my_b_safe_write(file, (uchar*)fields, field_block_len))
 
3324
      return 1;
 
3325
  }
 
3326
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
 
3327
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
 
3328
          my_b_safe_write(file, (uchar*)fname, fname_len));
 
3329
}
 
3330
 
 
3331
 
 
3332
/*
 
3333
  Load_log_event::Load_log_event()
 
3334
*/
 
3335
 
 
3336
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
 
3337
                               const char *db_arg, const char *table_name_arg,
 
3338
                               List<Item> &fields_arg,
 
3339
                               enum enum_duplicates handle_dup,
 
3340
                               bool ignore, bool using_trans)
 
3341
  :Log_event(thd_arg,
 
3342
             thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
 
3343
             using_trans),
 
3344
   thread_id(thd_arg->thread_id),
 
3345
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
 
3346
   num_fields(0),fields(0),
 
3347
   field_lens(0),field_block_len(0),
 
3348
   table_name(table_name_arg ? table_name_arg : ""),
 
3349
   db(db_arg), fname(ex->file_name), local_fname(FALSE)
 
3350
{
 
3351
  time_t end_time;
 
3352
  time(&end_time);
 
3353
  exec_time = (ulong) (end_time  - thd_arg->start_time);
 
3354
  /* db can never be a zero pointer in 4.0 */
 
3355
  db_len = (uint32) strlen(db);
 
3356
  table_name_len = (uint32) strlen(table_name);
 
3357
  fname_len = (fname) ? (uint) strlen(fname) : 0;
 
3358
  sql_ex.field_term = (char*) ex->field_term->ptr();
 
3359
  sql_ex.field_term_len = (uint8) ex->field_term->length();
 
3360
  sql_ex.enclosed = (char*) ex->enclosed->ptr();
 
3361
  sql_ex.enclosed_len = (uint8) ex->enclosed->length();
 
3362
  sql_ex.line_term = (char*) ex->line_term->ptr();
 
3363
  sql_ex.line_term_len = (uint8) ex->line_term->length();
 
3364
  sql_ex.line_start = (char*) ex->line_start->ptr();
 
3365
  sql_ex.line_start_len = (uint8) ex->line_start->length();
 
3366
  sql_ex.escaped = (char*) ex->escaped->ptr();
 
3367
  sql_ex.escaped_len = (uint8) ex->escaped->length();
 
3368
  sql_ex.opt_flags = 0;
 
3369
  sql_ex.cached_new_format = -1;
 
3370
    
 
3371
  if (ex->dumpfile)
 
3372
    sql_ex.opt_flags|= DUMPFILE_FLAG;
 
3373
  if (ex->opt_enclosed)
 
3374
    sql_ex.opt_flags|= OPT_ENCLOSED_FLAG;
 
3375
 
 
3376
  sql_ex.empty_flags= 0;
 
3377
 
 
3378
  switch (handle_dup) {
 
3379
  case DUP_REPLACE:
 
3380
    sql_ex.opt_flags|= REPLACE_FLAG;
 
3381
    break;
 
3382
  case DUP_UPDATE:                              // Impossible here
 
3383
  case DUP_ERROR:
 
3384
    break;      
 
3385
  }
 
3386
  if (ignore)
 
3387
    sql_ex.opt_flags|= IGNORE_FLAG;
 
3388
 
 
3389
  if (!ex->field_term->length())
 
3390
    sql_ex.empty_flags |= FIELD_TERM_EMPTY;
 
3391
  if (!ex->enclosed->length())
 
3392
    sql_ex.empty_flags |= ENCLOSED_EMPTY;
 
3393
  if (!ex->line_term->length())
 
3394
    sql_ex.empty_flags |= LINE_TERM_EMPTY;
 
3395
  if (!ex->line_start->length())
 
3396
    sql_ex.empty_flags |= LINE_START_EMPTY;
 
3397
  if (!ex->escaped->length())
 
3398
    sql_ex.empty_flags |= ESCAPED_EMPTY;
 
3399
    
 
3400
  skip_lines = ex->skip_lines;
 
3401
 
 
3402
  List_iterator<Item> li(fields_arg);
 
3403
  field_lens_buf.length(0);
 
3404
  fields_buf.length(0);
 
3405
  Item* item;
 
3406
  while ((item = li++))
 
3407
  {
 
3408
    num_fields++;
 
3409
    uchar len = (uchar) strlen(item->name);
 
3410
    field_block_len += len + 1;
 
3411
    fields_buf.append(item->name, len + 1);
 
3412
    field_lens_buf.append((char*)&len, 1);
 
3413
  }
 
3414
 
 
3415
  field_lens = (const uchar*)field_lens_buf.ptr();
 
3416
  fields = fields_buf.ptr();
 
3417
}
 
3418
#endif /* !MYSQL_CLIENT */
 
3419
 
 
3420
 
 
3421
/**
 
3422
  @note
 
3423
    The caller must do buf[event_len] = 0 before he starts using the
 
3424
    constructed event.
 
3425
*/
 
3426
Load_log_event::Load_log_event(const char *buf, uint event_len,
 
3427
                               const Format_description_log_event *description_event)
 
3428
  :Log_event(buf, description_event), num_fields(0), fields(0),
 
3429
   field_lens(0),field_block_len(0),
 
3430
   table_name(0), db(0), fname(0), local_fname(FALSE)
 
3431
{
 
3432
  DBUG_ENTER("Load_log_event");
 
3433
  /*
 
3434
    I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
 
3435
    4.0->5.0 and 5.0->5.0 and it works.
 
3436
  */
 
3437
  if (event_len)
 
3438
    copy_log_event(buf, event_len,
 
3439
                   ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
 
3440
                    LOAD_HEADER_LEN + 
 
3441
                    description_event->common_header_len :
 
3442
                    LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
 
3443
                   description_event);
 
3444
  /* otherwise it's a derived class, will call copy_log_event() itself */
 
3445
  DBUG_VOID_RETURN;
 
3446
}
 
3447
 
 
3448
 
 
3449
/*
 
3450
  Load_log_event::copy_log_event()
 
3451
*/
 
3452
 
 
3453
int Load_log_event::copy_log_event(const char *buf, ulong event_len,
 
3454
                                   int body_offset,
 
3455
                                   const Format_description_log_event *description_event)
 
3456
{
 
3457
  DBUG_ENTER("Load_log_event::copy_log_event");
 
3458
  uint data_len;
 
3459
  char* buf_end = (char*)buf + event_len;
 
3460
  /* this is the beginning of the post-header */
 
3461
  const char* data_head = buf + description_event->common_header_len;
 
3462
  slave_proxy_id= thread_id= uint4korr(data_head + L_THREAD_ID_OFFSET);
 
3463
  exec_time = uint4korr(data_head + L_EXEC_TIME_OFFSET);
 
3464
  skip_lines = uint4korr(data_head + L_SKIP_LINES_OFFSET);
 
3465
  table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
 
3466
  db_len = (uint)data_head[L_DB_LEN_OFFSET];
 
3467
  num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
 
3468
          
 
3469
  if ((int) event_len < body_offset)
 
3470
    DBUG_RETURN(1);
 
3471
  /*
 
3472
    Sql_ex.init() on success returns the pointer to the first byte after
 
3473
    the sql_ex structure, which is the start of field lengths array.
 
3474
  */
 
3475
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
 
3476
                                        buf_end,
 
3477
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
 
3478
    DBUG_RETURN(1);
 
3479
  
 
3480
  data_len = event_len - body_offset;
 
3481
  if (num_fields > data_len) // simple sanity check against corruption
 
3482
    DBUG_RETURN(1);
 
3483
  for (uint i = 0; i < num_fields; i++)
 
3484
    field_block_len += (uint)field_lens[i] + 1;
 
3485
 
 
3486
  fields = (char*)field_lens + num_fields;
 
3487
  table_name  = fields + field_block_len;
 
3488
  db = table_name + table_name_len + 1;
 
3489
  fname = db + db_len + 1;
 
3490
  fname_len = strlen(fname);
 
3491
  // null termination is accomplished by the caller doing buf[event_len]=0
 
3492
 
 
3493
  DBUG_RETURN(0);
 
3494
}
 
3495
 
 
3496
 
 
3497
/*
 
3498
  Load_log_event::print()
 
3499
*/
 
3500
 
 
3501
#ifdef MYSQL_CLIENT
 
3502
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3503
{
 
3504
  print(file, print_event_info, 0);
 
3505
}
 
3506
 
 
3507
 
 
3508
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 
3509
                           bool commented)
 
3510
{
 
3511
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
3512
 
 
3513
  DBUG_ENTER("Load_log_event::print");
 
3514
  if (!print_event_info->short_form)
 
3515
  {
 
3516
    print_header(&cache, print_event_info, FALSE);
 
3517
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 
3518
                thread_id, exec_time);
 
3519
  }
 
3520
 
 
3521
  bool different_db= 1;
 
3522
  if (db)
 
3523
  {
 
3524
    /*
 
3525
      If the database is different from the one of the previous statement, we
 
3526
      need to print the "use" command, and we update the last_db.
 
3527
      But if commented, the "use" is going to be commented so we should not
 
3528
      update the last_db.
 
3529
    */
 
3530
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
 
3531
        !commented)
 
3532
      memcpy(print_event_info->db, db, db_len + 1);
 
3533
  }
 
3534
  
 
3535
  if (db && db[0] && different_db)
 
3536
    my_b_printf(&cache, "%suse %s%s\n", 
 
3537
            commented ? "# " : "",
 
3538
            db, print_event_info->delimiter);
 
3539
 
 
3540
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
 
3541
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
 
3542
            commented ? "# " : "", (ulong)thread_id,
 
3543
            print_event_info->delimiter);
 
3544
  my_b_printf(&cache, "%sLOAD DATA ",
 
3545
              commented ? "# " : "");
 
3546
  if (check_fname_outside_temp_buf())
 
3547
    my_b_printf(&cache, "LOCAL ");
 
3548
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
 
3549
 
 
3550
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3551
    my_b_printf(&cache," REPLACE ");
 
3552
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3553
    my_b_printf(&cache," IGNORE ");
 
3554
  
 
3555
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
 
3556
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
 
3557
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
 
3558
 
 
3559
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3560
    my_b_printf(&cache," OPTIONALLY ");
 
3561
  my_b_printf(&cache, " ENCLOSED BY ");
 
3562
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
 
3563
     
 
3564
  my_b_printf(&cache, " ESCAPED BY ");
 
3565
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
 
3566
     
 
3567
  my_b_printf(&cache," LINES TERMINATED BY ");
 
3568
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
 
3569
 
 
3570
 
 
3571
  if (sql_ex.line_start)
 
3572
  {
 
3573
    my_b_printf(&cache," STARTING BY ");
 
3574
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
 
3575
  }
 
3576
  if ((long) skip_lines > 0)
 
3577
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
 
3578
 
 
3579
  if (num_fields)
 
3580
  {
 
3581
    uint i;
 
3582
    const char* field = fields;
 
3583
    my_b_printf(&cache, " (");
 
3584
    for (i = 0; i < num_fields; i++)
 
3585
    {
 
3586
      if (i)
 
3587
        my_b_printf(&cache, ",");
 
3588
      my_b_printf(&cache, field);
 
3589
          
 
3590
      field += field_lens[i]  + 1;
 
3591
    }
 
3592
    my_b_printf(&cache, ")");
 
3593
  }
 
3594
 
 
3595
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
 
3596
  DBUG_VOID_RETURN;
 
3597
}
 
3598
#endif /* MYSQL_CLIENT */
 
3599
 
 
3600
#ifndef MYSQL_CLIENT
 
3601
 
 
3602
/**
 
3603
  Load_log_event::set_fields()
 
3604
 
 
3605
  @note
 
3606
    This function can not use the member variable 
 
3607
    for the database, since LOAD DATA INFILE on the slave
 
3608
    can be for a different database than the current one.
 
3609
    This is the reason for the affected_db argument to this method.
 
3610
*/
 
3611
 
 
3612
void Load_log_event::set_fields(const char* affected_db, 
 
3613
                                List<Item> &field_list,
 
3614
                                Name_resolution_context *context)
 
3615
{
 
3616
  uint i;
 
3617
  const char* field = fields;
 
3618
  for (i= 0; i < num_fields; i++)
 
3619
  {
 
3620
    field_list.push_back(new Item_field(context,
 
3621
                                        affected_db, table_name, field));
 
3622
    field+= field_lens[i]  + 1;
 
3623
  }
 
3624
}
 
3625
#endif /* !MYSQL_CLIENT */
 
3626
 
 
3627
 
 
3628
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3629
/**
 
3630
  Does the data loading job when executing a LOAD DATA on the slave.
 
3631
 
 
3632
  @param net
 
3633
  @param rli
 
3634
  @param use_rli_only_for_errors     If set to 1, rli is provided to
 
3635
                                     Load_log_event::exec_event only for this
 
3636
                                     function to have RPL_LOG_NAME and
 
3637
                                     rli->last_slave_error, both being used by
 
3638
                                     error reports. rli's position advancing
 
3639
                                     is skipped (done by the caller which is
 
3640
                                     Execute_load_log_event::exec_event).
 
3641
                                     If set to 0, rli is provided for full use,
 
3642
                                     i.e. for error reports and position
 
3643
                                     advancing.
 
3644
 
 
3645
  @todo
 
3646
    fix this; this can be done by testing rules in
 
3647
    Create_file_log_event::exec_event() and then discarding Append_block and
 
3648
    al.
 
3649
  @todo
 
3650
    this is a bug - this needs to be moved to the I/O thread
 
3651
 
 
3652
  @retval
 
3653
    0           Success
 
3654
  @retval
 
3655
    1           Failure
 
3656
*/
 
3657
 
 
3658
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
 
3659
                                   bool use_rli_only_for_errors)
 
3660
{
 
3661
  LEX_STRING new_db;
 
3662
  new_db.length= db_len;
 
3663
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
 
3664
  thd->set_db(new_db.str, new_db.length);
 
3665
  DBUG_ASSERT(thd->query == 0);
 
3666
  thd->query_length= 0;                         // Should not be needed
 
3667
  thd->is_slave_error= 0;
 
3668
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
3669
 
 
3670
  /* see Query_log_event::do_apply_event() and BUG#13360 */
 
3671
  DBUG_ASSERT(!rli->m_table_map.count());
 
3672
  /*
 
3673
    Usually lex_start() is called by mysql_parse(), but we need it here
 
3674
    as the present method does not call mysql_parse().
 
3675
  */
 
3676
  lex_start(thd);
 
3677
  mysql_reset_thd_for_next_command(thd);
 
3678
 
 
3679
  if (!use_rli_only_for_errors)
 
3680
  {
 
3681
    /*
 
3682
      Saved for InnoDB, see comment in
 
3683
      Query_log_event::do_apply_event()
 
3684
    */
 
3685
    const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
 
3686
    DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
 
3687
  }
 
3688
 
 
3689
   /*
 
3690
    We test replicate_*_db rules. Note that we have already prepared
 
3691
    the file to load, even if we are going to ignore and delete it
 
3692
    now. So it is possible that we did a lot of disk writes for
 
3693
    nothing. In other words, a big LOAD DATA INFILE on the master will
 
3694
    still consume a lot of space on the slave (space in the relay log
 
3695
    + space of temp files: twice the space of the file to load...)
 
3696
    even if it will finally be ignored.  TODO: fix this; this can be
 
3697
    done by testing rules in Create_file_log_event::do_apply_event()
 
3698
    and then discarding Append_block and al. Another way is do the
 
3699
    filtering in the I/O thread (more efficient: no disk writes at
 
3700
    all).
 
3701
 
 
3702
 
 
3703
    Note:   We do not need to execute reset_one_shot_variables() if this
 
3704
            db_ok() test fails.
 
3705
    Reason: The db stored in binlog events is the same for SET and for
 
3706
            its companion query.  If the SET is ignored because of
 
3707
            db_ok(), the companion query will also be ignored, and if
 
3708
            the companion query is ignored in the db_ok() test of
 
3709
            ::do_apply_event(), then the companion SET also have so
 
3710
            we don't need to reset_one_shot_variables().
 
3711
  */
 
3712
  if (rpl_filter->db_ok(thd->db))
 
3713
  {
 
3714
    thd->set_time((time_t)when);
 
3715
    VOID(pthread_mutex_lock(&LOCK_thread_count));
 
3716
    thd->query_id = next_query_id();
 
3717
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
3718
    /*
 
3719
      Initing thd->row_count is not necessary in theory as this variable has no
 
3720
      influence in the case of the slave SQL thread (it is used to generate a
 
3721
      "data truncated" warning but which is absorbed and never gets to the
 
3722
      error log); still we init it to avoid a Valgrind message.
 
3723
    */
 
3724
    mysql_reset_errors(thd, 0);
 
3725
 
 
3726
    TABLE_LIST tables;
 
3727
    bzero((char*) &tables,sizeof(tables));
 
3728
    tables.db= thd->strmake(thd->db, thd->db_length);
 
3729
    tables.alias = tables.table_name = (char*) table_name;
 
3730
    tables.lock_type = TL_WRITE;
 
3731
    tables.updating= 1;
 
3732
 
 
3733
    // the table will be opened in mysql_load    
 
3734
    if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
 
3735
    {
 
3736
      // TODO: this is a bug - this needs to be moved to the I/O thread
 
3737
      if (net)
 
3738
        skip_load_data_infile(net);
 
3739
    }
 
3740
    else
 
3741
    {
 
3742
      char llbuff[22];
 
3743
      char *end;
 
3744
      enum enum_duplicates handle_dup;
 
3745
      bool ignore= 0;
 
3746
      char *load_data_query;
 
3747
 
 
3748
      /*
 
3749
        Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
 
3750
        and written to slave's binlog if binlogging is on.
 
3751
      */
 
3752
      if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
 
3753
      {
 
3754
        /*
 
3755
          This will set thd->fatal_error in case of OOM. So we surely will notice
 
3756
          that something is wrong.
 
3757
        */
 
3758
        goto error;
 
3759
      }
 
3760
 
 
3761
      print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
 
3762
                  (char **)&thd->lex->fname_end);
 
3763
      *end= 0;
 
3764
      thd->query_length= end - load_data_query;
 
3765
      thd->query= load_data_query;
 
3766
 
 
3767
      if (sql_ex.opt_flags & REPLACE_FLAG)
 
3768
      {
 
3769
        handle_dup= DUP_REPLACE;
 
3770
      }
 
3771
      else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3772
      {
 
3773
        ignore= 1;
 
3774
        handle_dup= DUP_ERROR;
 
3775
      }
 
3776
      else
 
3777
      {
 
3778
        /*
 
3779
          When replication is running fine, if it was DUP_ERROR on the
 
3780
          master then we could choose IGNORE here, because if DUP_ERROR
 
3781
          suceeded on master, and data is identical on the master and slave,
 
3782
          then there should be no uniqueness errors on slave, so IGNORE is
 
3783
          the same as DUP_ERROR. But in the unlikely case of uniqueness errors
 
3784
          (because the data on the master and slave happen to be different
 
3785
          (user error or bug), we want LOAD DATA to print an error message on
 
3786
          the slave to discover the problem.
 
3787
 
 
3788
          If reading from net (a 3.23 master), mysql_load() will change this
 
3789
          to IGNORE.
 
3790
        */
 
3791
        handle_dup= DUP_ERROR;
 
3792
      }
 
3793
      /*
 
3794
        We need to set thd->lex->sql_command and thd->lex->duplicates
 
3795
        since InnoDB tests these variables to decide if this is a LOAD
 
3796
        DATA ... REPLACE INTO ... statement even though mysql_parse()
 
3797
        is not called.  This is not needed in 5.0 since there the LOAD
 
3798
        DATA ... statement is replicated using mysql_parse(), which
 
3799
        sets the thd->lex fields correctly.
 
3800
      */
 
3801
      thd->lex->sql_command= SQLCOM_LOAD;
 
3802
      thd->lex->duplicates= handle_dup;
 
3803
 
 
3804
      sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
 
3805
      String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
 
3806
      String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
 
3807
      String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
 
3808
      String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
 
3809
      String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
 
3810
      ex.field_term= &field_term;
 
3811
      ex.enclosed= &enclosed;
 
3812
      ex.line_term= &line_term;
 
3813
      ex.line_start= &line_start;
 
3814
      ex.escaped= &escaped;
 
3815
 
 
3816
      ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
 
3817
      if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
 
3818
        ex.field_term->length(0);
 
3819
 
 
3820
      ex.skip_lines = skip_lines;
 
3821
      List<Item> field_list;
 
3822
      thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
 
3823
      set_fields(tables.db, field_list, &thd->lex->select_lex.context);
 
3824
      thd->variables.pseudo_thread_id= thread_id;
 
3825
      if (net)
 
3826
      {
 
3827
        // mysql_load will use thd->net to read the file
 
3828
        thd->net.vio = net->vio;
 
3829
        /*
 
3830
          Make sure the client does not get confused about the packet sequence
 
3831
        */
 
3832
        thd->net.pkt_nr = net->pkt_nr;
 
3833
      }
 
3834
      /*
 
3835
        It is safe to use tmp_list twice because we are not going to
 
3836
        update it inside mysql_load().
 
3837
      */
 
3838
      List<Item> tmp_list;
 
3839
      if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
 
3840
                     handle_dup, ignore, net != 0))
 
3841
        thd->is_slave_error= 1;
 
3842
      if (thd->cuted_fields)
 
3843
      {
 
3844
        /* log_pos is the position of the LOAD event in the master log */
 
3845
        sql_print_warning("Slave: load data infile on table '%s' at "
 
3846
                          "log position %s in log '%s' produced %ld "
 
3847
                          "warning(s). Default database: '%s'",
 
3848
                          (char*) table_name,
 
3849
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
 
3850
                          (ulong) thd->cuted_fields,
 
3851
                          print_slave_db_safe(thd->db));
 
3852
      }
 
3853
      if (net)
 
3854
        net->pkt_nr= thd->net.pkt_nr;
 
3855
    }
 
3856
  }
 
3857
  else
 
3858
  {
 
3859
    /*
 
3860
      We will just ask the master to send us /dev/null if we do not
 
3861
      want to load the data.
 
3862
      TODO: this a bug - needs to be done in I/O thread
 
3863
    */
 
3864
    if (net)
 
3865
      skip_load_data_infile(net);
 
3866
  }
 
3867
 
 
3868
error:
 
3869
  thd->net.vio = 0; 
 
3870
  const char *remember_db= thd->db;
 
3871
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
3872
  thd->catalog= 0;
 
3873
  thd->set_db(NULL, 0);                   /* will free the current database */
 
3874
  thd->query= 0;
 
3875
  thd->query_length= 0;
 
3876
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
3877
  close_thread_tables(thd);
 
3878
 
 
3879
  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
 
3880
                  thd->is_slave_error= 0; thd->is_fatal_error= 1;);
 
3881
 
 
3882
  if (thd->is_slave_error)
 
3883
  {
 
3884
    /* this err/sql_errno code is copy-paste from net_send_error() */
 
3885
    const char *err;
 
3886
    int sql_errno;
 
3887
    if (thd->is_error())
 
3888
    {
 
3889
      err= thd->main_da.message();
 
3890
      sql_errno= thd->main_da.sql_errno();
 
3891
    }
 
3892
    else
 
3893
    {
 
3894
      sql_errno=ER_UNKNOWN_ERROR;
 
3895
      err=ER(sql_errno);       
 
3896
    }
 
3897
    rli->report(ERROR_LEVEL, sql_errno,"\
 
3898
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
 
3899
                    err, (char*)table_name, print_slave_db_safe(remember_db));
 
3900
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
3901
    return 1;
 
3902
  }
 
3903
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
3904
 
 
3905
  if (thd->is_fatal_error)
 
3906
  {
 
3907
    char buf[256];
 
3908
    my_snprintf(buf, sizeof(buf),
 
3909
                "Running LOAD DATA INFILE on table '%-.64s'."
 
3910
                " Default database: '%-.64s'",
 
3911
                (char*)table_name,
 
3912
                print_slave_db_safe(remember_db));
 
3913
 
 
3914
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
 
3915
                ER(ER_SLAVE_FATAL_ERROR), buf);
 
3916
    return 1;
 
3917
  }
 
3918
 
 
3919
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
 
3920
}
 
3921
#endif
 
3922
 
 
3923
 
 
3924
/**************************************************************************
 
3925
  Rotate_log_event methods
 
3926
**************************************************************************/
 
3927
 
 
3928
/*
 
3929
  Rotate_log_event::pack_info()
 
3930
*/
 
3931
 
 
3932
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3933
void Rotate_log_event::pack_info(Protocol *protocol)
 
3934
{
 
3935
  char buf1[256], buf[22];
 
3936
  String tmp(buf1, sizeof(buf1), log_cs);
 
3937
  tmp.length(0);
 
3938
  tmp.append(new_log_ident, ident_len);
 
3939
  tmp.append(STRING_WITH_LEN(";pos="));
 
3940
  tmp.append(llstr(pos,buf));
 
3941
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
 
3942
}
 
3943
#endif
 
3944
 
 
3945
 
 
3946
/*
 
3947
  Rotate_log_event::print()
 
3948
*/
 
3949
 
 
3950
#ifdef MYSQL_CLIENT
 
3951
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3952
{
 
3953
  char buf[22];
 
3954
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
3955
                               Write_on_release_cache::FLUSH_F);
 
3956
 
 
3957
  if (print_event_info->short_form)
 
3958
    return;
 
3959
  print_header(&cache, print_event_info, FALSE);
 
3960
  my_b_printf(&cache, "\tRotate to ");
 
3961
  if (new_log_ident)
 
3962
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
 
3963
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
 
3964
}
 
3965
#endif /* MYSQL_CLIENT */
 
3966
 
 
3967
 
 
3968
 
 
3969
/*
 
3970
  Rotate_log_event::Rotate_log_event() (2 constructors)
 
3971
*/
 
3972
 
 
3973
 
 
3974
#ifndef MYSQL_CLIENT
 
3975
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
 
3976
                                   uint ident_len_arg, ulonglong pos_arg,
 
3977
                                   uint flags_arg)
 
3978
  :Log_event(), new_log_ident(new_log_ident_arg),
 
3979
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
 
3980
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
 
3981
{
 
3982
#ifndef DBUG_OFF
 
3983
  char buff[22];
 
3984
  DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
 
3985
  DBUG_PRINT("enter",("new_log_ident: %s  pos: %s  flags: %lu", new_log_ident_arg,
 
3986
                      llstr(pos_arg, buff), (ulong) flags));
 
3987
#endif
 
3988
  if (flags & DUP_NAME)
 
3989
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
 
3990
  DBUG_VOID_RETURN;
 
3991
}
 
3992
#endif
 
3993
 
 
3994
 
 
3995
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
 
3996
                                   const Format_description_log_event* description_event)
 
3997
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
 
3998
{
 
3999
  DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
 
4000
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
 
4001
  uint8 header_size= description_event->common_header_len;
 
4002
  uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
 
4003
  uint ident_offset;
 
4004
  if (event_len < header_size)
 
4005
    DBUG_VOID_RETURN;
 
4006
  buf += header_size;
 
4007
  pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
 
4008
  ident_len = (uint)(event_len -
 
4009
                     (header_size+post_header_len)); 
 
4010
  ident_offset = post_header_len; 
 
4011
  set_if_smaller(ident_len,FN_REFLEN-1);
 
4012
  new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
 
4013
  DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
 
4014
  DBUG_VOID_RETURN;
 
4015
}
 
4016
 
 
4017
 
 
4018
/*
 
4019
  Rotate_log_event::write()
 
4020
*/
 
4021
 
 
4022
#ifndef MYSQL_CLIENT
 
4023
bool Rotate_log_event::write(IO_CACHE* file)
 
4024
{
 
4025
  char buf[ROTATE_HEADER_LEN];
 
4026
  int8store(buf + R_POS_OFFSET, pos);
 
4027
  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
 
4028
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
 
4029
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
 
4030
}
 
4031
#endif
 
4032
 
 
4033
 
 
4034
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4035
 
 
4036
/*
 
4037
  Got a rotate log event from the master.
 
4038
 
 
4039
  This is mainly used so that we can later figure out the logname and
 
4040
  position for the master.
 
4041
 
 
4042
  We can't rotate the slave's BINlog as this will cause infinitive rotations
 
4043
  in a A -> B -> A setup.
 
4044
  The NOTES below is a wrong comment which will disappear when 4.1 is merged.
 
4045
 
 
4046
  @retval
 
4047
    0   ok
 
4048
*/
 
4049
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
 
4050
{
 
4051
  DBUG_ENTER("Rotate_log_event::do_update_pos");
 
4052
#ifndef DBUG_OFF
 
4053
  char buf[32];
 
4054
#endif
 
4055
 
 
4056
  DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
 
4057
                      (ulong) this->server_id, (ulong) ::server_id));
 
4058
  DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
 
4059
  DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
 
4060
 
 
4061
  pthread_mutex_lock(&rli->data_lock);
 
4062
  rli->event_relay_log_pos= my_b_tell(rli->cur_log);
 
4063
  /*
 
4064
    If we are in a transaction or in a group: the only normal case is
 
4065
    when the I/O thread was copying a big transaction, then it was
 
4066
    stopped and restarted: we have this in the relay log:
 
4067
 
 
4068
    BEGIN
 
4069
    ...
 
4070
    ROTATE (a fake one)
 
4071
    ...
 
4072
    COMMIT or ROLLBACK
 
4073
 
 
4074
    In that case, we don't want to touch the coordinates which
 
4075
    correspond to the beginning of the transaction.  Starting from
 
4076
    5.0.0, there also are some rotates from the slave itself, in the
 
4077
    relay log, which shall not change the group positions.
 
4078
  */
 
4079
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
 
4080
      !rli->is_in_group())
 
4081
  {
 
4082
    DBUG_PRINT("info", ("old group_master_log_name: '%s'  "
 
4083
                        "old group_master_log_pos: %lu",
 
4084
                        rli->group_master_log_name,
 
4085
                        (ulong) rli->group_master_log_pos));
 
4086
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
 
4087
    rli->notify_group_master_log_name_update();
 
4088
    rli->group_master_log_pos= pos;
 
4089
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
 
4090
            sizeof(rli->group_relay_log_name) - 1);
 
4091
    rli->notify_group_relay_log_name_update();
 
4092
    rli->group_relay_log_pos= rli->event_relay_log_pos;
 
4093
    DBUG_PRINT("info", ("new group_master_log_name: '%s'  "
 
4094
                        "new group_master_log_pos: %lu",
 
4095
                        rli->group_master_log_name,
 
4096
                        (ulong) rli->group_master_log_pos));
 
4097
    /*
 
4098
      Reset thd->options and sql_mode etc, because this could be the signal of
 
4099
      a master's downgrade from 5.0 to 4.0.
 
4100
      However, no need to reset description_event_for_exec: indeed, if the next
 
4101
      master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
 
4102
      master is 4.0 then the events are in the slave's format (conversion).
 
4103
    */
 
4104
    set_slave_thread_options(thd);
 
4105
    set_slave_thread_default_charset(thd, rli);
 
4106
    thd->variables.auto_increment_increment=
 
4107
      thd->variables.auto_increment_offset= 1;
 
4108
  }
 
4109
  pthread_mutex_unlock(&rli->data_lock);
 
4110
  pthread_cond_broadcast(&rli->data_cond);
 
4111
  flush_relay_log_info(rli);
 
4112
 
 
4113
  DBUG_RETURN(0);
 
4114
}
 
4115
 
 
4116
 
 
4117
Log_event::enum_skip_reason
 
4118
Rotate_log_event::do_shall_skip(Relay_log_info *rli)
 
4119
{
 
4120
  enum_skip_reason reason= Log_event::do_shall_skip(rli);
 
4121
 
 
4122
  switch (reason) {
 
4123
  case Log_event::EVENT_SKIP_NOT:
 
4124
  case Log_event::EVENT_SKIP_COUNT:
 
4125
    return Log_event::EVENT_SKIP_NOT;
 
4126
 
 
4127
  case Log_event::EVENT_SKIP_IGNORE:
 
4128
    return Log_event::EVENT_SKIP_IGNORE;
 
4129
  }
 
4130
  DBUG_ASSERT(0);
 
4131
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
 
4132
}
 
4133
 
 
4134
#endif
 
4135
 
 
4136
 
 
4137
/**************************************************************************
 
4138
        Intvar_log_event methods
 
4139
**************************************************************************/
 
4140
 
 
4141
/*
 
4142
  Intvar_log_event::pack_info()
 
4143
*/
 
4144
 
 
4145
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4146
void Intvar_log_event::pack_info(Protocol *protocol)
 
4147
{
 
4148
  char buf[256], *pos;
 
4149
  pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
 
4150
  *pos++= '=';
 
4151
  pos= longlong10_to_str(val, pos, -10);
 
4152
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
 
4153
}
 
4154
#endif
 
4155
 
 
4156
 
 
4157
/*
 
4158
  Intvar_log_event::Intvar_log_event()
 
4159
*/
 
4160
 
 
4161
Intvar_log_event::Intvar_log_event(const char* buf,
 
4162
                                   const Format_description_log_event* description_event)
 
4163
  :Log_event(buf, description_event)
 
4164
{
 
4165
  buf+= description_event->common_header_len;
 
4166
  type= buf[I_TYPE_OFFSET];
 
4167
  val= uint8korr(buf+I_VAL_OFFSET);
 
4168
}
 
4169
 
 
4170
 
 
4171
/*
 
4172
  Intvar_log_event::get_var_type_name()
 
4173
*/
 
4174
 
 
4175
const char* Intvar_log_event::get_var_type_name()
 
4176
{
 
4177
  switch(type) {
 
4178
  case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
 
4179
  case INSERT_ID_EVENT: return "INSERT_ID";
 
4180
  default: /* impossible */ return "UNKNOWN";
 
4181
  }
 
4182
}
 
4183
 
 
4184
 
 
4185
/*
 
4186
  Intvar_log_event::write()
 
4187
*/
 
4188
 
 
4189
#ifndef MYSQL_CLIENT
 
4190
bool Intvar_log_event::write(IO_CACHE* file)
 
4191
{
 
4192
  uchar buf[9];
 
4193
  buf[I_TYPE_OFFSET]= (uchar) type;
 
4194
  int8store(buf + I_VAL_OFFSET, val);
 
4195
  return (write_header(file, sizeof(buf)) ||
 
4196
          my_b_safe_write(file, buf, sizeof(buf)));
 
4197
}
 
4198
#endif
 
4199
 
 
4200
 
 
4201
/*
 
4202
  Intvar_log_event::print()
 
4203
*/
 
4204
 
 
4205
#ifdef MYSQL_CLIENT
 
4206
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4207
{
 
4208
  char llbuff[22];
 
4209
  const char *msg;
 
4210
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4211
                               Write_on_release_cache::FLUSH_F);
 
4212
 
 
4213
  if (!print_event_info->short_form)
 
4214
  {
 
4215
    print_header(&cache, print_event_info, FALSE);
 
4216
    my_b_printf(&cache, "\tIntvar\n");
 
4217
  }
 
4218
 
 
4219
  my_b_printf(&cache, "SET ");
 
4220
  switch (type) {
 
4221
  case LAST_INSERT_ID_EVENT:
 
4222
    msg="LAST_INSERT_ID";
 
4223
    break;
 
4224
  case INSERT_ID_EVENT:
 
4225
    msg="INSERT_ID";
 
4226
    break;
 
4227
  case INVALID_INT_EVENT:
 
4228
  default: // cannot happen
 
4229
    msg="INVALID_INT";
 
4230
    break;
 
4231
  }
 
4232
  my_b_printf(&cache, "%s=%s%s\n",
 
4233
              msg, llstr(val,llbuff), print_event_info->delimiter);
 
4234
}
 
4235
#endif
 
4236
 
 
4237
 
 
4238
/*
 
4239
  Intvar_log_event::do_apply_event()
 
4240
*/
 
4241
 
 
4242
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
 
4243
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
 
4244
{
 
4245
  /*
 
4246
    We are now in a statement until the associated query log event has
 
4247
    been processed.
 
4248
   */
 
4249
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
4250
 
 
4251
  switch (type) {
 
4252
  case LAST_INSERT_ID_EVENT:
 
4253
    thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
 
4254
    thd->first_successful_insert_id_in_prev_stmt= val;
 
4255
    break;
 
4256
  case INSERT_ID_EVENT:
 
4257
    thd->force_one_auto_inc_interval(val);
 
4258
    break;
 
4259
  }
 
4260
  return 0;
 
4261
}
 
4262
 
 
4263
int Intvar_log_event::do_update_pos(Relay_log_info *rli)
 
4264
{
 
4265
  rli->inc_event_relay_log_pos();
 
4266
  return 0;
 
4267
}
 
4268
 
 
4269
 
 
4270
Log_event::enum_skip_reason
 
4271
Intvar_log_event::do_shall_skip(Relay_log_info *rli)
 
4272
{
 
4273
  /*
 
4274
    It is a common error to set the slave skip counter to 1 instead of
 
4275
    2 when recovering from an insert which used a auto increment,
 
4276
    rand, or user var.  Therefore, if the slave skip counter is 1, we
 
4277
    just say that this event should be skipped by ignoring it, meaning
 
4278
    that we do not change the value of the slave skip counter since it
 
4279
    will be decreased by the following insert event.
 
4280
  */
 
4281
  return continue_group(rli);
 
4282
}
 
4283
 
 
4284
#endif
 
4285
 
 
4286
 
 
4287
/**************************************************************************
 
4288
  Rand_log_event methods
 
4289
**************************************************************************/
 
4290
 
 
4291
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4292
void Rand_log_event::pack_info(Protocol *protocol)
 
4293
{
 
4294
  char buf1[256], *pos;
 
4295
  pos= strmov(buf1,"rand_seed1=");
 
4296
  pos= int10_to_str((long) seed1, pos, 10);
 
4297
  pos= strmov(pos, ",rand_seed2=");
 
4298
  pos= int10_to_str((long) seed2, pos, 10);
 
4299
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
 
4300
}
 
4301
#endif
 
4302
 
 
4303
 
 
4304
Rand_log_event::Rand_log_event(const char* buf,
 
4305
                               const Format_description_log_event* description_event)
 
4306
  :Log_event(buf, description_event)
 
4307
{
 
4308
  buf+= description_event->common_header_len;
 
4309
  seed1= uint8korr(buf+RAND_SEED1_OFFSET);
 
4310
  seed2= uint8korr(buf+RAND_SEED2_OFFSET);
 
4311
}
 
4312
 
 
4313
 
 
4314
#ifndef MYSQL_CLIENT
 
4315
bool Rand_log_event::write(IO_CACHE* file)
 
4316
{
 
4317
  uchar buf[16];
 
4318
  int8store(buf + RAND_SEED1_OFFSET, seed1);
 
4319
  int8store(buf + RAND_SEED2_OFFSET, seed2);
 
4320
  return (write_header(file, sizeof(buf)) ||
 
4321
          my_b_safe_write(file, buf, sizeof(buf)));
 
4322
}
 
4323
#endif
 
4324
 
 
4325
 
 
4326
#ifdef MYSQL_CLIENT
 
4327
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4328
{
 
4329
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4330
                               Write_on_release_cache::FLUSH_F);
 
4331
 
 
4332
  char llbuff[22],llbuff2[22];
 
4333
  if (!print_event_info->short_form)
 
4334
  {
 
4335
    print_header(&cache, print_event_info, FALSE);
 
4336
    my_b_printf(&cache, "\tRand\n");
 
4337
  }
 
4338
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
 
4339
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
 
4340
              print_event_info->delimiter);
 
4341
}
 
4342
#endif /* MYSQL_CLIENT */
 
4343
 
 
4344
 
 
4345
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4346
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
 
4347
{
 
4348
  /*
 
4349
    We are now in a statement until the associated query log event has
 
4350
    been processed.
 
4351
   */
 
4352
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
4353
 
 
4354
  thd->rand.seed1= (ulong) seed1;
 
4355
  thd->rand.seed2= (ulong) seed2;
 
4356
  return 0;
 
4357
}
 
4358
 
 
4359
int Rand_log_event::do_update_pos(Relay_log_info *rli)
 
4360
{
 
4361
  rli->inc_event_relay_log_pos();
 
4362
  return 0;
 
4363
}
 
4364
 
 
4365
 
 
4366
Log_event::enum_skip_reason
 
4367
Rand_log_event::do_shall_skip(Relay_log_info *rli)
 
4368
{
 
4369
  /*
 
4370
    It is a common error to set the slave skip counter to 1 instead of
 
4371
    2 when recovering from an insert which used a auto increment,
 
4372
    rand, or user var.  Therefore, if the slave skip counter is 1, we
 
4373
    just say that this event should be skipped by ignoring it, meaning
 
4374
    that we do not change the value of the slave skip counter since it
 
4375
    will be decreased by the following insert event.
 
4376
  */
 
4377
  return continue_group(rli);
 
4378
}
 
4379
 
 
4380
#endif /* !MYSQL_CLIENT */
 
4381
 
 
4382
 
 
4383
/**************************************************************************
 
4384
  Xid_log_event methods
 
4385
**************************************************************************/
 
4386
 
 
4387
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4388
void Xid_log_event::pack_info(Protocol *protocol)
 
4389
{
 
4390
  char buf[128], *pos;
 
4391
  pos= strmov(buf, "COMMIT /* xid=");
 
4392
  pos= longlong10_to_str(xid, pos, 10);
 
4393
  pos= strmov(pos, " */");
 
4394
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
 
4395
}
 
4396
#endif
 
4397
 
 
4398
/**
 
4399
  @note
 
4400
  It's ok not to use int8store here,
 
4401
  as long as xid_t::set(ulonglong) and
 
4402
  xid_t::get_my_xid doesn't do it either.
 
4403
  We don't care about actual values of xids as long as
 
4404
  identical numbers compare identically
 
4405
*/
 
4406
 
 
4407
Xid_log_event::
 
4408
Xid_log_event(const char* buf,
 
4409
              const Format_description_log_event *description_event)
 
4410
  :Log_event(buf, description_event)
 
4411
{
 
4412
  buf+= description_event->common_header_len;
 
4413
  memcpy((char*) &xid, buf, sizeof(xid));
 
4414
}
 
4415
 
 
4416
 
 
4417
#ifndef MYSQL_CLIENT
 
4418
bool Xid_log_event::write(IO_CACHE* file)
 
4419
{
 
4420
  DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
 
4421
  return write_header(file, sizeof(xid)) ||
 
4422
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
 
4423
}
 
4424
#endif
 
4425
 
 
4426
 
 
4427
#ifdef MYSQL_CLIENT
 
4428
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4429
{
 
4430
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4431
                               Write_on_release_cache::FLUSH_F);
 
4432
 
 
4433
  if (!print_event_info->short_form)
 
4434
  {
 
4435
    char buf[64];
 
4436
    longlong10_to_str(xid, buf, 10);
 
4437
 
 
4438
    print_header(&cache, print_event_info, FALSE);
 
4439
    my_b_printf(&cache, "\tXid = %s\n", buf);
 
4440
  }
 
4441
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
 
4442
}
 
4443
#endif /* MYSQL_CLIENT */
 
4444
 
 
4445
 
 
4446
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4447
int Xid_log_event::do_apply_event(Relay_log_info const *rli)
 
4448
{
 
4449
  /* For a slave Xid_log_event is COMMIT */
 
4450
  general_log_print(thd, COM_QUERY,
 
4451
                    "COMMIT /* implicit, from Xid_log_event */");
 
4452
  return end_trans(thd, COMMIT);
 
4453
}
 
4454
 
 
4455
Log_event::enum_skip_reason
 
4456
Xid_log_event::do_shall_skip(Relay_log_info *rli)
 
4457
{
 
4458
  DBUG_ENTER("Xid_log_event::do_shall_skip");
 
4459
  if (rli->slave_skip_counter > 0) {
 
4460
    thd->options&= ~OPTION_BEGIN;
 
4461
    DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
 
4462
  }
 
4463
  DBUG_RETURN(Log_event::do_shall_skip(rli));
 
4464
}
 
4465
#endif /* !MYSQL_CLIENT */
 
4466
 
 
4467
 
 
4468
/**************************************************************************
 
4469
  User_var_log_event methods
 
4470
**************************************************************************/
 
4471
 
 
4472
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4473
void User_var_log_event::pack_info(Protocol* protocol)
 
4474
{
 
4475
  char *buf= 0;
 
4476
  uint val_offset= 4 + name_len;
 
4477
  uint event_len= val_offset;
 
4478
 
 
4479
  if (is_null)
 
4480
  {
 
4481
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
 
4482
      return;
 
4483
    strmov(buf + val_offset, "NULL");
 
4484
    event_len= val_offset + 4;
 
4485
  }
 
4486
  else
 
4487
  {
 
4488
    switch (type) {
 
4489
    case REAL_RESULT:
 
4490
      double real_val;
 
4491
      float8get(real_val, val);
 
4492
      if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
 
4493
                                   MYF(MY_WME))))
 
4494
        return;
 
4495
      event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
 
4496
                          buf + val_offset, NULL);
 
4497
      break;
 
4498
    case INT_RESULT:
 
4499
      if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
 
4500
        return;
 
4501
      event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
 
4502
      break;
 
4503
    case DECIMAL_RESULT:
 
4504
    {
 
4505
      if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
 
4506
                                   MYF(MY_WME))))
 
4507
        return;
 
4508
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
 
4509
      my_decimal dec;
 
4510
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
 
4511
                        val[1]);
 
4512
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
 
4513
      event_len= str.length() + val_offset;
 
4514
      break;
 
4515
    } 
 
4516
    case STRING_RESULT:
 
4517
      /* 15 is for 'COLLATE' and other chars */
 
4518
      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
 
4519
                             MYF(MY_WME));
 
4520
      CHARSET_INFO *cs;
 
4521
      if (!buf)
 
4522
        return;
 
4523
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4524
      {
 
4525
        strmov(buf+val_offset, "???");
 
4526
        event_len+= 3;
 
4527
      }
 
4528
      else
 
4529
      {
 
4530
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
 
4531
        p= str_to_hex(p, val, val_len);
 
4532
        p= strxmov(p, " COLLATE ", cs->name, NullS);
 
4533
        event_len= p-buf;
 
4534
      }
 
4535
      break;
 
4536
    case ROW_RESULT:
 
4537
    default:
 
4538
      DBUG_ASSERT(1);
 
4539
      return;
 
4540
    }
 
4541
  }
 
4542
  buf[0]= '@';
 
4543
  buf[1]= '`';
 
4544
  memcpy(buf+2, name, name_len);
 
4545
  buf[2+name_len]= '`';
 
4546
  buf[3+name_len]= '=';
 
4547
  protocol->store(buf, event_len, &my_charset_bin);
 
4548
  my_free(buf, MYF(0));
 
4549
}
 
4550
#endif /* !MYSQL_CLIENT */
 
4551
 
 
4552
 
 
4553
User_var_log_event::
 
4554
User_var_log_event(const char* buf,
 
4555
                   const Format_description_log_event* description_event)
 
4556
  :Log_event(buf, description_event)
 
4557
{
 
4558
  buf+= description_event->common_header_len;
 
4559
  name_len= uint4korr(buf);
 
4560
  name= (char *) buf + UV_NAME_LEN_SIZE;
 
4561
  buf+= UV_NAME_LEN_SIZE + name_len;
 
4562
  is_null= (bool) *buf;
 
4563
  if (is_null)
 
4564
  {
 
4565
    type= STRING_RESULT;
 
4566
    charset_number= my_charset_bin.number;
 
4567
    val_len= 0;
 
4568
    val= 0;  
 
4569
  }
 
4570
  else
 
4571
  {
 
4572
    type= (Item_result) buf[UV_VAL_IS_NULL];
 
4573
    charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
 
4574
    val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
 
4575
                       UV_CHARSET_NUMBER_SIZE);
 
4576
    val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
 
4577
                   UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
 
4578
  }
 
4579
}
 
4580
 
 
4581
 
 
4582
#ifndef MYSQL_CLIENT
 
4583
bool User_var_log_event::write(IO_CACHE* file)
 
4584
{
 
4585
  char buf[UV_NAME_LEN_SIZE];
 
4586
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
 
4587
            UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
 
4588
  uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
 
4589
  uint buf1_length;
 
4590
  ulong event_length;
 
4591
 
 
4592
  int4store(buf, name_len);
 
4593
  
 
4594
  if ((buf1[0]= is_null))
 
4595
  {
 
4596
    buf1_length= 1;
 
4597
    val_len= 0;                                 // Length of 'pos'
 
4598
  }    
 
4599
  else
 
4600
  {
 
4601
    buf1[1]= type;
 
4602
    int4store(buf1 + 2, charset_number);
 
4603
 
 
4604
    switch (type) {
 
4605
    case REAL_RESULT:
 
4606
      float8store(buf2, *(double*) val);
 
4607
      break;
 
4608
    case INT_RESULT:
 
4609
      int8store(buf2, *(longlong*) val);
 
4610
      break;
 
4611
    case DECIMAL_RESULT:
 
4612
    {
 
4613
      my_decimal *dec= (my_decimal *)val;
 
4614
      dec->fix_buffer_pointer();
 
4615
      buf2[0]= (char)(dec->intg + dec->frac);
 
4616
      buf2[1]= (char)dec->frac;
 
4617
      decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
 
4618
      val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
 
4619
      break;
 
4620
    }
 
4621
    case STRING_RESULT:
 
4622
      pos= (uchar*) val;
 
4623
      break;
 
4624
    case ROW_RESULT:
 
4625
    default:
 
4626
      DBUG_ASSERT(1);
 
4627
      return 0;
 
4628
    }
 
4629
    int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
 
4630
    buf1_length= 10;
 
4631
  }
 
4632
 
 
4633
  /* Length of the whole event */
 
4634
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
 
4635
 
 
4636
  return (write_header(file, event_length) ||
 
4637
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
 
4638
          my_b_safe_write(file, (uchar*) name, name_len)     ||
 
4639
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
 
4640
          my_b_safe_write(file, pos, val_len));
 
4641
}
 
4642
#endif
 
4643
 
 
4644
 
 
4645
/*
 
4646
  User_var_log_event::print()
 
4647
*/
 
4648
 
 
4649
#ifdef MYSQL_CLIENT
 
4650
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4651
{
 
4652
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4653
                               Write_on_release_cache::FLUSH_F);
 
4654
 
 
4655
  if (!print_event_info->short_form)
 
4656
  {
 
4657
    print_header(&cache, print_event_info, FALSE);
 
4658
    my_b_printf(&cache, "\tUser_var\n");
 
4659
  }
 
4660
 
 
4661
  my_b_printf(&cache, "SET @`");
 
4662
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
 
4663
  my_b_printf(&cache, "`");
 
4664
 
 
4665
  if (is_null)
 
4666
  {
 
4667
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
 
4668
  }
 
4669
  else
 
4670
  {
 
4671
    switch (type) {
 
4672
    case REAL_RESULT:
 
4673
      double real_val;
 
4674
      char real_buf[FMT_G_BUFSIZE(14)];
 
4675
      float8get(real_val, val);
 
4676
      my_sprintf(real_buf, (real_buf, "%.14g", real_val));
 
4677
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
 
4678
      break;
 
4679
    case INT_RESULT:
 
4680
      char int_buf[22];
 
4681
      longlong10_to_str(uint8korr(val), int_buf, -10);
 
4682
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
 
4683
      break;
 
4684
    case DECIMAL_RESULT:
 
4685
    {
 
4686
      char str_buf[200];
 
4687
      int str_len= sizeof(str_buf) - 1;
 
4688
      int precision= (int)val[0];
 
4689
      int scale= (int)val[1];
 
4690
      decimal_digit_t dec_buf[10];
 
4691
      decimal_t dec;
 
4692
      dec.len= 10;
 
4693
      dec.buf= dec_buf;
 
4694
 
 
4695
      bin2decimal((uchar*) val+2, &dec, precision, scale);
 
4696
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
 
4697
      str_buf[str_len]= 0;
 
4698
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
 
4699
      break;
 
4700
    }
 
4701
    case STRING_RESULT:
 
4702
    {
 
4703
      /*
 
4704
        Let's express the string in hex. That's the most robust way. If we
 
4705
        print it in character form instead, we need to escape it with
 
4706
        character_set_client which we don't know (we will know it in 5.0, but
 
4707
        in 4.1 we don't know it easily when we are printing
 
4708
        User_var_log_event). Explanation why we would need to bother with
 
4709
        character_set_client (quoting Bar):
 
4710
        > Note, the parser doesn't switch to another unescaping mode after
 
4711
        > it has met a character set introducer.
 
4712
        > For example, if an SJIS client says something like:
 
4713
        > SET @a= _ucs2 \0a\0b'
 
4714
        > the string constant is still unescaped according to SJIS, not
 
4715
        > according to UCS2.
 
4716
      */
 
4717
      char *hex_str;
 
4718
      CHARSET_INFO *cs;
 
4719
 
 
4720
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
 
4721
        break; // no error, as we are 'void'
 
4722
      str_to_hex(hex_str, val, val_len);
 
4723
      /*
 
4724
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
 
4725
        specify the variable's collation. It will however cause problems when
 
4726
        people want to mysqlbinlog|mysql into another server not supporting the
 
4727
        character set. But there's not much to do about this and it's unlikely.
 
4728
      */
 
4729
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4730
        /*
 
4731
          Generate an unusable command (=> syntax error) is probably the best
 
4732
          thing we can do here.
 
4733
        */
 
4734
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
 
4735
      else
 
4736
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
 
4737
                    cs->csname, hex_str, cs->name,
 
4738
                    print_event_info->delimiter);
 
4739
      my_afree(hex_str);
 
4740
    }
 
4741
      break;
 
4742
    case ROW_RESULT:
 
4743
    default:
 
4744
      DBUG_ASSERT(1);
 
4745
      return;
 
4746
    }
 
4747
  }
 
4748
}
 
4749
#endif
 
4750
 
 
4751
 
 
4752
/*
 
4753
  User_var_log_event::do_apply_event()
 
4754
*/
 
4755
 
 
4756
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4757
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
 
4758
{
 
4759
  Item *it= 0;
 
4760
  CHARSET_INFO *charset;
 
4761
  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
 
4762
    return 1;
 
4763
  LEX_STRING user_var_name;
 
4764
  user_var_name.str= name;
 
4765
  user_var_name.length= name_len;
 
4766
  double real_val;
 
4767
  longlong int_val;
 
4768
 
 
4769
  /*
 
4770
    We are now in a statement until the associated query log event has
 
4771
    been processed.
 
4772
   */
 
4773
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
4774
 
 
4775
  if (is_null)
 
4776
  {
 
4777
    it= new Item_null();
 
4778
  }
 
4779
  else
 
4780
  {
 
4781
    switch (type) {
 
4782
    case REAL_RESULT:
 
4783
      float8get(real_val, val);
 
4784
      it= new Item_float(real_val, 0);
 
4785
      val= (char*) &real_val;           // Pointer to value in native format
 
4786
      val_len= 8;
 
4787
      break;
 
4788
    case INT_RESULT:
 
4789
      int_val= (longlong) uint8korr(val);
 
4790
      it= new Item_int(int_val);
 
4791
      val= (char*) &int_val;            // Pointer to value in native format
 
4792
      val_len= 8;
 
4793
      break;
 
4794
    case DECIMAL_RESULT:
 
4795
    {
 
4796
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
 
4797
      it= dec;
 
4798
      val= (char *)dec->val_decimal(NULL);
 
4799
      val_len= sizeof(my_decimal);
 
4800
      break;
 
4801
    }
 
4802
    case STRING_RESULT:
 
4803
      it= new Item_string(val, val_len, charset);
 
4804
      break;
 
4805
    case ROW_RESULT:
 
4806
    default:
 
4807
      DBUG_ASSERT(1);
 
4808
      return 0;
 
4809
    }
 
4810
  }
 
4811
  Item_func_set_user_var e(user_var_name, it);
 
4812
  /*
 
4813
    Item_func_set_user_var can't substitute something else on its place =>
 
4814
    0 can be passed as last argument (reference on item)
 
4815
  */
 
4816
  e.fix_fields(thd, 0);
 
4817
  /*
 
4818
    A variable can just be considered as a table with
 
4819
    a single record and with a single column. Thus, like
 
4820
    a column value, it could always have IMPLICIT derivation.
 
4821
   */
 
4822
  e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
 
4823
  free_root(thd->mem_root,0);
 
4824
 
 
4825
  return 0;
 
4826
}
 
4827
 
 
4828
int User_var_log_event::do_update_pos(Relay_log_info *rli)
 
4829
{
 
4830
  rli->inc_event_relay_log_pos();
 
4831
  return 0;
 
4832
}
 
4833
 
 
4834
Log_event::enum_skip_reason
 
4835
User_var_log_event::do_shall_skip(Relay_log_info *rli)
 
4836
{
 
4837
  /*
 
4838
    It is a common error to set the slave skip counter to 1 instead
 
4839
    of 2 when recovering from an insert which used a auto increment,
 
4840
    rand, or user var.  Therefore, if the slave skip counter is 1, we
 
4841
    just say that this event should be skipped by ignoring it, meaning
 
4842
    that we do not change the value of the slave skip counter since it
 
4843
    will be decreased by the following insert event.
 
4844
  */
 
4845
  return continue_group(rli);
 
4846
}
 
4847
#endif /* !MYSQL_CLIENT */
 
4848
 
 
4849
 
 
4850
/**************************************************************************
 
4851
  Slave_log_event methods
 
4852
**************************************************************************/
 
4853
 
 
4854
#ifdef HAVE_REPLICATION
 
4855
#ifdef MYSQL_CLIENT
 
4856
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
 
4857
{
 
4858
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
4859
 
 
4860
  if (print_event_info->short_form)
 
4861
    return;
 
4862
  print_header(&cache, print_event_info, FALSE);
 
4863
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
 
4864
}
 
4865
#endif  
 
4866
 
 
4867
#ifndef MYSQL_CLIENT
 
4868
void Slave_log_event::pack_info(Protocol *protocol)
 
4869
{
 
4870
  char buf[256+HOSTNAME_LENGTH], *pos;
 
4871
  pos= strmov(buf, "host=");
 
4872
  pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
 
4873
  pos= strmov(pos, ",port=");
 
4874
  pos= int10_to_str((long) master_port, pos, 10);
 
4875
  pos= strmov(pos, ",log=");
 
4876
  pos= strmov(pos, master_log);
 
4877
  pos= strmov(pos, ",pos=");
 
4878
  pos= longlong10_to_str(master_pos, pos, 10);
 
4879
  protocol->store(buf, pos-buf, &my_charset_bin);
 
4880
}
 
4881
#endif /* !MYSQL_CLIENT */
 
4882
 
 
4883
 
 
4884
#ifndef MYSQL_CLIENT
 
4885
/**
 
4886
  @todo
 
4887
  re-write this better without holding both locks at the same time
 
4888
*/
 
4889
Slave_log_event::Slave_log_event(THD* thd_arg,
 
4890
                                 Relay_log_info* rli)
 
4891
  :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
 
4892
{
 
4893
  DBUG_ENTER("Slave_log_event");
 
4894
  if (!rli->inited)                             // QQ When can this happen ?
 
4895
    DBUG_VOID_RETURN;
 
4896
 
 
4897
  Master_info* mi = rli->mi;
 
4898
  // TODO: re-write this better without holding both locks at the same time
 
4899
  pthread_mutex_lock(&mi->data_lock);
 
4900
  pthread_mutex_lock(&rli->data_lock);
 
4901
  master_host_len = strlen(mi->host);
 
4902
  master_log_len = strlen(rli->group_master_log_name);
 
4903
  // on OOM, just do not initialize the structure and print the error
 
4904
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
 
4905
                                   MYF(MY_WME))))
 
4906
  {
 
4907
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
 
4908
    memcpy(master_host, mi->host, master_host_len + 1);
 
4909
    master_log = master_host + master_host_len + 1;
 
4910
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
 
4911
    master_port = mi->port;
 
4912
    master_pos = rli->group_master_log_pos;
 
4913
    DBUG_PRINT("info", ("master_log: %s  pos: %lu", master_log,
 
4914
                        (ulong) master_pos));
 
4915
  }
 
4916
  else
 
4917
    sql_print_error("Out of memory while recording slave event");
 
4918
  pthread_mutex_unlock(&rli->data_lock);
 
4919
  pthread_mutex_unlock(&mi->data_lock);
 
4920
  DBUG_VOID_RETURN;
 
4921
}
 
4922
#endif /* !MYSQL_CLIENT */
 
4923
 
 
4924
 
 
4925
Slave_log_event::~Slave_log_event()
 
4926
{
 
4927
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 
4928
}
 
4929
 
 
4930
 
 
4931
#ifdef MYSQL_CLIENT
 
4932
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4933
{
 
4934
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
4935
 
 
4936
  char llbuff[22];
 
4937
  if (print_event_info->short_form)
 
4938
    return;
 
4939
  print_header(&cache, print_event_info, FALSE);
 
4940
  my_b_printf(&cache, "\n\
 
4941
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 
4942
          master_host, master_port, master_log, llstr(master_pos, llbuff));
 
4943
}
 
4944
#endif /* MYSQL_CLIENT */
 
4945
 
 
4946
 
 
4947
int Slave_log_event::get_data_size()
 
4948
{
 
4949
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
 
4950
}
 
4951
 
 
4952
 
 
4953
#ifndef MYSQL_CLIENT
 
4954
bool Slave_log_event::write(IO_CACHE* file)
 
4955
{
 
4956
  ulong event_length= get_data_size();
 
4957
  int8store(mem_pool + SL_MASTER_POS_OFFSET, master_pos);
 
4958
  int2store(mem_pool + SL_MASTER_PORT_OFFSET, master_port);
 
4959
  // log and host are already there
 
4960
 
 
4961
  return (write_header(file, event_length) ||
 
4962
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
 
4963
}
 
4964
#endif
 
4965
 
 
4966
 
 
4967
void Slave_log_event::init_from_mem_pool(int data_size)
 
4968
{
 
4969
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
 
4970
  master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
 
4971
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
 
4972
  master_host_len = strlen(master_host);
 
4973
  // safety
 
4974
  master_log = master_host + master_host_len + 1;
 
4975
  if (master_log > mem_pool + data_size)
 
4976
  {
 
4977
    master_host = 0;
 
4978
    return;
 
4979
  }
 
4980
  master_log_len = strlen(master_log);
 
4981
}
 
4982
 
 
4983
 
 
4984
/** This code is not used, so has not been updated to be format-tolerant. */
 
4985
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
 
4986
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
 
4987
{
 
4988
  if (event_len < LOG_EVENT_HEADER_LEN)
 
4989
    return;
 
4990
  event_len -= LOG_EVENT_HEADER_LEN;
 
4991
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
 
4992
    return;
 
4993
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
 
4994
  mem_pool[event_len] = 0;
 
4995
  init_from_mem_pool(event_len);
 
4996
}
 
4997
 
 
4998
 
 
4999
#ifndef MYSQL_CLIENT
 
5000
int Slave_log_event::do_apply_event(Relay_log_info const *rli)
 
5001
{
 
5002
  if (mysql_bin_log.is_open())
 
5003
    mysql_bin_log.write(this);
 
5004
  return 0;
 
5005
}
 
5006
#endif /* !MYSQL_CLIENT */
 
5007
 
 
5008
 
 
5009
/**************************************************************************
 
5010
        Stop_log_event methods
 
5011
**************************************************************************/
 
5012
 
 
5013
/*
 
5014
  Stop_log_event::print()
 
5015
*/
 
5016
 
 
5017
#ifdef MYSQL_CLIENT
 
5018
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5019
{
 
5020
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
5021
                               Write_on_release_cache::FLUSH_F);
 
5022
 
 
5023
  if (print_event_info->short_form)
 
5024
    return;
 
5025
 
 
5026
  print_header(&cache, print_event_info, FALSE);
 
5027
  my_b_printf(&cache, "\tStop\n");
 
5028
}
 
5029
#endif /* MYSQL_CLIENT */
 
5030
 
 
5031
 
 
5032
#ifndef MYSQL_CLIENT
 
5033
/*
 
5034
  The master stopped.  We used to clean up all temporary tables but
 
5035
  this is useless as, as the master has shut down properly, it has
 
5036
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
 
5037
  TODO only when we binlog prep stmts).  We used to clean up
 
5038
  slave_load_tmpdir, but this is useless as it has been cleared at the
 
5039
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
 
5040
  were we must do this cleaning is in
 
5041
  Start_log_event_v3::do_apply_event(), not here. Because if we come
 
5042
  here, the master was sane.
 
5043
*/
 
5044
int Stop_log_event::do_update_pos(Relay_log_info *rli)
 
5045
{
 
5046
  /*
 
5047
    We do not want to update master_log pos because we get a rotate event
 
5048
    before stop, so by now group_master_log_name is set to the next log.
 
5049
    If we updated it, we will have incorrect master coordinates and this
 
5050
    could give false triggers in MASTER_POS_WAIT() that we have reached
 
5051
    the target position when in fact we have not.
 
5052
  */
 
5053
  if (thd->options & OPTION_BEGIN)
 
5054
    rli->inc_event_relay_log_pos();
 
5055
  else
 
5056
  {
 
5057
    rli->inc_group_relay_log_pos(0);
 
5058
    flush_relay_log_info(rli);
 
5059
  }
 
5060
  return 0;
 
5061
}
 
5062
 
 
5063
#endif /* !MYSQL_CLIENT */
 
5064
#endif /* HAVE_REPLICATION */
 
5065
 
 
5066
 
 
5067
/**************************************************************************
 
5068
        Create_file_log_event methods
 
5069
**************************************************************************/
 
5070
 
 
5071
/*
 
5072
  Create_file_log_event ctor
 
5073
*/
 
5074
 
 
5075
#ifndef MYSQL_CLIENT
 
5076
Create_file_log_event::
 
5077
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
 
5078
                      const char* db_arg, const char* table_name_arg,
 
5079
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
 
5080
                      bool ignore,
 
5081
                      uchar* block_arg, uint block_len_arg, bool using_trans)
 
5082
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
 
5083
                  using_trans),
 
5084
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
 
5085
   file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
 
5086
{
 
5087
  DBUG_ENTER("Create_file_log_event");
 
5088
  sql_ex.force_new_format();
 
5089
  DBUG_VOID_RETURN;
 
5090
}
 
5091
 
 
5092
 
 
5093
/*
 
5094
  Create_file_log_event::write_data_body()
 
5095
*/
 
5096
 
 
5097
bool Create_file_log_event::write_data_body(IO_CACHE* file)
 
5098
{
 
5099
  bool res;
 
5100
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
 
5101
    return res;
 
5102
  return (my_b_safe_write(file, (uchar*) "", 1) ||
 
5103
          my_b_safe_write(file, (uchar*) block, block_len));
 
5104
}
 
5105
 
 
5106
 
 
5107
/*
 
5108
  Create_file_log_event::write_data_header()
 
5109
*/
 
5110
 
 
5111
bool Create_file_log_event::write_data_header(IO_CACHE* file)
 
5112
{
 
5113
  bool res;
 
5114
  uchar buf[CREATE_FILE_HEADER_LEN];
 
5115
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
 
5116
    return res;
 
5117
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
 
5118
  return my_b_safe_write(file, buf, CREATE_FILE_HEADER_LEN) != 0;
 
5119
}
 
5120
 
 
5121
 
 
5122
/*
 
5123
  Create_file_log_event::write_base()
 
5124
*/
 
5125
 
 
5126
bool Create_file_log_event::write_base(IO_CACHE* file)
 
5127
{
 
5128
  bool res;
 
5129
  fake_base= 1;                                 // pretend we are Load event
 
5130
  res= write(file);
 
5131
  fake_base= 0;
 
5132
  return res;
 
5133
}
 
5134
 
 
5135
#endif /* !MYSQL_CLIENT */
 
5136
 
 
5137
/*
 
5138
  Create_file_log_event ctor
 
5139
*/
 
5140
 
 
5141
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
 
5142
                                             const Format_description_log_event* description_event)
 
5143
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
 
5144
{
 
5145
  DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
 
5146
  uint block_offset;
 
5147
  uint header_len= description_event->common_header_len;
 
5148
  uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
 
5149
  uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
 
5150
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
 
5151
      copy_log_event(event_buf,len,
 
5152
                     ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
 
5153
                      load_header_len + header_len :
 
5154
                      (fake_base ? (header_len+load_header_len) :
 
5155
                       (header_len+load_header_len) +
 
5156
                       create_file_header_len)),
 
5157
                     description_event))
 
5158
    DBUG_VOID_RETURN;
 
5159
  if (description_event->binlog_version!=1)
 
5160
  {
 
5161
    file_id= uint4korr(buf + 
 
5162
                       header_len +
 
5163
                       load_header_len + CF_FILE_ID_OFFSET);
 
5164
    /*
 
5165
      Note that it's ok to use get_data_size() below, because it is computed
 
5166
      with values we have already read from this event (because we called
 
5167
      copy_log_event()); we are not using slave's format info to decode
 
5168
      master's format, we are really using master's format info.
 
5169
      Anyway, both formats should be identical (except the common_header_len)
 
5170
      as these Load events are not changed between 4.0 and 5.0 (as logging of
 
5171
      LOAD DATA INFILE does not use Load_log_event in 5.0).
 
5172
 
 
5173
      The + 1 is for \0 terminating fname  
 
5174
    */
 
5175
    block_offset= (description_event->common_header_len +
 
5176
                   Load_log_event::get_data_size() +
 
5177
                   create_file_header_len + 1);
 
5178
    if (len < block_offset)
 
5179
      DBUG_VOID_RETURN;
 
5180
    block = (uchar*)buf + block_offset;
 
5181
    block_len = len - block_offset;
 
5182
  }
 
5183
  else
 
5184
  {
 
5185
    sql_ex.force_new_format();
 
5186
    inited_from_old = 1;
 
5187
  }
 
5188
  DBUG_VOID_RETURN;
 
5189
}
 
5190
 
 
5191
 
 
5192
/*
 
5193
  Create_file_log_event::print()
 
5194
*/
 
5195
 
 
5196
#ifdef MYSQL_CLIENT
 
5197
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
 
5198
                                  bool enable_local)
 
5199
{
 
5200
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5201
 
 
5202
  if (print_event_info->short_form)
 
5203
  {
 
5204
    if (enable_local && check_fname_outside_temp_buf())
 
5205
      Load_log_event::print(file, print_event_info);
 
5206
    return;
 
5207
  }
 
5208
 
 
5209
  if (enable_local)
 
5210
  {
 
5211
    Load_log_event::print(file, print_event_info,
 
5212
                          !check_fname_outside_temp_buf());
 
5213
    /* 
 
5214
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
 
5215
       SHOW BINLOG EVENTS we don't.
 
5216
    */
 
5217
    my_b_printf(&cache, "#"); 
 
5218
  }
 
5219
 
 
5220
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
 
5221
}
 
5222
 
 
5223
 
 
5224
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5225
{
 
5226
  print(file, print_event_info, 0);
 
5227
}
 
5228
#endif /* MYSQL_CLIENT */
 
5229
 
 
5230
 
 
5231
/*
 
5232
  Create_file_log_event::pack_info()
 
5233
*/
 
5234
 
 
5235
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5236
void Create_file_log_event::pack_info(Protocol *protocol)
 
5237
{
 
5238
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
 
5239
  pos= strmov(buf, "db=");
 
5240
  memcpy(pos, db, db_len);
 
5241
  pos= strmov(pos + db_len, ";table=");
 
5242
  memcpy(pos, table_name, table_name_len);
 
5243
  pos= strmov(pos + table_name_len, ";file_id=");
 
5244
  pos= int10_to_str((long) file_id, pos, 10);
 
5245
  pos= strmov(pos, ";block_len=");
 
5246
  pos= int10_to_str((long) block_len, pos, 10);
 
5247
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
 
5248
}
 
5249
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5250
 
 
5251
 
 
5252
/*
 
5253
  Create_file_log_event::do_apply_event()
 
5254
*/
 
5255
 
 
5256
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5257
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
 
5258
{
 
5259
  char proc_info[17+FN_REFLEN+10], *fname_buf;
 
5260
  char *ext;
 
5261
  int fd = -1;
 
5262
  IO_CACHE file;
 
5263
  int error = 1;
 
5264
 
 
5265
  bzero((char*)&file, sizeof(file));
 
5266
  fname_buf= strmov(proc_info, "Making temp file ");
 
5267
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
 
5268
  thd_proc_info(thd, proc_info);
 
5269
  my_delete(fname_buf, MYF(0)); // old copy may exist already
 
5270
  if ((fd= my_create(fname_buf, CREATE_MODE,
 
5271
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5272
                     MYF(MY_WME))) < 0 ||
 
5273
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
 
5274
                    MYF(MY_WME|MY_NABP)))
 
5275
  {
 
5276
    rli->report(ERROR_LEVEL, my_errno,
 
5277
                "Error in Create_file event: could not open file '%s'",
 
5278
                fname_buf);
 
5279
    goto err;
 
5280
  }
 
5281
  
 
5282
  // a trick to avoid allocating another buffer
 
5283
  fname= fname_buf;
 
5284
  fname_len= (uint) (strmov(ext, ".data") - fname);
 
5285
  if (write_base(&file))
 
5286
  {
 
5287
    strmov(ext, ".info"); // to have it right in the error message
 
5288
    rli->report(ERROR_LEVEL, my_errno,
 
5289
                "Error in Create_file event: could not write to file '%s'",
 
5290
                fname_buf);
 
5291
    goto err;
 
5292
  }
 
5293
  end_io_cache(&file);
 
5294
  my_close(fd, MYF(0));
 
5295
  
 
5296
  // fname_buf now already has .data, not .info, because we did our trick
 
5297
  my_delete(fname_buf, MYF(0)); // old copy may exist already
 
5298
  if ((fd= my_create(fname_buf, CREATE_MODE,
 
5299
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5300
                     MYF(MY_WME))) < 0)
 
5301
  {
 
5302
    rli->report(ERROR_LEVEL, my_errno,
 
5303
                "Error in Create_file event: could not open file '%s'",
 
5304
                fname_buf);
 
5305
    goto err;
 
5306
  }
 
5307
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5308
  {
 
5309
    rli->report(ERROR_LEVEL, my_errno,
 
5310
                "Error in Create_file event: write to '%s' failed",
 
5311
                fname_buf);
 
5312
    goto err;
 
5313
  }
 
5314
  error=0;                                      // Everything is ok
 
5315
 
 
5316
err:
 
5317
  if (error)
 
5318
    end_io_cache(&file);
 
5319
  if (fd >= 0)
 
5320
    my_close(fd, MYF(0));
 
5321
  thd_proc_info(thd, 0);
 
5322
  return error == 0;
 
5323
}
 
5324
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5325
 
 
5326
 
 
5327
/**************************************************************************
 
5328
        Append_block_log_event methods
 
5329
**************************************************************************/
 
5330
 
 
5331
/*
 
5332
  Append_block_log_event ctor
 
5333
*/
 
5334
 
 
5335
#ifndef MYSQL_CLIENT  
 
5336
Append_block_log_event::Append_block_log_event(THD *thd_arg,
 
5337
                                               const char *db_arg,
 
5338
                                               uchar *block_arg,
 
5339
                                               uint block_len_arg,
 
5340
                                               bool using_trans)
 
5341
  :Log_event(thd_arg,0, using_trans), block(block_arg),
 
5342
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
 
5343
{
 
5344
}
 
5345
#endif
 
5346
 
 
5347
 
 
5348
/*
 
5349
  Append_block_log_event ctor
 
5350
*/
 
5351
 
 
5352
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
 
5353
                                               const Format_description_log_event* description_event)
 
5354
  :Log_event(buf, description_event),block(0)
 
5355
{
 
5356
  DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
 
5357
  uint8 common_header_len= description_event->common_header_len; 
 
5358
  uint8 append_block_header_len=
 
5359
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
 
5360
  uint total_header_len= common_header_len+append_block_header_len;
 
5361
  if (len < total_header_len)
 
5362
    DBUG_VOID_RETURN;
 
5363
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
 
5364
  block= (uchar*)buf + total_header_len;
 
5365
  block_len= len - total_header_len;
 
5366
  DBUG_VOID_RETURN;
 
5367
}
 
5368
 
 
5369
 
 
5370
/*
 
5371
  Append_block_log_event::write()
 
5372
*/
 
5373
 
 
5374
#ifndef MYSQL_CLIENT
 
5375
bool Append_block_log_event::write(IO_CACHE* file)
 
5376
{
 
5377
  uchar buf[APPEND_BLOCK_HEADER_LEN];
 
5378
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
 
5379
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
 
5380
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
 
5381
          my_b_safe_write(file, (uchar*) block, block_len));
 
5382
}
 
5383
#endif
 
5384
 
 
5385
 
 
5386
/*
 
5387
  Append_block_log_event::print()
 
5388
*/
 
5389
 
 
5390
#ifdef MYSQL_CLIENT  
 
5391
void Append_block_log_event::print(FILE* file,
 
5392
                                   PRINT_EVENT_INFO* print_event_info)
 
5393
{
 
5394
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5395
 
 
5396
  if (print_event_info->short_form)
 
5397
    return;
 
5398
  print_header(&cache, print_event_info, FALSE);
 
5399
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
 
5400
              get_type_str(), file_id, block_len);
 
5401
}
 
5402
#endif /* MYSQL_CLIENT */
 
5403
 
 
5404
 
 
5405
/*
 
5406
  Append_block_log_event::pack_info()
 
5407
*/
 
5408
 
 
5409
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5410
void Append_block_log_event::pack_info(Protocol *protocol)
 
5411
{
 
5412
  char buf[256];
 
5413
  uint length;
 
5414
  length= (uint) my_sprintf(buf,
 
5415
                            (buf, ";file_id=%u;block_len=%u", file_id,
 
5416
                             block_len));
 
5417
  protocol->store(buf, length, &my_charset_bin);
 
5418
}
 
5419
 
 
5420
 
 
5421
/*
 
5422
  Append_block_log_event::get_create_or_append()
 
5423
*/
 
5424
 
 
5425
int Append_block_log_event::get_create_or_append() const
 
5426
{
 
5427
  return 0; /* append to the file, fail if not exists */
 
5428
}
 
5429
 
 
5430
/*
 
5431
  Append_block_log_event::do_apply_event()
 
5432
*/
 
5433
 
 
5434
int Append_block_log_event::do_apply_event(Relay_log_info const *rli)
 
5435
{
 
5436
  char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
 
5437
  int fd;
 
5438
  int error = 1;
 
5439
  DBUG_ENTER("Append_block_log_event::do_apply_event");
 
5440
 
 
5441
  fname= strmov(proc_info, "Making temp file ");
 
5442
  slave_load_file_stem(fname, file_id, server_id, ".data");
 
5443
  thd_proc_info(thd, proc_info);
 
5444
  if (get_create_or_append())
 
5445
  {
 
5446
    my_delete(fname, MYF(0)); // old copy may exist already
 
5447
    if ((fd= my_create(fname, CREATE_MODE,
 
5448
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5449
                       MYF(MY_WME))) < 0)
 
5450
    {
 
5451
      rli->report(ERROR_LEVEL, my_errno,
 
5452
                  "Error in %s event: could not create file '%s'",
 
5453
                  get_type_str(), fname);
 
5454
      goto err;
 
5455
    }
 
5456
  }
 
5457
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
 
5458
                         MYF(MY_WME))) < 0)
 
5459
  {
 
5460
    rli->report(ERROR_LEVEL, my_errno,
 
5461
                "Error in %s event: could not open file '%s'",
 
5462
                get_type_str(), fname);
 
5463
    goto err;
 
5464
  }
 
5465
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5466
  {
 
5467
    rli->report(ERROR_LEVEL, my_errno,
 
5468
                "Error in %s event: write to '%s' failed",
 
5469
                get_type_str(), fname);
 
5470
    goto err;
 
5471
  }
 
5472
  error=0;
 
5473
 
 
5474
err:
 
5475
  if (fd >= 0)
 
5476
    my_close(fd, MYF(0));
 
5477
  thd_proc_info(thd, 0);
 
5478
  DBUG_RETURN(error);
 
5479
}
 
5480
#endif
 
5481
 
 
5482
 
 
5483
/**************************************************************************
 
5484
        Delete_file_log_event methods
 
5485
**************************************************************************/
 
5486
 
 
5487
/*
 
5488
  Delete_file_log_event ctor
 
5489
*/
 
5490
 
 
5491
#ifndef MYSQL_CLIENT
 
5492
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
 
5493
                                             bool using_trans)
 
5494
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
 
5495
{
 
5496
}
 
5497
#endif
 
5498
 
 
5499
/*
 
5500
  Delete_file_log_event ctor
 
5501
*/
 
5502
 
 
5503
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
 
5504
                                             const Format_description_log_event* description_event)
 
5505
  :Log_event(buf, description_event),file_id(0)
 
5506
{
 
5507
  uint8 common_header_len= description_event->common_header_len;
 
5508
  uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
 
5509
  if (len < (uint)(common_header_len + delete_file_header_len))
 
5510
    return;
 
5511
  file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
 
5512
}
 
5513
 
 
5514
 
 
5515
/*
 
5516
  Delete_file_log_event::write()
 
5517
*/
 
5518
 
 
5519
#ifndef MYSQL_CLIENT
 
5520
bool Delete_file_log_event::write(IO_CACHE* file)
 
5521
{
 
5522
 uchar buf[DELETE_FILE_HEADER_LEN];
 
5523
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
 
5524
 return (write_header(file, sizeof(buf)) ||
 
5525
         my_b_safe_write(file, buf, sizeof(buf)));
 
5526
}
 
5527
#endif
 
5528
 
 
5529
 
 
5530
/*
 
5531
  Delete_file_log_event::print()
 
5532
*/
 
5533
 
 
5534
#ifdef MYSQL_CLIENT  
 
5535
void Delete_file_log_event::print(FILE* file,
 
5536
                                  PRINT_EVENT_INFO* print_event_info)
 
5537
{
 
5538
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5539
 
 
5540
  if (print_event_info->short_form)
 
5541
    return;
 
5542
  print_header(&cache, print_event_info, FALSE);
 
5543
  my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
 
5544
}
 
5545
#endif /* MYSQL_CLIENT */
 
5546
 
 
5547
/*
 
5548
  Delete_file_log_event::pack_info()
 
5549
*/
 
5550
 
 
5551
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5552
void Delete_file_log_event::pack_info(Protocol *protocol)
 
5553
{
 
5554
  char buf[64];
 
5555
  uint length;
 
5556
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5557
  protocol->store(buf, (int32) length, &my_charset_bin);
 
5558
}
 
5559
#endif
 
5560
 
 
5561
/*
 
5562
  Delete_file_log_event::do_apply_event()
 
5563
*/
 
5564
 
 
5565
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5566
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
 
5567
{
 
5568
  char fname[FN_REFLEN+10];
 
5569
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
 
5570
  (void) my_delete(fname, MYF(MY_WME));
 
5571
  strmov(ext, ".info");
 
5572
  (void) my_delete(fname, MYF(MY_WME));
 
5573
  return 0;
 
5574
}
 
5575
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5576
 
 
5577
 
 
5578
/**************************************************************************
 
5579
        Execute_load_log_event methods
 
5580
**************************************************************************/
 
5581
 
 
5582
/*
 
5583
  Execute_load_log_event ctor
 
5584
*/
 
5585
 
 
5586
#ifndef MYSQL_CLIENT  
 
5587
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
 
5588
                                               const char* db_arg,
 
5589
                                               bool using_trans)
 
5590
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
 
5591
{
 
5592
}
 
5593
#endif
 
5594
  
 
5595
 
 
5596
/*
 
5597
  Execute_load_log_event ctor
 
5598
*/
 
5599
 
 
5600
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
 
5601
                                               const Format_description_log_event* description_event)
 
5602
  :Log_event(buf, description_event), file_id(0)
 
5603
{
 
5604
  uint8 common_header_len= description_event->common_header_len;
 
5605
  uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
 
5606
  if (len < (uint)(common_header_len+exec_load_header_len))
 
5607
    return;
 
5608
  file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
 
5609
}
 
5610
 
 
5611
 
 
5612
/*
 
5613
  Execute_load_log_event::write()
 
5614
*/
 
5615
 
 
5616
#ifndef MYSQL_CLIENT
 
5617
bool Execute_load_log_event::write(IO_CACHE* file)
 
5618
{
 
5619
  uchar buf[EXEC_LOAD_HEADER_LEN];
 
5620
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
 
5621
  return (write_header(file, sizeof(buf)) || 
 
5622
          my_b_safe_write(file, buf, sizeof(buf)));
 
5623
}
 
5624
#endif
 
5625
 
 
5626
 
 
5627
/*
 
5628
  Execute_load_log_event::print()
 
5629
*/
 
5630
 
 
5631
#ifdef MYSQL_CLIENT  
 
5632
void Execute_load_log_event::print(FILE* file,
 
5633
                                   PRINT_EVENT_INFO* print_event_info)
 
5634
{
 
5635
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5636
 
 
5637
  if (print_event_info->short_form)
 
5638
    return;
 
5639
  print_header(&cache, print_event_info, FALSE);
 
5640
  my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
 
5641
              file_id);
 
5642
}
 
5643
#endif
 
5644
 
 
5645
/*
 
5646
  Execute_load_log_event::pack_info()
 
5647
*/
 
5648
 
 
5649
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5650
void Execute_load_log_event::pack_info(Protocol *protocol)
 
5651
{
 
5652
  char buf[64];
 
5653
  uint length;
 
5654
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5655
  protocol->store(buf, (int32) length, &my_charset_bin);
 
5656
}
 
5657
 
 
5658
 
 
5659
/*
 
5660
  Execute_load_log_event::do_apply_event()
 
5661
*/
 
5662
 
 
5663
int Execute_load_log_event::do_apply_event(Relay_log_info const *rli)
 
5664
{
 
5665
  char fname[FN_REFLEN+10];
 
5666
  char *ext;
 
5667
  int fd;
 
5668
  int error= 1;
 
5669
  IO_CACHE file;
 
5670
  Load_log_event *lev= 0;
 
5671
 
 
5672
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
 
5673
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
 
5674
                    MYF(MY_WME))) < 0 ||
 
5675
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
 
5676
                    MYF(MY_WME|MY_NABP)))
 
5677
  {
 
5678
    rli->report(ERROR_LEVEL, my_errno,
 
5679
                "Error in Exec_load event: could not open file '%s'",
 
5680
                fname);
 
5681
    goto err;
 
5682
  }
 
5683
  if (!(lev = (Load_log_event*)Log_event::read_log_event(&file,
 
5684
                                                         (pthread_mutex_t*)0,
 
5685
                                                         rli->relay_log.description_event_for_exec)) ||
 
5686
      lev->get_type_code() != NEW_LOAD_EVENT)
 
5687
  {
 
5688
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
 
5689
                    "file '%s' appears corrupted", fname);
 
5690
    goto err;
 
5691
  }
 
5692
 
 
5693
  lev->thd = thd;
 
5694
  /*
 
5695
    lev->do_apply_event should use rli only for errors i.e. should
 
5696
    not advance rli's position.
 
5697
 
 
5698
    lev->do_apply_event is the place where the table is loaded (it
 
5699
    calls mysql_load()).
 
5700
  */
 
5701
 
 
5702
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
 
5703
  if (lev->do_apply_event(0,rli,1)) 
 
5704
  {
 
5705
    /*
 
5706
      We want to indicate the name of the file that could not be loaded
 
5707
      (SQL_LOADxxx).
 
5708
      But as we are here we are sure the error is in rli->last_slave_error and
 
5709
      rli->last_slave_errno (example of error: duplicate entry for key), so we
 
5710
      don't want to overwrite it with the filename.
 
5711
      What we want instead is add the filename to the current error message.
 
5712
    */
 
5713
    char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
 
5714
    if (tmp)
 
5715
    {
 
5716
      rli->report(ERROR_LEVEL, rli->last_error().number,
 
5717
                  "%s. Failed executing load from '%s'", tmp, fname);
 
5718
      my_free(tmp,MYF(0));
 
5719
    }
 
5720
    goto err;
 
5721
  }
 
5722
  /*
 
5723
    We have an open file descriptor to the .info file; we need to close it
 
5724
    or Windows will refuse to delete the file in my_delete().
 
5725
  */
 
5726
  if (fd >= 0)
 
5727
  {
 
5728
    my_close(fd, MYF(0));
 
5729
    end_io_cache(&file);
 
5730
    fd= -1;
 
5731
  }
 
5732
  (void) my_delete(fname, MYF(MY_WME));
 
5733
  memcpy(ext, ".data", 6);
 
5734
  (void) my_delete(fname, MYF(MY_WME));
 
5735
  error = 0;
 
5736
 
 
5737
err:
 
5738
  delete lev;
 
5739
  if (fd >= 0)
 
5740
  {
 
5741
    my_close(fd, MYF(0));
 
5742
    end_io_cache(&file);
 
5743
  }
 
5744
  return error;
 
5745
}
 
5746
 
 
5747
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5748
 
 
5749
 
 
5750
/**************************************************************************
 
5751
        Begin_load_query_log_event methods
 
5752
**************************************************************************/
 
5753
 
 
5754
#ifndef MYSQL_CLIENT
 
5755
Begin_load_query_log_event::
 
5756
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
 
5757
                           uint block_len_arg, bool using_trans)
 
5758
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
 
5759
                          using_trans)
 
5760
{
 
5761
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
 
5762
}
 
5763
#endif
 
5764
 
 
5765
 
 
5766
Begin_load_query_log_event::
 
5767
Begin_load_query_log_event(const char* buf, uint len,
 
5768
                           const Format_description_log_event* desc_event)
 
5769
  :Append_block_log_event(buf, len, desc_event)
 
5770
{
 
5771
}
 
5772
 
 
5773
 
 
5774
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5775
int Begin_load_query_log_event::get_create_or_append() const
 
5776
{
 
5777
  return 1; /* create the file */
 
5778
}
 
5779
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5780
 
 
5781
 
 
5782
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
5783
Log_event::enum_skip_reason
 
5784
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
 
5785
{
 
5786
  /*
 
5787
    If the slave skip counter is 1, then we should not start executing
 
5788
    on the next event.
 
5789
  */
 
5790
  return continue_group(rli);
 
5791
}
 
5792
#endif
 
5793
 
 
5794
 
 
5795
/**************************************************************************
 
5796
        Execute_load_query_log_event methods
 
5797
**************************************************************************/
 
5798
 
 
5799
 
 
5800
#ifndef MYSQL_CLIENT
 
5801
Execute_load_query_log_event::
 
5802
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
 
5803
                             ulong query_length_arg, uint fn_pos_start_arg,
 
5804
                             uint fn_pos_end_arg,
 
5805
                             enum_load_dup_handling dup_handling_arg,
 
5806
                             bool using_trans, bool suppress_use,
 
5807
                             THD::killed_state killed_err_arg):
 
5808
  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
 
5809
                  suppress_use, killed_err_arg),
 
5810
  file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
 
5811
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
 
5812
{
 
5813
}
 
5814
#endif /* !MYSQL_CLIENT */
 
5815
 
 
5816
 
 
5817
Execute_load_query_log_event::
 
5818
Execute_load_query_log_event(const char* buf, uint event_len,
 
5819
                             const Format_description_log_event* desc_event):
 
5820
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
 
5821
  file_id(0), fn_pos_start(0), fn_pos_end(0)
 
5822
{
 
5823
  if (!Query_log_event::is_valid())
 
5824
    return;
 
5825
 
 
5826
  buf+= desc_event->common_header_len;
 
5827
 
 
5828
  fn_pos_start= uint4korr(buf + ELQ_FN_POS_START_OFFSET);
 
5829
  fn_pos_end= uint4korr(buf + ELQ_FN_POS_END_OFFSET);
 
5830
  dup_handling= (enum_load_dup_handling)(*(buf + ELQ_DUP_HANDLING_OFFSET));
 
5831
 
 
5832
  if (fn_pos_start > q_len || fn_pos_end > q_len ||
 
5833
      dup_handling > LOAD_DUP_REPLACE)
 
5834
    return;
 
5835
 
 
5836
  file_id= uint4korr(buf + ELQ_FILE_ID_OFFSET);
 
5837
}
 
5838
 
 
5839
 
 
5840
ulong Execute_load_query_log_event::get_post_header_size_for_derived()
 
5841
{
 
5842
  return EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN;
 
5843
}
 
5844
 
 
5845
 
 
5846
#ifndef MYSQL_CLIENT
 
5847
bool
 
5848
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
 
5849
{
 
5850
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
5851
  int4store(buf, file_id);
 
5852
  int4store(buf + 4, fn_pos_start);
 
5853
  int4store(buf + 4 + 4, fn_pos_end);
 
5854
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
 
5855
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
 
5856
}
 
5857
#endif
 
5858
 
 
5859
 
 
5860
#ifdef MYSQL_CLIENT
 
5861
void Execute_load_query_log_event::print(FILE* file,
 
5862
                                         PRINT_EVENT_INFO* print_event_info)
 
5863
{
 
5864
  print(file, print_event_info, 0);
 
5865
}
 
5866
 
 
5867
/**
 
5868
  Prints the query as LOAD DATA LOCAL and with rewritten filename.
 
5869
*/
 
5870
void Execute_load_query_log_event::print(FILE* file,
 
5871
                                         PRINT_EVENT_INFO* print_event_info,
 
5872
                                         const char *local_fname)
 
5873
{
 
5874
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5875
 
 
5876
  print_query_header(&cache, print_event_info);
 
5877
 
 
5878
  if (local_fname)
 
5879
  {
 
5880
    my_b_write(&cache, (uchar*) query, fn_pos_start);
 
5881
    my_b_printf(&cache, " LOCAL INFILE \'");
 
5882
    my_b_printf(&cache, local_fname);
 
5883
    my_b_printf(&cache, "\'");
 
5884
    if (dup_handling == LOAD_DUP_REPLACE)
 
5885
      my_b_printf(&cache, " REPLACE");
 
5886
    my_b_printf(&cache, " INTO");
 
5887
    my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
 
5888
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5889
  }
 
5890
  else
 
5891
  {
 
5892
    my_b_write(&cache, (uchar*) query, q_len);
 
5893
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5894
  }
 
5895
 
 
5896
  if (!print_event_info->short_form)
 
5897
    my_b_printf(&cache, "# file_id: %d \n", file_id);
 
5898
}
 
5899
#endif
 
5900
 
 
5901
 
 
5902
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5903
void Execute_load_query_log_event::pack_info(Protocol *protocol)
 
5904
{
 
5905
  char *buf, *pos;
 
5906
  if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
 
5907
    return;
 
5908
  pos= buf;
 
5909
  if (db && db_len)
 
5910
  {
 
5911
    pos= strmov(buf, "use `");
 
5912
    memcpy(pos, db, db_len);
 
5913
    pos= strmov(pos+db_len, "`; ");
 
5914
  }
 
5915
  if (query && q_len)
 
5916
  {
 
5917
    memcpy(pos, query, q_len);
 
5918
    pos+= q_len;
 
5919
  }
 
5920
  pos= strmov(pos, " ;file_id=");
 
5921
  pos= int10_to_str((long) file_id, pos, 10);
 
5922
  protocol->store(buf, pos-buf, &my_charset_bin);
 
5923
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
5924
}
 
5925
 
 
5926
 
 
5927
int
 
5928
Execute_load_query_log_event::do_apply_event(Relay_log_info const *rli)
 
5929
{
 
5930
  char *p;
 
5931
  char *buf;
 
5932
  char *fname;
 
5933
  char *fname_end;
 
5934
  int error;
 
5935
 
 
5936
  buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
 
5937
                         (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
 
5938
 
 
5939
  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf, MYF(0)); buf= NULL;);
 
5940
 
 
5941
  /* Replace filename and LOCAL keyword in query before executing it */
 
5942
  if (buf == NULL)
 
5943
  {
 
5944
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
 
5945
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
 
5946
    return 1;
 
5947
  }
 
5948
 
 
5949
  p= buf;
 
5950
  memcpy(p, query, fn_pos_start);
 
5951
  p+= fn_pos_start;
 
5952
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
 
5953
  p= slave_load_file_stem(p, file_id, server_id, ".data");
 
5954
  fname_end= p= strend(p);                      // Safer than p=p+5
 
5955
  *(p++)='\'';
 
5956
  switch (dup_handling) {
 
5957
  case LOAD_DUP_IGNORE:
 
5958
    p= strmake(p, STRING_WITH_LEN(" IGNORE"));
 
5959
    break;
 
5960
  case LOAD_DUP_REPLACE:
 
5961
    p= strmake(p, STRING_WITH_LEN(" REPLACE"));
 
5962
    break;
 
5963
  default:
 
5964
    /* Ordinary load data */
 
5965
    break;
 
5966
  }
 
5967
  p= strmake(p, STRING_WITH_LEN(" INTO"));
 
5968
  p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
 
5969
 
 
5970
  error= Query_log_event::do_apply_event(rli, buf, p-buf);
 
5971
 
 
5972
  /* Forging file name for deletion in same buffer */
 
5973
  *fname_end= 0;
 
5974
 
 
5975
  /*
 
5976
    If there was an error the slave is going to stop, leave the
 
5977
    file so that we can re-execute this event at START SLAVE.
 
5978
  */
 
5979
  if (!error)
 
5980
    (void) my_delete(fname, MYF(MY_WME));
 
5981
 
 
5982
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
5983
  return error;
 
5984
}
 
5985
#endif
 
5986
 
 
5987
 
 
5988
/**************************************************************************
 
5989
        sql_ex_info methods
 
5990
**************************************************************************/
 
5991
 
 
5992
/*
 
5993
  sql_ex_info::write_data()
 
5994
*/
 
5995
 
 
5996
bool sql_ex_info::write_data(IO_CACHE* file)
 
5997
{
 
5998
  if (new_format())
 
5999
  {
 
6000
    return (write_str(file, field_term, (uint) field_term_len) ||
 
6001
            write_str(file, enclosed,   (uint) enclosed_len) ||
 
6002
            write_str(file, line_term,  (uint) line_term_len) ||
 
6003
            write_str(file, line_start, (uint) line_start_len) ||
 
6004
            write_str(file, escaped,    (uint) escaped_len) ||
 
6005
            my_b_safe_write(file,(uchar*) &opt_flags,1));
 
6006
  }
 
6007
  else
 
6008
  {
 
6009
    /**
 
6010
      @todo This is sensitive to field padding. We should write a
 
6011
      char[7], not an old_sql_ex. /sven
 
6012
    */
 
6013
    old_sql_ex old_ex;
 
6014
    old_ex.field_term= *field_term;
 
6015
    old_ex.enclosed=   *enclosed;
 
6016
    old_ex.line_term=  *line_term;
 
6017
    old_ex.line_start= *line_start;
 
6018
    old_ex.escaped=    *escaped;
 
6019
    old_ex.opt_flags=  opt_flags;
 
6020
    old_ex.empty_flags=empty_flags;
 
6021
    return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
 
6022
  }
 
6023
}
 
6024
 
 
6025
 
 
6026
/*
 
6027
  sql_ex_info::init()
 
6028
*/
 
6029
 
 
6030
const char *sql_ex_info::init(const char *buf, const char *buf_end,
 
6031
                              bool use_new_format)
 
6032
{
 
6033
  cached_new_format = use_new_format;
 
6034
  if (use_new_format)
 
6035
  {
 
6036
    empty_flags=0;
 
6037
    /*
 
6038
      The code below assumes that buf will not disappear from
 
6039
      under our feet during the lifetime of the event. This assumption
 
6040
      holds true in the slave thread if the log is in new format, but is not
 
6041
      the case when we have old format because we will be reusing net buffer
 
6042
      to read the actual file before we write out the Create_file event.
 
6043
    */
 
6044
    if (read_str(&buf, buf_end, &field_term, &field_term_len) ||
 
6045
        read_str(&buf, buf_end, &enclosed,   &enclosed_len) ||
 
6046
        read_str(&buf, buf_end, &line_term,  &line_term_len) ||
 
6047
        read_str(&buf, buf_end, &line_start, &line_start_len) ||
 
6048
        read_str(&buf, buf_end, &escaped,    &escaped_len))
 
6049
      return 0;
 
6050
    opt_flags = *buf++;
 
6051
  }
 
6052
  else
 
6053
  {
 
6054
    field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
 
6055
    field_term = buf++;                 // Use first byte in string
 
6056
    enclosed=    buf++;
 
6057
    line_term=   buf++;
 
6058
    line_start=  buf++;
 
6059
    escaped=     buf++;
 
6060
    opt_flags =  *buf++;
 
6061
    empty_flags= *buf++;
 
6062
    if (empty_flags & FIELD_TERM_EMPTY)
 
6063
      field_term_len=0;
 
6064
    if (empty_flags & ENCLOSED_EMPTY)
 
6065
      enclosed_len=0;
 
6066
    if (empty_flags & LINE_TERM_EMPTY)
 
6067
      line_term_len=0;
 
6068
    if (empty_flags & LINE_START_EMPTY)
 
6069
      line_start_len=0;
 
6070
    if (empty_flags & ESCAPED_EMPTY)
 
6071
      escaped_len=0;
 
6072
  }
 
6073
  return buf;
 
6074
}
 
6075
 
 
6076
 
 
6077
/**************************************************************************
 
6078
        Rows_log_event member functions
 
6079
**************************************************************************/
 
6080
 
 
6081
#ifndef MYSQL_CLIENT
 
6082
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
 
6083
                               MY_BITMAP const *cols, bool is_transactional)
 
6084
  : Log_event(thd_arg, 0, is_transactional),
 
6085
    m_row_count(0),
 
6086
    m_table(tbl_arg),
 
6087
    m_table_id(tid),
 
6088
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
 
6089
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
6090
#ifdef HAVE_REPLICATION
 
6091
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
6092
#endif
 
6093
{
 
6094
  /*
 
6095
    We allow a special form of dummy event when the table, and cols
 
6096
    are null and the table id is ~0UL.  This is a temporary
 
6097
    solution, to be able to terminate a started statement in the
 
6098
    binary log: the extraneous events will be removed in the future.
 
6099
   */
 
6100
  DBUG_ASSERT(tbl_arg && tbl_arg->s && tid != ~0UL ||
 
6101
              !tbl_arg && !cols && tid == ~0UL);
 
6102
 
 
6103
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
 
6104
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
 
6105
  if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
 
6106
      set_flags(RELAXED_UNIQUE_CHECKS_F);
 
6107
  /* if bitmap_init fails, caught in is_valid() */
 
6108
  if (likely(!bitmap_init(&m_cols,
 
6109
                          m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
 
6110
                          m_width,
 
6111
                          false)))
 
6112
  {
 
6113
    DBUG_PRINT_BITSET("debug", "init cols: %s", cols);
 
6114
    /* Cols can be zero if this is a dummy binrows event */
 
6115
    if (likely(cols != NULL))
 
6116
    {
 
6117
      memcpy(m_cols.bitmap, cols->bitmap, no_bytes_in_map(cols));
 
6118
      create_last_word_mask(&m_cols);
 
6119
    }
 
6120
  }
 
6121
  else
 
6122
  {
 
6123
    // Needed because bitmap_init() does not set it to null on failure
 
6124
    m_cols.bitmap= 0;
 
6125
  }
 
6126
}
 
6127
#endif
 
6128
 
 
6129
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
 
6130
                               Log_event_type event_type,
 
6131
                               const Format_description_log_event
 
6132
                               *description_event)
 
6133
  : Log_event(buf, description_event),
 
6134
    m_row_count(0),
 
6135
#ifndef MYSQL_CLIENT
 
6136
    m_table(NULL),
 
6137
#endif
 
6138
    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
 
6139
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
6140
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
6141
#endif
 
6142
{
 
6143
  DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
 
6144
  uint8 const common_header_len= description_event->common_header_len;
 
6145
  uint8 const post_header_len= description_event->post_header_len[event_type-1];
 
6146
 
 
6147
  DBUG_PRINT("enter",("event_len: %u  common_header_len: %d  "
 
6148
                      "post_header_len: %d",
 
6149
                      event_len, common_header_len,
 
6150
                      post_header_len));
 
6151
 
 
6152
  const char *post_start= buf + common_header_len;
 
6153
  post_start+= RW_MAPID_OFFSET;
 
6154
  if (post_header_len == 6)
 
6155
  {
 
6156
    /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
 
6157
    m_table_id= uint4korr(post_start);
 
6158
    post_start+= 4;
 
6159
  }
 
6160
  else
 
6161
  {
 
6162
    m_table_id= (ulong) uint6korr(post_start);
 
6163
    post_start+= RW_FLAGS_OFFSET;
 
6164
  }
 
6165
 
 
6166
  m_flags= uint2korr(post_start);
 
6167
 
 
6168
  uchar const *const var_start=
 
6169
    (const uchar *)buf + common_header_len + post_header_len;
 
6170
  uchar const *const ptr_width= var_start;
 
6171
  uchar *ptr_after_width= (uchar*) ptr_width;
 
6172
  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
6173
  m_width = net_field_length(&ptr_after_width);
 
6174
  DBUG_PRINT("debug", ("m_width=%lu", m_width));
 
6175
  /* if bitmap_init fails, catched in is_valid() */
 
6176
  if (likely(!bitmap_init(&m_cols,
 
6177
                          m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
 
6178
                          m_width,
 
6179
                          false)))
 
6180
  {
 
6181
    DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
6182
    memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
 
6183
    create_last_word_mask(&m_cols);
 
6184
    ptr_after_width+= (m_width + 7) / 8;
 
6185
    DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
 
6186
  }
 
6187
  else
 
6188
  {
 
6189
    // Needed because bitmap_init() does not set it to null on failure
 
6190
    m_cols.bitmap= NULL;
 
6191
    DBUG_VOID_RETURN;
 
6192
  }
 
6193
 
 
6194
  m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
 
6195
 
 
6196
  if (event_type == UPDATE_ROWS_EVENT)
 
6197
  {
 
6198
    DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
6199
 
 
6200
    /* if bitmap_init fails, caught in is_valid() */
 
6201
    if (likely(!bitmap_init(&m_cols_ai,
 
6202
                            m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
 
6203
                            m_width,
 
6204
                            false)))
 
6205
    {
 
6206
      DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
6207
      memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
 
6208
      create_last_word_mask(&m_cols_ai);
 
6209
      ptr_after_width+= (m_width + 7) / 8;
 
6210
      DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
 
6211
                no_bytes_in_map(&m_cols_ai));
 
6212
    }
 
6213
    else
 
6214
    {
 
6215
      // Needed because bitmap_init() does not set it to null on failure
 
6216
      m_cols_ai.bitmap= 0;
 
6217
      DBUG_VOID_RETURN;
 
6218
    }
 
6219
  }
 
6220
 
 
6221
  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
 
6222
 
 
6223
  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
 
6224
  DBUG_PRINT("info",("m_table_id: %lu  m_flags: %d  m_width: %lu  data_size: %lu",
 
6225
                     m_table_id, m_flags, m_width, (ulong) data_size));
 
6226
 
 
6227
  m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
 
6228
  if (likely((bool)m_rows_buf))
 
6229
  {
 
6230
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
6231
    m_curr_row= m_rows_buf;
 
6232
#endif
 
6233
    m_rows_end= m_rows_buf + data_size;
 
6234
    m_rows_cur= m_rows_end;
 
6235
    memcpy(m_rows_buf, ptr_rows_data, data_size);
 
6236
  }
 
6237
  else
 
6238
    m_cols.bitmap= 0; // to not free it
 
6239
 
 
6240
  DBUG_VOID_RETURN;
 
6241
}
 
6242
 
 
6243
Rows_log_event::~Rows_log_event()
 
6244
{
 
6245
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
 
6246
    m_cols.bitmap= 0; // so no my_free in bitmap_free
 
6247
  bitmap_free(&m_cols); // To pair with bitmap_init().
 
6248
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
 
6249
}
 
6250
 
 
6251
int Rows_log_event::get_data_size()
 
6252
{
 
6253
  int const type_code= get_type_code();
 
6254
 
 
6255
  uchar buf[sizeof(m_width)+1];
 
6256
  uchar *end= net_store_length(buf, (m_width + 7) / 8);
 
6257
 
 
6258
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
6259
                  return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
 
6260
                  (type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
 
6261
                  (m_rows_cur - m_rows_buf););
 
6262
  int data_size= ROWS_HEADER_LEN;
 
6263
  data_size+= no_bytes_in_map(&m_cols);
 
6264
  data_size+= end - buf;
 
6265
 
 
6266
  if (type_code == UPDATE_ROWS_EVENT)
 
6267
    data_size+= no_bytes_in_map(&m_cols_ai);
 
6268
 
 
6269
  data_size+= (m_rows_cur - m_rows_buf);
 
6270
  return data_size; 
 
6271
}
 
6272
 
 
6273
 
 
6274
#ifndef MYSQL_CLIENT
 
6275
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
 
6276
{
 
6277
  /*
 
6278
    When the table has a primary key, we would probably want, by default, to
 
6279
    log only the primary key value instead of the entire "before image". This
 
6280
    would save binlog space. TODO
 
6281
  */
 
6282
  DBUG_ENTER("Rows_log_event::do_add_row_data");
 
6283
  DBUG_PRINT("enter", ("row_data: 0x%lx  length: %lu", (ulong) row_data,
 
6284
                       (ulong) length));
 
6285
 
 
6286
  /*
 
6287
    If length is zero, there is nothing to write, so we just
 
6288
    return. Note that this is not an optimization, since calling
 
6289
    realloc() with size 0 means free().
 
6290
   */
 
6291
  if (length == 0)
 
6292
  {
 
6293
    m_row_count++;
 
6294
    DBUG_RETURN(0);
 
6295
  }
 
6296
 
 
6297
  /*
 
6298
    Don't print debug messages when running valgrind since they can
 
6299
    trigger false warnings.
 
6300
   */
 
6301
#ifndef HAVE_purify
 
6302
  DBUG_DUMP("row_data", row_data, min(length, 32));
 
6303
#endif
 
6304
 
 
6305
  DBUG_ASSERT(m_rows_buf <= m_rows_cur);
 
6306
  DBUG_ASSERT(!m_rows_buf || m_rows_end && m_rows_buf <= m_rows_end);
 
6307
  DBUG_ASSERT(m_rows_cur <= m_rows_end);
 
6308
 
 
6309
  /* The cast will always work since m_rows_cur <= m_rows_end */
 
6310
  if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
 
6311
  {
 
6312
    size_t const block_size= 1024;
 
6313
    my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
 
6314
    my_ptrdiff_t const new_alloc= 
 
6315
        block_size * ((cur_size + length + block_size - 1) / block_size);
 
6316
 
 
6317
    uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
 
6318
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
 
6319
    if (unlikely(!new_buf))
 
6320
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
6321
 
 
6322
    /* If the memory moved, we need to move the pointers */
 
6323
    if (new_buf != m_rows_buf)
 
6324
    {
 
6325
      m_rows_buf= new_buf;
 
6326
      m_rows_cur= m_rows_buf + cur_size;
 
6327
    }
 
6328
 
 
6329
    /*
 
6330
       The end pointer should always be changed to point to the end of
 
6331
       the allocated memory.
 
6332
    */
 
6333
    m_rows_end= m_rows_buf + new_alloc;
 
6334
  }
 
6335
 
 
6336
  DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
 
6337
  memcpy(m_rows_cur, row_data, length);
 
6338
  m_rows_cur+= length;
 
6339
  m_row_count++;
 
6340
  DBUG_RETURN(0);
 
6341
}
 
6342
#endif
 
6343
 
 
6344
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
6345
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
 
6346
{
 
6347
  DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
 
6348
  int error= 0;
 
6349
  /*
 
6350
    If m_table_id == ~0UL, then we have a dummy event that does not
 
6351
    contain any data.  In that case, we just remove all tables in the
 
6352
    tables_to_lock list, close the thread tables, and return with
 
6353
    success.
 
6354
   */
 
6355
  if (m_table_id == ~0UL)
 
6356
  {
 
6357
    /*
 
6358
       This one is supposed to be set: just an extra check so that
 
6359
       nothing strange has happened.
 
6360
     */
 
6361
    DBUG_ASSERT(get_flags(STMT_END_F));
 
6362
 
 
6363
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
6364
    close_thread_tables(thd);
 
6365
    thd->clear_error();
 
6366
    DBUG_RETURN(0);
 
6367
  }
 
6368
 
 
6369
  /*
 
6370
    'thd' has been set by exec_relay_log_event(), just before calling
 
6371
    do_apply_event(). We still check here to prevent future coding
 
6372
    errors.
 
6373
  */
 
6374
  DBUG_ASSERT(rli->sql_thd == thd);
 
6375
 
 
6376
  /*
 
6377
    If there is no locks taken, this is the first binrow event seen
 
6378
    after the table map events.  We should then lock all the tables
 
6379
    used in the transaction and proceed with execution of the actual
 
6380
    event.
 
6381
  */
 
6382
  if (!thd->lock)
 
6383
  {
 
6384
    bool need_reopen= 1; /* To execute the first lap of the loop below */
 
6385
 
 
6386
    /*
 
6387
      lock_tables() reads the contents of thd->lex, so they must be
 
6388
      initialized. Contrary to in
 
6389
      Table_map_log_event::do_apply_event() we don't call
 
6390
      mysql_init_query() as that may reset the binlog format.
 
6391
    */
 
6392
    lex_start(thd);
 
6393
 
 
6394
    /*
 
6395
      There are a few flags that are replicated with each row event.
 
6396
      Make sure to set/clear them before executing the main body of
 
6397
      the event.
 
6398
    */
 
6399
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
 
6400
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
6401
    else
 
6402
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
6403
 
 
6404
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
 
6405
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
6406
    else
 
6407
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
6408
    /* A small test to verify that objects have consistent types */
 
6409
    DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6410
 
 
6411
 
 
6412
    while ((error= lock_tables(thd, rli->tables_to_lock,
 
6413
                               rli->tables_to_lock_count, &need_reopen)))
 
6414
    {
 
6415
      if (!need_reopen)
 
6416
      {
 
6417
        if (thd->is_slave_error || thd->is_fatal_error)
 
6418
        {
 
6419
          /*
 
6420
            Error reporting borrowed from Query_log_event with many excessive
 
6421
            simplifications (we don't honour --slave-skip-errors)
 
6422
          */
 
6423
          uint actual_error= thd->main_da.sql_errno();
 
6424
          rli->report(ERROR_LEVEL, actual_error,
 
6425
                      "Error '%s' in %s event: when locking tables",
 
6426
                      (actual_error ? thd->main_da.message():
 
6427
                       "unexpected success or fatal error"),
 
6428
                      get_type_str());
 
6429
          thd->is_fatal_error= 1;
 
6430
        }
 
6431
        else
 
6432
        {
 
6433
          rli->report(ERROR_LEVEL, error,
 
6434
                      "Error in %s event: when locking tables",
 
6435
                      get_type_str());
 
6436
        }
 
6437
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
6438
        DBUG_RETURN(error);
 
6439
      }
 
6440
 
 
6441
      /*
 
6442
        So we need to reopen the tables.
 
6443
 
 
6444
        We need to flush the pending RBR event, since it keeps a
 
6445
        pointer to an open table.
 
6446
 
 
6447
        ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
 
6448
        the pending RBR event and reset the table pointer after the
 
6449
        tables has been reopened.
 
6450
 
 
6451
        NOTE: For this new scheme there should be no pending event:
 
6452
        need to add code to assert that is the case.
 
6453
       */
 
6454
      thd->binlog_flush_pending_rows_event(false);
 
6455
      TABLE_LIST *tables= rli->tables_to_lock;
 
6456
      close_tables_for_reopen(thd, &tables);
 
6457
 
 
6458
      uint tables_count= rli->tables_to_lock_count;
 
6459
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
 
6460
      {
 
6461
        if (thd->is_slave_error || thd->is_fatal_error)
 
6462
        {
 
6463
          /*
 
6464
            Error reporting borrowed from Query_log_event with many excessive
 
6465
            simplifications (we don't honour --slave-skip-errors)
 
6466
          */
 
6467
          uint actual_error= thd->main_da.sql_errno();
 
6468
          rli->report(ERROR_LEVEL, actual_error,
 
6469
                      "Error '%s' on reopening tables",
 
6470
                      (actual_error ? thd->main_da.message() :
 
6471
                       "unexpected success or fatal error"));
 
6472
          thd->is_slave_error= 1;
 
6473
        }
 
6474
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
6475
        DBUG_RETURN(error);
 
6476
      }
 
6477
    }
 
6478
 
 
6479
    /*
 
6480
      When the open and locking succeeded, we check all tables to
 
6481
      ensure that they still have the correct type.
 
6482
 
 
6483
      We can use a down cast here since we know that every table added
 
6484
      to the tables_to_lock is a RPL_TABLE_LIST.
 
6485
    */
 
6486
 
 
6487
    {
 
6488
      RPL_TABLE_LIST *ptr= rli->tables_to_lock;
 
6489
      for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
 
6490
      {
 
6491
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
 
6492
        {
 
6493
          mysql_unlock_tables(thd, thd->lock);
 
6494
          thd->lock= 0;
 
6495
          thd->is_slave_error= 1;
 
6496
          const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
6497
          DBUG_RETURN(ERR_BAD_TABLE_DEF);
 
6498
        }
 
6499
      }
 
6500
    }
 
6501
 
 
6502
    /*
 
6503
      ... and then we add all the tables to the table map and remove
 
6504
      them from tables to lock.
 
6505
 
 
6506
      We also invalidate the query cache for all the tables, since
 
6507
      they will now be changed.
 
6508
 
 
6509
      TODO [/Matz]: Maybe the query cache should not be invalidated
 
6510
      here? It might be that a table is not changed, even though it
 
6511
      was locked for the statement.  We do know that each
 
6512
      Rows_log_event contain at least one row, so after processing one
 
6513
      Rows_log_event, we can invalidate the query cache for the
 
6514
      associated table.
 
6515
     */
 
6516
    for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
 
6517
    {
 
6518
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
 
6519
    }
 
6520
  }
 
6521
 
 
6522
  TABLE* 
 
6523
    table= 
 
6524
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
 
6525
 
 
6526
  if (table)
 
6527
  {
 
6528
    /*
 
6529
      table == NULL means that this table should not be replicated
 
6530
      (this was set up by Table_map_log_event::do_apply_event()
 
6531
      which tested replicate-* rules).
 
6532
    */
 
6533
 
 
6534
    /*
 
6535
      It's not needed to set_time() but
 
6536
      1) it continues the property that "Time" in SHOW PROCESSLIST shows how
 
6537
      much slave is behind
 
6538
      2) it will be needed when we allow replication from a table with no
 
6539
      TIMESTAMP column to a table with one.
 
6540
      So we call set_time(), like in SBR. Presently it changes nothing.
 
6541
    */
 
6542
    thd->set_time((time_t)when);
 
6543
    /*
 
6544
      There are a few flags that are replicated with each row event.
 
6545
      Make sure to set/clear them before executing the main body of
 
6546
      the event.
 
6547
    */
 
6548
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
 
6549
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
6550
    else
 
6551
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
6552
 
 
6553
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
 
6554
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
6555
    else
 
6556
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
6557
    
 
6558
    if (slave_allow_batching)
 
6559
      thd->options|= OPTION_ALLOW_BATCH;
 
6560
    else
 
6561
      thd->options&= ~OPTION_ALLOW_BATCH;
 
6562
    
 
6563
    /* A small test to verify that objects have consistent types */
 
6564
    DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6565
 
 
6566
    /*
 
6567
      Now we are in a statement and will stay in a statement until we
 
6568
      see a STMT_END_F.
 
6569
 
 
6570
      We set this flag here, before actually applying any rows, in
 
6571
      case the SQL thread is stopped and we need to detect that we're
 
6572
      inside a statement and halting abruptly might cause problems
 
6573
      when restarting.
 
6574
     */
 
6575
    const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
 
6576
 
 
6577
     if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
 
6578
      set_flags(COMPLETE_ROWS_F);
 
6579
 
 
6580
    /* 
 
6581
      Set tables write and read sets.
 
6582
      
 
6583
      Read_set contains all slave columns (in case we are going to fetch
 
6584
      a complete record from slave)
 
6585
      
 
6586
      Write_set equals the m_cols bitmap sent from master but it can be 
 
6587
      longer if slave has extra columns. 
 
6588
     */ 
 
6589
 
 
6590
    DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols);
 
6591
 
 
6592
    bitmap_set_all(table->read_set);
 
6593
    bitmap_set_all(table->write_set);
 
6594
    if (!get_flags(COMPLETE_ROWS_F))
 
6595
      bitmap_intersect(table->write_set,&m_cols);
 
6596
 
 
6597
    this->slave_exec_mode= slave_exec_mode_options; // fix the mode
 
6598
 
 
6599
    // Do event specific preparations 
 
6600
    error= do_before_row_operations(rli);
 
6601
 
 
6602
    // row processing loop
 
6603
 
 
6604
    while (error == 0 && m_curr_row < m_rows_end)
 
6605
    {
 
6606
      /* in_use can have been set to NULL in close_tables_for_reopen */
 
6607
      THD* old_thd= table->in_use;
 
6608
      if (!table->in_use)
 
6609
        table->in_use= thd;
 
6610
 
 
6611
      error= do_exec_row(rli);
 
6612
 
 
6613
      table->in_use = old_thd;
 
6614
      switch (error)
 
6615
      {
 
6616
      case 0:
 
6617
        break;
 
6618
      /*
 
6619
        The following list of "idempotent" errors
 
6620
        means that an error from the list might happen
 
6621
        because of idempotent (more than once) 
 
6622
        applying of a binlog file.
 
6623
        Notice, that binlog has a  ddl operation its
 
6624
        second applying may cause
 
6625
 
 
6626
        case HA_ERR_TABLE_DEF_CHANGED:
 
6627
        case HA_ERR_CANNOT_ADD_FOREIGN:
 
6628
        
 
6629
        which are not included into to the list.
 
6630
      */
 
6631
      case HA_ERR_RECORD_CHANGED:
 
6632
      case HA_ERR_RECORD_DELETED:
 
6633
      case HA_ERR_KEY_NOT_FOUND:
 
6634
      case HA_ERR_END_OF_FILE:
 
6635
      case HA_ERR_FOUND_DUPP_KEY:
 
6636
      case HA_ERR_FOUND_DUPP_UNIQUE:
 
6637
      case HA_ERR_FOREIGN_DUPLICATE_KEY:
 
6638
      case HA_ERR_NO_REFERENCED_ROW:
 
6639
      case HA_ERR_ROW_IS_REFERENCED:
 
6640
 
 
6641
        DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
 
6642
        if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
6643
        {
 
6644
          if (global_system_variables.log_warnings)
 
6645
            slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
 
6646
                                    get_type_str(),
 
6647
                                    RPL_LOG_NAME, (ulong) log_pos);
 
6648
          error= 0;
 
6649
        }
 
6650
        break;
 
6651
        
 
6652
      default:
 
6653
        thd->is_slave_error= 1;
 
6654
        break;
 
6655
      }
 
6656
 
 
6657
      /*
 
6658
       If m_curr_row_end  was not set during event execution (e.g., because
 
6659
       of errors) we can't proceed to the next row. If the error is transient
 
6660
       (i.e., error==0 at this point) we must call unpack_current_row() to set 
 
6661
       m_curr_row_end.
 
6662
      */ 
 
6663
   
 
6664
      DBUG_PRINT("info", ("error: %d", error));
 
6665
      DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
 
6666
                          (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
 
6667
 
 
6668
      if (!m_curr_row_end && !error)
 
6669
        unpack_current_row(rli, &m_cols);
 
6670
  
 
6671
      // at this moment m_curr_row_end should be set
 
6672
      DBUG_ASSERT(error || m_curr_row_end != NULL); 
 
6673
      DBUG_ASSERT(error || m_curr_row < m_curr_row_end);
 
6674
      DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
 
6675
  
 
6676
      m_curr_row= m_curr_row_end;
 
6677
 
 
6678
    } // row processing loop
 
6679
 
 
6680
    DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
 
6681
                    const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
 
6682
    error= do_after_row_operations(rli, error);
 
6683
    if (!cache_stmt)
 
6684
    {
 
6685
      DBUG_PRINT("info", ("Marked that we need to keep log"));
 
6686
      thd->options|= OPTION_KEEP_LOG;
 
6687
    }
 
6688
  } // if (table)
 
6689
 
 
6690
  /*
 
6691
    We need to delay this clear until here bacause unpack_current_row() uses
 
6692
    master-side table definitions stored in rli.
 
6693
  */
 
6694
  if (rli->tables_to_lock && get_flags(STMT_END_F))
 
6695
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
 
6696
  /* reset OPTION_ALLOW_BATCH as not affect later events */
 
6697
  thd->options&= ~OPTION_ALLOW_BATCH;
 
6698
  
 
6699
  if (error)
 
6700
  {                     /* error has occured during the transaction */
 
6701
    slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
 
6702
                            get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
 
6703
  }
 
6704
  if (error)
 
6705
  {
 
6706
    /*
 
6707
      If one day we honour --skip-slave-errors in row-based replication, and
 
6708
      the error should be skipped, then we would clear mappings, rollback,
 
6709
      close tables, but the slave SQL thread would not stop and then may
 
6710
      assume the mapping is still available, the tables are still open...
 
6711
      So then we should clear mappings/rollback/close here only if this is a
 
6712
      STMT_END_F.
 
6713
      For now we code, knowing that error is not skippable and so slave SQL
 
6714
      thread is certainly going to stop.
 
6715
      rollback at the caller along with sbr.
 
6716
    */
 
6717
    thd->reset_current_stmt_binlog_row_based();
 
6718
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
 
6719
    thd->is_slave_error= 1;
 
6720
    DBUG_RETURN(error);
 
6721
  }
 
6722
 
 
6723
  /*
 
6724
    This code would ideally be placed in do_update_pos() instead, but
 
6725
    since we have no access to table there, we do the setting of
 
6726
    last_event_start_time here instead.
 
6727
  */
 
6728
  if (table && (table->s->primary_key == MAX_KEY) &&
 
6729
      !cache_stmt && get_flags(STMT_END_F) == RLE_NO_FLAGS)
 
6730
  {
 
6731
    /*
 
6732
      ------------ Temporary fix until WL#2975 is implemented ---------
 
6733
 
 
6734
      This event is not the last one (no STMT_END_F). If we stop now
 
6735
      (in case of terminate_slave_thread()), how will we restart? We
 
6736
      have to restart from Table_map_log_event, but as this table is
 
6737
      not transactional, the rows already inserted will still be
 
6738
      present, and idempotency is not guaranteed (no PK) so we risk
 
6739
      that repeating leads to double insert. So we desperately try to
 
6740
      continue, hope we'll eventually leave this buggy situation (by
 
6741
      executing the final Rows_log_event). If we are in a hopeless
 
6742
      wait (reached end of last relay log and nothing gets appended
 
6743
      there), we timeout after one minute, and notify DBA about the
 
6744
      problem.  When WL#2975 is implemented, just remove the member
 
6745
      Relay_log_info::last_event_start_time and all its occurrences.
 
6746
    */
 
6747
    const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
 
6748
  }
 
6749
 
 
6750
  DBUG_RETURN(0);
 
6751
}
 
6752
 
 
6753
Log_event::enum_skip_reason
 
6754
Rows_log_event::do_shall_skip(Relay_log_info *rli)
 
6755
{
 
6756
  /*
 
6757
    If the slave skip counter is 1 and this event does not end a
 
6758
    statement, then we should not start executing on the next event.
 
6759
    Otherwise, we defer the decision to the normal skipping logic.
 
6760
  */
 
6761
  if (rli->slave_skip_counter == 1 && !get_flags(STMT_END_F))
 
6762
    return Log_event::EVENT_SKIP_IGNORE;
 
6763
  else
 
6764
    return Log_event::do_shall_skip(rli);
 
6765
}
 
6766
 
 
6767
int
 
6768
Rows_log_event::do_update_pos(Relay_log_info *rli)
 
6769
{
 
6770
  DBUG_ENTER("Rows_log_event::do_update_pos");
 
6771
  int error= 0;
 
6772
 
 
6773
  DBUG_PRINT("info", ("flags: %s",
 
6774
                      get_flags(STMT_END_F) ? "STMT_END_F " : ""));
 
6775
 
 
6776
  if (get_flags(STMT_END_F))
 
6777
  {
 
6778
    /*
 
6779
      This is the end of a statement or transaction, so close (and
 
6780
      unlock) the tables we opened when processing the
 
6781
      Table_map_log_event starting the statement.
 
6782
 
 
6783
      OBSERVER.  This will clear *all* mappings, not only those that
 
6784
      are open for the table. There is not good handle for on-close
 
6785
      actions for tables.
 
6786
 
 
6787
      NOTE. Even if we have no table ('table' == 0) we still need to be
 
6788
      here, so that we increase the group relay log position. If we didn't, we
 
6789
      could have a group relay log position which lags behind "forever"
 
6790
      (assume the last master's transaction is ignored by the slave because of
 
6791
      replicate-ignore rules).
 
6792
    */
 
6793
    thd->binlog_flush_pending_rows_event(true);
 
6794
 
 
6795
    /*
 
6796
      If this event is not in a transaction, the call below will, if some
 
6797
      transactional storage engines are involved, commit the statement into
 
6798
      them and flush the pending event to binlog.
 
6799
      If this event is in a transaction, the call will do nothing, but a
 
6800
      Xid_log_event will come next which will, if some transactional engines
 
6801
      are involved, commit the transaction and flush the pending event to the
 
6802
      binlog.
 
6803
    */
 
6804
    error= ha_autocommit_or_rollback(thd, 0);
 
6805
 
 
6806
    /*
 
6807
      Now what if this is not a transactional engine? we still need to
 
6808
      flush the pending event to the binlog; we did it with
 
6809
      thd->binlog_flush_pending_rows_event(). Note that we imitate
 
6810
      what is done for real queries: a call to
 
6811
      ha_autocommit_or_rollback() (sometimes only if involves a
 
6812
      transactional engine), and a call to be sure to have the pending
 
6813
      event flushed.
 
6814
    */
 
6815
 
 
6816
    thd->reset_current_stmt_binlog_row_based();
 
6817
 
 
6818
    rli->cleanup_context(thd, 0);
 
6819
    if (error == 0)
 
6820
    {
 
6821
      /*
 
6822
        Indicate that a statement is finished.
 
6823
        Step the group log position if we are not in a transaction,
 
6824
        otherwise increase the event log position.
 
6825
       */
 
6826
      rli->stmt_done(log_pos, when);
 
6827
 
 
6828
      /*
 
6829
        Clear any errors pushed in thd->net.last_err* if for example "no key
 
6830
        found" (as this is allowed). This is a safety measure; apparently
 
6831
        those errors (e.g. when executing a Delete_rows_log_event of a
 
6832
        non-existing row, like in rpl_row_mystery22.test,
 
6833
        thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
 
6834
        do not become visible. We still prefer to wipe them out.
 
6835
      */
 
6836
      thd->clear_error();
 
6837
    }
 
6838
    else
 
6839
      rli->report(ERROR_LEVEL, error,
 
6840
                  "Error in %s event: commit of row events failed, "
 
6841
                  "table `%s`.`%s`",
 
6842
                  get_type_str(), m_table->s->db.str,
 
6843
                  m_table->s->table_name.str);
 
6844
  }
 
6845
  else
 
6846
  {
 
6847
    rli->inc_event_relay_log_pos();
 
6848
  }
 
6849
 
 
6850
  DBUG_RETURN(error);
 
6851
}
 
6852
 
 
6853
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
6854
 
 
6855
#ifndef MYSQL_CLIENT
 
6856
bool Rows_log_event::write_data_header(IO_CACHE *file)
 
6857
{
 
6858
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
6859
  DBUG_ASSERT(m_table_id != ~0UL);
 
6860
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
6861
                  {
 
6862
                    int4store(buf + 0, m_table_id);
 
6863
                    int2store(buf + 4, m_flags);
 
6864
                    return (my_b_safe_write(file, buf, 6));
 
6865
                  });
 
6866
  int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
 
6867
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
 
6868
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
 
6869
}
 
6870
 
 
6871
bool Rows_log_event::write_data_body(IO_CACHE*file)
 
6872
{
 
6873
  /*
 
6874
     Note that this should be the number of *bits*, not the number of
 
6875
     bytes.
 
6876
  */
 
6877
  uchar sbuf[sizeof(m_width)];
 
6878
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
 
6879
  bool res= false;
 
6880
  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
 
6881
  DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
 
6882
 
 
6883
  DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
 
6884
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
 
6885
 
 
6886
  DBUG_PRINT_BITSET("debug", "writing cols: %s", &m_cols);
 
6887
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
 
6888
                              no_bytes_in_map(&m_cols));
 
6889
  /*
 
6890
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
 
6891
   */
 
6892
  if (get_type_code() == UPDATE_ROWS_EVENT)
 
6893
  {
 
6894
    DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
 
6895
              no_bytes_in_map(&m_cols_ai));
 
6896
    res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
 
6897
                                no_bytes_in_map(&m_cols_ai));
 
6898
  }
 
6899
  DBUG_DUMP("rows", m_rows_buf, data_size);
 
6900
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
 
6901
 
 
6902
  return res;
 
6903
 
 
6904
}
 
6905
#endif
 
6906
 
 
6907
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
6908
void Rows_log_event::pack_info(Protocol *protocol)
 
6909
{
 
6910
  char buf[256];
 
6911
  char const *const flagstr=
 
6912
    get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
 
6913
  size_t bytes= my_snprintf(buf, sizeof(buf),
 
6914
                               "table_id: %lu%s", m_table_id, flagstr);
 
6915
  protocol->store(buf, bytes, &my_charset_bin);
 
6916
}
 
6917
#endif
 
6918
 
 
6919
#ifdef MYSQL_CLIENT
 
6920
void Rows_log_event::print_helper(FILE *file,
 
6921
                                  PRINT_EVENT_INFO *print_event_info,
 
6922
                                  char const *const name)
 
6923
{
 
6924
  IO_CACHE *const head= &print_event_info->head_cache;
 
6925
  IO_CACHE *const body= &print_event_info->body_cache;
 
6926
  if (!print_event_info->short_form)
 
6927
  {
 
6928
    bool const last_stmt_event= get_flags(STMT_END_F);
 
6929
    print_header(head, print_event_info, !last_stmt_event);
 
6930
    my_b_printf(head, "\t%s: table id %lu%s\n",
 
6931
                name, m_table_id,
 
6932
                last_stmt_event ? " flags: STMT_END_F" : "");
 
6933
    print_base64(body, print_event_info, !last_stmt_event);
 
6934
  }
 
6935
 
 
6936
  if (get_flags(STMT_END_F))
 
6937
  {
 
6938
    copy_event_cache_to_file_and_reinit(head, file);
 
6939
    copy_event_cache_to_file_and_reinit(body, file);
 
6940
  }
 
6941
}
 
6942
#endif
 
6943
 
 
6944
/**************************************************************************
 
6945
        Table_map_log_event member functions and support functions
 
6946
**************************************************************************/
 
6947
 
 
6948
/**
 
6949
  @page How replication of field metadata works.
 
6950
  
 
6951
  When a table map is created, the master first calls 
 
6952
  Table_map_log_event::save_field_metadata() which calculates how many 
 
6953
  values will be in the field metadata. Only those fields that require the 
 
6954
  extra data are added. The method also loops through all of the fields in 
 
6955
  the table calling the method Field::save_field_metadata() which returns the
 
6956
  values for the field that will be saved in the metadata and replicated to
 
6957
  the slave. Once all fields have been processed, the table map is written to
 
6958
  the binlog adding the size of the field metadata and the field metadata to
 
6959
  the end of the body of the table map.
 
6960
 
 
6961
  When a table map is read on the slave, the field metadata is read from the 
 
6962
  table map and passed to the table_def class constructor which saves the 
 
6963
  field metadata from the table map into an array based on the type of the 
 
6964
  field. Field metadata values not present (those fields that do not use extra 
 
6965
  data) in the table map are initialized as zero (0). The array size is the 
 
6966
  same as the columns for the table on the slave.
 
6967
 
 
6968
  Additionally, values saved for field metadata on the master are saved as a 
 
6969
  string of bytes (uchar) in the binlog. A field may require 1 or more bytes
 
6970
  to store the information. In cases where values require multiple bytes 
 
6971
  (e.g. values > 255), the endian-safe methods are used to properly encode 
 
6972
  the values on the master and decode them on the slave. When the field
 
6973
  metadata values are captured on the slave, they are stored in an array of
 
6974
  type uint16. This allows the least number of casts to prevent casting bugs
 
6975
  when the field metadata is used in comparisons of field attributes. When
 
6976
  the field metadata is used for calculating addresses in pointer math, the
 
6977
  type used is uint32. 
 
6978
*/
 
6979
 
 
6980
#if !defined(MYSQL_CLIENT)
 
6981
/**
 
6982
  Save the field metadata based on the real_type of the field.
 
6983
  The metadata saved depends on the type of the field. Some fields
 
6984
  store a single byte for pack_length() while others store two bytes
 
6985
  for field_length (max length).
 
6986
  
 
6987
  @retval  0  Ok.
 
6988
 
 
6989
  @todo
 
6990
  We may want to consider changing the encoding of the information.
 
6991
  Currently, the code attempts to minimize the number of bytes written to 
 
6992
  the tablemap. There are at least two other alternatives; 1) using 
 
6993
  net_store_length() to store the data allowing it to choose the number of
 
6994
  bytes that are appropriate thereby making the code much easier to 
 
6995
  maintain (only 1 place to change the encoding), or 2) use a fixed number
 
6996
  of bytes for each field. The problem with option 1 is that net_store_length()
 
6997
  will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
 
6998
  for fields like CHAR which can be no larger than 255 characters, the method
 
6999
  will use 3 bytes when the value is > 250. Further, every value that is
 
7000
  encoded using 2 parts (e.g., pack_length, field_length) will be numerically
 
7001
  > 250 therefore will use 3 bytes for eah value. The problem with option 2
 
7002
  is less wasteful for space but does waste 1 byte for every field that does
 
7003
  not encode 2 parts. 
 
7004
*/
 
7005
int Table_map_log_event::save_field_metadata()
 
7006
{
 
7007
  DBUG_ENTER("Table_map_log_event::save_field_metadata");
 
7008
  int index= 0;
 
7009
  for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
 
7010
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
 
7011
  DBUG_RETURN(index);
 
7012
}
 
7013
#endif /* !defined(MYSQL_CLIENT) */
 
7014
 
 
7015
/*
 
7016
  Constructor used to build an event for writing to the binary log.
 
7017
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
 
7018
  (tbl->s->db etc) and not pointer content.
 
7019
 */
 
7020
#if !defined(MYSQL_CLIENT)
 
7021
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
 
7022
                                         bool is_transactional, uint16 flags)
 
7023
  : Log_event(thd, 0, true),
 
7024
    m_table(tbl),
 
7025
    m_dbnam(tbl->s->db.str),
 
7026
    m_dblen(m_dbnam ? tbl->s->db.length : 0),
 
7027
    m_tblnam(tbl->s->table_name.str),
 
7028
    m_tbllen(tbl->s->table_name.length),
 
7029
    m_colcnt(tbl->s->fields),
 
7030
    m_memory(NULL),
 
7031
    m_table_id(tid),
 
7032
    m_flags(flags),
 
7033
    m_data_size(0),
 
7034
    m_field_metadata(0),
 
7035
    m_field_metadata_size(0),
 
7036
    m_null_bits(0),
 
7037
    m_meta_memory(NULL)
 
7038
{
 
7039
  DBUG_ASSERT(m_table_id != ~0UL);
 
7040
  /*
 
7041
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
 
7042
    table.cc / alloc_table_share():
 
7043
      Use the fact the key is db/0/table_name/0
 
7044
    As we rely on this let's assert it.
 
7045
  */
 
7046
  DBUG_ASSERT((tbl->s->db.str == 0) ||
 
7047
              (tbl->s->db.str[tbl->s->db.length] == 0));
 
7048
  DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
 
7049
 
 
7050
 
 
7051
  m_data_size=  TABLE_MAP_HEADER_LEN;
 
7052
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
 
7053
  m_data_size+= m_dblen + 2;    // Include length and terminating \0
 
7054
  m_data_size+= m_tbllen + 2;   // Include length and terminating \0
 
7055
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
 
7056
 
 
7057
  /* If malloc fails, caught in is_valid() */
 
7058
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
 
7059
  {
 
7060
    m_coltype= reinterpret_cast<uchar*>(m_memory);
 
7061
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
 
7062
      m_coltype[i]= m_table->field[i]->type();
 
7063
  }
 
7064
 
 
7065
  /*
 
7066
    Calculate a bitmap for the results of maybe_null() for all columns.
 
7067
    The bitmap is used to determine when there is a column from the master
 
7068
    that is not on the slave and is null and thus not in the row data during
 
7069
    replication.
 
7070
  */
 
7071
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
 
7072
  m_data_size+= num_null_bytes;
 
7073
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
 
7074
                                 &m_null_bits, num_null_bytes,
 
7075
                                 &m_field_metadata, (m_colcnt * 2),
 
7076
                                 NULL);
 
7077
 
 
7078
  bzero(m_field_metadata, (m_colcnt * 2));
 
7079
 
 
7080
  /*
 
7081
    Create an array for the field metadata and store it.
 
7082
  */
 
7083
  m_field_metadata_size= save_field_metadata();
 
7084
  DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
 
7085
 
 
7086
  /*
 
7087
    Now set the size of the data to the size of the field metadata array
 
7088
    plus one or two bytes for number of elements in the field metadata array.
 
7089
  */
 
7090
  if (m_field_metadata_size > 255)
 
7091
    m_data_size+= m_field_metadata_size + 2; 
 
7092
  else
 
7093
    m_data_size+= m_field_metadata_size + 1; 
 
7094
 
 
7095
  bzero(m_null_bits, num_null_bytes);
 
7096
  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
 
7097
    if (m_table->field[i]->maybe_null())
 
7098
      m_null_bits[(i / 8)]+= 1 << (i % 8);
 
7099
 
 
7100
}
 
7101
#endif /* !defined(MYSQL_CLIENT) */
 
7102
 
 
7103
/*
 
7104
  Constructor used by slave to read the event from the binary log.
 
7105
 */
 
7106
#if defined(HAVE_REPLICATION)
 
7107
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
 
7108
                                         const Format_description_log_event
 
7109
                                         *description_event)
 
7110
 
 
7111
  : Log_event(buf, description_event),
 
7112
#ifndef MYSQL_CLIENT
 
7113
    m_table(NULL),
 
7114
#endif
 
7115
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
 
7116
    m_colcnt(0), m_coltype(0),
 
7117
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
 
7118
    m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
 
7119
    m_null_bits(0), m_meta_memory(NULL)
 
7120
{
 
7121
  unsigned int bytes_read= 0;
 
7122
  DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
 
7123
 
 
7124
  uint8 common_header_len= description_event->common_header_len;
 
7125
  uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
 
7126
  DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
 
7127
                     event_len, common_header_len, post_header_len));
 
7128
 
 
7129
  /*
 
7130
    Don't print debug messages when running valgrind since they can
 
7131
    trigger false warnings.
 
7132
   */
 
7133
#ifndef HAVE_purify
 
7134
  DBUG_DUMP("event buffer", (uchar*) buf, event_len);
 
7135
#endif
 
7136
 
 
7137
  /* Read the post-header */
 
7138
  const char *post_start= buf + common_header_len;
 
7139
 
 
7140
  post_start+= TM_MAPID_OFFSET;
 
7141
  if (post_header_len == 6)
 
7142
  {
 
7143
    /* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
 
7144
    m_table_id= uint4korr(post_start);
 
7145
    post_start+= 4;
 
7146
  }
 
7147
  else
 
7148
  {
 
7149
    DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
 
7150
    m_table_id= (ulong) uint6korr(post_start);
 
7151
    post_start+= TM_FLAGS_OFFSET;
 
7152
  }
 
7153
 
 
7154
  DBUG_ASSERT(m_table_id != ~0UL);
 
7155
 
 
7156
  m_flags= uint2korr(post_start);
 
7157
 
 
7158
  /* Read the variable part of the event */
 
7159
  const char *const vpart= buf + common_header_len + post_header_len;
 
7160
 
 
7161
  /* Extract the length of the various parts from the buffer */
 
7162
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
 
7163
  m_dblen= *(uchar*) ptr_dblen;
 
7164
 
 
7165
  /* Length of database name + counter + terminating null */
 
7166
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
7167
  m_tbllen= *(uchar*) ptr_tbllen;
 
7168
 
 
7169
  /* Length of table name + counter + terminating null */
 
7170
  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
 
7171
  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
 
7172
  m_colcnt= net_field_length(&ptr_after_colcnt);
 
7173
 
 
7174
  DBUG_PRINT("info",("m_dblen: %lu  off: %ld  m_tbllen: %lu  off: %ld  m_colcnt: %lu  off: %ld",
 
7175
                     (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart), 
 
7176
                     (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
 
7177
                     m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
 
7178
 
 
7179
  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
 
7180
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
 
7181
                                     &m_dbnam, (uint) m_dblen + 1,
 
7182
                                     &m_tblnam, (uint) m_tbllen + 1,
 
7183
                                     &m_coltype, (uint) m_colcnt,
 
7184
                                     NullS);
 
7185
 
 
7186
  if (m_memory)
 
7187
  {
 
7188
    /* Copy the different parts into their memory */
 
7189
    strncpy(const_cast<char*>(m_dbnam), (const char*)ptr_dblen  + 1, m_dblen + 1);
 
7190
    strncpy(const_cast<char*>(m_tblnam), (const char*)ptr_tbllen + 1, m_tbllen + 1);
 
7191
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
 
7192
 
 
7193
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
 
7194
    bytes_read= ptr_after_colcnt - (uchar *)buf;
 
7195
    DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
 
7196
    if (bytes_read < event_len)
 
7197
    {
 
7198
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
 
7199
      DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
 
7200
      uint num_null_bytes= (m_colcnt + 7) / 8;
 
7201
      m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
 
7202
                                     &m_null_bits, num_null_bytes,
 
7203
                                     &m_field_metadata, m_field_metadata_size,
 
7204
                                     NULL);
 
7205
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
 
7206
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
 
7207
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
 
7208
    }
 
7209
  }
 
7210
 
 
7211
  DBUG_VOID_RETURN;
 
7212
}
 
7213
#endif
 
7214
 
 
7215
Table_map_log_event::~Table_map_log_event()
 
7216
{
 
7217
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
 
7218
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
 
7219
}
 
7220
 
 
7221
/*
 
7222
  Return value is an error code, one of:
 
7223
 
 
7224
      -1     Failure to open table   [from open_tables()]
 
7225
       0     Success
 
7226
       1     No room for more tables [from set_table()]
 
7227
       2     Out of memory           [from set_table()]
 
7228
       3     Wrong table definition
 
7229
       4     Daisy-chaining RBR with SBR not possible
 
7230
 */
 
7231
 
 
7232
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
7233
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
 
7234
{
 
7235
  RPL_TABLE_LIST *table_list;
 
7236
  char *db_mem, *tname_mem;
 
7237
  size_t dummy_len;
 
7238
  void *memory;
 
7239
  DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
 
7240
  DBUG_ASSERT(rli->sql_thd == thd);
 
7241
 
 
7242
  /* Step the query id to mark what columns that are actually used. */
 
7243
  pthread_mutex_lock(&LOCK_thread_count);
 
7244
  thd->query_id= next_query_id();
 
7245
  pthread_mutex_unlock(&LOCK_thread_count);
 
7246
 
 
7247
  if (!(memory= my_multi_malloc(MYF(MY_WME),
 
7248
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
 
7249
                                &db_mem, (uint) NAME_LEN + 1,
 
7250
                                &tname_mem, (uint) NAME_LEN + 1,
 
7251
                                NullS)))
 
7252
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
 
7253
 
 
7254
  bzero(table_list, sizeof(*table_list));
 
7255
  table_list->db = db_mem;
 
7256
  table_list->alias= table_list->table_name = tname_mem;
 
7257
  table_list->lock_type= TL_WRITE;
 
7258
  table_list->next_global= table_list->next_local= 0;
 
7259
  table_list->table_id= m_table_id;
 
7260
  table_list->updating= 1;
 
7261
  strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
 
7262
  strmov(table_list->table_name, m_tblnam);
 
7263
 
 
7264
  int error= 0;
 
7265
 
 
7266
  if (!rpl_filter->db_ok(table_list->db) ||
 
7267
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
 
7268
  {
 
7269
    my_free(memory, MYF(MY_WME));
 
7270
  }
 
7271
  else
 
7272
  {
 
7273
    /*
 
7274
      open_tables() reads the contents of thd->lex, so they must be
 
7275
      initialized, so we should call lex_start(); to be even safer, we
 
7276
      call mysql_init_query() which does a more complete set of inits.
 
7277
    */
 
7278
    lex_start(thd);
 
7279
    mysql_reset_thd_for_next_command(thd);
 
7280
    /*
 
7281
      Check if the slave is set to use SBR.  If so, it should switch
 
7282
      to using RBR until the end of the "statement", i.e., next
 
7283
      STMT_END_F or next error.
 
7284
    */
 
7285
    if (!thd->current_stmt_binlog_row_based &&
 
7286
        mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
 
7287
    {
 
7288
      thd->set_current_stmt_binlog_row_based();
 
7289
    }
 
7290
 
 
7291
    /*
 
7292
      Open the table if it is not already open and add the table to
 
7293
      table map.  Note that for any table that should not be
 
7294
      replicated, a filter is needed.
 
7295
 
 
7296
      The creation of a new TABLE_LIST is used to up-cast the
 
7297
      table_list consisting of RPL_TABLE_LIST items. This will work
 
7298
      since the only case where the argument to open_tables() is
 
7299
      changed, is when thd->lex->query_tables == table_list, i.e.,
 
7300
      when the statement requires prelocking. Since this is not
 
7301
      executed when a statement is executed, this case will not occur.
 
7302
      As a precaution, an assertion is added to ensure that the bad
 
7303
      case is not a fact.
 
7304
 
 
7305
      Either way, the memory in the list is *never* released
 
7306
      internally in the open_tables() function, hence we take a copy
 
7307
      of the pointer to make sure that it's not lost.
 
7308
    */
 
7309
    uint count;
 
7310
    DBUG_ASSERT(thd->lex->query_tables != table_list);
 
7311
    TABLE_LIST *tmp_table_list= table_list;
 
7312
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
 
7313
    {
 
7314
      if (thd->is_slave_error || thd->is_fatal_error)
 
7315
      {
 
7316
        /*
 
7317
          Error reporting borrowed from Query_log_event with many excessive
 
7318
          simplifications (we don't honour --slave-skip-errors)
 
7319
        */
 
7320
        uint actual_error= thd->main_da.sql_errno();
 
7321
        rli->report(ERROR_LEVEL, actual_error,
 
7322
                    "Error '%s' on opening table `%s`.`%s`",
 
7323
                    (actual_error ? thd->main_da.message() :
 
7324
                     "unexpected success or fatal error"),
 
7325
                    table_list->db, table_list->table_name);
 
7326
        thd->is_slave_error= 1;
 
7327
      }
 
7328
      goto err;
 
7329
    }
 
7330
 
 
7331
    m_table= table_list->table;
 
7332
 
 
7333
    /*
 
7334
      This will fail later otherwise, the 'in_use' field should be
 
7335
      set to the current thread.
 
7336
    */
 
7337
    DBUG_ASSERT(m_table->in_use);
 
7338
 
 
7339
    /*
 
7340
      Use placement new to construct the table_def instance in the
 
7341
      memory allocated for it inside table_list.
 
7342
 
 
7343
      The memory allocated by the table_def structure (i.e., not the
 
7344
      memory allocated *for* the table_def structure) is released
 
7345
      inside Relay_log_info::clear_tables_to_lock() by calling the
 
7346
      table_def destructor explicitly.
 
7347
    */
 
7348
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, 
 
7349
         m_field_metadata, m_field_metadata_size, m_null_bits);
 
7350
    table_list->m_tabledef_valid= TRUE;
 
7351
 
 
7352
    /*
 
7353
      We record in the slave's information that the table should be
 
7354
      locked by linking the table into the list of tables to lock.
 
7355
    */
 
7356
    table_list->next_global= table_list->next_local= rli->tables_to_lock;
 
7357
    const_cast<Relay_log_info*>(rli)->tables_to_lock= table_list;
 
7358
    const_cast<Relay_log_info*>(rli)->tables_to_lock_count++;
 
7359
    /* 'memory' is freed in clear_tables_to_lock */
 
7360
  }
 
7361
 
 
7362
  DBUG_RETURN(error);
 
7363
 
 
7364
err:
 
7365
  my_free(memory, MYF(MY_WME));
 
7366
  DBUG_RETURN(error);
 
7367
}
 
7368
 
 
7369
Log_event::enum_skip_reason
 
7370
Table_map_log_event::do_shall_skip(Relay_log_info *rli)
 
7371
{
 
7372
  /*
 
7373
    If the slave skip counter is 1, then we should not start executing
 
7374
    on the next event.
 
7375
  */
 
7376
  return continue_group(rli);
 
7377
}
 
7378
 
 
7379
int Table_map_log_event::do_update_pos(Relay_log_info *rli)
 
7380
{
 
7381
  rli->inc_event_relay_log_pos();
 
7382
  return 0;
 
7383
}
 
7384
 
 
7385
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7386
 
 
7387
#ifndef MYSQL_CLIENT
 
7388
bool Table_map_log_event::write_data_header(IO_CACHE *file)
 
7389
{
 
7390
  DBUG_ASSERT(m_table_id != ~0UL);
 
7391
  uchar buf[TABLE_MAP_HEADER_LEN];
 
7392
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
7393
                  {
 
7394
                    int4store(buf + 0, m_table_id);
 
7395
                    int2store(buf + 4, m_flags);
 
7396
                    return (my_b_safe_write(file, buf, 6));
 
7397
                  });
 
7398
  int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
 
7399
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
 
7400
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
 
7401
}
 
7402
 
 
7403
bool Table_map_log_event::write_data_body(IO_CACHE *file)
 
7404
{
 
7405
  DBUG_ASSERT(m_dbnam != NULL);
 
7406
  DBUG_ASSERT(m_tblnam != NULL);
 
7407
  /* We use only one byte per length for storage in event: */
 
7408
  DBUG_ASSERT(m_dblen < 128);
 
7409
  DBUG_ASSERT(m_tbllen < 128);
 
7410
 
 
7411
  uchar const dbuf[]= { (uchar) m_dblen };
 
7412
  uchar const tbuf[]= { (uchar) m_tbllen };
 
7413
 
 
7414
  uchar cbuf[sizeof(m_colcnt)];
 
7415
  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
 
7416
  DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
 
7417
 
 
7418
  /*
 
7419
    Store the size of the field metadata.
 
7420
  */
 
7421
  uchar mbuf[sizeof(m_field_metadata_size)];
 
7422
  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
 
7423
 
 
7424
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
 
7425
          my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
 
7426
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
 
7427
          my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
 
7428
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
 
7429
          my_b_safe_write(file, m_coltype, m_colcnt) ||
 
7430
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
 
7431
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
 
7432
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
 
7433
 }
 
7434
#endif
 
7435
 
 
7436
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
7437
 
 
7438
/*
 
7439
  Print some useful information for the SHOW BINARY LOG information
 
7440
  field.
 
7441
 */
 
7442
 
 
7443
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
7444
void Table_map_log_event::pack_info(Protocol *protocol)
 
7445
{
 
7446
    char buf[256];
 
7447
    size_t bytes= my_snprintf(buf, sizeof(buf),
 
7448
                                 "table_id: %lu (%s.%s)",
 
7449
                              m_table_id, m_dbnam, m_tblnam);
 
7450
    protocol->store(buf, bytes, &my_charset_bin);
 
7451
}
 
7452
#endif
 
7453
 
 
7454
 
 
7455
#endif
 
7456
 
 
7457
 
 
7458
#ifdef MYSQL_CLIENT
 
7459
void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
 
7460
{
 
7461
  if (!print_event_info->short_form)
 
7462
  {
 
7463
    print_header(&print_event_info->head_cache, print_event_info, TRUE);
 
7464
    my_b_printf(&print_event_info->head_cache,
 
7465
                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
 
7466
                m_dbnam, m_tblnam, m_table_id);
 
7467
    print_base64(&print_event_info->body_cache, print_event_info, TRUE);
 
7468
  }
 
7469
}
 
7470
#endif
 
7471
 
 
7472
/**************************************************************************
 
7473
        Write_rows_log_event member functions
 
7474
**************************************************************************/
 
7475
 
 
7476
/*
 
7477
  Constructor used to build an event for writing to the binary log.
 
7478
 */
 
7479
#if !defined(MYSQL_CLIENT)
 
7480
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
7481
                                           ulong tid_arg,
 
7482
                                           bool is_transactional)
 
7483
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
 
7484
{
 
7485
}
 
7486
#endif
 
7487
 
 
7488
/*
 
7489
  Constructor used by slave to read the event from the binary log.
 
7490
 */
 
7491
#ifdef HAVE_REPLICATION
 
7492
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
 
7493
                                           const Format_description_log_event
 
7494
                                           *description_event)
 
7495
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
 
7496
{
 
7497
}
 
7498
#endif
 
7499
 
 
7500
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
7501
int 
 
7502
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 
7503
{
 
7504
  int error= 0;
 
7505
 
 
7506
  /**
 
7507
     todo: to introduce a property for the event (handler?) which forces
 
7508
     applying the event in the replace (idempotent) fashion.
 
7509
  */
 
7510
  if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
7511
  {
 
7512
    /*
 
7513
      We are using REPLACE semantics and not INSERT IGNORE semantics
 
7514
      when writing rows, that is: new rows replace old rows.  We need to
 
7515
      inform the storage engine that it should use this behaviour.
 
7516
    */
 
7517
    
 
7518
    /* Tell the storage engine that we are using REPLACE semantics. */
 
7519
    thd->lex->duplicates= DUP_REPLACE;
 
7520
    
 
7521
    /*
 
7522
      Pretend we're executing a REPLACE command: this is needed for
 
7523
      InnoDB since it is not (properly) checking the
 
7524
      lex->duplicates flag.
 
7525
    */
 
7526
    thd->lex->sql_command= SQLCOM_REPLACE;
 
7527
    /* 
 
7528
       Do not raise the error flag in case of hitting to an unique attribute
 
7529
    */
 
7530
    m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
 
7531
  }
 
7532
 
 
7533
  m_table->file->ha_start_bulk_insert(0);
 
7534
  /*
 
7535
    We need TIMESTAMP_NO_AUTO_SET otherwise ha_write_row() will not use fill
 
7536
    any TIMESTAMP column with data from the row but instead will use
 
7537
    the event's current time.
 
7538
    As we replicate from TIMESTAMP to TIMESTAMP and slave has no extra
 
7539
    columns, we know that all TIMESTAMP columns on slave will receive explicit
 
7540
    data from the row, so TIMESTAMP_NO_AUTO_SET is ok.
 
7541
    When we allow a table without TIMESTAMP to be replicated to a table having
 
7542
    more columns including a TIMESTAMP column, or when we allow a TIMESTAMP
 
7543
    column to be replicated into a BIGINT column and the slave's table has a
 
7544
    TIMESTAMP column, then the slave's TIMESTAMP column will take its value
 
7545
    from set_time() which we called earlier (consistent with SBR). And then in
 
7546
    some cases we won't want TIMESTAMP_NO_AUTO_SET (will require some code to
 
7547
    analyze if explicit data is provided for slave's TIMESTAMP columns).
 
7548
  */
 
7549
  m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
7550
 
 
7551
  return error;
 
7552
}
 
7553
 
 
7554
int 
 
7555
Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
 
7556
                                              int error)
 
7557
{
 
7558
  int local_error= 0;
 
7559
  if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
 
7560
  {
 
7561
    m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
 
7562
    m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
 
7563
    /*
 
7564
      resetting the extra with 
 
7565
      table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); 
 
7566
      fires bug#27077
 
7567
      explanation: file->reset() performs this duty
 
7568
      ultimately. Still todo: fix
 
7569
    */
 
7570
  }
 
7571
  if ((local_error= m_table->file->ha_end_bulk_insert()))
 
7572
  {
 
7573
    m_table->file->print_error(local_error, MYF(0));
 
7574
  }
 
7575
  return error? error : local_error;
 
7576
}
 
7577
 
 
7578
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
7579
 
 
7580
/*
 
7581
  Check if there are more UNIQUE keys after the given key.
 
7582
*/
 
7583
static int
 
7584
last_uniq_key(TABLE *table, uint keyno)
 
7585
{
 
7586
  while (++keyno < table->s->keys)
 
7587
    if (table->key_info[keyno].flags & HA_NOSAME)
 
7588
      return 0;
 
7589
  return 1;
 
7590
}
 
7591
 
 
7592
/**
 
7593
   Check if an error is a duplicate key error.
 
7594
 
 
7595
   This function is used to check if an error code is one of the
 
7596
   duplicate key error, i.e., and error code for which it is sensible
 
7597
   to do a <code>get_dup_key()</code> to retrieve the duplicate key.
 
7598
 
 
7599
   @param errcode The error code to check.
 
7600
 
 
7601
   @return <code>true</code> if the error code is such that
 
7602
   <code>get_dup_key()</code> will return true, <code>false</code>
 
7603
   otherwise.
 
7604
 */
 
7605
bool
 
7606
is_duplicate_key_error(int errcode)
 
7607
{
 
7608
  switch (errcode)
 
7609
  {
 
7610
  case HA_ERR_FOUND_DUPP_KEY:
 
7611
  case HA_ERR_FOUND_DUPP_UNIQUE:
 
7612
    return true;
 
7613
  }
 
7614
  return false;
 
7615
}
 
7616
 
 
7617
/**
 
7618
  Write the current row into event's table.
 
7619
 
 
7620
  The row is located in the row buffer, pointed by @c m_curr_row member.
 
7621
  Number of columns of the row is stored in @c m_width member (it can be 
 
7622
  different from the number of columns in the table to which we insert). 
 
7623
  Bitmap @c m_cols indicates which columns are present in the row. It is assumed 
 
7624
  that event's table is already open and pointed by @c m_table.
 
7625
 
 
7626
  If the same record already exists in the table it can be either overwritten 
 
7627
  or an error is reported depending on the value of @c overwrite flag 
 
7628
  (error reporting not yet implemented). Note that the matching record can be
 
7629
  different from the row we insert if we use primary keys to identify records in
 
7630
  the table.
 
7631
 
 
7632
  The row to be inserted can contain values only for selected columns. The 
 
7633
  missing columns are filled with default values using @c prepare_record() 
 
7634
  function. If a matching record is found in the table and @c overwritte is
 
7635
  true, the missing columns are taken from it.
 
7636
 
 
7637
  @param  rli   Relay log info (needed for row unpacking).
 
7638
  @param  overwrite  
 
7639
                Shall we overwrite if the row already exists or signal 
 
7640
                error (currently ignored).
 
7641
 
 
7642
  @returns Error code on failure, 0 on success.
 
7643
 
 
7644
  This method, if successful, sets @c m_curr_row_end pointer to point at the
 
7645
  next row in the rows buffer. This is done when unpacking the row to be 
 
7646
  inserted.
 
7647
 
 
7648
  @note If a matching record is found, it is either updated using 
 
7649
  @c ha_update_row() or first deleted and then new record written.
 
7650
*/ 
 
7651
 
 
7652
int
 
7653
Rows_log_event::write_row(const Relay_log_info *const rli,
 
7654
                          const bool overwrite)
 
7655
{
 
7656
  DBUG_ENTER("write_row");
 
7657
  DBUG_ASSERT(m_table != NULL && thd != NULL);
 
7658
 
 
7659
  TABLE *table= m_table;  // pointer to event's table
 
7660
  int error;
 
7661
  int keynum;
 
7662
  auto_afree_ptr<char> key(NULL);
 
7663
 
 
7664
  /* fill table->record[0] with default values */
 
7665
 
 
7666
  /*
 
7667
     We only check if the columns have default values for non-NDB
 
7668
     engines, for NDB we ignore the check since updates are sent as
 
7669
     writes, causing errors when trying to prepare the record.
 
7670
 
 
7671
     TODO[ndb]: Elimiate this hard-coded dependency on NDB. Ideally,
 
7672
     the engine should be able to set a flag that it want the default
 
7673
     values filled in and one flag to handle the case that the default
 
7674
     values should be checked. Maybe these two flags can be combined.
 
7675
  */
 
7676
  if ((error= prepare_record(table, &m_cols, m_width,
 
7677
                             table->file->ht->db_type != DB_TYPE_NDBCLUSTER)))
 
7678
    DBUG_RETURN(error);
 
7679
  
 
7680
  /* unpack row into table->record[0] */
 
7681
  error= unpack_current_row(rli, &m_cols);
 
7682
 
 
7683
  // Temporary fix to find out why it fails [/Matz]
 
7684
  memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
 
7685
 
 
7686
#ifndef DBUG_OFF
 
7687
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
7688
  DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
 
7689
  DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
 
7690
#endif
 
7691
 
 
7692
  /* 
 
7693
    Try to write record. If a corresponding record already exists in the table,
 
7694
    we try to change it using ha_update_row() if possible. Otherwise we delete
 
7695
    it and repeat the whole process again. 
 
7696
 
 
7697
    TODO: Add safety measures against infinite looping. 
 
7698
   */
 
7699
 
 
7700
  while ((error= table->file->ha_write_row(table->record[0])))
 
7701
  {
 
7702
    if (error == HA_ERR_LOCK_DEADLOCK ||
 
7703
        error == HA_ERR_LOCK_WAIT_TIMEOUT ||
 
7704
        (keynum= table->file->get_dup_key(error)) < 0 ||
 
7705
        !overwrite)
 
7706
    {
 
7707
      DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
 
7708
      /*
 
7709
        Deadlock, waiting for lock or just an error from the handler
 
7710
        such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
 
7711
        Retrieval of the duplicate key number may fail
 
7712
        - either because the error was not "duplicate key" error
 
7713
        - or because the information which key is not available
 
7714
      */
 
7715
      table->file->print_error(error, MYF(0));
 
7716
      DBUG_RETURN(error);
 
7717
    }
 
7718
    /*
 
7719
       We need to retrieve the old row into record[1] to be able to
 
7720
       either update or delete the offending record.  We either:
 
7721
 
 
7722
       - use rnd_pos() with a row-id (available as dupp_row) to the
 
7723
         offending row, if that is possible (MyISAM and Blackhole), or else
 
7724
 
 
7725
       - use index_read_idx() with the key that is duplicated, to
 
7726
         retrieve the offending row.
 
7727
     */
 
7728
    if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
 
7729
    {
 
7730
      DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
 
7731
      if (table->file->inited && (error= table->file->ha_index_end()))
 
7732
        DBUG_RETURN(error);
 
7733
      if ((error= table->file->ha_rnd_init(FALSE)))
 
7734
        DBUG_RETURN(error);
 
7735
 
 
7736
      error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
 
7737
      table->file->ha_rnd_end();
 
7738
      if (error)
 
7739
      {
 
7740
        DBUG_PRINT("info",("rnd_pos() returns error %d",error));
 
7741
        table->file->print_error(error, MYF(0));
 
7742
        DBUG_RETURN(error);
 
7743
      }
 
7744
    }
 
7745
    else
 
7746
    {
 
7747
      DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
 
7748
 
 
7749
      if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
 
7750
      {
 
7751
        DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
 
7752
        DBUG_RETURN(my_errno);
 
7753
      }
 
7754
 
 
7755
      if (key.get() == NULL)
 
7756
      {
 
7757
        key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
 
7758
        if (key.get() == NULL)
 
7759
        {
 
7760
          DBUG_PRINT("info",("Can't allocate key buffer"));
 
7761
          DBUG_RETURN(ENOMEM);
 
7762
        }
 
7763
      }
 
7764
 
 
7765
      key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
 
7766
               0);
 
7767
      error= table->file->index_read_idx_map(table->record[1], keynum,
 
7768
                                             (const uchar*)key.get(),
 
7769
                                             HA_WHOLE_KEY,
 
7770
                                             HA_READ_KEY_EXACT);
 
7771
      if (error)
 
7772
      {
 
7773
        DBUG_PRINT("info",("index_read_idx() returns error %d",error)); 
 
7774
        table->file->print_error(error, MYF(0));
 
7775
        DBUG_RETURN(error);
 
7776
      }
 
7777
    }
 
7778
 
 
7779
    /*
 
7780
       Now, record[1] should contain the offending row.  That
 
7781
       will enable us to update it or, alternatively, delete it (so
 
7782
       that we can insert the new row afterwards).
 
7783
     */
 
7784
 
 
7785
    /*
 
7786
      If row is incomplete we will use the record found to fill 
 
7787
      missing columns.  
 
7788
    */
 
7789
    if (!get_flags(COMPLETE_ROWS_F))
 
7790
    {
 
7791
      restore_record(table,record[1]);
 
7792
      error= unpack_current_row(rli, &m_cols);
 
7793
    }
 
7794
 
 
7795
#ifndef DBUG_OFF
 
7796
    DBUG_PRINT("debug",("preparing for update: before and after image"));
 
7797
    DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
 
7798
    DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
 
7799
#endif
 
7800
 
 
7801
    /*
 
7802
       REPLACE is defined as either INSERT or DELETE + INSERT.  If
 
7803
       possible, we can replace it with an UPDATE, but that will not
 
7804
       work on InnoDB if FOREIGN KEY checks are necessary.
 
7805
 
 
7806
       I (Matz) am not sure of the reason for the last_uniq_key()
 
7807
       check as, but I'm guessing that it's something along the
 
7808
       following lines.
 
7809
 
 
7810
       Suppose that we got the duplicate key to be a key that is not
 
7811
       the last unique key for the table and we perform an update:
 
7812
       then there might be another key for which the unique check will
 
7813
       fail, so we're better off just deleting the row and inserting
 
7814
       the correct row.
 
7815
     */
 
7816
    if (last_uniq_key(table, keynum) &&
 
7817
        !table->file->referenced_by_foreign_key())
 
7818
    {
 
7819
      DBUG_PRINT("info",("Updating row using ha_update_row()"));
 
7820
      error=table->file->ha_update_row(table->record[1],
 
7821
                                       table->record[0]);
 
7822
      switch (error) {
 
7823
                
 
7824
      case HA_ERR_RECORD_IS_THE_SAME:
 
7825
        DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
 
7826
                           " ha_update_row()"));
 
7827
        error= 0;
 
7828
      
 
7829
      case 0:
 
7830
        break;
 
7831
        
 
7832
      default:    
 
7833
        DBUG_PRINT("info",("ha_update_row() returns error %d",error));
 
7834
        table->file->print_error(error, MYF(0));
 
7835
      }
 
7836
      
 
7837
      DBUG_RETURN(error);
 
7838
    }
 
7839
    else
 
7840
    {
 
7841
      DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
 
7842
      if ((error= table->file->ha_delete_row(table->record[1])))
 
7843
      {
 
7844
        DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
 
7845
        table->file->print_error(error, MYF(0));
 
7846
        DBUG_RETURN(error);
 
7847
      }
 
7848
      /* Will retry ha_write_row() with the offending row removed. */
 
7849
    }
 
7850
  }
 
7851
 
 
7852
  DBUG_RETURN(error);
 
7853
}
 
7854
 
 
7855
#endif
 
7856
 
 
7857
int 
 
7858
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
 
7859
{
 
7860
  DBUG_ASSERT(m_table != NULL);
 
7861
  int error=
 
7862
    write_row(rli,        /* if 1 then overwrite */
 
7863
              bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
 
7864
    
 
7865
  if (error && !thd->is_error())
 
7866
  {
 
7867
    DBUG_ASSERT(0);
 
7868
    my_error(ER_UNKNOWN_ERROR, MYF(0));
 
7869
  }
 
7870
  
 
7871
  return error; 
 
7872
}
 
7873
 
 
7874
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7875
 
 
7876
#ifdef MYSQL_CLIENT
 
7877
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
 
7878
{
 
7879
  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
 
7880
}
 
7881
#endif
 
7882
 
 
7883
/**************************************************************************
 
7884
        Delete_rows_log_event member functions
 
7885
**************************************************************************/
 
7886
 
 
7887
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
7888
/*
 
7889
  Compares table->record[0] and table->record[1]
 
7890
 
 
7891
  Returns TRUE if different.
 
7892
*/
 
7893
static bool record_compare(TABLE *table)
 
7894
{
 
7895
  /*
 
7896
    Need to set the X bit and the filler bits in both records since
 
7897
    there are engines that do not set it correctly.
 
7898
 
 
7899
    In addition, since MyISAM checks that one hasn't tampered with the
 
7900
    record, it is necessary to restore the old bytes into the record
 
7901
    after doing the comparison.
 
7902
 
 
7903
    TODO[record format ndb]: Remove it once NDB returns correct
 
7904
    records. Check that the other engines also return correct records.
 
7905
   */
 
7906
 
 
7907
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
7908
  DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
 
7909
 
 
7910
  bool result= FALSE;
 
7911
  uchar saved_x[2], saved_filler[2];
 
7912
 
 
7913
  if (table->s->null_bytes > 0)
 
7914
  {
 
7915
    for (int i = 0 ; i < 2 ; ++i)
 
7916
    {
 
7917
      saved_x[i]= table->record[i][0];
 
7918
      saved_filler[i]= table->record[i][table->s->null_bytes - 1];
 
7919
      table->record[i][0]|= 1U;
 
7920
      table->record[i][table->s->null_bytes - 1]|=
 
7921
        256U - (1U << table->s->last_null_bit_pos);
 
7922
    }
 
7923
  }
 
7924
 
 
7925
  if (table->s->blob_fields + table->s->varchar_fields == 0)
 
7926
  {
 
7927
    result= cmp_record(table,record[1]);
 
7928
    goto record_compare_exit;
 
7929
  }
 
7930
 
 
7931
  /* Compare null bits */
 
7932
  if (memcmp(table->null_flags,
 
7933
             table->null_flags+table->s->rec_buff_length,
 
7934
             table->s->null_bytes))
 
7935
  {
 
7936
    result= TRUE;                               // Diff in NULL value
 
7937
    goto record_compare_exit;
 
7938
  }
 
7939
 
 
7940
  /* Compare updated fields */
 
7941
  for (Field **ptr=table->field ; *ptr ; ptr++)
 
7942
  {
 
7943
    if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
 
7944
    {
 
7945
      result= TRUE;
 
7946
      goto record_compare_exit;
 
7947
    }
 
7948
  }
 
7949
 
 
7950
record_compare_exit:
 
7951
  /*
 
7952
    Restore the saved bytes.
 
7953
 
 
7954
    TODO[record format ndb]: Remove this code once NDB returns the
 
7955
    correct record format.
 
7956
  */
 
7957
  if (table->s->null_bytes > 0)
 
7958
  {
 
7959
    for (int i = 0 ; i < 2 ; ++i)
 
7960
    {
 
7961
      table->record[i][0]= saved_x[i];
 
7962
      table->record[i][table->s->null_bytes - 1]= saved_filler[i];
 
7963
    }
 
7964
  }
 
7965
 
 
7966
  return result;
 
7967
}
 
7968
 
 
7969
/**
 
7970
  Locate the current row in event's table.
 
7971
 
 
7972
  The current row is pointed by @c m_curr_row. Member @c m_width tells how many 
 
7973
  columns are there in the row (this can be differnet from the number of columns 
 
7974
  in the table). It is assumed that event's table is already open and pointed 
 
7975
  by @c m_table.
 
7976
 
 
7977
  If a corresponding record is found in the table it is stored in 
 
7978
  @c m_table->record[0]. Note that when record is located based on a primary 
 
7979
  key, it is possible that the record found differs from the row being located.
 
7980
 
 
7981
  If no key is specified or table does not have keys, a table scan is used to 
 
7982
  find the row. In that case the row should be complete and contain values for
 
7983
  all columns. However, it can still be shorter than the table, i.e. the table 
 
7984
  can contain extra columns not present in the row. It is also possible that 
 
7985
  the table has fewer columns than the row being located. 
 
7986
 
 
7987
  @returns Error code on failure, 0 on success. 
 
7988
  
 
7989
  @post In case of success @c m_table->record[0] contains the record found. 
 
7990
  Also, the internal "cursor" of the table is positioned at the record found.
 
7991
 
 
7992
  @note If the engine allows random access of the records, a combination of
 
7993
  @c position() and @c rnd_pos() will be used. 
 
7994
 */
 
7995
 
 
7996
int Rows_log_event::find_row(const Relay_log_info *rli)
 
7997
{
 
7998
  DBUG_ENTER("Rows_log_event::find_row");
 
7999
 
 
8000
  DBUG_ASSERT(m_table && m_table->in_use != NULL);
 
8001
 
 
8002
  TABLE *table= m_table;
 
8003
  int error;
 
8004
 
 
8005
  /* unpack row - missing fields get default values */
 
8006
  prepare_record(table, &m_cols, m_width, FALSE /* don't check errors */); 
 
8007
  error= unpack_current_row(rli, &m_cols);
 
8008
 
 
8009
  // Temporary fix to find out why it fails [/Matz]
 
8010
  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
 
8011
 
 
8012
#ifndef DBUG_OFF
 
8013
  DBUG_PRINT("info",("looking for the following record"));
 
8014
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
8015
  DBUG_DUMP("read_set", (uchar*) table->read_set->bitmap, (table->read_set->n_bits + 7) / 8);
 
8016
#endif
 
8017
 
 
8018
  if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
 
8019
      table->s->primary_key < MAX_KEY)
 
8020
  {
 
8021
    /*
 
8022
      Use a more efficient method to fetch the record given by
 
8023
      table->record[0] if the engine allows it.  We first compute a
 
8024
      row reference using the position() member function (it will be
 
8025
      stored in table->file->ref) and the use rnd_pos() to position
 
8026
      the "cursor" (i.e., record[0] in this case) at the correct row.
 
8027
 
 
8028
      TODO: Add a check that the correct record has been fetched by
 
8029
      comparing with the original record. Take into account that the
 
8030
      record on the master and slave can be of different
 
8031
      length. Something along these lines should work:
 
8032
 
 
8033
      ADD>>>  store_record(table,record[1]);
 
8034
              int error= table->file->rnd_pos(table->record[0], table->file->ref);
 
8035
      ADD>>>  DBUG_ASSERT(memcmp(table->record[1], table->record[0],
 
8036
                                 table->s->reclength) == 0);
 
8037
    */
 
8038
 
 
8039
    DBUG_PRINT("info",("locating record using primary key (position)"));
 
8040
    int error= table->file->rnd_pos_by_record(table->record[0]);
 
8041
    table->file->ha_rnd_end();
 
8042
    if (error)
 
8043
    {
 
8044
      DBUG_PRINT("info",("rnd_pos returns error %d",error));
 
8045
      table->file->print_error(error, MYF(0));
 
8046
    }
 
8047
    DBUG_RETURN(error);
 
8048
  }
 
8049
 
 
8050
  // We can't use position() - try other methods.
 
8051
  
 
8052
  /*
 
8053
    Save copy of the record in table->record[1]. It might be needed 
 
8054
    later if linear search is used to find exact match.
 
8055
   */ 
 
8056
  store_record(table,record[1]);    
 
8057
 
 
8058
  if (table->s->keys > 0)
 
8059
  {
 
8060
    DBUG_PRINT("info",("locating record using primary key (index_read)"));
 
8061
 
 
8062
    /* We have a key: search the table using the index */
 
8063
    if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
 
8064
    {
 
8065
      DBUG_PRINT("info",("ha_index_init returns error %d",error));
 
8066
      table->file->print_error(error, MYF(0));
 
8067
      goto err;
 
8068
    }
 
8069
 
 
8070
    /* Fill key data for the row */
 
8071
 
 
8072
    DBUG_ASSERT(m_key);
 
8073
    key_copy(m_key, table->record[0], table->key_info, 0);
 
8074
 
 
8075
    /*
 
8076
      Don't print debug messages when running valgrind since they can
 
8077
      trigger false warnings.
 
8078
     */
 
8079
#ifndef HAVE_purify
 
8080
    DBUG_DUMP("key data", m_key, table->key_info->key_length);
 
8081
#endif
 
8082
 
 
8083
    /*
 
8084
      We need to set the null bytes to ensure that the filler bit are
 
8085
      all set when returning.  There are storage engines that just set
 
8086
      the necessary bits on the bytes and don't set the filler bits
 
8087
      correctly.
 
8088
    */
 
8089
    my_ptrdiff_t const pos=
 
8090
      table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
 
8091
    table->record[0][pos]= 0xFF;
 
8092
    
 
8093
    if ((error= table->file->index_read_map(table->record[0], m_key, 
 
8094
                                            HA_WHOLE_KEY,
 
8095
                                            HA_READ_KEY_EXACT)))
 
8096
    {
 
8097
      DBUG_PRINT("info",("no record matching the key found in the table"));
 
8098
      table->file->print_error(error, MYF(0));
 
8099
      table->file->ha_index_end();
 
8100
      goto err;
 
8101
    }
 
8102
 
 
8103
  /*
 
8104
    Don't print debug messages when running valgrind since they can
 
8105
    trigger false warnings.
 
8106
   */
 
8107
#ifndef HAVE_purify
 
8108
    DBUG_PRINT("info",("found first matching record")); 
 
8109
    DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
8110
#endif
 
8111
    /*
 
8112
      Below is a minor "optimization".  If the key (i.e., key number
 
8113
      0) has the HA_NOSAME flag set, we know that we have found the
 
8114
      correct record (since there can be no duplicates); otherwise, we
 
8115
      have to compare the record with the one found to see if it is
 
8116
      the correct one.
 
8117
 
 
8118
      CAVEAT! This behaviour is essential for the replication of,
 
8119
      e.g., the mysql.proc table since the correct record *shall* be
 
8120
      found using the primary key *only*.  There shall be no
 
8121
      comparison of non-PK columns to decide if the correct record is
 
8122
      found.  I can see no scenario where it would be incorrect to
 
8123
      chose the row to change only using a PK or an UNNI.
 
8124
    */
 
8125
    if (table->key_info->flags & HA_NOSAME)
 
8126
    {
 
8127
      table->file->ha_index_end();
 
8128
      goto ok;
 
8129
    }
 
8130
 
 
8131
    /*
 
8132
      In case key is not unique, we still have to iterate over records found
 
8133
      and find the one which is identical to the row given. A copy of the 
 
8134
      record we are looking for is stored in record[1].
 
8135
     */ 
 
8136
    DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); 
 
8137
 
 
8138
    while (record_compare(table))
 
8139
    {
 
8140
      /*
 
8141
        We need to set the null bytes to ensure that the filler bit
 
8142
        are all set when returning.  There are storage engines that
 
8143
        just set the necessary bits on the bytes and don't set the
 
8144
        filler bits correctly.
 
8145
 
 
8146
        TODO[record format ndb]: Remove this code once NDB returns the
 
8147
        correct record format.
 
8148
      */
 
8149
      if (table->s->null_bytes > 0)
 
8150
      {
 
8151
        table->record[0][table->s->null_bytes - 1]|=
 
8152
          256U - (1U << table->s->last_null_bit_pos);
 
8153
      }
 
8154
 
 
8155
      if ((error= table->file->index_next(table->record[0])))
 
8156
      {
 
8157
        DBUG_PRINT("info",("no record matching the given row found"));
 
8158
        table->file->print_error(error, MYF(0));
 
8159
        table->file->ha_index_end();
 
8160
        goto err;
 
8161
      }
 
8162
    }
 
8163
 
 
8164
    /*
 
8165
      Have to restart the scan to be able to fetch the next row.
 
8166
    */
 
8167
    table->file->ha_index_end();
 
8168
  }
 
8169
  else
 
8170
  {
 
8171
    DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
 
8172
 
 
8173
    int restart_count= 0; // Number of times scanning has restarted from top
 
8174
 
 
8175
    /* We don't have a key: search the table using rnd_next() */
 
8176
    if ((error= table->file->ha_rnd_init(1)))
 
8177
    {
 
8178
      DBUG_PRINT("info",("error initializing table scan"
 
8179
                         " (ha_rnd_init returns %d)",error));
 
8180
      table->file->print_error(error, MYF(0));
 
8181
      goto err;
 
8182
    }
 
8183
 
 
8184
    /* Continue until we find the right record or have made a full loop */
 
8185
    do
 
8186
    {
 
8187
      error= table->file->rnd_next(table->record[0]);
 
8188
 
 
8189
      switch (error) {
 
8190
 
 
8191
      case 0:
 
8192
      case HA_ERR_RECORD_DELETED:
 
8193
        break;
 
8194
 
 
8195
      case HA_ERR_END_OF_FILE:
 
8196
        if (++restart_count < 2)
 
8197
          table->file->ha_rnd_init(1);
 
8198
        break;
 
8199
 
 
8200
      default:
 
8201
        DBUG_PRINT("info", ("Failed to get next record"
 
8202
                            " (rnd_next returns %d)",error));
 
8203
        table->file->print_error(error, MYF(0));
 
8204
        table->file->ha_rnd_end();
 
8205
        goto err;
 
8206
      }
 
8207
    }
 
8208
    while (restart_count < 2 && record_compare(table));
 
8209
    
 
8210
    /* 
 
8211
      Note: above record_compare will take into accout all record fields 
 
8212
      which might be incorrect in case a partial row was given in the event
 
8213
     */
 
8214
 
 
8215
    /*
 
8216
      Have to restart the scan to be able to fetch the next row.
 
8217
    */
 
8218
    if (restart_count == 2)
 
8219
    {
 
8220
      DBUG_PRINT("info", ("Record not found"));
 
8221
    }
 
8222
    else
 
8223
    {
 
8224
      DBUG_DUMP("record found", table->record[0], table->s->reclength);
 
8225
    }
 
8226
    table->file->ha_rnd_end();
 
8227
 
 
8228
    DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
 
8229
    goto err;
 
8230
  }
 
8231
ok:
 
8232
  table->default_column_bitmaps();
 
8233
  DBUG_RETURN(0);
 
8234
err:
 
8235
  table->default_column_bitmaps();
 
8236
  DBUG_RETURN(error);
 
8237
}
 
8238
 
 
8239
#endif
 
8240
 
 
8241
/*
 
8242
  Constructor used to build an event for writing to the binary log.
 
8243
 */
 
8244
 
 
8245
#ifndef MYSQL_CLIENT
 
8246
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
8247
                                             ulong tid,
 
8248
                                             bool is_transactional)
 
8249
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
8250
{
 
8251
}
 
8252
#endif /* #if !defined(MYSQL_CLIENT) */
 
8253
 
 
8254
/*
 
8255
  Constructor used by slave to read the event from the binary log.
 
8256
 */
 
8257
#ifdef HAVE_REPLICATION
 
8258
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
 
8259
                                             const Format_description_log_event
 
8260
                                             *description_event)
 
8261
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
 
8262
{
 
8263
}
 
8264
#endif
 
8265
 
 
8266
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
8267
 
 
8268
int 
 
8269
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 
8270
{
 
8271
  if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
 
8272
      m_table->s->primary_key < MAX_KEY)
 
8273
  {
 
8274
    /*
 
8275
      We don't need to allocate any memory for m_key since it is not used.
 
8276
    */
 
8277
    return 0;
 
8278
  }
 
8279
 
 
8280
  if (m_table->s->keys > 0)
 
8281
  {
 
8282
    // Allocate buffer for key searches
 
8283
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8284
    if (!m_key)
 
8285
      return HA_ERR_OUT_OF_MEM;
 
8286
  }
 
8287
 
 
8288
  return 0;
 
8289
}
 
8290
 
 
8291
int 
 
8292
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
8293
                                               int error)
 
8294
{
 
8295
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
 
8296
  m_table->file->ha_index_or_rnd_end();
 
8297
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
 
8298
  m_key= NULL;
 
8299
 
 
8300
  return error;
 
8301
}
 
8302
 
 
8303
int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
 
8304
{
 
8305
  int error;
 
8306
  DBUG_ASSERT(m_table != NULL);
 
8307
 
 
8308
  if (!(error= find_row(rli))) 
 
8309
  { 
 
8310
    /*
 
8311
      Delete the record found, located in record[0]
 
8312
    */
 
8313
    error= m_table->file->ha_delete_row(m_table->record[0]);
 
8314
  }
 
8315
  return error;
 
8316
}
 
8317
 
 
8318
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8319
 
 
8320
#ifdef MYSQL_CLIENT
 
8321
void Delete_rows_log_event::print(FILE *file,
 
8322
                                  PRINT_EVENT_INFO* print_event_info)
 
8323
{
 
8324
  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
 
8325
}
 
8326
#endif
 
8327
 
 
8328
 
 
8329
/**************************************************************************
 
8330
        Update_rows_log_event member functions
 
8331
**************************************************************************/
 
8332
 
 
8333
/*
 
8334
  Constructor used to build an event for writing to the binary log.
 
8335
 */
 
8336
#if !defined(MYSQL_CLIENT)
 
8337
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
8338
                                             ulong tid,
 
8339
                                             bool is_transactional)
 
8340
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
8341
{
 
8342
  init(tbl_arg->write_set);
 
8343
}
 
8344
 
 
8345
void Update_rows_log_event::init(MY_BITMAP const *cols)
 
8346
{
 
8347
  /* if bitmap_init fails, caught in is_valid() */
 
8348
  if (likely(!bitmap_init(&m_cols_ai,
 
8349
                          m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
 
8350
                          m_width,
 
8351
                          false)))
 
8352
  {
 
8353
    /* Cols can be zero if this is a dummy binrows event */
 
8354
    if (likely(cols != NULL))
 
8355
    {
 
8356
      memcpy(m_cols_ai.bitmap, cols->bitmap, no_bytes_in_map(cols));
 
8357
      create_last_word_mask(&m_cols_ai);
 
8358
    }
 
8359
  }
 
8360
}
 
8361
#endif /* !defined(MYSQL_CLIENT) */
 
8362
 
 
8363
 
 
8364
Update_rows_log_event::~Update_rows_log_event()
 
8365
{
 
8366
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
 
8367
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
 
8368
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
 
8369
}
 
8370
 
 
8371
 
 
8372
/*
 
8373
  Constructor used by slave to read the event from the binary log.
 
8374
 */
 
8375
#ifdef HAVE_REPLICATION
 
8376
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
 
8377
                                             const
 
8378
                                             Format_description_log_event
 
8379
                                             *description_event)
 
8380
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
 
8381
{
 
8382
}
 
8383
#endif
 
8384
 
 
8385
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
 
8386
 
 
8387
int 
 
8388
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
 
8389
{
 
8390
  if (m_table->s->keys > 0)
 
8391
  {
 
8392
    // Allocate buffer for key searches
 
8393
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8394
    if (!m_key)
 
8395
      return HA_ERR_OUT_OF_MEM;
 
8396
  }
 
8397
 
 
8398
  m_table->timestamp_field_type= TIMESTAMP_NO_AUTO_SET;
 
8399
 
 
8400
  return 0;
 
8401
}
 
8402
 
 
8403
int 
 
8404
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
8405
                                               int error)
 
8406
{
 
8407
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
 
8408
  m_table->file->ha_index_or_rnd_end();
 
8409
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
 
8410
  m_key= NULL;
 
8411
 
 
8412
  return error;
 
8413
}
 
8414
 
 
8415
int 
 
8416
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
 
8417
{
 
8418
  DBUG_ASSERT(m_table != NULL);
 
8419
 
 
8420
  int error= find_row(rli); 
 
8421
  if (error)
 
8422
  {
 
8423
    /*
 
8424
      We need to read the second image in the event of error to be
 
8425
      able to skip to the next pair of updates
 
8426
    */
 
8427
    m_curr_row= m_curr_row_end;
 
8428
    unpack_current_row(rli, &m_cols_ai);
 
8429
    return error;
 
8430
  }
 
8431
 
 
8432
  /*
 
8433
    This is the situation after locating BI:
 
8434
 
 
8435
    ===|=== before image ====|=== after image ===|===
 
8436
       ^                     ^
 
8437
       m_curr_row            m_curr_row_end
 
8438
 
 
8439
    BI found in the table is stored in record[0]. We copy it to record[1]
 
8440
    and unpack AI to record[0].
 
8441
   */
 
8442
 
 
8443
  store_record(m_table,record[1]);
 
8444
 
 
8445
  m_curr_row= m_curr_row_end;
 
8446
  error= unpack_current_row(rli, &m_cols_ai); // this also updates m_curr_row_end
 
8447
 
 
8448
  /*
 
8449
    Now we have the right row to update.  The old row (the one we're
 
8450
    looking for) is in record[1] and the new row is in record[0].
 
8451
  */
 
8452
#ifndef HAVE_purify
 
8453
  /*
 
8454
    Don't print debug messages when running valgrind since they can
 
8455
    trigger false warnings.
 
8456
   */
 
8457
  DBUG_PRINT("info",("Updating row in table"));
 
8458
  DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
 
8459
  DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
 
8460
#endif
 
8461
 
 
8462
  // Temporary fix to find out why it fails [/Matz]
 
8463
  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
 
8464
  memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
 
8465
 
 
8466
  error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
 
8467
  if (error == HA_ERR_RECORD_IS_THE_SAME)
 
8468
    error= 0;
 
8469
 
 
8470
  return error;
 
8471
}
 
8472
 
 
8473
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8474
 
 
8475
#ifdef MYSQL_CLIENT
 
8476
void Update_rows_log_event::print(FILE *file,
 
8477
                                  PRINT_EVENT_INFO* print_event_info)
 
8478
{
 
8479
  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
 
8480
}
 
8481
#endif
 
8482
 
 
8483
 
 
8484
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
 
8485
                                       const Format_description_log_event *descr_event)
 
8486
  : Log_event(buf, descr_event)
 
8487
{
 
8488
  DBUG_ENTER("Incident_log_event::Incident_log_event");
 
8489
  uint8 const common_header_len=
 
8490
    descr_event->common_header_len;
 
8491
  uint8 const post_header_len=
 
8492
    descr_event->post_header_len[INCIDENT_EVENT-1];
 
8493
 
 
8494
  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
 
8495
                     event_len, common_header_len, post_header_len));
 
8496
 
 
8497
  m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
 
8498
  char const *ptr= buf + common_header_len + post_header_len;
 
8499
  char const *const str_end= buf + event_len;
 
8500
  uint8 len= 0;                   // Assignment to keep compiler happy
 
8501
  const char *str= NULL;          // Assignment to keep compiler happy
 
8502
  read_str(&ptr, str_end, &str, &len);
 
8503
  m_message.str= const_cast<char*>(str);
 
8504
  m_message.length= len;
 
8505
  DBUG_PRINT("info", ("m_incident: %d", m_incident));
 
8506
  DBUG_VOID_RETURN;
 
8507
}
 
8508
 
 
8509
 
 
8510
Incident_log_event::~Incident_log_event()
 
8511
{
 
8512
}
 
8513
 
 
8514
 
 
8515
const char *
 
8516
Incident_log_event::description() const
 
8517
{
 
8518
  static const char *const description[]= {
 
8519
    "NOTHING",                                  // Not used
 
8520
    "LOST_EVENTS"
 
8521
  };
 
8522
 
 
8523
  DBUG_PRINT("info", ("m_incident: %d", m_incident));
 
8524
 
 
8525
  DBUG_ASSERT(0 <= m_incident);
 
8526
  DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
 
8527
 
 
8528
  return description[m_incident];
 
8529
}
 
8530
 
 
8531
 
 
8532
#ifndef MYSQL_CLIENT
 
8533
void Incident_log_event::pack_info(Protocol *protocol)
 
8534
{
 
8535
  char buf[256];
 
8536
  size_t bytes;
 
8537
  if (m_message.length > 0)
 
8538
    bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
 
8539
                       m_incident, description());
 
8540
  else
 
8541
    bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
 
8542
                       m_incident, description(), m_message.str);
 
8543
  protocol->store(buf, bytes, &my_charset_bin);
 
8544
}
 
8545
#endif
 
8546
 
 
8547
 
 
8548
#ifdef MYSQL_CLIENT
 
8549
void
 
8550
Incident_log_event::print(FILE *file,
 
8551
                          PRINT_EVENT_INFO *print_event_info)
 
8552
{
 
8553
  if (print_event_info->short_form)
 
8554
    return;
 
8555
 
 
8556
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
8557
  print_header(&cache, print_event_info, FALSE);
 
8558
  my_b_printf(&cache, "\n# Incident: %s", description());
 
8559
}
 
8560
#endif
 
8561
 
 
8562
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
8563
int
 
8564
Incident_log_event::do_apply_event(Relay_log_info const *rli)
 
8565
{
 
8566
  DBUG_ENTER("Incident_log_event::do_apply_event");
 
8567
  rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
 
8568
              ER(ER_SLAVE_INCIDENT),
 
8569
              description(),
 
8570
              m_message.length > 0 ? m_message.str : "<none>");
 
8571
  DBUG_RETURN(1);
 
8572
}
 
8573
#endif
 
8574
 
 
8575
bool
 
8576
Incident_log_event::write_data_header(IO_CACHE *file)
 
8577
{
 
8578
  DBUG_ENTER("Incident_log_event::write_data_header");
 
8579
  DBUG_PRINT("enter", ("m_incident: %d", m_incident));
 
8580
  uchar buf[sizeof(int16)];
 
8581
  int2store(buf, (int16) m_incident);
 
8582
  DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
 
8583
}
 
8584
 
 
8585
bool
 
8586
Incident_log_event::write_data_body(IO_CACHE *file)
 
8587
{
 
8588
  DBUG_ENTER("Incident_log_event::write_data_body");
 
8589
  DBUG_RETURN(write_str(file, m_message.str, m_message.length));
 
8590
}
 
8591
 
 
8592
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
8593
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
 
8594
                    const Format_description_log_event* description_event)
 
8595
  :Log_event(buf, description_event)
 
8596
{
 
8597
  uint8 header_size= description_event->common_header_len;
 
8598
  ident_len = event_len - header_size;
 
8599
  set_if_smaller(ident_len,FN_REFLEN-1);
 
8600
  log_ident= buf + header_size;
 
8601
}
 
8602
#endif
 
8603
 
 
8604
 
 
8605
#ifdef MYSQL_CLIENT
 
8606
/**
 
8607
  The default values for these variables should be values that are
 
8608
  *incorrect*, i.e., values that cannot occur in an event.  This way,
 
8609
  they will always be printed for the first event.
 
8610
*/
 
8611
st_print_event_info::st_print_event_info()
 
8612
  :flags2_inited(0), sql_mode_inited(0),
 
8613
   auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
 
8614
   lc_time_names_number(~0),
 
8615
   charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
 
8616
   thread_id(0), thread_id_printed(false),
 
8617
   base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
 
8618
{
 
8619
  /*
 
8620
    Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
 
8621
    program's startup, but these explicit bzero() is for the day someone
 
8622
    creates dynamic instances.
 
8623
  */
 
8624
  bzero(db, sizeof(db));
 
8625
  bzero(charset, sizeof(charset));
 
8626
  bzero(time_zone_str, sizeof(time_zone_str));
 
8627
  delimiter[0]= ';';
 
8628
  delimiter[1]= 0;
 
8629
  myf const flags = MYF(MY_WME | MY_NABP);
 
8630
  open_cached_file(&head_cache, NULL, NULL, 0, flags);
 
8631
  open_cached_file(&body_cache, NULL, NULL, 0, flags);
 
8632
}
 
8633
#endif