~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Brian Aker
  • Date: 2008-08-22 19:59:34 UTC
  • Revision ID: brian@tangent.org-20080822195934-c2krkt6759jct6mf
Removed dead bits.

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