~drizzle-trunk/drizzle/development

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