~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

pandora-build v0.100 - Fixes several bugs found by cb1kenobi. Add several thoughts from folks at LCA.

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