~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/log_event.cc

  • Committer: Monty Taylor
  • Date: 2008-07-02 14:35:48 UTC
  • mto: This revision was merged to the branch mainline in revision 51.
  • Revision ID: monty@inaugust.com-20080702143548-onj30ry0sugr01uw
Removed all references to THREAD.

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
 
#include <drizzled/server_includes.h>
 
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"
18
29
#include "rpl_rli.h"
19
30
#include "rpl_mi.h"
20
31
#include "rpl_filter.h"
21
32
#include "rpl_utility.h"
22
33
#include "rpl_record.h"
23
 
#include <mysys/my_dir.h>
24
 
#include <drizzled/drizzled_error_messages.h>
25
 
 
26
 
#include <algorithm>
27
 
 
28
 
#include <mysys/base64.h>
29
 
#include <mysys/my_bitmap.h>
30
 
 
31
 
#include <libdrizzle/gettext.h>
32
 
#include <libdrizzle/libdrizzle.h>
33
 
 
34
 
#define log_cs  &my_charset_utf8_general_ci
 
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
35
42
 
36
43
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
37
44
 
45
52
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
46
53
 
47
54
 
 
55
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
48
56
static const char *HA_ERR(int i)
49
57
{
50
58
  switch (i) {
117
125
*/
118
126
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
119
127
                                           Relay_log_info const *rli, THD *thd,
120
 
                                           Table *table, const char * type,
 
128
                                           TABLE *table, const char * type,
121
129
                                           const char *log_name, ulong pos)
122
130
{
123
131
  const char *handler_error= HA_ERR(ha_error);
124
132
  char buff[MAX_SLAVE_ERRMSG], *slider;
125
133
  const char *buff_end= buff + sizeof(buff);
126
 
  uint32_t len;
127
 
  List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
128
 
  DRIZZLE_ERROR *err;
 
134
  uint len;
 
135
  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
136
  MYSQL_ERROR *err;
129
137
  buff[0]= 0;
130
138
 
131
139
  for (err= it++, slider= buff; err && slider < buff_end - 1;
132
140
       slider += len, err= it++)
133
141
  {
134
 
    len= snprintf(slider, buff_end - slider,
135
 
                  _(" %s, Error_code: %d;"), err->msg, err->code);
 
142
    len= my_snprintf(slider, buff_end - slider,
 
143
                     " %s, Error_code: %d;", err->msg, err->code);
136
144
  }
137
145
  
138
146
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
139
 
              _("Could not execute %s event on table %s.%s;"
140
 
                "%s handler error %s; "
141
 
                "the event's master log %s, end_log_pos %lu"),
 
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",
142
150
              type, table->s->db.str,
143
151
              table->s->table_name.str,
144
152
              buff,
145
 
              handler_error == NULL? _("<unknown>") : handler_error,
 
153
              handler_error == NULL? "<unknown>" : handler_error,
146
154
              log_name, pos);
147
155
}
148
 
 
 
156
#endif
149
157
 
150
158
/*
151
159
  Cache that will automatically be written to a dedicated file on
186
194
  Write_on_release_cache(IO_CACHE *cache, FILE *file, flag_set flags = 0)
187
195
    : m_cache(cache), m_file(file), m_flags(flags)
188
196
  {
189
 
    reinit_io_cache(m_cache, WRITE_CACHE, 0L, false, true);
 
197
    reinit_io_cache(m_cache, WRITE_CACHE, 0L, FALSE, TRUE);
190
198
  }
191
199
 
192
200
  ~Write_on_release_cache()
225
233
  flag_set m_flags;
226
234
};
227
235
 
228
 
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
236
#ifndef DBUG_OFF
 
237
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
238
#endif
229
239
 
230
240
/*
231
241
  pretty_print_str()
232
242
*/
233
243
 
 
244
#ifdef MYSQL_CLIENT
 
245
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
 
246
{
 
247
  const char* end = str + len;
 
248
  my_b_printf(cache, "\'");
 
249
  while (str < end)
 
250
  {
 
251
    char c;
 
252
    switch ((c=*str++)) {
 
253
    case '\n': my_b_printf(cache, "\\n"); break;
 
254
    case '\r': my_b_printf(cache, "\\r"); break;
 
255
    case '\\': my_b_printf(cache, "\\\\"); break;
 
256
    case '\b': my_b_printf(cache, "\\b"); break;
 
257
    case '\t': my_b_printf(cache, "\\t"); break;
 
258
    case '\'': my_b_printf(cache, "\\'"); break;
 
259
    case 0   : my_b_printf(cache, "\\0"); break;
 
260
    default:
 
261
      my_b_printf(cache, "%c", c);
 
262
      break;
 
263
    }
 
264
  }
 
265
  my_b_printf(cache, "\'");
 
266
}
 
267
#endif /* MYSQL_CLIENT */
 
268
 
 
269
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
270
 
234
271
static void clear_all_errors(THD *thd, Relay_log_info *rli)
235
272
{
236
273
  thd->is_slave_error = 0;
248
285
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
249
286
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
250
287
}
 
288
#endif
251
289
 
252
290
 
253
291
/*
254
292
  pretty_print_str()
255
293
*/
256
294
 
 
295
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
257
296
static char *pretty_print_str(char *packet, const char *str, int len)
258
297
{
259
298
  const char *end= str + len;
278
317
  *pos++= '\'';
279
318
  return pos;
280
319
}
281
 
 
 
320
#endif /* !MYSQL_CLIENT */
 
321
 
 
322
 
 
323
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
282
324
 
283
325
/**
284
326
  Creates a temporary name for load data infile:.
292
334
    Pointer to start of extension
293
335
*/
294
336
 
295
 
static char *slave_load_file_stem(char *buf, uint32_t file_id,
 
337
static char *slave_load_file_stem(char *buf, uint file_id,
296
338
                                  int event_server_id, const char *ext)
297
339
{
298
340
  char *res;
299
341
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
300
342
  to_unix_path(buf);
301
343
 
302
 
  buf= strchr(buf, '\0');
303
 
  buf= int10_to_str(::server_id, buf, 10);
 
344
  buf = strend(buf);
 
345
  buf = int10_to_str(::server_id, buf, 10);
304
346
  *buf++ = '-';
305
 
  buf= int10_to_str(event_server_id, buf, 10);
 
347
  buf = int10_to_str(event_server_id, buf, 10);
306
348
  *buf++ = '-';
307
349
  res= int10_to_str(file_id, buf, 10);
308
 
  my_stpcpy(res, ext);                             // Add extension last
 
350
  strmov(res, ext);                             // Add extension last
309
351
  return res;                                   // Pointer to extension
310
352
}
311
 
 
 
353
#endif
 
354
 
 
355
 
 
356
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
312
357
 
313
358
/**
314
359
  Delete all temporary files used for SQL_LOAD.
318
363
{
319
364
  MY_DIR *dirp;
320
365
  FILEINFO *file;
321
 
  uint32_t i;
 
366
  uint i;
322
367
  char fname[FN_REFLEN], prefbuf[31], *p;
323
368
 
324
369
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
349
394
 
350
395
  my_dirend(dirp);
351
396
}
 
397
#endif
352
398
 
353
399
 
354
400
/*
355
401
  write_str()
356
402
*/
357
403
 
358
 
static bool write_str(IO_CACHE *file, const char *str, uint32_t length)
 
404
static bool write_str(IO_CACHE *file, const char *str, uint length)
359
405
{
360
 
  unsigned char tmp[1];
361
 
  tmp[0]= (unsigned char) length;
 
406
  uchar tmp[1];
 
407
  tmp[0]= (uchar) length;
362
408
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
363
 
          my_b_safe_write(file, (unsigned char*) str, length));
 
409
          my_b_safe_write(file, (uchar*) str, length));
364
410
}
365
411
 
366
412
 
369
415
*/
370
416
 
371
417
static inline int read_str(const char **buf, const char *buf_end,
372
 
                           const char **str, uint8_t *len)
 
418
                           const char **str, uint8 *len)
373
419
{
374
 
  if (*buf + ((uint) (unsigned char) **buf) >= buf_end)
 
420
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
375
421
    return 1;
376
 
  *len= (uint8_t) **buf;
 
422
  *len= (uint8) **buf;
377
423
  *str= (*buf)+1;
378
424
  (*buf)+= (uint) *len+1;
379
425
  return 0;
384
430
  Transforms a string into "" or its expression in 0x... form.
385
431
*/
386
432
 
387
 
char *str_to_hex(char *to, const char *from, uint32_t len)
 
433
char *str_to_hex(char *to, const char *from, uint len)
388
434
{
389
435
  if (len)
390
436
  {
393
439
    to= octet2hex(to, from, len);
394
440
  }
395
441
  else
396
 
    to= my_stpcpy(to, "\"\"");
 
442
    to= strmov(to, "\"\"");
397
443
  return to;                               // pointer to end 0 of 'to'
398
444
}
399
445
 
 
446
#ifndef MYSQL_CLIENT
400
447
 
401
448
/**
402
449
  Append a version of the 'from' string suitable for use in a query to
405
452
*/
406
453
 
407
454
int
408
 
append_query_string(const CHARSET_INFO * const csinfo,
 
455
append_query_string(CHARSET_INFO *csinfo,
409
456
                    String const *from, String *to)
410
457
{
411
458
  char *beg, *ptr;
412
 
  uint32_t const orig_len= to->length();
 
459
  uint32 const orig_len= to->length();
413
460
  if (to->reserve(orig_len + from->length()*2+3))
414
461
    return 1;
415
462
 
420
467
  else
421
468
  {
422
469
    *ptr++= '\'';
423
 
    ptr+= drizzle_escape_string(ptr, from->ptr(), from->length());
 
470
    ptr+= escape_string_for_mysql(csinfo, ptr, 0,
 
471
                                  from->ptr(), from->length());
424
472
    *ptr++='\'';
425
473
  }
426
474
  to->length(orig_len + ptr - beg);
427
475
  return 0;
428
476
}
429
 
 
 
477
#endif
 
478
 
 
479
 
 
480
/**
 
481
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
 
482
  commands just before it prints a query.
 
483
*/
 
484
 
 
485
#ifdef MYSQL_CLIENT
 
486
 
 
487
static void print_set_option(IO_CACHE* file, uint32 bits_changed,
 
488
                             uint32 option, uint32 flags, const char* name,
 
489
                             bool* need_comma)
 
490
{
 
491
  if (bits_changed & option)
 
492
  {
 
493
    if (*need_comma)
 
494
      my_b_printf(file,", ");
 
495
    my_b_printf(file,"%s=%d", name, test(flags & option));
 
496
    *need_comma= 1;
 
497
  }
 
498
}
 
499
#endif
430
500
 
431
501
/**************************************************************************
432
502
        Log_event methods (= the parent class of all events)
480
550
  Log_event::Log_event()
481
551
*/
482
552
 
483
 
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
 
553
#ifndef MYSQL_CLIENT
 
554
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
484
555
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
485
556
{
486
557
  server_id=    thd->server_id;
508
579
  when=         0;
509
580
  log_pos=      0;
510
581
}
 
582
#endif /* !MYSQL_CLIENT */
511
583
 
512
584
 
513
585
/*
518
590
                     const Format_description_log_event* description_event)
519
591
  :temp_buf(0), cache_stmt(0)
520
592
{
521
 
  thd= 0;
522
 
  when= uint4korr(buf);
523
 
  server_id= uint4korr(buf + SERVER_ID_OFFSET);
 
593
#ifndef MYSQL_CLIENT
 
594
  thd = 0;
 
595
#endif
 
596
  when = uint4korr(buf);
 
597
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
524
598
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
525
599
  if (description_event->binlog_version==1)
526
600
  {
556
630
      */
557
631
    log_pos+= data_written; /* purecov: inspected */
558
632
  }
 
633
  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
559
634
 
560
635
  flags= uint2korr(buf + FLAGS_OFFSET);
561
636
  if ((buf[EVENT_TYPE_OFFSET] == FORMAT_DESCRIPTION_EVENT) ||
579
654
  /* otherwise, go on with reading the header from buf (nothing now) */
580
655
}
581
656
 
 
657
#ifndef MYSQL_CLIENT
 
658
#ifdef HAVE_REPLICATION
582
659
 
583
660
int Log_event::do_update_pos(Relay_log_info *rli)
584
661
{
602
679
      rli->last_master_timestamp for only one time -
603
680
      the first FLUSH LOGS in the test.
604
681
    */
605
 
    if (debug_not_change_ts_if_art_event == 1
606
 
        && is_artificial_event())
607
 
      debug_not_change_ts_if_art_event= 0;
 
682
    DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
 
683
                    if (debug_not_change_ts_if_art_event == 1
 
684
                        && is_artificial_event())
 
685
                    {
 
686
                      debug_not_change_ts_if_art_event= 0;
 
687
                    });
 
688
#ifndef DBUG_OFF
608
689
    rli->stmt_done(log_pos, 
609
690
                   is_artificial_event() &&
610
691
                   debug_not_change_ts_if_art_event > 0 ? 0 : when);
611
 
    if (debug_not_change_ts_if_art_event == 0)
612
 
      debug_not_change_ts_if_art_event= 2;
 
692
#else
 
693
    rli->stmt_done(log_pos, is_artificial_event()? 0 : when);
 
694
#endif
 
695
    DBUG_EXECUTE_IF("let_first_flush_log_change_timestamp",
 
696
                    if (debug_not_change_ts_if_art_event == 0)
 
697
                    {
 
698
                      debug_not_change_ts_if_art_event= 2;
 
699
                    });
613
700
  }
614
701
  return 0;                                   // Cannot fail currently
615
702
}
618
705
Log_event::enum_skip_reason
619
706
Log_event::do_shall_skip(Relay_log_info *rli)
620
707
{
 
708
  DBUG_PRINT("info", ("ev->server_id=%lu, ::server_id=%lu,"
 
709
                      " rli->replicate_same_server_id=%d,"
 
710
                      " rli->slave_skip_counter=%d",
 
711
                      (ulong) server_id, (ulong) ::server_id,
 
712
                      rli->replicate_same_server_id,
 
713
                      rli->slave_skip_counter));
621
714
  if ((server_id == ::server_id && !rli->replicate_same_server_id) || (rli->slave_skip_counter == 1 && rli->is_in_group()))
622
715
    return EVENT_SKIP_IGNORE;
623
716
  else if (rli->slave_skip_counter > 0)
638
731
 
639
732
 
640
733
/**
 
734
  Only called by SHOW BINLOG EVENTS
 
735
*/
 
736
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
 
737
{
 
738
  const char *p= strrchr(log_name, FN_LIBCHAR);
 
739
  const char *event_type;
 
740
  if (p)
 
741
    log_name = p + 1;
 
742
 
 
743
  protocol->prepare_for_resend();
 
744
  protocol->store(log_name, &my_charset_bin);
 
745
  protocol->store((ulonglong) pos);
 
746
  event_type = get_type_str();
 
747
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
 
748
  protocol->store((uint32) server_id);
 
749
  protocol->store((ulonglong) log_pos);
 
750
  pack_info(protocol);
 
751
  return protocol->write();
 
752
}
 
753
#endif /* HAVE_REPLICATION */
 
754
 
 
755
 
 
756
/**
641
757
  init_show_field_list() prepares the column names and types for the
642
758
  output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
643
759
  EVENTS.
647
763
{
648
764
  field_list->push_back(new Item_empty_string("Log_name", 20));
649
765
  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
650
 
                                            DRIZZLE_TYPE_LONGLONG));
 
766
                                            MYSQL_TYPE_LONGLONG));
651
767
  field_list->push_back(new Item_empty_string("Event_type", 20));
652
768
  field_list->push_back(new Item_return_int("Server_id", 10,
653
 
                                            DRIZZLE_TYPE_LONG));
 
769
                                            MYSQL_TYPE_LONG));
654
770
  field_list->push_back(new Item_return_int("End_log_pos",
655
771
                                            MY_INT32_NUM_DECIMAL_DIGITS,
656
 
                                            DRIZZLE_TYPE_LONGLONG));
 
772
                                            MYSQL_TYPE_LONGLONG));
657
773
  field_list->push_back(new Item_empty_string("Info", 20));
658
774
}
659
775
 
 
776
 
660
777
/*
661
778
  Log_event::write()
662
779
*/
663
780
 
664
781
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
665
782
{
666
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
783
  uchar header[LOG_EVENT_HEADER_LEN];
667
784
  ulong now;
 
785
  DBUG_ENTER("Log_event::write_header");
668
786
 
669
787
  /* Store number of bytes that will be written by this event */
670
788
  data_written= event_data_length + sizeof(header);
700
818
      relay log, we use the (new) my_b_safe_tell().
701
819
 
702
820
      Note that this raises a question on the correctness of all these
703
 
      assert(my_b_tell()=rli->event_relay_log_pos).
 
821
      DBUG_ASSERT(my_b_tell()=rli->event_relay_log_pos).
704
822
 
705
823
      If in a transaction, the log_pos which we calculate below is not
706
824
      very good (because then my_b_safe_tell() returns start position
730
848
  int4store(header+ LOG_POS_OFFSET, log_pos);
731
849
  int2store(header+ FLAGS_OFFSET, flags);
732
850
 
733
 
  return(my_b_safe_write(file, header, sizeof(header)) != 0);
 
851
  DBUG_RETURN(my_b_safe_write(file, header, sizeof(header)) != 0);
734
852
}
735
853
 
736
854
 
745
863
  ulong data_len;
746
864
  int result=0;
747
865
  char buf[LOG_EVENT_MINIMAL_HEADER_LEN];
 
866
  DBUG_ENTER("Log_event::read_log_event");
748
867
 
749
868
  if (log_lock)
750
869
    pthread_mutex_lock(log_lock);
751
 
  if (my_b_read(file, (unsigned char*) buf, sizeof(buf)))
 
870
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
752
871
  {
753
872
    /*
754
873
      If the read hits eof, we must report it as eof so the caller
755
874
      will know it can go into cond_wait to be woken up on the next
756
875
      update to the log.
757
876
    */
 
877
    DBUG_PRINT("error",("file->error: %d", file->error));
758
878
    if (!file->error)
759
879
      result= LOG_READ_EOF;
760
880
    else
765
885
  if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
766
886
      data_len > current_thd->variables.max_allowed_packet)
767
887
  {
 
888
    DBUG_PRINT("error",("data_len: %ld", data_len));
768
889
    result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
769
890
             LOG_READ_TOO_LARGE);
770
891
    goto end;
804
925
end:
805
926
  if (log_lock)
806
927
    pthread_mutex_unlock(log_lock);
807
 
  return(result);
 
928
  DBUG_RETURN(result);
808
929
}
 
930
#endif /* !MYSQL_CLIENT */
809
931
 
 
932
#ifndef MYSQL_CLIENT
810
933
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
811
934
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
 
935
#else
 
936
#define UNLOCK_MUTEX
 
937
#define LOCK_MUTEX
 
938
#endif
812
939
 
 
940
#ifndef MYSQL_CLIENT
813
941
/**
814
942
  @note
815
943
    Allocates memory;  The caller is responsible for clean-up.
818
946
                                     pthread_mutex_t* log_lock,
819
947
                                     const Format_description_log_event
820
948
                                     *description_event)
 
949
#else
 
950
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
951
                                     const Format_description_log_event
 
952
                                     *description_event)
 
953
#endif
821
954
{
822
 
  assert(description_event != 0);
 
955
  DBUG_ENTER("Log_event::read_log_event");
 
956
  DBUG_ASSERT(description_event != 0);
823
957
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
824
958
  /*
825
959
    First we only want to read at most LOG_EVENT_MINIMAL_HEADER_LEN, just to
828
962
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
829
963
    "minimal" over the set {MySQL >=4.0}).
830
964
  */
831
 
  uint32_t header_size= cmin(description_event->common_header_len,
 
965
  uint header_size= min(description_event->common_header_len,
832
966
                        LOG_EVENT_MINIMAL_HEADER_LEN);
833
967
 
834
968
  LOCK_MUTEX;
835
 
  if (my_b_read(file, (unsigned char *) head, header_size))
 
969
  DBUG_PRINT("info", ("my_b_tell: %lu", (ulong) my_b_tell(file)));
 
970
  if (my_b_read(file, (uchar *) head, header_size))
836
971
  {
 
972
    DBUG_PRINT("info", ("Log_event::read_log_event(IO_CACHE*,Format_desc*) \
 
973
failed my_b_read"));
837
974
    UNLOCK_MUTEX;
838
975
    /*
839
976
      No error here; it could be that we are at the file's end. However
840
977
      if the next my_b_read() fails (below), it will be an error as we
841
978
      were able to read the first bytes.
842
979
    */
843
 
    return(0);
 
980
    DBUG_RETURN(0);
844
981
  }
845
 
  uint32_t data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
982
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
846
983
  char *buf= 0;
847
984
  const char *error= 0;
848
985
  Log_event *res=  0;
849
986
#ifndef max_allowed_packet
850
987
  THD *thd=current_thd;
851
 
  uint32_t max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
 
988
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
852
989
#endif
853
990
 
854
991
  if (data_len > max_allowed_packet)
871
1008
  }
872
1009
  buf[data_len] = 0;
873
1010
  memcpy(buf, head, header_size);
874
 
  if (my_b_read(file, (unsigned char*) buf + header_size, data_len - header_size))
 
1011
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
875
1012
  {
876
1013
    error = "read error";
877
1014
    goto err;
883
1020
  UNLOCK_MUTEX;
884
1021
  if (!res)
885
1022
  {
886
 
    assert(error != 0);
887
 
    sql_print_error(_("Error in Log_event::read_log_event(): "
888
 
                    "'%s', data_len: %d, event_type: %d"),
 
1023
    DBUG_ASSERT(error != 0);
 
1024
    sql_print_error("Error in Log_event::read_log_event(): "
 
1025
                    "'%s', data_len: %d, event_type: %d",
889
1026
                    error,data_len,head[EVENT_TYPE_OFFSET]);
890
 
    free(buf);
 
1027
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
891
1028
    /*
892
1029
      The SQL slave thread will check if file->error<0 to know
893
1030
      if there was an I/O error. Even if there is no "low-level" I/O errors
898
1035
    */
899
1036
    file->error= -1;
900
1037
  }
901
 
  return(res);
 
1038
  DBUG_RETURN(res);
902
1039
}
903
1040
 
904
1041
 
907
1044
  constructors.
908
1045
*/
909
1046
 
910
 
Log_event* Log_event::read_log_event(const char* buf, uint32_t event_len,
 
1047
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
911
1048
                                     const char **error,
912
1049
                                     const Format_description_log_event *description_event)
913
1050
{
914
1051
  Log_event* ev;
915
 
  assert(description_event != 0);
 
1052
  DBUG_ENTER("Log_event::read_log_event(char*,...)");
 
1053
  DBUG_ASSERT(description_event != 0);
 
1054
  DBUG_PRINT("info", ("binlog_version: %d", description_event->binlog_version));
 
1055
  DBUG_DUMP("data", (unsigned char*) buf, event_len);
916
1056
 
917
1057
  /* Check the integrity */
918
1058
  if (event_len < EVENT_LEN_OFFSET ||
920
1060
      (uint) event_len != uint4korr(buf+EVENT_LEN_OFFSET))
921
1061
  {
922
1062
    *error="Sanity check failed";               // Needed to free buffer
923
 
    return(NULL); // general sanity check - will fail on a partial read
 
1063
    DBUG_RETURN(NULL); // general sanity check - will fail on a partial read
924
1064
  }
925
1065
 
926
 
  uint32_t event_type= buf[EVENT_TYPE_OFFSET];
 
1066
  uint event_type= buf[EVENT_TYPE_OFFSET];
927
1067
  if (event_type > description_event->number_of_event_types &&
928
1068
      event_type != FORMAT_DESCRIPTION_EVENT)
929
1069
  {
931
1071
      It is unsafe to use the description_event if its post_header_len
932
1072
      array does not include the event type.
933
1073
    */
 
1074
    DBUG_PRINT("error", ("event type %d found, but the current "
 
1075
                         "Format_description_log_event supports only %d event "
 
1076
                         "types", event_type,
 
1077
                         description_event->number_of_event_types));
934
1078
    ev= NULL;
935
1079
  }
936
1080
  else
946
1090
      was read.
947
1091
    */
948
1092
    if (description_event->event_type_permutation)
 
1093
    {
 
1094
      IF_DBUG({
 
1095
          int new_event_type=
 
1096
            description_event->event_type_permutation[event_type];
 
1097
          DBUG_PRINT("info",
 
1098
                     ("converting event type %d to %d (%s)",
 
1099
                      event_type, new_event_type,
 
1100
                      get_type_str((Log_event_type)new_event_type)));
 
1101
        });
949
1102
      event_type= description_event->event_type_permutation[event_type];
 
1103
    }
950
1104
 
951
1105
    switch(event_type) {
952
1106
    case QUERY_EVENT:
961
1115
    case ROTATE_EVENT:
962
1116
      ev = new Rotate_log_event(buf, event_len, description_event);
963
1117
      break;
 
1118
#ifdef HAVE_REPLICATION
 
1119
    case SLAVE_EVENT: /* can never happen (unused event) */
 
1120
      ev = new Slave_log_event(buf, event_len);
 
1121
      break;
 
1122
#endif /* HAVE_REPLICATION */
964
1123
    case CREATE_FILE_EVENT:
965
1124
      ev = new Create_file_log_event(buf, event_len, description_event);
966
1125
      break;
994
1153
    case FORMAT_DESCRIPTION_EVENT:
995
1154
      ev = new Format_description_log_event(buf, event_len, description_event);
996
1155
      break;
 
1156
#if defined(HAVE_REPLICATION) 
997
1157
    case WRITE_ROWS_EVENT:
998
1158
      ev = new Write_rows_log_event(buf, event_len, description_event);
999
1159
      break;
1006
1166
    case TABLE_MAP_EVENT:
1007
1167
      ev = new Table_map_log_event(buf, event_len, description_event);
1008
1168
      break;
 
1169
#endif
1009
1170
    case BEGIN_LOAD_QUERY_EVENT:
1010
1171
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
1011
1172
      break;
1016
1177
      ev = new Incident_log_event(buf, event_len, description_event);
1017
1178
      break;
1018
1179
    default:
 
1180
      DBUG_PRINT("error",("Unknown event code: %d",
 
1181
                          (int) buf[EVENT_TYPE_OFFSET]));
1019
1182
      ev= NULL;
1020
1183
      break;
1021
1184
    }
1022
1185
  }
1023
1186
 
 
1187
  DBUG_PRINT("read_event", ("%s(type_code: %d; event_len: %d)",
 
1188
                            ev ? ev->get_type_str() : "<unknown>",
 
1189
                            buf[EVENT_TYPE_OFFSET],
 
1190
                            event_len));
1024
1191
  /*
1025
1192
    is_valid() are small event-specific sanity tests which are
1026
1193
    important; for example there are some my_malloc() in constructors
1032
1199
  */
1033
1200
  if (!ev || !ev->is_valid())
1034
1201
  {
 
1202
    DBUG_PRINT("error",("Found invalid event in binary log"));
 
1203
 
1035
1204
    delete ev;
 
1205
#ifdef MYSQL_CLIENT
 
1206
    if (!force_opt) /* then mysqlbinlog dies */
 
1207
    {
 
1208
      *error= "Found invalid event in binary log";
 
1209
      DBUG_RETURN(0);
 
1210
    }
 
1211
    ev= new Unknown_log_event(buf, description_event);
 
1212
#else
1036
1213
    *error= "Found invalid event in binary log";
1037
 
    return(0);
1038
 
  }
1039
 
  return(ev);  
1040
 
}
1041
 
 
 
1214
    DBUG_RETURN(0);
 
1215
#endif
 
1216
  }
 
1217
  DBUG_RETURN(ev);  
 
1218
}
 
1219
 
 
1220
#ifdef MYSQL_CLIENT
 
1221
 
 
1222
/*
 
1223
  Log_event::print_header()
 
1224
*/
 
1225
 
 
1226
void Log_event::print_header(IO_CACHE* file,
 
1227
                             PRINT_EVENT_INFO* print_event_info,
 
1228
                             bool is_more __attribute__((unused)))
 
1229
{
 
1230
  char llbuff[22];
 
1231
  my_off_t hexdump_from= print_event_info->hexdump_from;
 
1232
  DBUG_ENTER("Log_event::print_header");
 
1233
 
 
1234
  my_b_printf(file, "#");
 
1235
  print_timestamp(file);
 
1236
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
 
1237
              llstr(log_pos,llbuff));
 
1238
 
 
1239
  /* mysqlbinlog --hexdump */
 
1240
  if (print_event_info->hexdump_from)
 
1241
  {
 
1242
    my_b_printf(file, "\n");
 
1243
    uchar *ptr= (uchar*)temp_buf;
 
1244
    my_off_t size=
 
1245
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
 
1246
    my_off_t i;
 
1247
 
 
1248
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
 
1249
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
 
1250
    char *c, char_string[16+1]= {0};
 
1251
 
 
1252
    /* Pretty-print event common header if header is exactly 19 bytes */
 
1253
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
 
1254
    {
 
1255
      char emit_buf[256];               // Enough for storing one line
 
1256
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
 
1257
                  "Size      Master Pos    Flags \n");
 
1258
      int const bytes_written=
 
1259
        my_snprintf(emit_buf, sizeof(emit_buf),
 
1260
                    "# %8.8lx %02x %02x %02x %02x   %02x   "
 
1261
                    "%02x %02x %02x %02x   %02x %02x %02x %02x   "
 
1262
                    "%02x %02x %02x %02x   %02x %02x\n",
 
1263
                    (unsigned long) hexdump_from,
 
1264
                    ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
 
1265
                    ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
 
1266
                    ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
 
1267
      DBUG_ASSERT(bytes_written >= 0);
 
1268
      DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1269
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1270
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1271
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1272
    }
 
1273
 
 
1274
    /* Rest of event (without common header) */
 
1275
    for (i= 0, c= char_string, h=hex_string;
 
1276
         i < size;
 
1277
         i++, ptr++)
 
1278
    {
 
1279
      my_snprintf(h, 4, "%02x ", *ptr);
 
1280
      h += 3;
 
1281
 
 
1282
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
 
1283
 
 
1284
      if (i % 16 == 15)
 
1285
      {
 
1286
        /*
 
1287
          my_b_printf() does not support full printf() formats, so we
 
1288
          have to do it this way.
 
1289
 
 
1290
          TODO: Rewrite my_b_printf() to support full printf() syntax.
 
1291
         */
 
1292
        char emit_buf[256];
 
1293
        int const bytes_written=
 
1294
          my_snprintf(emit_buf, sizeof(emit_buf),
 
1295
                      "# %8.8lx %-48.48s |%16s|\n",
 
1296
                      (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1297
                      hex_string, char_string);
 
1298
        DBUG_ASSERT(bytes_written >= 0);
 
1299
        DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1300
        my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1301
        hex_string[0]= 0;
 
1302
        char_string[0]= 0;
 
1303
        c= char_string;
 
1304
        h= hex_string;
 
1305
      }
 
1306
      else if (i % 8 == 7) *h++ = ' ';
 
1307
    }
 
1308
    *c= '\0';
 
1309
 
 
1310
    if (hex_string[0])
 
1311
    {
 
1312
      char emit_buf[256];
 
1313
      int const bytes_written=
 
1314
        my_snprintf(emit_buf, sizeof(emit_buf),
 
1315
                    "# %8.8lx %-48.48s |%s|\n",
 
1316
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1317
                    hex_string, char_string);
 
1318
      DBUG_ASSERT(bytes_written >= 0);
 
1319
      DBUG_ASSERT(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1320
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1321
    }
 
1322
    /*
 
1323
      need a # to prefix the rest of printouts for example those of
 
1324
      Rows_log_event::print_helper().
 
1325
    */
 
1326
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
 
1327
  }
 
1328
  DBUG_VOID_RETURN;
 
1329
}
 
1330
 
 
1331
 
 
1332
void Log_event::print_base64(IO_CACHE* file,
 
1333
                             PRINT_EVENT_INFO* print_event_info,
 
1334
                             bool more)
 
1335
{
 
1336
  const uchar *ptr= (const uchar *)temp_buf;
 
1337
  uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
 
1338
  DBUG_ENTER("Log_event::print_base64");
 
1339
 
 
1340
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
 
1341
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
 
1342
  if (!tmp_str) {
 
1343
    fprintf(stderr, "\nError: Out of memory. "
 
1344
            "Could not print correct binlog event.\n");
 
1345
    DBUG_VOID_RETURN;
 
1346
  }
 
1347
 
 
1348
  if (base64_encode(ptr, (size_t) size, tmp_str))
 
1349
  {
 
1350
    DBUG_ASSERT(0);
 
1351
  }
 
1352
 
 
1353
  if (my_b_tell(file) == 0)
 
1354
    my_b_printf(file, "\nBINLOG '\n");
 
1355
 
 
1356
  my_b_printf(file, "%s\n", tmp_str);
 
1357
 
 
1358
  if (!more)
 
1359
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
 
1360
 
 
1361
  my_free(tmp_str, MYF(0));
 
1362
  DBUG_VOID_RETURN;
 
1363
}
 
1364
 
 
1365
 
 
1366
/*
 
1367
  Log_event::print_timestamp()
 
1368
*/
 
1369
 
 
1370
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
 
1371
{
 
1372
  struct tm *res;
 
1373
  DBUG_ENTER("Log_event::print_timestamp");
 
1374
  if (!ts)
 
1375
    ts = &when;
 
1376
#ifdef MYSQL_SERVER                             // This is always false
 
1377
  struct tm tm_tmp;
 
1378
  localtime_r(ts,(res= &tm_tmp));
 
1379
#else
 
1380
  res=localtime(ts);
 
1381
#endif
 
1382
 
 
1383
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
 
1384
              res->tm_year % 100,
 
1385
              res->tm_mon+1,
 
1386
              res->tm_mday,
 
1387
              res->tm_hour,
 
1388
              res->tm_min,
 
1389
              res->tm_sec);
 
1390
  DBUG_VOID_RETURN;
 
1391
}
 
1392
 
 
1393
#endif /* MYSQL_CLIENT */
 
1394
 
 
1395
 
 
1396
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1042
1397
inline Log_event::enum_skip_reason
1043
1398
Log_event::continue_group(Relay_log_info *rli)
1044
1399
{
1046
1401
    return Log_event::EVENT_SKIP_IGNORE;
1047
1402
  return Log_event::do_shall_skip(rli);
1048
1403
}
 
1404
#endif
1049
1405
 
1050
1406
/**************************************************************************
1051
1407
        Query_log_event methods
1052
1408
**************************************************************************/
1053
1409
 
 
1410
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
1411
 
1054
1412
/**
1055
1413
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
1056
1414
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1070
1428
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1071
1429
      && db && db_len)
1072
1430
  {
1073
 
    pos= my_stpcpy(buf, "use `");
 
1431
    pos= strmov(buf, "use `");
1074
1432
    memcpy(pos, db, db_len);
1075
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
1433
    pos= strmov(pos+db_len, "`; ");
1076
1434
  }
1077
1435
  if (query && q_len)
1078
1436
  {
1080
1438
    pos+= q_len;
1081
1439
  }
1082
1440
  protocol->store(buf, pos-buf, &my_charset_bin);
1083
 
  free(buf);
 
1441
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1084
1442
}
 
1443
#endif
1085
1444
 
 
1445
#ifndef MYSQL_CLIENT
1086
1446
 
1087
1447
/**
1088
1448
  Utility function for the next method (Query_log_event::write()) .
1089
1449
*/
1090
1450
static void write_str_with_code_and_len(char **dst, const char *src,
1091
 
                                        int len, uint32_t code)
 
1451
                                        int len, uint code)
1092
1452
{
1093
 
  assert(src);
 
1453
  DBUG_ASSERT(src);
1094
1454
  *((*dst)++)= code;
1095
 
  *((*dst)++)= (unsigned char) len;
1096
 
  memcpy(*dst, src, len);
 
1455
  *((*dst)++)= (uchar) len;
 
1456
  bmove(*dst, src, len);
1097
1457
  (*dst)+= len;
1098
1458
}
1099
1459
 
1114
1474
    replicating it correctly, since the length is stored in a byte
1115
1475
    /sven
1116
1476
  */
1117
 
  unsigned char buf[QUERY_HEADER_LEN+
 
1477
  uchar buf[QUERY_HEADER_LEN+
1118
1478
            1+4+           // code of flags2 and flags2
1119
1479
            1+8+           // code of sql_mode and sql_mode
1120
1480
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1186
1546
  if (sql_mode_inited)
1187
1547
  {
1188
1548
    *start++= Q_SQL_MODE_CODE;
1189
 
    int8store(start, (uint64_t)sql_mode);
 
1549
    int8store(start, (ulonglong)sql_mode);
1190
1550
    start+= 8;
1191
1551
  }
1192
1552
  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1228
1588
  if (time_zone_len)
1229
1589
  {
1230
1590
    /* In the TZ sys table, column Name is of length 64 so this should be ok */
1231
 
    assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
 
1591
    DBUG_ASSERT(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1232
1592
    *start++= Q_TIME_ZONE_CODE;
1233
1593
    *start++= time_zone_len;
1234
1594
    memcpy(start, time_zone_str, time_zone_len);
1236
1596
  }
1237
1597
  if (lc_time_names_number)
1238
1598
  {
1239
 
    assert(lc_time_names_number <= 0xFFFF);
 
1599
    DBUG_ASSERT(lc_time_names_number <= 0xFFFF);
1240
1600
    *start++= Q_LC_TIME_NAMES_CODE;
1241
1601
    int2store(start, lc_time_names_number);
1242
1602
    start+= 2;
1243
1603
  }
1244
1604
  if (charset_database_number)
1245
1605
  {
1246
 
    assert(charset_database_number <= 0xFFFF);
 
1606
    DBUG_ASSERT(charset_database_number <= 0xFFFF);
1247
1607
    *start++= Q_CHARSET_DATABASE_CODE;
1248
1608
    int2store(start, charset_database_number);
1249
1609
    start+= 2;
1260
1620
  
1261
1621
  /* Store length of status variables */
1262
1622
  status_vars_len= (uint) (start-start_of_status);
1263
 
  assert(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
 
1623
  DBUG_ASSERT(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
1264
1624
  int2store(buf + Q_STATUS_VARS_LEN_OFFSET, status_vars_len);
1265
1625
 
1266
1626
  /*
1270
1630
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1271
1631
 
1272
1632
  return (write_header(file, event_length) ||
1273
 
          my_b_safe_write(file, (unsigned char*) buf, QUERY_HEADER_LEN) ||
 
1633
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1274
1634
          write_post_header_for_derived(file) ||
1275
 
          my_b_safe_write(file, (unsigned char*) start_of_status,
 
1635
          my_b_safe_write(file, (uchar*) start_of_status,
1276
1636
                          (uint) (start-start_of_status)) ||
1277
 
          my_b_safe_write(file, (db) ? (unsigned char*) db : (unsigned char*)"", db_len + 1) ||
1278
 
          my_b_safe_write(file, (unsigned char*) query, q_len)) ? 1 : 0;
 
1637
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
 
1638
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1279
1639
}
1280
1640
 
1281
1641
/**
1316
1676
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1317
1677
             using_trans),
1318
1678
   data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1319
 
   db(thd_arg->db), q_len((uint32_t) query_length),
 
1679
   db(thd_arg->db), q_len((uint32) query_length),
1320
1680
   thread_id(thd_arg->thread_id),
1321
1681
   /* save the original thread id; we already know the server id */
1322
1682
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1331
1691
 
1332
1692
  if (killed_status_arg == THD::KILLED_NO_VALUE)
1333
1693
    killed_status_arg= thd_arg->killed;
1334
 
 
1335
1694
  error_code=
1336
1695
    (killed_status_arg == THD::NOT_KILLED) ?
1337
1696
    (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1338
 
    (thd_arg->killed_errno());
 
1697
    ((thd_arg->system_thread & SYSTEM_THREAD_DELAYED_INSERT) ? 0 :
 
1698
     thd_arg->killed_errno());
1339
1699
  
1340
1700
  time(&end_time);
1341
1701
  exec_time = (ulong) (end_time  - thd_arg->start_time);
1343
1703
    @todo this means that if we have no catalog, then it is replicated
1344
1704
    as an existing catalog of length zero. is that safe? /sven
1345
1705
  */
1346
 
  catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
 
1706
  catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
1347
1707
  /* status_vars_len is set just before writing the event */
1348
 
  db_len = (db) ? (uint32_t) strlen(db) : 0;
 
1708
  db_len = (db) ? (uint32) strlen(db) : 0;
1349
1709
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
1350
1710
    charset_database_number= thd_arg->variables.collation_database->number;
1351
1711
  
1356
1716
    But it's likely that we don't want to use 32 bits for 3 bits; in the future
1357
1717
    we will probably want to reclaim the 29 bits. So we need the &.
1358
1718
  */
1359
 
  flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1360
 
  assert(thd_arg->variables.character_set_client->number < 256*256);
1361
 
  assert(thd_arg->variables.collation_connection->number < 256*256);
1362
 
  assert(thd_arg->variables.collation_server->number < 256*256);
1363
 
  assert(thd_arg->variables.character_set_client->mbminlen == 1);
 
1719
  flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
 
1720
  DBUG_ASSERT(thd_arg->variables.character_set_client->number < 256*256);
 
1721
  DBUG_ASSERT(thd_arg->variables.collation_connection->number < 256*256);
 
1722
  DBUG_ASSERT(thd_arg->variables.collation_server->number < 256*256);
 
1723
  DBUG_ASSERT(thd_arg->variables.character_set_client->mbminlen == 1);
1364
1724
  int2store(charset, thd_arg->variables.character_set_client->number);
1365
1725
  int2store(charset+2, thd_arg->variables.collation_connection->number);
1366
1726
  int2store(charset+4, thd_arg->variables.collation_server->number);
1376
1736
  }
1377
1737
  else
1378
1738
    time_zone_len= 0;
 
1739
  DBUG_PRINT("info",("Query_log_event has flags2: %lu  sql_mode: %lu",
 
1740
                     (ulong) flags2, sql_mode));
1379
1741
}
 
1742
#endif /* MYSQL_CLIENT */
1380
1743
 
1381
1744
 
1382
1745
/* 2 utility functions for the next method */
1408
1771
static int
1409
1772
get_str_len_and_pointer(const Log_event::Byte **src,
1410
1773
                        const char **dst,
1411
 
                        uint32_t *len,
 
1774
                        uint *len,
1412
1775
                        const Log_event::Byte *end)
1413
1776
{
1414
1777
  if (*src >= end)
1415
1778
    return -1;       // Will be UINT_MAX in two-complement arithmetics
1416
 
  uint32_t length= **src;
 
1779
  uint length= **src;
1417
1780
  if (length > 0)
1418
1781
  {
1419
1782
    if (*src + length >= end)
1427
1790
 
1428
1791
static void copy_str_and_move(const char **src, 
1429
1792
                              Log_event::Byte **dst, 
1430
 
                              uint32_t len)
 
1793
                              uint len)
1431
1794
{
1432
1795
  memcpy(*dst, *src, len);
1433
1796
  *src= (const char *)*dst;
1436
1799
}
1437
1800
 
1438
1801
 
 
1802
#ifndef DBUG_OFF
 
1803
static char const *
 
1804
code_name(int code)
 
1805
{
 
1806
  static char buf[255];
 
1807
  switch (code) {
 
1808
  case Q_FLAGS2_CODE: return "Q_FLAGS2_CODE";
 
1809
  case Q_SQL_MODE_CODE: return "Q_SQL_MODE_CODE";
 
1810
  case Q_CATALOG_CODE: return "Q_CATALOG_CODE";
 
1811
  case Q_AUTO_INCREMENT: return "Q_AUTO_INCREMENT";
 
1812
  case Q_CHARSET_CODE: return "Q_CHARSET_CODE";
 
1813
  case Q_TIME_ZONE_CODE: return "Q_TIME_ZONE_CODE";
 
1814
  case Q_CATALOG_NZ_CODE: return "Q_CATALOG_NZ_CODE";
 
1815
  case Q_LC_TIME_NAMES_CODE: return "Q_LC_TIME_NAMES_CODE";
 
1816
  case Q_CHARSET_DATABASE_CODE: return "Q_CHARSET_DATABASE_CODE";
 
1817
  }
 
1818
  sprintf(buf, "CODE#%d", code);
 
1819
  return buf;
 
1820
}
 
1821
#endif
 
1822
 
1439
1823
/**
1440
1824
   Macro to check that there is enough space to read from memory.
1441
1825
 
1445
1829
 */
1446
1830
#define CHECK_SPACE(PTR,END,CNT)                      \
1447
1831
  do {                                                \
1448
 
    assert((PTR) + (CNT) <= (END));                   \
 
1832
    DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
 
1833
    DBUG_ASSERT((PTR) + (CNT) <= (END));              \
1449
1834
    if ((PTR) + (CNT) > (END)) {                      \
 
1835
      DBUG_PRINT("info", ("query= 0"));               \
1450
1836
      query= 0;                                       \
1451
 
      return;                                         \
 
1837
      DBUG_VOID_RETURN;                               \
1452
1838
    }                                                 \
1453
1839
  } while (0)
1454
1840
 
1456
1842
/**
1457
1843
  This is used by the SQL slave thread to prepare the event before execution.
1458
1844
*/
1459
 
Query_log_event::Query_log_event(const char* buf, uint32_t event_len,
 
1845
Query_log_event::Query_log_event(const char* buf, uint event_len,
1460
1846
                                 const Format_description_log_event
1461
1847
                                 *description_event,
1462
1848
                                 Log_event_type event_type)
1463
 
  :Log_event(buf, description_event), data_buf(0), query(NULL),
1464
 
   db(NULL), catalog_len(0), status_vars_len(0),
 
1849
  :Log_event(buf, description_event), data_buf(0), query(NullS),
 
1850
   db(NullS), catalog_len(0), status_vars_len(0),
1465
1851
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1466
1852
   auto_increment_increment(1), auto_increment_offset(1),
1467
1853
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1468
1854
{
1469
 
  uint32_t data_len;
1470
 
  uint32_t tmp;
1471
 
  uint8_t common_header_len, post_header_len;
 
1855
  ulong data_len;
 
1856
  uint32 tmp;
 
1857
  uint8 common_header_len, post_header_len;
1472
1858
  Log_event::Byte *start;
1473
1859
  const Log_event::Byte *end;
1474
1860
  bool catalog_nz= 1;
 
1861
  DBUG_ENTER("Query_log_event::Query_log_event(char*,...)");
1475
1862
 
1476
1863
  common_header_len= description_event->common_header_len;
1477
1864
  post_header_len= description_event->post_header_len[event_type-1];
 
1865
  DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
 
1866
                     event_len, common_header_len, post_header_len));
1478
1867
  
1479
1868
  /*
1480
1869
    We test if the event's length is sensible, and if so we compute data_len.
1482
1871
    We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
1483
1872
  */
1484
1873
  if (event_len < (uint)(common_header_len + post_header_len))
1485
 
    return;                             
 
1874
    DBUG_VOID_RETURN;                           
1486
1875
  data_len = event_len - (common_header_len + post_header_len);
1487
1876
  buf+= common_header_len;
1488
1877
  
1506
1895
      be even bigger, but this will suffice to catch most corruption
1507
1896
      errors that can lead to a crash.
1508
1897
    */
1509
 
    if (status_vars_len > cmin(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
 
1898
    if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
1510
1899
    {
 
1900
      DBUG_PRINT("info", ("status_vars_len (%u) > data_len (%lu); query= 0",
 
1901
                          status_vars_len, data_len));
1511
1902
      query= 0;
1512
 
      return;
 
1903
      DBUG_VOID_RETURN;
1513
1904
    }
1514
1905
    data_len-= status_vars_len;
 
1906
    DBUG_PRINT("info", ("Query_log_event has status_vars_len: %u",
 
1907
                        (uint) status_vars_len));
1515
1908
    tmp-= 2;
1516
1909
  }
1517
1910
  /*
1531
1924
      CHECK_SPACE(pos, end, 4);
1532
1925
      flags2_inited= 1;
1533
1926
      flags2= uint4korr(pos);
 
1927
      DBUG_PRINT("info",("In Query_log_event, read flags2: %lu", (ulong) flags2));
1534
1928
      pos+= 4;
1535
1929
      break;
1536
1930
    case Q_SQL_MODE_CODE:
1537
1931
    {
 
1932
#ifndef DBUG_OFF
 
1933
      char buff[22];
 
1934
#endif
1538
1935
      CHECK_SPACE(pos, end, 8);
1539
1936
      sql_mode_inited= 1;
1540
 
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is uint64_t
 
1937
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is ulonglong
 
1938
      DBUG_PRINT("info",("In Query_log_event, read sql_mode: %s",
 
1939
                         llstr(sql_mode, buff)));
1541
1940
      pos+= 8;
1542
1941
      break;
1543
1942
    }
1544
1943
    case Q_CATALOG_NZ_CODE:
 
1944
      DBUG_PRINT("info", ("case Q_CATALOG_NZ_CODE; pos: 0x%lx; end: 0x%lx",
 
1945
                          (ulong) pos, (ulong) end));
1545
1946
      if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
1546
1947
      {
 
1948
        DBUG_PRINT("info", ("query= 0"));
1547
1949
        query= 0;
1548
 
        return;
 
1950
        DBUG_VOID_RETURN;
1549
1951
      }
1550
1952
      break;
1551
1953
    case Q_AUTO_INCREMENT:
1554
1956
      auto_increment_offset=    uint2korr(pos+2);
1555
1957
      pos+= 4;
1556
1958
      break;
 
1959
    case Q_CHARSET_CODE:
 
1960
    {
 
1961
      CHECK_SPACE(pos, end, 6);
 
1962
      charset_inited= 1;
 
1963
      memcpy(charset, pos, 6);
 
1964
      pos+= 6;
 
1965
      break;
 
1966
    }
1557
1967
    case Q_TIME_ZONE_CODE:
1558
1968
    {
1559
1969
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1560
1970
      {
 
1971
        DBUG_PRINT("info", ("Q_TIME_ZONE_CODE: query= 0"));
1561
1972
        query= 0;
1562
 
        return;
 
1973
        DBUG_VOID_RETURN;
1563
1974
      }
1564
1975
      break;
1565
1976
    }
1583
1994
      break;
1584
1995
    default:
1585
1996
      /* That's why you must write status vars in growing order of code */
1586
 
      pos= (const unsigned char*) end;                         // Break loop
 
1997
      DBUG_PRINT("info",("Query_log_event has unknown status vars (first has\
 
1998
 code: %u), skipping the rest of them", (uint) *(pos-1)));
 
1999
      pos= (const uchar*) end;                         // Break loop
1587
2000
    }
1588
2001
  }
1589
2002
  
1591
2004
                                             time_zone_len + 1 +
1592
2005
                                             data_len + 1,
1593
2006
                                             MYF(MY_WME))))
1594
 
      return;
 
2007
      DBUG_VOID_RETURN;
1595
2008
  if (catalog_len)                                  // If catalog is given
1596
2009
  {
1597
2010
    /**
1619
2032
  */
1620
2033
 
1621
2034
  /* A 2nd variable part; this is common to all versions */ 
1622
 
  memcpy(start, end, data_len);          // Copy db and query
 
2035
  memcpy((char*) start, end, data_len);          // Copy db and query
1623
2036
  start[data_len]= '\0';              // End query with \0 (For safetly)
1624
2037
  db= (char *)start;
1625
2038
  query= (char *)(start + db_len + 1);
1626
2039
  q_len= data_len - db_len -1;
1627
 
  return;
1628
 
}
 
2040
  DBUG_VOID_RETURN;
 
2041
}
 
2042
 
 
2043
 
 
2044
#ifdef MYSQL_CLIENT
 
2045
/**
 
2046
  Query_log_event::print().
 
2047
 
 
2048
  @todo
 
2049
    print the catalog ??
 
2050
*/
 
2051
void Query_log_event::print_query_header(IO_CACHE* file,
 
2052
                                         PRINT_EVENT_INFO* print_event_info)
 
2053
{
 
2054
  // TODO: print the catalog ??
 
2055
  char buff[40],*end;                           // Enough for SET TIMESTAMP
 
2056
  bool different_db= 1;
 
2057
  uint32 tmp;
 
2058
 
 
2059
  if (!print_event_info->short_form)
 
2060
  {
 
2061
    print_header(file, print_event_info, FALSE);
 
2062
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 
2063
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
 
2064
                error_code);
 
2065
  }
 
2066
 
 
2067
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
 
2068
  {
 
2069
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
 
2070
      memcpy(print_event_info->db, db, db_len + 1);
 
2071
    if (db[0] && different_db) 
 
2072
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
 
2073
  }
 
2074
 
 
2075
  end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
 
2076
  end= strmov(end, print_event_info->delimiter);
 
2077
  *end++='\n';
 
2078
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
 
2079
  if ((!print_event_info->thread_id_printed ||
 
2080
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
 
2081
        thread_id != print_event_info->thread_id)))
 
2082
  {
 
2083
    // If --short-form, print deterministic value instead of pseudo_thread_id.
 
2084
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
 
2085
                short_form ? 999999999 : (ulong)thread_id,
 
2086
                print_event_info->delimiter);
 
2087
    print_event_info->thread_id= thread_id;
 
2088
    print_event_info->thread_id_printed= 1;
 
2089
  }
 
2090
 
 
2091
  /*
 
2092
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
 
2093
    print (remember we don't produce mixed relay logs so there cannot be
 
2094
    5.0 events before that one so there is nothing to reset).
 
2095
  */
 
2096
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
 
2097
  {
 
2098
    /* tmp is a bitmask of bits which have changed. */
 
2099
    if (likely(print_event_info->flags2_inited)) 
 
2100
      /* All bits which have changed */
 
2101
      tmp= (print_event_info->flags2) ^ flags2;
 
2102
    else /* that's the first Query event we read */
 
2103
    {
 
2104
      print_event_info->flags2_inited= 1;
 
2105
      tmp= ~((uint32)0); /* all bits have changed */
 
2106
    }
 
2107
 
 
2108
    if (unlikely(tmp)) /* some bits have changed */
 
2109
    {
 
2110
      bool need_comma= 0;
 
2111
      my_b_printf(file, "SET ");
 
2112
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
 
2113
                   "@@session.foreign_key_checks", &need_comma);
 
2114
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
 
2115
                   "@@session.sql_auto_is_null", &need_comma);
 
2116
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
 
2117
                   "@@session.unique_checks", &need_comma);
 
2118
      my_b_printf(file,"%s\n", print_event_info->delimiter);
 
2119
      print_event_info->flags2= flags2;
 
2120
    }
 
2121
  }
 
2122
 
 
2123
  /*
 
2124
    Now the session variables;
 
2125
    it's more efficient to pass SQL_MODE as a number instead of a
 
2126
    comma-separated list.
 
2127
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
 
2128
    variables (they have no global version; they're not listed in
 
2129
    sql_class.h), The tests below work for pure binlogs or pure relay
 
2130
    logs. Won't work for mixed relay logs but we don't create mixed
 
2131
    relay logs (that is, there is no relay log with a format change
 
2132
    except within the 3 first events, which mysqlbinlog handles
 
2133
    gracefully). So this code should always be good.
 
2134
  */
 
2135
 
 
2136
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
 
2137
      print_event_info->auto_increment_offset != auto_increment_offset)
 
2138
  {
 
2139
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
 
2140
                auto_increment_increment,auto_increment_offset,
 
2141
                print_event_info->delimiter);
 
2142
    print_event_info->auto_increment_increment= auto_increment_increment;
 
2143
    print_event_info->auto_increment_offset=    auto_increment_offset;
 
2144
  }
 
2145
 
 
2146
  /* TODO: print the catalog when we feature SET CATALOG */
 
2147
 
 
2148
  if (likely(charset_inited) &&
 
2149
      (unlikely(!print_event_info->charset_inited ||
 
2150
                bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
 
2151
  {
 
2152
    CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
 
2153
    if (cs_info)
 
2154
    {
 
2155
      /* for mysql client */
 
2156
      my_b_printf(file, "/*!\\C %s */%s\n",
 
2157
                  cs_info->csname, print_event_info->delimiter);
 
2158
    }
 
2159
    my_b_printf(file,"SET "
 
2160
                "@@session.character_set_client=%d,"
 
2161
                "@@session.collation_connection=%d,"
 
2162
                "@@session.collation_server=%d"
 
2163
                "%s\n",
 
2164
                uint2korr(charset),
 
2165
                uint2korr(charset+2),
 
2166
                uint2korr(charset+4),
 
2167
                print_event_info->delimiter);
 
2168
    memcpy(print_event_info->charset, charset, 6);
 
2169
    print_event_info->charset_inited= 1;
 
2170
  }
 
2171
  if (time_zone_len)
 
2172
  {
 
2173
    if (bcmp((uchar*) print_event_info->time_zone_str,
 
2174
             (uchar*) time_zone_str, time_zone_len+1))
 
2175
    {
 
2176
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
 
2177
                  time_zone_str, print_event_info->delimiter);
 
2178
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
 
2179
    }
 
2180
  }
 
2181
  if (lc_time_names_number != print_event_info->lc_time_names_number)
 
2182
  {
 
2183
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
 
2184
                lc_time_names_number, print_event_info->delimiter);
 
2185
    print_event_info->lc_time_names_number= lc_time_names_number;
 
2186
  }
 
2187
  if (charset_database_number != print_event_info->charset_database_number)
 
2188
  {
 
2189
    if (charset_database_number)
 
2190
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
 
2191
                  charset_database_number, print_event_info->delimiter);
 
2192
    else
 
2193
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
2194
                  print_event_info->delimiter);
 
2195
    print_event_info->charset_database_number= charset_database_number;
 
2196
  }
 
2197
}
 
2198
 
 
2199
 
 
2200
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2201
{
 
2202
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
2203
 
 
2204
  print_query_header(&cache, print_event_info);
 
2205
  my_b_write(&cache, (uchar*) query, q_len);
 
2206
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
2207
}
 
2208
#endif /* MYSQL_CLIENT */
1629
2209
 
1630
2210
 
1631
2211
/*
1632
2212
  Query_log_event::do_apply_event()
1633
2213
*/
 
2214
 
 
2215
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2216
 
1634
2217
int Query_log_event::do_apply_event(Relay_log_info const *rli)
1635
2218
{
1636
2219
  return do_apply_event(rli, query, q_len);
1642
2225
  Compare the values of "affected rows" around here. Something
1643
2226
  like:
1644
2227
  @code
1645
 
     if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
 
2228
     if ((uint32) affected_in_event != (uint32) affected_on_slave)
1646
2229
     {
1647
2230
     sql_print_error("Slave: did not get the expected number of affected \
1648
2231
     rows running query from master - expected %d, got %d (this numbers \
1655
2238
  to ignore it you would use --slave-skip-errors...
1656
2239
*/
1657
2240
int Query_log_event::do_apply_event(Relay_log_info const *rli,
1658
 
                                      const char *query_arg, uint32_t q_len_arg)
 
2241
                                      const char *query_arg, uint32 q_len_arg)
1659
2242
{
1660
2243
  LEX_STRING new_db;
1661
2244
  int expected_error,actual_error= 0;
1684
2267
    access it.
1685
2268
  */
1686
2269
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
 
2270
  DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
1687
2271
 
1688
2272
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
1689
2273
  const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
1703
2287
    thd->set_time((time_t)when);
1704
2288
    thd->query_length= q_len_arg;
1705
2289
    thd->query= (char*)query_arg;
1706
 
    pthread_mutex_lock(&LOCK_thread_count);
 
2290
    VOID(pthread_mutex_lock(&LOCK_thread_count));
1707
2291
    thd->query_id = next_query_id();
1708
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
2292
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
1709
2293
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
 
2294
    DBUG_PRINT("query",("%s",thd->query));
1710
2295
 
1711
2296
    if (ignored_error_code((expected_error= error_code)) ||
1712
2297
        !check_expected_error(thd,rli,expected_error))
1717
2302
          must take their value from flags2.
1718
2303
        */
1719
2304
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2305
      /*
 
2306
        else, we are in a 3.23/4.0 binlog; we previously received a
 
2307
        Rotate_log_event which reset thd->options and sql_mode etc, so
 
2308
        nothing to do.
 
2309
      */
 
2310
      if (charset_inited)
 
2311
      {
 
2312
        if (rli->cached_charset_compare(charset))
 
2313
        {
 
2314
          /* Verify that we support the charsets found in the event. */
 
2315
          if (!(thd->variables.character_set_client=
 
2316
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
 
2317
              !(thd->variables.collation_connection=
 
2318
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
 
2319
              !(thd->variables.collation_server=
 
2320
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
 
2321
          {
 
2322
            /*
 
2323
              We updated the thd->variables with nonsensical values (0). Let's
 
2324
              set them to something safe (i.e. which avoids crash), and we'll
 
2325
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
 
2326
              ignore this error).
 
2327
            */
 
2328
            set_slave_thread_default_charset(thd, rli);
 
2329
            goto compare_errors;
 
2330
          }
 
2331
          thd->update_charset(); // for the charset change to take effect
 
2332
        }
 
2333
      }
1720
2334
      if (time_zone_len)
1721
2335
      {
1722
2336
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1742
2356
        thd->variables.lc_time_names= &my_locale_en_US;
1743
2357
      if (charset_database_number)
1744
2358
      {
1745
 
        const CHARSET_INFO *cs;
 
2359
        CHARSET_INFO *cs;
1746
2360
        if (!(cs= get_charset(charset_database_number, MYF(0))))
1747
2361
        {
1748
2362
          char buf[20];
1773
2387
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
1774
2388
      else
1775
2389
      {
1776
 
        rli->report(ERROR_LEVEL, expected_error,
1777
 
                    _("Query partially completed on the master "
1778
 
                      "(error on master: %d) and was aborted. There is a "
1779
 
                      "chance that your master is inconsistent at this "
1780
 
                      "point. If you are sure that your master is ok, run "
1781
 
                      "this query manually on the slave and then restart the "
1782
 
                      "slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; "
1783
 
                      "START SLAVE; . Query: '%s'"),
1784
 
                    expected_error, thd->query);
 
2390
        rli->report(ERROR_LEVEL, expected_error, 
 
2391
                          "\
 
2392
Query partially completed on the master (error on master: %d) \
 
2393
and was aborted. There is a chance that your master is inconsistent at this \
 
2394
point. If you are sure that your master is ok, run this query manually on the \
 
2395
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
 
2396
START SLAVE; . Query: '%s'", expected_error, thd->query);
1785
2397
        thd->is_slave_error= 1;
1786
2398
      }
1787
2399
      goto end;
1788
2400
    }
1789
2401
 
 
2402
    /* If the query was not ignored, it is printed to the general log */
 
2403
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
 
2404
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
 
2405
 
1790
2406
compare_errors:
1791
2407
 
1792
2408
     /*
1794
2410
      code, and none of them should be ignored.
1795
2411
    */
1796
2412
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
 
2413
    DBUG_PRINT("info",("expected_error: %d  sql_errno: %d",
 
2414
                       expected_error, actual_error));
1797
2415
    if ((expected_error != actual_error) &&
1798
 
        expected_error &&
1799
 
        !ignored_error_code(actual_error) &&
1800
 
        !ignored_error_code(expected_error))
 
2416
        expected_error &&
 
2417
        !ignored_error_code(actual_error) &&
 
2418
        !ignored_error_code(expected_error))
1801
2419
    {
1802
2420
      rli->report(ERROR_LEVEL, 0,
1803
 
                  _("Query caused differenxt errors on master and slave.\n"
1804
 
                    "Error on master: '%s' (%d), Error on slave: '%s' (%d).\n"
1805
 
                    "Default database: '%s'. Query: '%s'"),
1806
 
                  ER_SAFE(expected_error),
1807
 
                  expected_error,
1808
 
                  actual_error ? thd->main_da.message() : _("no error"),
1809
 
                  actual_error,
1810
 
                  print_slave_db_safe(db), query_arg);
 
2421
                      "\
 
2422
Query caused different errors on master and slave.     \
 
2423
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
 
2424
Default database: '%s'. Query: '%s'",
 
2425
                      ER_SAFE(expected_error),
 
2426
                      expected_error,
 
2427
                      actual_error ? thd->main_da.message() : "no error",
 
2428
                      actual_error,
 
2429
                      print_slave_db_safe(db), query_arg);
1811
2430
      thd->is_slave_error= 1;
1812
2431
    }
1813
2432
    /*
1816
2435
    else if (expected_error == actual_error ||
1817
2436
             ignored_error_code(actual_error))
1818
2437
    {
 
2438
      DBUG_PRINT("info",("error ignored"));
1819
2439
      clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
1820
2440
      thd->killed= THD::NOT_KILLED;
1821
2441
    }
1825
2445
    else if (thd->is_slave_error || thd->is_fatal_error)
1826
2446
    {
1827
2447
      rli->report(ERROR_LEVEL, actual_error,
1828
 
                  _("Error '%s' on query. Default database: '%s'. Query: '%s'"),
1829
 
                  (actual_error ? thd->main_da.message() :
1830
 
                   _("unexpected success or fatal error")),
 
2448
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
 
2449
                      (actual_error ? thd->main_da.message() :
 
2450
                       "unexpected success or fatal error"),
1831
2451
                      print_slave_db_safe(thd->db), query_arg);
1832
2452
      thd->is_slave_error= 1;
1833
2453
    }
1835
2455
    /*
1836
2456
      TODO: compare the values of "affected rows" around here. Something
1837
2457
      like:
1838
 
      if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
 
2458
      if ((uint32) affected_in_event != (uint32) affected_on_slave)
1839
2459
      {
1840
2460
      sql_print_error("Slave: did not get the expected number of affected \
1841
2461
      rows running query from master - expected %d, got %d (this numbers \
1856
2476
  } /* End of if (db_ok(... */
1857
2477
 
1858
2478
end:
1859
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2479
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1860
2480
  /*
1861
2481
    Probably we have set thd->query, thd->db, thd->catalog to point to places
1862
2482
    in the data_buf of this event. Now the event is going to be deleted
1863
2483
    probably, so data_buf will be freed, so the thd->... listed above will be
1864
2484
    pointers to freed memory. 
1865
2485
    So we must set them to 0, so that those bad pointers values are not later
1866
 
    used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
 
2486
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
1867
2487
    don't suffer from these assignments to 0 as DROP TEMPORARY
1868
 
    Table uses the db.table syntax.
 
2488
    TABLE uses the db.table syntax.
1869
2489
  */
1870
2490
  thd->catalog= 0;
1871
2491
  thd->set_db(NULL, 0);                 /* will free the current database */
 
2492
  DBUG_PRINT("info", ("end: query= 0"));
1872
2493
  thd->query= 0;                        // just to be sure
1873
2494
  thd->query_length= 0;
1874
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2495
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1875
2496
  close_thread_tables(thd);      
1876
2497
  /*
1877
2498
    As a disk space optimization, future masters will not log an event for
1907
2528
Log_event::enum_skip_reason
1908
2529
Query_log_event::do_shall_skip(Relay_log_info *rli)
1909
2530
{
1910
 
  assert(query && q_len > 0);
 
2531
  DBUG_ENTER("Query_log_event::do_shall_skip");
 
2532
  DBUG_PRINT("debug", ("query: %s; q_len: %d", query, q_len));
 
2533
  DBUG_ASSERT(query && q_len > 0);
1911
2534
 
1912
2535
  if (rli->slave_skip_counter > 0)
1913
2536
  {
1914
2537
    if (strcmp("BEGIN", query) == 0)
1915
2538
    {
1916
2539
      thd->options|= OPTION_BEGIN;
1917
 
      return(Log_event::continue_group(rli));
 
2540
      DBUG_RETURN(Log_event::continue_group(rli));
1918
2541
    }
1919
2542
 
1920
2543
    if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
1921
2544
    {
1922
2545
      thd->options&= ~OPTION_BEGIN;
1923
 
      return(Log_event::EVENT_SKIP_COUNT);
 
2546
      DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
1924
2547
    }
1925
2548
  }
1926
 
  return(Log_event::do_shall_skip(rli));
 
2549
  DBUG_RETURN(Log_event::do_shall_skip(rli));
1927
2550
}
1928
2551
 
 
2552
#endif
 
2553
 
1929
2554
 
1930
2555
/**************************************************************************
1931
2556
        Start_log_event_v3 methods
1932
2557
**************************************************************************/
1933
2558
 
 
2559
#ifndef MYSQL_CLIENT
1934
2560
Start_log_event_v3::Start_log_event_v3()
1935
2561
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
1936
2562
   artificial_event(0), dont_set_created(0)
1937
2563
{
1938
2564
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
1939
2565
}
 
2566
#endif
1940
2567
 
1941
2568
/*
1942
2569
  Start_log_event_v3::pack_info()
1943
2570
*/
1944
2571
 
 
2572
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1945
2573
void Start_log_event_v3::pack_info(Protocol *protocol)
1946
2574
{
1947
2575
  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
1948
 
  pos= my_stpcpy(buf, "Server ver: ");
1949
 
  pos= my_stpcpy(pos, server_version);
1950
 
  pos= my_stpcpy(pos, ", Binlog ver: ");
 
2576
  pos= strmov(buf, "Server ver: ");
 
2577
  pos= strmov(pos, server_version);
 
2578
  pos= strmov(pos, ", Binlog ver: ");
1951
2579
  pos= int10_to_str(binlog_version, pos, 10);
1952
2580
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
1953
2581
}
1954
 
 
 
2582
#endif
 
2583
 
 
2584
 
 
2585
/*
 
2586
  Start_log_event_v3::print()
 
2587
*/
 
2588
 
 
2589
#ifdef MYSQL_CLIENT
 
2590
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2591
{
 
2592
  DBUG_ENTER("Start_log_event_v3::print");
 
2593
 
 
2594
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
2595
                               Write_on_release_cache::FLUSH_F);
 
2596
 
 
2597
  if (!print_event_info->short_form)
 
2598
  {
 
2599
    print_header(&cache, print_event_info, FALSE);
 
2600
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
 
2601
                binlog_version, server_version);
 
2602
    print_timestamp(&cache);
 
2603
    if (created)
 
2604
      my_b_printf(&cache," at startup");
 
2605
    my_b_printf(&cache, "\n");
 
2606
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
 
2607
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
 
2608
                  "Most probably mysqld crashed writing it.\n");
 
2609
  }
 
2610
  if (!artificial_event && created)
 
2611
  {
 
2612
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
 
2613
    /*
 
2614
      This is for mysqlbinlog: like in replication, we want to delete the stale
 
2615
      tmp files left by an unclean shutdown of mysqld (temporary tables)
 
2616
      and rollback unfinished transaction.
 
2617
      Probably this can be done with RESET CONNECTION (syntax to be defined).
 
2618
    */
 
2619
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
 
2620
#else
 
2621
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
 
2622
#endif
 
2623
  }
 
2624
  if (temp_buf &&
 
2625
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
 
2626
      !print_event_info->short_form)
 
2627
  {
 
2628
    my_b_printf(&cache, "BINLOG '\n");
 
2629
    print_base64(&cache, print_event_info, FALSE);
 
2630
    print_event_info->printed_fd_event= TRUE;
 
2631
  }
 
2632
  DBUG_VOID_RETURN;
 
2633
}
 
2634
#endif /* MYSQL_CLIENT */
1955
2635
 
1956
2636
/*
1957
2637
  Start_log_event_v3::Start_log_event_v3()
1979
2659
  Start_log_event_v3::write()
1980
2660
*/
1981
2661
 
 
2662
#ifndef MYSQL_CLIENT
1982
2663
bool Start_log_event_v3::write(IO_CACHE* file)
1983
2664
{
1984
2665
  char buff[START_V3_HEADER_LEN];
1988
2669
    created= when= get_time();
1989
2670
  int4store(buff + ST_CREATED_OFFSET,created);
1990
2671
  return (write_header(file, sizeof(buff)) ||
1991
 
          my_b_safe_write(file, (unsigned char*) buff, sizeof(buff)));
 
2672
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
1992
2673
}
1993
 
 
 
2674
#endif
 
2675
 
 
2676
 
 
2677
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1994
2678
 
1995
2679
/**
1996
2680
  Start_log_event_v3::do_apply_event() .
1998
2682
 
1999
2683
    IMPLEMENTATION
2000
2684
    - To handle the case where the master died without having time to write
2001
 
    DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
 
2685
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
2002
2686
    TODO), we clean up all temporary tables that we got, if we are sure we
2003
2687
    can (see below).
2004
2688
 
2012
2696
 
2013
2697
int Start_log_event_v3::do_apply_event(Relay_log_info const *rli)
2014
2698
{
 
2699
  DBUG_ENTER("Start_log_event_v3::do_apply_event");
2015
2700
  switch (binlog_version)
2016
2701
  {
2017
2702
  case 3:
2051
2736
    break;
2052
2737
  default:
2053
2738
    /* this case is impossible */
2054
 
    return(1);
 
2739
    DBUG_RETURN(1);
2055
2740
  }
2056
 
  return(0);
 
2741
  DBUG_RETURN(0);
2057
2742
}
 
2743
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
2058
2744
 
2059
2745
/***************************************************************************
2060
2746
       Format_description_log_event methods
2077
2763
*/
2078
2764
 
2079
2765
Format_description_log_event::
2080
 
Format_description_log_event(uint8_t binlog_ver, const char* server_ver)
 
2766
Format_description_log_event(uint8 binlog_ver, const char* server_ver)
2081
2767
  :Start_log_event_v3(), event_type_permutation(0)
2082
2768
{
2083
2769
  binlog_version= binlog_ver;
2084
2770
  switch (binlog_ver) {
2085
2771
  case 4: /* MySQL 5.0 */
2086
2772
    memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
 
2773
    DBUG_EXECUTE_IF("pretend_version_50034_in_binlog",
 
2774
                    strmov(server_version, "5.0.34"););
2087
2775
    common_header_len= LOG_EVENT_HEADER_LEN;
2088
2776
    number_of_event_types= LOG_EVENT_TYPES;
2089
2777
    /* we'll catch my_malloc() error in is_valid() */
2090
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
 
2778
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2091
2779
                                       MYF(MY_ZEROFILL));
2092
2780
    /*
2093
2781
      This long list of assignments is not beautiful, but I see no way to
2110
2798
      post_header_len[WRITE_ROWS_EVENT-1]=   ROWS_HEADER_LEN;
2111
2799
      post_header_len[UPDATE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
2112
2800
      post_header_len[DELETE_ROWS_EVENT-1]=  ROWS_HEADER_LEN;
 
2801
      /*
 
2802
        We here have the possibility to simulate a master of before we changed
 
2803
        the table map id to be stored in 6 bytes: when it was stored in 4
 
2804
        bytes (=> post_header_len was 6). This is used to test backward
 
2805
        compatibility.
 
2806
        This code can be removed after a few months (today is Dec 21st 2005),
 
2807
        when we know that the 4-byte masters are not deployed anymore (check
 
2808
        with Tomas Ulin first!), and the accompanying test (rpl_row_4_bytes)
 
2809
        too.
 
2810
      */
 
2811
      DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
2812
                      post_header_len[TABLE_MAP_EVENT-1]=
 
2813
                      post_header_len[WRITE_ROWS_EVENT-1]=
 
2814
                      post_header_len[UPDATE_ROWS_EVENT-1]=
 
2815
                      post_header_len[DELETE_ROWS_EVENT-1]= 6;);
2113
2816
      post_header_len[BEGIN_LOAD_QUERY_EVENT-1]= post_header_len[APPEND_BLOCK_EVENT-1];
2114
2817
      post_header_len[EXECUTE_LOAD_QUERY_EVENT-1]= EXECUTE_LOAD_QUERY_HEADER_LEN;
2115
2818
      post_header_len[INCIDENT_EVENT-1]= INCIDENT_HEADER_LEN;
2124
2827
      describes what those old master versions send.
2125
2828
    */
2126
2829
    if (binlog_ver==1)
2127
 
      my_stpcpy(server_version, server_ver ? server_ver : "3.23");
 
2830
      strmov(server_version, server_ver ? server_ver : "3.23");
2128
2831
    else
2129
 
      my_stpcpy(server_version, server_ver ? server_ver : "4.0");
 
2832
      strmov(server_version, server_ver ? server_ver : "4.0");
2130
2833
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2131
2834
      LOG_EVENT_MINIMAL_HEADER_LEN;
2132
2835
    /*
2137
2840
      make the slave detect less corruptions).
2138
2841
    */
2139
2842
    number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
2140
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
 
2843
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2141
2844
                                       MYF(0));
2142
2845
    if (post_header_len)
2143
2846
    {
2185
2888
 
2186
2889
Format_description_log_event::
2187
2890
Format_description_log_event(const char* buf,
2188
 
                             uint32_t event_len,
 
2891
                             uint event_len,
2189
2892
                             const
2190
2893
                             Format_description_log_event*
2191
2894
                             description_event)
2192
2895
  :Start_log_event_v3(buf, description_event), event_type_permutation(0)
2193
2896
{
 
2897
  DBUG_ENTER("Format_description_log_event::Format_description_log_event(char*,...)");
2194
2898
  buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
2195
2899
  if ((common_header_len=buf[ST_COMMON_HEADER_LEN_OFFSET]) < OLD_HEADER_LEN)
2196
 
    return; /* sanity check */
 
2900
    DBUG_VOID_RETURN; /* sanity check */
2197
2901
  number_of_event_types=
2198
2902
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
 
2903
  DBUG_PRINT("info", ("common_header_len=%d number_of_event_types=%d",
 
2904
                      common_header_len, number_of_event_types));
2199
2905
  /* If alloc fails, we'll detect it in is_valid() */
2200
 
  post_header_len= (uint8_t*) my_memdup((unsigned char*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
 
2906
  post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2201
2907
                                      number_of_event_types*
2202
2908
                                      sizeof(*post_header_len), MYF(0));
2203
2909
  calc_server_version_split();
2271
2977
  {
2272
2978
    if (number_of_event_types != 22)
2273
2979
    {
 
2980
      DBUG_PRINT("info", (" number_of_event_types=%d",
 
2981
                          number_of_event_types));
2274
2982
      /* this makes is_valid() return false. */
2275
 
      free(post_header_len);
 
2983
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2276
2984
      post_header_len= NULL;
2277
 
      return;
 
2985
      DBUG_VOID_RETURN;
2278
2986
    }
2279
 
    static const uint8_t perm[23]=
 
2987
    static const uint8 perm[23]=
2280
2988
      {
2281
2989
        UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
2282
2990
        INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
2297
3005
      Since we use (permuted) event id's to index the post_header_len
2298
3006
      array, we need to permute the post_header_len array too.
2299
3007
    */
2300
 
    uint8_t post_header_len_temp[23];
 
3008
    uint8 post_header_len_temp[23];
2301
3009
    for (int i= 1; i < 23; i++)
2302
3010
      post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
2303
3011
    for (int i= 0; i < 22; i++)
2304
3012
      post_header_len[i] = post_header_len_temp[i];
2305
3013
  }
2306
 
  return;
 
3014
  DBUG_VOID_RETURN;
2307
3015
}
2308
3016
 
 
3017
#ifndef MYSQL_CLIENT
2309
3018
bool Format_description_log_event::write(IO_CACHE* file)
2310
3019
{
2311
3020
  /*
2312
3021
    We don't call Start_log_event_v3::write() because this would make 2
2313
3022
    my_b_safe_write().
2314
3023
  */
2315
 
  unsigned char buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
3024
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
2316
3025
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2317
 
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
 
3026
  memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2318
3027
  if (!dont_set_created)
2319
3028
    created= when= get_time();
2320
3029
  int4store(buff + ST_CREATED_OFFSET,created);
2321
3030
  buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
2322
 
  memcpy(buff+ST_COMMON_HEADER_LEN_OFFSET+1, post_header_len,
 
3031
  memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
2323
3032
         LOG_EVENT_TYPES);
2324
3033
  return (write_header(file, sizeof(buff)) ||
2325
3034
          my_b_safe_write(file, buff, sizeof(buff)));
2326
3035
}
2327
 
 
2328
 
 
 
3036
#endif
 
3037
 
 
3038
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2329
3039
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2330
3040
{
 
3041
  DBUG_ENTER("Format_description_log_event::do_apply_event");
 
3042
 
2331
3043
  /*
2332
3044
    As a transaction NEVER spans on 2 or more binlogs:
2333
3045
    if we have an active transaction at this point, the master died
2343
3055
  {
2344
3056
    /* This is not an error (XA is safe), just an information */
2345
3057
    rli->report(INFORMATION_LEVEL, 0,
2346
 
                _("Rolling back unfinished transaction (no COMMIT "
2347
 
                  "or ROLLBACK in relay log). A probable cause is that "
2348
 
                  "the master died while writing the transaction to "
2349
 
                  "its binary log, thus rolled back too."));
 
3058
                "Rolling back unfinished transaction (no COMMIT "
 
3059
                "or ROLLBACK in relay log). A probable cause is that "
 
3060
                "the master died while writing the transaction to "
 
3061
                "its binary log, thus rolled back too."); 
2350
3062
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2351
3063
  }
2352
3064
  /*
2354
3066
    perform, we don't call Start_log_event_v3::do_apply_event()
2355
3067
    (this was just to update the log's description event).
2356
3068
  */
2357
 
  if (server_id != (uint32_t) ::server_id)
 
3069
  if (server_id != (uint32) ::server_id)
2358
3070
  {
2359
3071
    /*
2360
3072
      If the event was not requested by the slave i.e. the master sent
2365
3077
      0, then 96, then jump to first really asked event (which is
2366
3078
      >96). So this is ok.
2367
3079
    */
2368
 
    return(Start_log_event_v3::do_apply_event(rli));
 
3080
    DBUG_RETURN(Start_log_event_v3::do_apply_event(rli));
2369
3081
  }
2370
 
  return(0);
 
3082
  DBUG_RETURN(0);
2371
3083
}
2372
3084
 
2373
3085
int Format_description_log_event::do_update_pos(Relay_log_info *rli)
2376
3088
  delete rli->relay_log.description_event_for_exec;
2377
3089
  rli->relay_log.description_event_for_exec= this;
2378
3090
 
2379
 
  if (server_id == (uint32_t) ::server_id)
 
3091
  if (server_id == (uint32) ::server_id)
2380
3092
  {
2381
3093
    /*
2382
3094
      We only increase the relay log position if we are skipping
2401
3113
}
2402
3114
 
2403
3115
Log_event::enum_skip_reason
2404
 
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((unused)))
 
3116
Format_description_log_event::do_shall_skip(Relay_log_info *rli)
2405
3117
{
2406
3118
  return Log_event::EVENT_SKIP_NOT;
2407
3119
}
2408
3120
 
 
3121
#endif
 
3122
 
2409
3123
 
2410
3124
/**
2411
3125
   Splits the event's 'server_version' string into three numeric pieces stored
2420
3134
{
2421
3135
  char *p= server_version, *r;
2422
3136
  ulong number;
2423
 
  for (uint32_t i= 0; i<=2; i++)
 
3137
  for (uint i= 0; i<=2; i++)
2424
3138
  {
2425
3139
    number= strtoul(p, &r, 10);
2426
 
    server_version_split[i]= (unsigned char)number;
2427
 
    assert(number < 256); // fit in unsigned char
 
3140
    server_version_split[i]= (uchar)number;
 
3141
    DBUG_ASSERT(number < 256); // fit in uchar
2428
3142
    p= r;
2429
 
    assert(!((i == 0) && (*r != '.'))); // should be true in practice
 
3143
    DBUG_ASSERT(!((i == 0) && (*r != '.'))); // should be true in practice
2430
3144
    if (*r == '.')
2431
3145
      p++; // skip the dot
2432
3146
  }
 
3147
  DBUG_PRINT("info",("Format_description_log_event::server_version_split:"
 
3148
                     " '%s' %d %d %d", server_version,
 
3149
                     server_version_split[0],
 
3150
                     server_version_split[1], server_version_split[2]));
2433
3151
}
2434
3152
 
2435
3153
 
2454
3172
  Load_log_event::pack_info()
2455
3173
*/
2456
3174
 
2457
 
uint32_t Load_log_event::get_query_buffer_length()
 
3175
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3176
uint Load_log_event::get_query_buffer_length()
2458
3177
{
2459
3178
  return
2460
3179
    5 + db_len + 3 +                        // "use DB; "
2461
3180
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
2462
3181
    7 +                                     // LOCAL
2463
3182
    9 +                                     // " REPLACE or IGNORE "
2464
 
    13 + table_name_len*2 +                 // "INTO Table `table`"
 
3183
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
2465
3184
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
2466
3185
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
2467
3186
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
2479
3198
 
2480
3199
  if (need_db && db && db_len)
2481
3200
  {
2482
 
    pos= my_stpcpy(pos, "use `");
 
3201
    pos= strmov(pos, "use `");
2483
3202
    memcpy(pos, db, db_len);
2484
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
3203
    pos= strmov(pos+db_len, "`; ");
2485
3204
  }
2486
3205
 
2487
 
  pos= my_stpcpy(pos, "LOAD DATA ");
 
3206
  pos= strmov(pos, "LOAD DATA ");
2488
3207
 
2489
3208
  if (fn_start)
2490
3209
    *fn_start= pos;
2491
3210
 
2492
3211
  if (check_fname_outside_temp_buf())
2493
 
    pos= my_stpcpy(pos, "LOCAL ");
2494
 
  pos= my_stpcpy(pos, "INFILE '");
 
3212
    pos= strmov(pos, "LOCAL ");
 
3213
  pos= strmov(pos, "INFILE '");
2495
3214
  memcpy(pos, fname, fname_len);
2496
 
  pos= my_stpcpy(pos+fname_len, "' ");
 
3215
  pos= strmov(pos+fname_len, "' ");
2497
3216
 
2498
3217
  if (sql_ex.opt_flags & REPLACE_FLAG)
2499
 
    pos= my_stpcpy(pos, " REPLACE ");
 
3218
    pos= strmov(pos, " REPLACE ");
2500
3219
  else if (sql_ex.opt_flags & IGNORE_FLAG)
2501
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3220
    pos= strmov(pos, " IGNORE ");
2502
3221
 
2503
 
  pos= my_stpcpy(pos ,"INTO");
 
3222
  pos= strmov(pos ,"INTO");
2504
3223
 
2505
3224
  if (fn_end)
2506
3225
    *fn_end= pos;
2507
3226
 
2508
 
  pos= my_stpcpy(pos ," Table `");
 
3227
  pos= strmov(pos ," TABLE `");
2509
3228
  memcpy(pos, table_name, table_name_len);
2510
3229
  pos+= table_name_len;
2511
3230
 
2512
3231
  /* We have to create all optinal fields as the default is not empty */
2513
 
  pos= my_stpcpy(pos, "` FIELDS TERMINATED BY ");
 
3232
  pos= strmov(pos, "` FIELDS TERMINATED BY ");
2514
3233
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
2515
3234
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
2516
 
    pos= my_stpcpy(pos, " OPTIONALLY ");
2517
 
  pos= my_stpcpy(pos, " ENCLOSED BY ");
 
3235
    pos= strmov(pos, " OPTIONALLY ");
 
3236
  pos= strmov(pos, " ENCLOSED BY ");
2518
3237
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
2519
3238
 
2520
 
  pos= my_stpcpy(pos, " ESCAPED BY ");
 
3239
  pos= strmov(pos, " ESCAPED BY ");
2521
3240
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
2522
3241
 
2523
 
  pos= my_stpcpy(pos, " LINES TERMINATED BY ");
 
3242
  pos= strmov(pos, " LINES TERMINATED BY ");
2524
3243
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
2525
3244
  if (sql_ex.line_start_len)
2526
3245
  {
2527
 
    pos= my_stpcpy(pos, " STARTING BY ");
 
3246
    pos= strmov(pos, " STARTING BY ");
2528
3247
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
2529
3248
  }
2530
3249
 
2531
3250
  if ((long) skip_lines > 0)
2532
3251
  {
2533
 
    pos= my_stpcpy(pos, " IGNORE ");
2534
 
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2535
 
    pos= my_stpcpy(pos," LINES ");    
 
3252
    pos= strmov(pos, " IGNORE ");
 
3253
    pos= longlong10_to_str((longlong) skip_lines, pos, 10);
 
3254
    pos= strmov(pos," LINES ");    
2536
3255
  }
2537
3256
 
2538
3257
  if (num_fields)
2539
3258
  {
2540
 
    uint32_t i;
 
3259
    uint i;
2541
3260
    const char *field= fields;
2542
 
    pos= my_stpcpy(pos, " (");
 
3261
    pos= strmov(pos, " (");
2543
3262
    for (i = 0; i < num_fields; i++)
2544
3263
    {
2545
3264
      if (i)
2564
3283
 
2565
3284
  if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
2566
3285
    return;
2567
 
  print_query(true, buf, &end, 0, 0);
 
3286
  print_query(TRUE, buf, &end, 0, 0);
2568
3287
  protocol->store(buf, end-buf, &my_charset_bin);
2569
 
  free(buf);
 
3288
  my_free(buf, MYF(0));
2570
3289
}
2571
 
 
 
3290
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
3291
 
 
3292
 
 
3293
#ifndef MYSQL_CLIENT
2572
3294
 
2573
3295
/*
2574
3296
  Load_log_event::write_data_header()
2583
3305
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
2584
3306
  buf[L_DB_LEN_OFFSET] = (char)db_len;
2585
3307
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
2586
 
  return my_b_safe_write(file, (unsigned char*)buf, LOAD_HEADER_LEN) != 0;
 
3308
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
2587
3309
}
2588
3310
 
2589
3311
 
2597
3319
    return 1;
2598
3320
  if (num_fields && fields && field_lens)
2599
3321
  {
2600
 
    if (my_b_safe_write(file, (unsigned char*)field_lens, num_fields) ||
2601
 
        my_b_safe_write(file, (unsigned char*)fields, field_block_len))
 
3322
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
 
3323
        my_b_safe_write(file, (uchar*)fields, field_block_len))
2602
3324
      return 1;
2603
3325
  }
2604
 
  return (my_b_safe_write(file, (unsigned char*)table_name, table_name_len + 1) ||
2605
 
          my_b_safe_write(file, (unsigned char*)db, db_len + 1) ||
2606
 
          my_b_safe_write(file, (unsigned char*)fname, fname_len));
 
3326
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
 
3327
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
 
3328
          my_b_safe_write(file, (uchar*)fname, fname_len));
2607
3329
}
2608
3330
 
2609
3331
 
2624
3346
   num_fields(0),fields(0),
2625
3347
   field_lens(0),field_block_len(0),
2626
3348
   table_name(table_name_arg ? table_name_arg : ""),
2627
 
   db(db_arg), fname(ex->file_name), local_fname(false)
 
3349
   db(db_arg), fname(ex->file_name), local_fname(FALSE)
2628
3350
{
2629
3351
  time_t end_time;
2630
3352
  time(&end_time);
2631
3353
  exec_time = (ulong) (end_time  - thd_arg->start_time);
2632
3354
  /* db can never be a zero pointer in 4.0 */
2633
 
  db_len = (uint32_t) strlen(db);
2634
 
  table_name_len = (uint32_t) strlen(table_name);
 
3355
  db_len = (uint32) strlen(db);
 
3356
  table_name_len = (uint32) strlen(table_name);
2635
3357
  fname_len = (fname) ? (uint) strlen(fname) : 0;
2636
3358
  sql_ex.field_term = (char*) ex->field_term->ptr();
2637
 
  sql_ex.field_term_len = (uint8_t) ex->field_term->length();
 
3359
  sql_ex.field_term_len = (uint8) ex->field_term->length();
2638
3360
  sql_ex.enclosed = (char*) ex->enclosed->ptr();
2639
 
  sql_ex.enclosed_len = (uint8_t) ex->enclosed->length();
 
3361
  sql_ex.enclosed_len = (uint8) ex->enclosed->length();
2640
3362
  sql_ex.line_term = (char*) ex->line_term->ptr();
2641
 
  sql_ex.line_term_len = (uint8_t) ex->line_term->length();
 
3363
  sql_ex.line_term_len = (uint8) ex->line_term->length();
2642
3364
  sql_ex.line_start = (char*) ex->line_start->ptr();
2643
 
  sql_ex.line_start_len = (uint8_t) ex->line_start->length();
 
3365
  sql_ex.line_start_len = (uint8) ex->line_start->length();
2644
3366
  sql_ex.escaped = (char*) ex->escaped->ptr();
2645
 
  sql_ex.escaped_len = (uint8_t) ex->escaped->length();
 
3367
  sql_ex.escaped_len = (uint8) ex->escaped->length();
2646
3368
  sql_ex.opt_flags = 0;
2647
3369
  sql_ex.cached_new_format = -1;
2648
3370
    
2684
3406
  while ((item = li++))
2685
3407
  {
2686
3408
    num_fields++;
2687
 
    unsigned char len = (unsigned char) strlen(item->name);
 
3409
    uchar len = (uchar) strlen(item->name);
2688
3410
    field_block_len += len + 1;
2689
3411
    fields_buf.append(item->name, len + 1);
2690
3412
    field_lens_buf.append((char*)&len, 1);
2691
3413
  }
2692
3414
 
2693
 
  field_lens = (const unsigned char*)field_lens_buf.ptr();
 
3415
  field_lens = (const uchar*)field_lens_buf.ptr();
2694
3416
  fields = fields_buf.ptr();
2695
3417
}
 
3418
#endif /* !MYSQL_CLIENT */
2696
3419
 
2697
3420
 
2698
3421
/**
2700
3423
    The caller must do buf[event_len] = 0 before he starts using the
2701
3424
    constructed event.
2702
3425
*/
2703
 
Load_log_event::Load_log_event(const char *buf, uint32_t event_len,
 
3426
Load_log_event::Load_log_event(const char *buf, uint event_len,
2704
3427
                               const Format_description_log_event *description_event)
2705
3428
  :Log_event(buf, description_event), num_fields(0), fields(0),
2706
3429
   field_lens(0),field_block_len(0),
2707
 
   table_name(0), db(0), fname(0), local_fname(false)
 
3430
   table_name(0), db(0), fname(0), local_fname(FALSE)
2708
3431
{
 
3432
  DBUG_ENTER("Load_log_event");
2709
3433
  /*
2710
3434
    I (Guilhem) manually tested replication of LOAD DATA INFILE for 3.23->5.0,
2711
3435
    4.0->5.0 and 5.0->5.0 and it works.
2718
3442
                    LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
2719
3443
                   description_event);
2720
3444
  /* otherwise it's a derived class, will call copy_log_event() itself */
2721
 
  return;
 
3445
  DBUG_VOID_RETURN;
2722
3446
}
2723
3447
 
2724
3448
 
2730
3454
                                   int body_offset,
2731
3455
                                   const Format_description_log_event *description_event)
2732
3456
{
2733
 
  uint32_t data_len;
 
3457
  DBUG_ENTER("Load_log_event::copy_log_event");
 
3458
  uint data_len;
2734
3459
  char* buf_end = (char*)buf + event_len;
2735
3460
  /* this is the beginning of the post-header */
2736
3461
  const char* data_head = buf + description_event->common_header_len;
2742
3467
  num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
2743
3468
          
2744
3469
  if ((int) event_len < body_offset)
2745
 
    return(1);
 
3470
    DBUG_RETURN(1);
2746
3471
  /*
2747
3472
    Sql_ex.init() on success returns the pointer to the first byte after
2748
3473
    the sql_ex structure, which is the start of field lengths array.
2749
3474
  */
2750
 
  if (!(field_lens= (unsigned char*)sql_ex.init((char*)buf + body_offset,
 
3475
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
2751
3476
                                        buf_end,
2752
3477
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
2753
 
    return(1);
 
3478
    DBUG_RETURN(1);
2754
3479
  
2755
3480
  data_len = event_len - body_offset;
2756
3481
  if (num_fields > data_len) // simple sanity check against corruption
2757
 
    return(1);
2758
 
  for (uint32_t i = 0; i < num_fields; i++)
 
3482
    DBUG_RETURN(1);
 
3483
  for (uint i = 0; i < num_fields; i++)
2759
3484
    field_block_len += (uint)field_lens[i] + 1;
2760
3485
 
2761
3486
  fields = (char*)field_lens + num_fields;
2765
3490
  fname_len = strlen(fname);
2766
3491
  // null termination is accomplished by the caller doing buf[event_len]=0
2767
3492
 
2768
 
  return(0);
2769
 
}
2770
 
 
 
3493
  DBUG_RETURN(0);
 
3494
}
 
3495
 
 
3496
 
 
3497
/*
 
3498
  Load_log_event::print()
 
3499
*/
 
3500
 
 
3501
#ifdef MYSQL_CLIENT
 
3502
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3503
{
 
3504
  print(file, print_event_info, 0);
 
3505
}
 
3506
 
 
3507
 
 
3508
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 
3509
                           bool commented)
 
3510
{
 
3511
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
3512
 
 
3513
  DBUG_ENTER("Load_log_event::print");
 
3514
  if (!print_event_info->short_form)
 
3515
  {
 
3516
    print_header(&cache, print_event_info, FALSE);
 
3517
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 
3518
                thread_id, exec_time);
 
3519
  }
 
3520
 
 
3521
  bool different_db= 1;
 
3522
  if (db)
 
3523
  {
 
3524
    /*
 
3525
      If the database is different from the one of the previous statement, we
 
3526
      need to print the "use" command, and we update the last_db.
 
3527
      But if commented, the "use" is going to be commented so we should not
 
3528
      update the last_db.
 
3529
    */
 
3530
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
 
3531
        !commented)
 
3532
      memcpy(print_event_info->db, db, db_len + 1);
 
3533
  }
 
3534
  
 
3535
  if (db && db[0] && different_db)
 
3536
    my_b_printf(&cache, "%suse %s%s\n", 
 
3537
            commented ? "# " : "",
 
3538
            db, print_event_info->delimiter);
 
3539
 
 
3540
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
 
3541
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
 
3542
            commented ? "# " : "", (ulong)thread_id,
 
3543
            print_event_info->delimiter);
 
3544
  my_b_printf(&cache, "%sLOAD DATA ",
 
3545
              commented ? "# " : "");
 
3546
  if (check_fname_outside_temp_buf())
 
3547
    my_b_printf(&cache, "LOCAL ");
 
3548
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
 
3549
 
 
3550
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3551
    my_b_printf(&cache," REPLACE ");
 
3552
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3553
    my_b_printf(&cache," IGNORE ");
 
3554
  
 
3555
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
 
3556
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
 
3557
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
 
3558
 
 
3559
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3560
    my_b_printf(&cache," OPTIONALLY ");
 
3561
  my_b_printf(&cache, " ENCLOSED BY ");
 
3562
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
 
3563
     
 
3564
  my_b_printf(&cache, " ESCAPED BY ");
 
3565
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
 
3566
     
 
3567
  my_b_printf(&cache," LINES TERMINATED BY ");
 
3568
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
 
3569
 
 
3570
 
 
3571
  if (sql_ex.line_start)
 
3572
  {
 
3573
    my_b_printf(&cache," STARTING BY ");
 
3574
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
 
3575
  }
 
3576
  if ((long) skip_lines > 0)
 
3577
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
 
3578
 
 
3579
  if (num_fields)
 
3580
  {
 
3581
    uint i;
 
3582
    const char* field = fields;
 
3583
    my_b_printf(&cache, " (");
 
3584
    for (i = 0; i < num_fields; i++)
 
3585
    {
 
3586
      if (i)
 
3587
        my_b_printf(&cache, ",");
 
3588
      my_b_printf(&cache, field);
 
3589
          
 
3590
      field += field_lens[i]  + 1;
 
3591
    }
 
3592
    my_b_printf(&cache, ")");
 
3593
  }
 
3594
 
 
3595
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
 
3596
  DBUG_VOID_RETURN;
 
3597
}
 
3598
#endif /* MYSQL_CLIENT */
 
3599
 
 
3600
#ifndef MYSQL_CLIENT
2771
3601
 
2772
3602
/**
2773
3603
  Load_log_event::set_fields()
2783
3613
                                List<Item> &field_list,
2784
3614
                                Name_resolution_context *context)
2785
3615
{
2786
 
  uint32_t i;
 
3616
  uint i;
2787
3617
  const char* field = fields;
2788
3618
  for (i= 0; i < num_fields; i++)
2789
3619
  {
2792
3622
    field+= field_lens[i]  + 1;
2793
3623
  }
2794
3624
}
2795
 
 
2796
 
 
 
3625
#endif /* !MYSQL_CLIENT */
 
3626
 
 
3627
 
 
3628
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2797
3629
/**
2798
3630
  Does the data loading job when executing a LOAD DATA on the slave.
2799
3631
 
2830
3662
  new_db.length= db_len;
2831
3663
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2832
3664
  thd->set_db(new_db.str, new_db.length);
2833
 
  assert(thd->query == 0);
 
3665
  DBUG_ASSERT(thd->query == 0);
2834
3666
  thd->query_length= 0;                         // Should not be needed
2835
3667
  thd->is_slave_error= 0;
2836
3668
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2837
3669
 
2838
3670
  /* see Query_log_event::do_apply_event() and BUG#13360 */
2839
 
  assert(!rli->m_table_map.count());
 
3671
  DBUG_ASSERT(!rli->m_table_map.count());
2840
3672
  /*
2841
3673
    Usually lex_start() is called by mysql_parse(), but we need it here
2842
3674
    as the present method does not call mysql_parse().
2851
3683
      Query_log_event::do_apply_event()
2852
3684
    */
2853
3685
    const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
 
3686
    DBUG_PRINT("info", ("log_pos: %lu", (ulong) log_pos));
2854
3687
  }
2855
3688
 
2856
3689
   /*
2879
3712
  if (rpl_filter->db_ok(thd->db))
2880
3713
  {
2881
3714
    thd->set_time((time_t)when);
2882
 
    pthread_mutex_lock(&LOCK_thread_count);
 
3715
    VOID(pthread_mutex_lock(&LOCK_thread_count));
2883
3716
    thd->query_id = next_query_id();
2884
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
3717
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
2885
3718
    /*
2886
3719
      Initing thd->row_count is not necessary in theory as this variable has no
2887
3720
      influence in the case of the slave SQL thread (it is used to generate a
2888
3721
      "data truncated" warning but which is absorbed and never gets to the
2889
3722
      error log); still we init it to avoid a Valgrind message.
2890
3723
    */
2891
 
    drizzle_reset_errors(thd, 0);
 
3724
    mysql_reset_errors(thd, 0);
2892
3725
 
2893
 
    TableList tables;
2894
 
    memset(&tables, 0, sizeof(tables));
 
3726
    TABLE_LIST tables;
 
3727
    bzero((char*) &tables,sizeof(tables));
2895
3728
    tables.db= thd->strmake(thd->db, thd->db_length);
2896
3729
    tables.alias = tables.table_name = (char*) table_name;
2897
3730
    tables.lock_type = TL_WRITE;
2925
3758
        goto error;
2926
3759
      }
2927
3760
 
2928
 
      print_query(false, load_data_query, &end, (char **)&thd->lex->fname_start,
 
3761
      print_query(FALSE, load_data_query, &end, (char **)&thd->lex->fname_start,
2929
3762
                  (char **)&thd->lex->fname_end);
2930
3763
      *end= 0;
2931
3764
      thd->query_length= end - load_data_query;
3009
3842
      if (thd->cuted_fields)
3010
3843
      {
3011
3844
        /* log_pos is the position of the LOAD event in the master log */
3012
 
        sql_print_warning(_("Slave: load data infile on table '%s' at "
 
3845
        sql_print_warning("Slave: load data infile on table '%s' at "
3013
3846
                          "log position %s in log '%s' produced %ld "
3014
 
                          "warning(s). Default database: '%s'"),
 
3847
                          "warning(s). Default database: '%s'",
3015
3848
                          (char*) table_name,
3016
3849
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
3017
3850
                          (ulong) thd->cuted_fields,
3035
3868
error:
3036
3869
  thd->net.vio = 0; 
3037
3870
  const char *remember_db= thd->db;
3038
 
  pthread_mutex_lock(&LOCK_thread_count);
 
3871
  VOID(pthread_mutex_lock(&LOCK_thread_count));
3039
3872
  thd->catalog= 0;
3040
3873
  thd->set_db(NULL, 0);                   /* will free the current database */
3041
3874
  thd->query= 0;
3042
3875
  thd->query_length= 0;
3043
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
3876
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
3044
3877
  close_thread_tables(thd);
3045
3878
 
 
3879
  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error",
 
3880
                  thd->is_slave_error= 0; thd->is_fatal_error= 1;);
 
3881
 
3046
3882
  if (thd->is_slave_error)
3047
3883
  {
3048
3884
    /* this err/sql_errno code is copy-paste from net_send_error() */
3056
3892
    else
3057
3893
    {
3058
3894
      sql_errno=ER_UNKNOWN_ERROR;
3059
 
      err=ER(sql_errno);
 
3895
      err=ER(sql_errno);       
3060
3896
    }
3061
 
    rli->report(ERROR_LEVEL, sql_errno,
3062
 
                _("Error '%s' running LOAD DATA INFILE on table '%s'. "
3063
 
                  "Default database: '%s'"),
3064
 
                err, (char*)table_name, print_slave_db_safe(remember_db));
 
3897
    rli->report(ERROR_LEVEL, sql_errno,"\
 
3898
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
 
3899
                    err, (char*)table_name, print_slave_db_safe(remember_db));
3065
3900
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3066
3901
    return 1;
3067
3902
  }
3070
3905
  if (thd->is_fatal_error)
3071
3906
  {
3072
3907
    char buf[256];
3073
 
    snprintf(buf, sizeof(buf),
3074
 
             _("Running LOAD DATA INFILE on table '%-.64s'."
3075
 
               " Default database: '%-.64s'"),
3076
 
             (char*)table_name,
3077
 
             print_slave_db_safe(remember_db));
 
3908
    my_snprintf(buf, sizeof(buf),
 
3909
                "Running LOAD DATA INFILE on table '%-.64s'."
 
3910
                " Default database: '%-.64s'",
 
3911
                (char*)table_name,
 
3912
                print_slave_db_safe(remember_db));
3078
3913
 
3079
3914
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
3080
3915
                ER(ER_SLAVE_FATAL_ERROR), buf);
3081
3916
    return 1;
3082
3917
  }
3083
3918
 
3084
 
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
 
3919
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
3085
3920
}
 
3921
#endif
3086
3922
 
3087
3923
 
3088
3924
/**************************************************************************
3093
3929
  Rotate_log_event::pack_info()
3094
3930
*/
3095
3931
 
 
3932
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3096
3933
void Rotate_log_event::pack_info(Protocol *protocol)
3097
3934
{
3098
3935
  char buf1[256], buf[22];
3103
3940
  tmp.append(llstr(pos,buf));
3104
3941
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3105
3942
}
 
3943
#endif
 
3944
 
 
3945
 
 
3946
/*
 
3947
  Rotate_log_event::print()
 
3948
*/
 
3949
 
 
3950
#ifdef MYSQL_CLIENT
 
3951
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3952
{
 
3953
  char buf[22];
 
3954
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
3955
                               Write_on_release_cache::FLUSH_F);
 
3956
 
 
3957
  if (print_event_info->short_form)
 
3958
    return;
 
3959
  print_header(&cache, print_event_info, FALSE);
 
3960
  my_b_printf(&cache, "\tRotate to ");
 
3961
  if (new_log_ident)
 
3962
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
 
3963
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
 
3964
}
 
3965
#endif /* MYSQL_CLIENT */
 
3966
 
3106
3967
 
3107
3968
 
3108
3969
/*
3110
3971
*/
3111
3972
 
3112
3973
 
 
3974
#ifndef MYSQL_CLIENT
3113
3975
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
3114
 
                                   uint32_t ident_len_arg, uint64_t pos_arg,
3115
 
                                   uint32_t flags_arg)
 
3976
                                   uint ident_len_arg, ulonglong pos_arg,
 
3977
                                   uint flags_arg)
3116
3978
  :Log_event(), new_log_ident(new_log_ident_arg),
3117
3979
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3118
3980
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
3119
3981
{
 
3982
#ifndef DBUG_OFF
 
3983
  char buff[22];
 
3984
  DBUG_ENTER("Rotate_log_event::Rotate_log_event(...,flags)");
 
3985
  DBUG_PRINT("enter",("new_log_ident: %s  pos: %s  flags: %lu", new_log_ident_arg,
 
3986
                      llstr(pos_arg, buff), (ulong) flags));
 
3987
#endif
3120
3988
  if (flags & DUP_NAME)
3121
3989
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
3122
 
  return;
 
3990
  DBUG_VOID_RETURN;
3123
3991
}
3124
 
 
3125
 
 
3126
 
Rotate_log_event::Rotate_log_event(const char* buf, uint32_t event_len,
 
3992
#endif
 
3993
 
 
3994
 
 
3995
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
3127
3996
                                   const Format_description_log_event* description_event)
3128
3997
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
3129
3998
{
 
3999
  DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
3130
4000
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
3131
 
  uint8_t header_size= description_event->common_header_len;
3132
 
  uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
3133
 
  uint32_t ident_offset;
 
4001
  uint8 header_size= description_event->common_header_len;
 
4002
  uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
 
4003
  uint ident_offset;
3134
4004
  if (event_len < header_size)
3135
 
    return;
 
4005
    DBUG_VOID_RETURN;
3136
4006
  buf += header_size;
3137
4007
  pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
3138
4008
  ident_len = (uint)(event_len -
3140
4010
  ident_offset = post_header_len; 
3141
4011
  set_if_smaller(ident_len,FN_REFLEN-1);
3142
4012
  new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
3143
 
  return;
 
4013
  DBUG_PRINT("debug", ("new_log_ident: '%s'", new_log_ident));
 
4014
  DBUG_VOID_RETURN;
3144
4015
}
3145
4016
 
3146
4017
 
3148
4019
  Rotate_log_event::write()
3149
4020
*/
3150
4021
 
 
4022
#ifndef MYSQL_CLIENT
3151
4023
bool Rotate_log_event::write(IO_CACHE* file)
3152
4024
{
3153
4025
  char buf[ROTATE_HEADER_LEN];
3154
4026
  int8store(buf + R_POS_OFFSET, pos);
3155
4027
  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
3156
 
          my_b_safe_write(file, (unsigned char*)buf, ROTATE_HEADER_LEN) ||
3157
 
          my_b_safe_write(file, (unsigned char*)new_log_ident, (uint) ident_len));
 
4028
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
 
4029
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
3158
4030
}
3159
 
 
 
4031
#endif
 
4032
 
 
4033
 
 
4034
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3160
4035
 
3161
4036
/*
3162
4037
  Got a rotate log event from the master.
3173
4048
*/
3174
4049
int Rotate_log_event::do_update_pos(Relay_log_info *rli)
3175
4050
{
 
4051
  DBUG_ENTER("Rotate_log_event::do_update_pos");
 
4052
#ifndef DBUG_OFF
 
4053
  char buf[32];
 
4054
#endif
 
4055
 
 
4056
  DBUG_PRINT("info", ("server_id=%lu; ::server_id=%lu",
 
4057
                      (ulong) this->server_id, (ulong) ::server_id));
 
4058
  DBUG_PRINT("info", ("new_log_ident: %s", this->new_log_ident));
 
4059
  DBUG_PRINT("info", ("pos: %s", llstr(this->pos, buf)));
 
4060
 
3176
4061
  pthread_mutex_lock(&rli->data_lock);
3177
4062
  rli->event_relay_log_pos= my_b_tell(rli->cur_log);
3178
4063
  /*
3194
4079
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3195
4080
      !rli->is_in_group())
3196
4081
  {
3197
 
    rli->group_master_log_name.assign(new_log_ident, ident_len+1);
 
4082
    DBUG_PRINT("info", ("old group_master_log_name: '%s'  "
 
4083
                        "old group_master_log_pos: %lu",
 
4084
                        rli->group_master_log_name,
 
4085
                        (ulong) rli->group_master_log_pos));
 
4086
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3198
4087
    rli->notify_group_master_log_name_update();
3199
4088
    rli->group_master_log_pos= pos;
3200
 
    rli->group_relay_log_name.assign(rli->event_relay_log_name);
 
4089
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
 
4090
            sizeof(rli->group_relay_log_name) - 1);
3201
4091
    rli->notify_group_relay_log_name_update();
3202
4092
    rli->group_relay_log_pos= rli->event_relay_log_pos;
 
4093
    DBUG_PRINT("info", ("new group_master_log_name: '%s'  "
 
4094
                        "new group_master_log_pos: %lu",
 
4095
                        rli->group_master_log_name,
 
4096
                        (ulong) rli->group_master_log_pos));
3203
4097
    /*
3204
4098
      Reset thd->options and sql_mode etc, because this could be the signal of
3205
4099
      a master's downgrade from 5.0 to 4.0.
3208
4102
      master is 4.0 then the events are in the slave's format (conversion).
3209
4103
    */
3210
4104
    set_slave_thread_options(thd);
 
4105
    set_slave_thread_default_charset(thd, rli);
3211
4106
    thd->variables.auto_increment_increment=
3212
4107
      thd->variables.auto_increment_offset= 1;
3213
4108
  }
3215
4110
  pthread_cond_broadcast(&rli->data_cond);
3216
4111
  flush_relay_log_info(rli);
3217
4112
 
3218
 
  return(0);
 
4113
  DBUG_RETURN(0);
3219
4114
}
3220
4115
 
3221
4116
 
3232
4127
  case Log_event::EVENT_SKIP_IGNORE:
3233
4128
    return Log_event::EVENT_SKIP_IGNORE;
3234
4129
  }
3235
 
  assert(0);
 
4130
  DBUG_ASSERT(0);
3236
4131
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
3237
4132
}
3238
4133
 
 
4134
#endif
 
4135
 
3239
4136
 
3240
4137
/**************************************************************************
3241
4138
        Intvar_log_event methods
3245
4142
  Intvar_log_event::pack_info()
3246
4143
*/
3247
4144
 
 
4145
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3248
4146
void Intvar_log_event::pack_info(Protocol *protocol)
3249
4147
{
3250
4148
  char buf[256], *pos;
3251
4149
  pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
3252
4150
  *pos++= '=';
3253
 
  pos= int64_t10_to_str(val, pos, -10);
 
4151
  pos= longlong10_to_str(val, pos, -10);
3254
4152
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3255
4153
}
 
4154
#endif
3256
4155
 
3257
4156
 
3258
4157
/*
3287
4186
  Intvar_log_event::write()
3288
4187
*/
3289
4188
 
 
4189
#ifndef MYSQL_CLIENT
3290
4190
bool Intvar_log_event::write(IO_CACHE* file)
3291
4191
{
3292
 
  unsigned char buf[9];
3293
 
  buf[I_TYPE_OFFSET]= (unsigned char) type;
 
4192
  uchar buf[9];
 
4193
  buf[I_TYPE_OFFSET]= (uchar) type;
3294
4194
  int8store(buf + I_VAL_OFFSET, val);
3295
4195
  return (write_header(file, sizeof(buf)) ||
3296
4196
          my_b_safe_write(file, buf, sizeof(buf)));
3297
4197
}
 
4198
#endif
3298
4199
 
3299
4200
 
3300
4201
/*
3301
4202
  Intvar_log_event::print()
3302
4203
*/
3303
4204
 
 
4205
#ifdef MYSQL_CLIENT
 
4206
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4207
{
 
4208
  char llbuff[22];
 
4209
  const char *msg;
 
4210
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4211
                               Write_on_release_cache::FLUSH_F);
 
4212
 
 
4213
  if (!print_event_info->short_form)
 
4214
  {
 
4215
    print_header(&cache, print_event_info, FALSE);
 
4216
    my_b_printf(&cache, "\tIntvar\n");
 
4217
  }
 
4218
 
 
4219
  my_b_printf(&cache, "SET ");
 
4220
  switch (type) {
 
4221
  case LAST_INSERT_ID_EVENT:
 
4222
    msg="LAST_INSERT_ID";
 
4223
    break;
 
4224
  case INSERT_ID_EVENT:
 
4225
    msg="INSERT_ID";
 
4226
    break;
 
4227
  case INVALID_INT_EVENT:
 
4228
  default: // cannot happen
 
4229
    msg="INVALID_INT";
 
4230
    break;
 
4231
  }
 
4232
  my_b_printf(&cache, "%s=%s%s\n",
 
4233
              msg, llstr(val,llbuff), print_event_info->delimiter);
 
4234
}
 
4235
#endif
 
4236
 
 
4237
 
3304
4238
/*
3305
4239
  Intvar_log_event::do_apply_event()
3306
4240
*/
3307
4241
 
 
4242
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
3308
4243
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
3309
4244
{
3310
4245
  /*
3346
4281
  return continue_group(rli);
3347
4282
}
3348
4283
 
 
4284
#endif
 
4285
 
3349
4286
 
3350
4287
/**************************************************************************
3351
4288
  Rand_log_event methods
3352
4289
**************************************************************************/
3353
4290
 
 
4291
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3354
4292
void Rand_log_event::pack_info(Protocol *protocol)
3355
4293
{
3356
4294
  char buf1[256], *pos;
3357
 
  pos= my_stpcpy(buf1,"rand_seed1=");
 
4295
  pos= strmov(buf1,"rand_seed1=");
3358
4296
  pos= int10_to_str((long) seed1, pos, 10);
3359
 
  pos= my_stpcpy(pos, ",rand_seed2=");
 
4297
  pos= strmov(pos, ",rand_seed2=");
3360
4298
  pos= int10_to_str((long) seed2, pos, 10);
3361
4299
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
3362
4300
}
 
4301
#endif
3363
4302
 
3364
4303
 
3365
4304
Rand_log_event::Rand_log_event(const char* buf,
3372
4311
}
3373
4312
 
3374
4313
 
 
4314
#ifndef MYSQL_CLIENT
3375
4315
bool Rand_log_event::write(IO_CACHE* file)
3376
4316
{
3377
 
  unsigned char buf[16];
 
4317
  uchar buf[16];
3378
4318
  int8store(buf + RAND_SEED1_OFFSET, seed1);
3379
4319
  int8store(buf + RAND_SEED2_OFFSET, seed2);
3380
4320
  return (write_header(file, sizeof(buf)) ||
3381
4321
          my_b_safe_write(file, buf, sizeof(buf)));
3382
4322
}
3383
 
 
3384
 
 
 
4323
#endif
 
4324
 
 
4325
 
 
4326
#ifdef MYSQL_CLIENT
 
4327
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4328
{
 
4329
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4330
                               Write_on_release_cache::FLUSH_F);
 
4331
 
 
4332
  char llbuff[22],llbuff2[22];
 
4333
  if (!print_event_info->short_form)
 
4334
  {
 
4335
    print_header(&cache, print_event_info, FALSE);
 
4336
    my_b_printf(&cache, "\tRand\n");
 
4337
  }
 
4338
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
 
4339
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
 
4340
              print_event_info->delimiter);
 
4341
}
 
4342
#endif /* MYSQL_CLIENT */
 
4343
 
 
4344
 
 
4345
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3385
4346
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
3386
4347
{
3387
4348
  /*
3416
4377
  return continue_group(rli);
3417
4378
}
3418
4379
 
 
4380
#endif /* !MYSQL_CLIENT */
 
4381
 
3419
4382
 
3420
4383
/**************************************************************************
3421
4384
  Xid_log_event methods
3422
4385
**************************************************************************/
3423
4386
 
 
4387
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3424
4388
void Xid_log_event::pack_info(Protocol *protocol)
3425
4389
{
3426
4390
  char buf[128], *pos;
3427
 
  pos= my_stpcpy(buf, "COMMIT /* xid=");
3428
 
  pos= int64_t10_to_str(xid, pos, 10);
3429
 
  pos= my_stpcpy(pos, " */");
 
4391
  pos= strmov(buf, "COMMIT /* xid=");
 
4392
  pos= longlong10_to_str(xid, pos, 10);
 
4393
  pos= strmov(pos, " */");
3430
4394
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3431
4395
}
 
4396
#endif
3432
4397
 
3433
4398
/**
3434
4399
  @note
3435
4400
  It's ok not to use int8store here,
3436
 
  as long as xid_t::set(uint64_t) and
 
4401
  as long as xid_t::set(ulonglong) and
3437
4402
  xid_t::get_my_xid doesn't do it either.
3438
4403
  We don't care about actual values of xids as long as
3439
4404
  identical numbers compare identically
3445
4410
  :Log_event(buf, description_event)
3446
4411
{
3447
4412
  buf+= description_event->common_header_len;
3448
 
  memcpy(&xid, buf, sizeof(xid));
 
4413
  memcpy((char*) &xid, buf, sizeof(xid));
3449
4414
}
3450
4415
 
3451
4416
 
 
4417
#ifndef MYSQL_CLIENT
3452
4418
bool Xid_log_event::write(IO_CACHE* file)
3453
4419
{
 
4420
  DBUG_EXECUTE_IF("do_not_write_xid", return 0;);
3454
4421
  return write_header(file, sizeof(xid)) ||
3455
 
         my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
3456
 
}
3457
 
 
3458
 
 
3459
 
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
3460
 
{
 
4422
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
 
4423
}
 
4424
#endif
 
4425
 
 
4426
 
 
4427
#ifdef MYSQL_CLIENT
 
4428
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4429
{
 
4430
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4431
                               Write_on_release_cache::FLUSH_F);
 
4432
 
 
4433
  if (!print_event_info->short_form)
 
4434
  {
 
4435
    char buf[64];
 
4436
    longlong10_to_str(xid, buf, 10);
 
4437
 
 
4438
    print_header(&cache, print_event_info, FALSE);
 
4439
    my_b_printf(&cache, "\tXid = %s\n", buf);
 
4440
  }
 
4441
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
 
4442
}
 
4443
#endif /* MYSQL_CLIENT */
 
4444
 
 
4445
 
 
4446
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4447
int Xid_log_event::do_apply_event(Relay_log_info const *rli)
 
4448
{
 
4449
  /* For a slave Xid_log_event is COMMIT */
 
4450
  general_log_print(thd, COM_QUERY,
 
4451
                    "COMMIT /* implicit, from Xid_log_event */");
3461
4452
  return end_trans(thd, COMMIT);
3462
4453
}
3463
4454
 
3464
4455
Log_event::enum_skip_reason
3465
4456
Xid_log_event::do_shall_skip(Relay_log_info *rli)
3466
4457
{
 
4458
  DBUG_ENTER("Xid_log_event::do_shall_skip");
3467
4459
  if (rli->slave_skip_counter > 0) {
3468
4460
    thd->options&= ~OPTION_BEGIN;
3469
 
    return(Log_event::EVENT_SKIP_COUNT);
 
4461
    DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
3470
4462
  }
3471
 
  return(Log_event::do_shall_skip(rli));
 
4463
  DBUG_RETURN(Log_event::do_shall_skip(rli));
3472
4464
}
 
4465
#endif /* !MYSQL_CLIENT */
3473
4466
 
3474
4467
 
3475
4468
/**************************************************************************
3476
4469
  User_var_log_event methods
3477
4470
**************************************************************************/
3478
4471
 
 
4472
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3479
4473
void User_var_log_event::pack_info(Protocol* protocol)
3480
4474
{
3481
4475
  char *buf= 0;
3482
 
  uint32_t val_offset= 4 + name_len;
3483
 
  uint32_t event_len= val_offset;
 
4476
  uint val_offset= 4 + name_len;
 
4477
  uint event_len= val_offset;
3484
4478
 
3485
4479
  if (is_null)
3486
4480
  {
3487
4481
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
3488
4482
      return;
3489
 
    my_stpcpy(buf + val_offset, "NULL");
 
4483
    strmov(buf + val_offset, "NULL");
3490
4484
    event_len= val_offset + 4;
3491
4485
  }
3492
4486
  else
3504
4498
    case INT_RESULT:
3505
4499
      if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
3506
4500
        return;
3507
 
      event_len= int64_t10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
 
4501
      event_len= longlong10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
3508
4502
      break;
3509
4503
    case DECIMAL_RESULT:
3510
4504
    {
3513
4507
        return;
3514
4508
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
3515
4509
      my_decimal dec;
3516
 
      binary2my_decimal(E_DEC_FATAL_ERROR, (unsigned char*) (val+2), &dec, val[0],
 
4510
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
3517
4511
                        val[1]);
3518
4512
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
3519
4513
      event_len= str.length() + val_offset;
3523
4517
      /* 15 is for 'COLLATE' and other chars */
3524
4518
      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
3525
4519
                             MYF(MY_WME));
3526
 
      const CHARSET_INFO *cs;
 
4520
      CHARSET_INFO *cs;
3527
4521
      if (!buf)
3528
4522
        return;
3529
4523
      if (!(cs= get_charset(charset_number, MYF(0))))
3530
4524
      {
3531
 
        my_stpcpy(buf+val_offset, "???");
 
4525
        strmov(buf+val_offset, "???");
3532
4526
        event_len+= 3;
3533
4527
      }
3534
4528
      else
3535
4529
      {
3536
 
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NULL);
 
4530
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
3537
4531
        p= str_to_hex(p, val, val_len);
3538
 
        p= strxmov(p, " COLLATE ", cs->name, NULL);
 
4532
        p= strxmov(p, " COLLATE ", cs->name, NullS);
3539
4533
        event_len= p-buf;
3540
4534
      }
3541
4535
      break;
3542
4536
    case ROW_RESULT:
3543
4537
    default:
3544
 
      assert(1);
 
4538
      DBUG_ASSERT(1);
3545
4539
      return;
3546
4540
    }
3547
4541
  }
3551
4545
  buf[2+name_len]= '`';
3552
4546
  buf[3+name_len]= '=';
3553
4547
  protocol->store(buf, event_len, &my_charset_bin);
3554
 
  free(buf);
 
4548
  my_free(buf, MYF(0));
3555
4549
}
 
4550
#endif /* !MYSQL_CLIENT */
3556
4551
 
3557
4552
 
3558
4553
User_var_log_event::
3584
4579
}
3585
4580
 
3586
4581
 
 
4582
#ifndef MYSQL_CLIENT
3587
4583
bool User_var_log_event::write(IO_CACHE* file)
3588
4584
{
3589
4585
  char buf[UV_NAME_LEN_SIZE];
3590
4586
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
3591
4587
            UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
3592
 
  unsigned char buf2[(8 > DECIMAL_MAX_FIELD_SIZE + 2) ? 8 : DECIMAL_MAX_FIELD_SIZE +2], *pos= buf2;
3593
 
  uint32_t buf1_length;
 
4588
  uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
 
4589
  uint buf1_length;
3594
4590
  ulong event_length;
3595
4591
 
3596
4592
  int4store(buf, name_len);
3610
4606
      float8store(buf2, *(double*) val);
3611
4607
      break;
3612
4608
    case INT_RESULT:
3613
 
      int8store(buf2, *(int64_t*) val);
 
4609
      int8store(buf2, *(longlong*) val);
3614
4610
      break;
3615
4611
    case DECIMAL_RESULT:
3616
4612
    {
3623
4619
      break;
3624
4620
    }
3625
4621
    case STRING_RESULT:
3626
 
      pos= (unsigned char*) val;
 
4622
      pos= (uchar*) val;
3627
4623
      break;
3628
4624
    case ROW_RESULT:
3629
4625
    default:
3630
 
      assert(1);
 
4626
      DBUG_ASSERT(1);
3631
4627
      return 0;
3632
4628
    }
3633
4629
    int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
3638
4634
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
3639
4635
 
3640
4636
  return (write_header(file, event_length) ||
3641
 
          my_b_safe_write(file, (unsigned char*) buf, sizeof(buf))   ||
3642
 
          my_b_safe_write(file, (unsigned char*) name, name_len)     ||
3643
 
          my_b_safe_write(file, (unsigned char*) buf1, buf1_length) ||
 
4637
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
 
4638
          my_b_safe_write(file, (uchar*) name, name_len)     ||
 
4639
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
3644
4640
          my_b_safe_write(file, pos, val_len));
3645
4641
}
3646
 
 
 
4642
#endif
 
4643
 
 
4644
 
 
4645
/*
 
4646
  User_var_log_event::print()
 
4647
*/
 
4648
 
 
4649
#ifdef MYSQL_CLIENT
 
4650
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4651
{
 
4652
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4653
                               Write_on_release_cache::FLUSH_F);
 
4654
 
 
4655
  if (!print_event_info->short_form)
 
4656
  {
 
4657
    print_header(&cache, print_event_info, FALSE);
 
4658
    my_b_printf(&cache, "\tUser_var\n");
 
4659
  }
 
4660
 
 
4661
  my_b_printf(&cache, "SET @`");
 
4662
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
 
4663
  my_b_printf(&cache, "`");
 
4664
 
 
4665
  if (is_null)
 
4666
  {
 
4667
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
 
4668
  }
 
4669
  else
 
4670
  {
 
4671
    switch (type) {
 
4672
    case REAL_RESULT:
 
4673
      double real_val;
 
4674
      char real_buf[FMT_G_BUFSIZE(14)];
 
4675
      float8get(real_val, val);
 
4676
      my_sprintf(real_buf, (real_buf, "%.14g", real_val));
 
4677
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
 
4678
      break;
 
4679
    case INT_RESULT:
 
4680
      char int_buf[22];
 
4681
      longlong10_to_str(uint8korr(val), int_buf, -10);
 
4682
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
 
4683
      break;
 
4684
    case DECIMAL_RESULT:
 
4685
    {
 
4686
      char str_buf[200];
 
4687
      int str_len= sizeof(str_buf) - 1;
 
4688
      int precision= (int)val[0];
 
4689
      int scale= (int)val[1];
 
4690
      decimal_digit_t dec_buf[10];
 
4691
      decimal_t dec;
 
4692
      dec.len= 10;
 
4693
      dec.buf= dec_buf;
 
4694
 
 
4695
      bin2decimal((uchar*) val+2, &dec, precision, scale);
 
4696
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
 
4697
      str_buf[str_len]= 0;
 
4698
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
 
4699
      break;
 
4700
    }
 
4701
    case STRING_RESULT:
 
4702
    {
 
4703
      /*
 
4704
        Let's express the string in hex. That's the most robust way. If we
 
4705
        print it in character form instead, we need to escape it with
 
4706
        character_set_client which we don't know (we will know it in 5.0, but
 
4707
        in 4.1 we don't know it easily when we are printing
 
4708
        User_var_log_event). Explanation why we would need to bother with
 
4709
        character_set_client (quoting Bar):
 
4710
        > Note, the parser doesn't switch to another unescaping mode after
 
4711
        > it has met a character set introducer.
 
4712
        > For example, if an SJIS client says something like:
 
4713
        > SET @a= _ucs2 \0a\0b'
 
4714
        > the string constant is still unescaped according to SJIS, not
 
4715
        > according to UCS2.
 
4716
      */
 
4717
      char *hex_str;
 
4718
      CHARSET_INFO *cs;
 
4719
 
 
4720
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
 
4721
        break; // no error, as we are 'void'
 
4722
      str_to_hex(hex_str, val, val_len);
 
4723
      /*
 
4724
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
 
4725
        specify the variable's collation. It will however cause problems when
 
4726
        people want to mysqlbinlog|mysql into another server not supporting the
 
4727
        character set. But there's not much to do about this and it's unlikely.
 
4728
      */
 
4729
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4730
        /*
 
4731
          Generate an unusable command (=> syntax error) is probably the best
 
4732
          thing we can do here.
 
4733
        */
 
4734
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
 
4735
      else
 
4736
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
 
4737
                    cs->csname, hex_str, cs->name,
 
4738
                    print_event_info->delimiter);
 
4739
      my_afree(hex_str);
 
4740
    }
 
4741
      break;
 
4742
    case ROW_RESULT:
 
4743
    default:
 
4744
      DBUG_ASSERT(1);
 
4745
      return;
 
4746
    }
 
4747
  }
 
4748
}
 
4749
#endif
3647
4750
 
3648
4751
 
3649
4752
/*
3650
4753
  User_var_log_event::do_apply_event()
3651
4754
*/
3652
4755
 
 
4756
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3653
4757
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
3654
4758
{
3655
4759
  Item *it= 0;
3656
 
  const CHARSET_INFO *charset;
 
4760
  CHARSET_INFO *charset;
3657
4761
  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
3658
4762
    return 1;
3659
4763
  LEX_STRING user_var_name;
3660
4764
  user_var_name.str= name;
3661
4765
  user_var_name.length= name_len;
3662
4766
  double real_val;
3663
 
  int64_t int_val;
 
4767
  longlong int_val;
3664
4768
 
3665
4769
  /*
3666
4770
    We are now in a statement until the associated query log event has
3682
4786
      val_len= 8;
3683
4787
      break;
3684
4788
    case INT_RESULT:
3685
 
      int_val= (int64_t) uint8korr(val);
 
4789
      int_val= (longlong) uint8korr(val);
3686
4790
      it= new Item_int(int_val);
3687
4791
      val= (char*) &int_val;            // Pointer to value in native format
3688
4792
      val_len= 8;
3689
4793
      break;
3690
4794
    case DECIMAL_RESULT:
3691
4795
    {
3692
 
      Item_decimal *dec= new Item_decimal((unsigned char*) val+2, val[0], val[1]);
 
4796
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
3693
4797
      it= dec;
3694
4798
      val= (char *)dec->val_decimal(NULL);
3695
4799
      val_len= sizeof(my_decimal);
3700
4804
      break;
3701
4805
    case ROW_RESULT:
3702
4806
    default:
3703
 
      assert(1);
 
4807
      DBUG_ASSERT(1);
3704
4808
      return 0;
3705
4809
    }
3706
4810
  }
3740
4844
  */
3741
4845
  return continue_group(rli);
3742
4846
}
 
4847
#endif /* !MYSQL_CLIENT */
3743
4848
 
3744
4849
 
3745
4850
/**************************************************************************
3746
4851
  Slave_log_event methods
3747
4852
**************************************************************************/
3748
4853
 
 
4854
#ifdef HAVE_REPLICATION
 
4855
#ifdef MYSQL_CLIENT
 
4856
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
 
4857
{
 
4858
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
4859
 
 
4860
  if (print_event_info->short_form)
 
4861
    return;
 
4862
  print_header(&cache, print_event_info, FALSE);
 
4863
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
 
4864
}
 
4865
#endif  
 
4866
 
 
4867
#ifndef MYSQL_CLIENT
3749
4868
void Slave_log_event::pack_info(Protocol *protocol)
3750
4869
{
3751
4870
  char buf[256+HOSTNAME_LENGTH], *pos;
3752
 
  pos= my_stpcpy(buf, "host=");
3753
 
  pos= my_stpncpy(pos, master_host.c_str(), HOSTNAME_LENGTH);
3754
 
  pos= my_stpcpy(pos, ",port=");
 
4871
  pos= strmov(buf, "host=");
 
4872
  pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
 
4873
  pos= strmov(pos, ",port=");
3755
4874
  pos= int10_to_str((long) master_port, pos, 10);
3756
 
  pos= my_stpcpy(pos, ",log=");
3757
 
  pos= my_stpcpy(pos, master_log.c_str());
3758
 
  pos= my_stpcpy(pos, ",pos=");
3759
 
  pos= int64_t10_to_str(master_pos, pos, 10);
 
4875
  pos= strmov(pos, ",log=");
 
4876
  pos= strmov(pos, master_log);
 
4877
  pos= strmov(pos, ",pos=");
 
4878
  pos= longlong10_to_str(master_pos, pos, 10);
3760
4879
  protocol->store(buf, pos-buf, &my_charset_bin);
3761
4880
}
3762
 
 
3763
 
 
 
4881
#endif /* !MYSQL_CLIENT */
 
4882
 
 
4883
 
 
4884
#ifndef MYSQL_CLIENT
3764
4885
/**
3765
4886
  @todo
3766
4887
  re-write this better without holding both locks at the same time
3769
4890
                                 Relay_log_info* rli)
3770
4891
  :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
3771
4892
{
 
4893
  DBUG_ENTER("Slave_log_event");
3772
4894
  if (!rli->inited)                             // QQ When can this happen ?
3773
 
    return;
 
4895
    DBUG_VOID_RETURN;
3774
4896
 
3775
4897
  Master_info* mi = rli->mi;
3776
4898
  // TODO: re-write this better without holding both locks at the same time
3777
4899
  pthread_mutex_lock(&mi->data_lock);
3778
4900
  pthread_mutex_lock(&rli->data_lock);
 
4901
  master_host_len = strlen(mi->host);
 
4902
  master_log_len = strlen(rli->group_master_log_name);
3779
4903
  // on OOM, just do not initialize the structure and print the error
3780
4904
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
3781
4905
                                   MYF(MY_WME))))
3782
4906
  {
3783
 
    master_host.assign(mi->getHostname());
3784
 
    master_log.assign(rli->group_master_log_name);
3785
 
    master_port = mi->getPort();
 
4907
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
 
4908
    memcpy(master_host, mi->host, master_host_len + 1);
 
4909
    master_log = master_host + master_host_len + 1;
 
4910
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
 
4911
    master_port = mi->port;
3786
4912
    master_pos = rli->group_master_log_pos;
 
4913
    DBUG_PRINT("info", ("master_log: %s  pos: %lu", master_log,
 
4914
                        (ulong) master_pos));
3787
4915
  }
3788
4916
  else
3789
 
    sql_print_error(_("Out of memory while recording slave event"));
 
4917
    sql_print_error("Out of memory while recording slave event");
3790
4918
  pthread_mutex_unlock(&rli->data_lock);
3791
4919
  pthread_mutex_unlock(&mi->data_lock);
3792
 
  return;
 
4920
  DBUG_VOID_RETURN;
3793
4921
}
 
4922
#endif /* !MYSQL_CLIENT */
3794
4923
 
3795
4924
 
3796
4925
Slave_log_event::~Slave_log_event()
3797
4926
{
3798
 
  free(mem_pool);
3799
 
}
 
4927
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 
4928
}
 
4929
 
 
4930
 
 
4931
#ifdef MYSQL_CLIENT
 
4932
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4933
{
 
4934
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
4935
 
 
4936
  char llbuff[22];
 
4937
  if (print_event_info->short_form)
 
4938
    return;
 
4939
  print_header(&cache, print_event_info, FALSE);
 
4940
  my_b_printf(&cache, "\n\
 
4941
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 
4942
          master_host, master_port, master_log, llstr(master_pos, llbuff));
 
4943
}
 
4944
#endif /* MYSQL_CLIENT */
3800
4945
 
3801
4946
 
3802
4947
int Slave_log_event::get_data_size()
3803
4948
{
3804
 
  return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
 
4949
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
3805
4950
}
3806
4951
 
3807
4952
 
 
4953
#ifndef MYSQL_CLIENT
3808
4954
bool Slave_log_event::write(IO_CACHE* file)
3809
4955
{
3810
4956
  ulong event_length= get_data_size();
3813
4959
  // log and host are already there
3814
4960
 
3815
4961
  return (write_header(file, event_length) ||
3816
 
          my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
 
4962
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
3817
4963
}
3818
 
 
3819
 
 
3820
 
void Slave_log_event::init_from_mem_pool()
 
4964
#endif
 
4965
 
 
4966
 
 
4967
void Slave_log_event::init_from_mem_pool(int data_size)
3821
4968
{
3822
4969
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
3823
4970
  master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
3824
 
#ifdef FIXME
3825
 
  /* Assign these correctly */
3826
 
  master_host.assign(mem_pool + SL_MASTER_HOST_OFFSET);
3827
 
  master_log.assign();
3828
 
#endif
3829
 
}
3830
 
 
3831
 
 
3832
 
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
4971
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
 
4972
  master_host_len = strlen(master_host);
 
4973
  // safety
 
4974
  master_log = master_host + master_host_len + 1;
 
4975
  if (master_log > mem_pool + data_size)
 
4976
  {
 
4977
    master_host = 0;
 
4978
    return;
 
4979
  }
 
4980
  master_log_len = strlen(master_log);
 
4981
}
 
4982
 
 
4983
 
 
4984
/** This code is not used, so has not been updated to be format-tolerant. */
 
4985
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
 
4986
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
 
4987
{
 
4988
  if (event_len < LOG_EVENT_HEADER_LEN)
 
4989
    return;
 
4990
  event_len -= LOG_EVENT_HEADER_LEN;
 
4991
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
 
4992
    return;
 
4993
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
 
4994
  mem_pool[event_len] = 0;
 
4995
  init_from_mem_pool(event_len);
 
4996
}
 
4997
 
 
4998
 
 
4999
#ifndef MYSQL_CLIENT
 
5000
int Slave_log_event::do_apply_event(Relay_log_info const *rli)
3833
5001
{
3834
5002
  if (mysql_bin_log.is_open())
3835
5003
    mysql_bin_log.write(this);
3836
5004
  return 0;
3837
5005
}
 
5006
#endif /* !MYSQL_CLIENT */
3838
5007
 
3839
5008
 
3840
5009
/**************************************************************************
3842
5011
**************************************************************************/
3843
5012
 
3844
5013
/*
 
5014
  Stop_log_event::print()
 
5015
*/
 
5016
 
 
5017
#ifdef MYSQL_CLIENT
 
5018
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5019
{
 
5020
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
5021
                               Write_on_release_cache::FLUSH_F);
 
5022
 
 
5023
  if (print_event_info->short_form)
 
5024
    return;
 
5025
 
 
5026
  print_header(&cache, print_event_info, FALSE);
 
5027
  my_b_printf(&cache, "\tStop\n");
 
5028
}
 
5029
#endif /* MYSQL_CLIENT */
 
5030
 
 
5031
 
 
5032
#ifndef MYSQL_CLIENT
 
5033
/*
3845
5034
  The master stopped.  We used to clean up all temporary tables but
3846
5035
  this is useless as, as the master has shut down properly, it has
3847
 
  written all DROP TEMPORARY Table (prepared statements' deletion is
 
5036
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
3848
5037
  TODO only when we binlog prep stmts).  We used to clean up
3849
5038
  slave_load_tmpdir, but this is useless as it has been cleared at the
3850
5039
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
3871
5060
  return 0;
3872
5061
}
3873
5062
 
 
5063
#endif /* !MYSQL_CLIENT */
 
5064
#endif /* HAVE_REPLICATION */
 
5065
 
3874
5066
 
3875
5067
/**************************************************************************
3876
5068
        Create_file_log_event methods
3880
5072
  Create_file_log_event ctor
3881
5073
*/
3882
5074
 
 
5075
#ifndef MYSQL_CLIENT
3883
5076
Create_file_log_event::
3884
5077
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3885
5078
                      const char* db_arg, const char* table_name_arg,
3886
5079
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
3887
5080
                      bool ignore,
3888
 
                      unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
 
5081
                      uchar* block_arg, uint block_len_arg, bool using_trans)
3889
5082
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3890
5083
                  using_trans),
3891
5084
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3892
5085
   file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
3893
5086
{
 
5087
  DBUG_ENTER("Create_file_log_event");
3894
5088
  sql_ex.force_new_format();
3895
 
  return;
 
5089
  DBUG_VOID_RETURN;
3896
5090
}
3897
5091
 
3898
5092
 
3905
5099
  bool res;
3906
5100
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
3907
5101
    return res;
3908
 
  return (my_b_safe_write(file, (unsigned char*) "", 1) ||
3909
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
 
5102
  return (my_b_safe_write(file, (uchar*) "", 1) ||
 
5103
          my_b_safe_write(file, (uchar*) block, block_len));
3910
5104
}
3911
5105
 
3912
5106
 
3917
5111
bool Create_file_log_event::write_data_header(IO_CACHE* file)
3918
5112
{
3919
5113
  bool res;
3920
 
  unsigned char buf[CREATE_FILE_HEADER_LEN];
 
5114
  uchar buf[CREATE_FILE_HEADER_LEN];
3921
5115
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
3922
5116
    return res;
3923
5117
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
3938
5132
  return res;
3939
5133
}
3940
5134
 
 
5135
#endif /* !MYSQL_CLIENT */
 
5136
 
3941
5137
/*
3942
5138
  Create_file_log_event ctor
3943
5139
*/
3944
5140
 
3945
 
Create_file_log_event::Create_file_log_event(const char* buf, uint32_t len,
 
5141
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
3946
5142
                                             const Format_description_log_event* description_event)
3947
5143
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
3948
5144
{
3949
 
  uint32_t block_offset;
3950
 
  uint32_t header_len= description_event->common_header_len;
3951
 
  uint8_t load_header_len= description_event->post_header_len[LOAD_EVENT-1];
3952
 
  uint8_t create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
 
5145
  DBUG_ENTER("Create_file_log_event::Create_file_log_event(char*,...)");
 
5146
  uint block_offset;
 
5147
  uint header_len= description_event->common_header_len;
 
5148
  uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
 
5149
  uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
3953
5150
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
3954
5151
      copy_log_event(event_buf,len,
3955
5152
                     ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
3958
5155
                       (header_len+load_header_len) +
3959
5156
                       create_file_header_len)),
3960
5157
                     description_event))
3961
 
    return;
 
5158
    DBUG_VOID_RETURN;
3962
5159
  if (description_event->binlog_version!=1)
3963
5160
  {
3964
5161
    file_id= uint4korr(buf + 
3979
5176
                   Load_log_event::get_data_size() +
3980
5177
                   create_file_header_len + 1);
3981
5178
    if (len < block_offset)
3982
 
      return;
3983
 
    block = (unsigned char*)buf + block_offset;
 
5179
      DBUG_VOID_RETURN;
 
5180
    block = (uchar*)buf + block_offset;
3984
5181
    block_len = len - block_offset;
3985
5182
  }
3986
5183
  else
3988
5185
    sql_ex.force_new_format();
3989
5186
    inited_from_old = 1;
3990
5187
  }
3991
 
  return;
3992
 
}
 
5188
  DBUG_VOID_RETURN;
 
5189
}
 
5190
 
 
5191
 
 
5192
/*
 
5193
  Create_file_log_event::print()
 
5194
*/
 
5195
 
 
5196
#ifdef MYSQL_CLIENT
 
5197
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
 
5198
                                  bool enable_local)
 
5199
{
 
5200
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5201
 
 
5202
  if (print_event_info->short_form)
 
5203
  {
 
5204
    if (enable_local && check_fname_outside_temp_buf())
 
5205
      Load_log_event::print(file, print_event_info);
 
5206
    return;
 
5207
  }
 
5208
 
 
5209
  if (enable_local)
 
5210
  {
 
5211
    Load_log_event::print(file, print_event_info,
 
5212
                          !check_fname_outside_temp_buf());
 
5213
    /* 
 
5214
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
 
5215
       SHOW BINLOG EVENTS we don't.
 
5216
    */
 
5217
    my_b_printf(&cache, "#"); 
 
5218
  }
 
5219
 
 
5220
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
 
5221
}
 
5222
 
 
5223
 
 
5224
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5225
{
 
5226
  print(file, print_event_info, 0);
 
5227
}
 
5228
#endif /* MYSQL_CLIENT */
3993
5229
 
3994
5230
 
3995
5231
/*
3996
5232
  Create_file_log_event::pack_info()
3997
5233
*/
3998
5234
 
 
5235
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3999
5236
void Create_file_log_event::pack_info(Protocol *protocol)
4000
5237
{
4001
5238
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
4002
 
  pos= my_stpcpy(buf, "db=");
 
5239
  pos= strmov(buf, "db=");
4003
5240
  memcpy(pos, db, db_len);
4004
 
  pos= my_stpcpy(pos + db_len, ";table=");
 
5241
  pos= strmov(pos + db_len, ";table=");
4005
5242
  memcpy(pos, table_name, table_name_len);
4006
 
  pos= my_stpcpy(pos + table_name_len, ";file_id=");
 
5243
  pos= strmov(pos + table_name_len, ";file_id=");
4007
5244
  pos= int10_to_str((long) file_id, pos, 10);
4008
 
  pos= my_stpcpy(pos, ";block_len=");
 
5245
  pos= strmov(pos, ";block_len=");
4009
5246
  pos= int10_to_str((long) block_len, pos, 10);
4010
5247
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4011
5248
}
 
5249
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4012
5250
 
4013
5251
 
4014
5252
/*
4015
5253
  Create_file_log_event::do_apply_event()
4016
5254
*/
4017
5255
 
 
5256
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4018
5257
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
4019
5258
{
4020
5259
  char proc_info[17+FN_REFLEN+10], *fname_buf;
4023
5262
  IO_CACHE file;
4024
5263
  int error = 1;
4025
5264
 
4026
 
  memset(&file, 0, sizeof(file));
4027
 
  fname_buf= my_stpcpy(proc_info, "Making temp file ");
 
5265
  bzero((char*)&file, sizeof(file));
 
5266
  fname_buf= strmov(proc_info, "Making temp file ");
4028
5267
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
4029
 
  thd->set_proc_info(proc_info);
 
5268
  thd_proc_info(thd, proc_info);
4030
5269
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4031
5270
  if ((fd= my_create(fname_buf, CREATE_MODE,
4032
 
                     O_WRONLY | O_EXCL,
 
5271
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4033
5272
                     MYF(MY_WME))) < 0 ||
4034
5273
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
4035
5274
                    MYF(MY_WME|MY_NABP)))
4036
5275
  {
4037
5276
    rli->report(ERROR_LEVEL, my_errno,
4038
 
                _("Error in Create_file event: could not open file '%s'"),
 
5277
                "Error in Create_file event: could not open file '%s'",
4039
5278
                fname_buf);
4040
5279
    goto err;
4041
5280
  }
4042
5281
  
4043
5282
  // a trick to avoid allocating another buffer
4044
5283
  fname= fname_buf;
4045
 
  fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
 
5284
  fname_len= (uint) (strmov(ext, ".data") - fname);
4046
5285
  if (write_base(&file))
4047
5286
  {
4048
 
    my_stpcpy(ext, ".info"); // to have it right in the error message
 
5287
    strmov(ext, ".info"); // to have it right in the error message
4049
5288
    rli->report(ERROR_LEVEL, my_errno,
4050
 
                _("Error in Create_file event: could not write to file '%s'"),
 
5289
                "Error in Create_file event: could not write to file '%s'",
4051
5290
                fname_buf);
4052
5291
    goto err;
4053
5292
  }
4054
5293
  end_io_cache(&file);
4055
5294
  my_close(fd, MYF(0));
4056
 
 
 
5295
  
4057
5296
  // fname_buf now already has .data, not .info, because we did our trick
4058
5297
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4059
5298
  if ((fd= my_create(fname_buf, CREATE_MODE,
4060
 
                     O_WRONLY | O_EXCL,
4061
 
                     MYF(MY_WME))) < 0)
 
5299
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5300
                     MYF(MY_WME))) < 0)
4062
5301
  {
4063
5302
    rli->report(ERROR_LEVEL, my_errno,
4064
 
                _("Error in Create_file event: could not open file '%s'"),
 
5303
                "Error in Create_file event: could not open file '%s'",
4065
5304
                fname_buf);
4066
5305
    goto err;
4067
5306
  }
4068
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5307
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4069
5308
  {
4070
5309
    rli->report(ERROR_LEVEL, my_errno,
4071
 
                _("Error in Create_file event: write to '%s' failed"),
 
5310
                "Error in Create_file event: write to '%s' failed",
4072
5311
                fname_buf);
4073
5312
    goto err;
4074
5313
  }
4079
5318
    end_io_cache(&file);
4080
5319
  if (fd >= 0)
4081
5320
    my_close(fd, MYF(0));
4082
 
  thd->set_proc_info(0);
 
5321
  thd_proc_info(thd, 0);
4083
5322
  return error == 0;
4084
5323
}
 
5324
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4085
5325
 
4086
5326
 
4087
5327
/**************************************************************************
4092
5332
  Append_block_log_event ctor
4093
5333
*/
4094
5334
 
 
5335
#ifndef MYSQL_CLIENT  
4095
5336
Append_block_log_event::Append_block_log_event(THD *thd_arg,
4096
5337
                                               const char *db_arg,
4097
 
                                               unsigned char *block_arg,
4098
 
                                               uint32_t block_len_arg,
 
5338
                                               uchar *block_arg,
 
5339
                                               uint block_len_arg,
4099
5340
                                               bool using_trans)
4100
5341
  :Log_event(thd_arg,0, using_trans), block(block_arg),
4101
5342
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
4102
5343
{
4103
5344
}
 
5345
#endif
4104
5346
 
4105
5347
 
4106
5348
/*
4107
5349
  Append_block_log_event ctor
4108
5350
*/
4109
5351
 
4110
 
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
 
5352
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
4111
5353
                                               const Format_description_log_event* description_event)
4112
5354
  :Log_event(buf, description_event),block(0)
4113
5355
{
4114
 
  uint8_t common_header_len= description_event->common_header_len; 
4115
 
  uint8_t append_block_header_len=
 
5356
  DBUG_ENTER("Append_block_log_event::Append_block_log_event(char*,...)");
 
5357
  uint8 common_header_len= description_event->common_header_len; 
 
5358
  uint8 append_block_header_len=
4116
5359
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
4117
 
  uint32_t total_header_len= common_header_len+append_block_header_len;
 
5360
  uint total_header_len= common_header_len+append_block_header_len;
4118
5361
  if (len < total_header_len)
4119
 
    return;
 
5362
    DBUG_VOID_RETURN;
4120
5363
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
4121
 
  block= (unsigned char*)buf + total_header_len;
 
5364
  block= (uchar*)buf + total_header_len;
4122
5365
  block_len= len - total_header_len;
4123
 
  return;
 
5366
  DBUG_VOID_RETURN;
4124
5367
}
4125
5368
 
4126
5369
 
4128
5371
  Append_block_log_event::write()
4129
5372
*/
4130
5373
 
 
5374
#ifndef MYSQL_CLIENT
4131
5375
bool Append_block_log_event::write(IO_CACHE* file)
4132
5376
{
4133
 
  unsigned char buf[APPEND_BLOCK_HEADER_LEN];
 
5377
  uchar buf[APPEND_BLOCK_HEADER_LEN];
4134
5378
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
4135
5379
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
4136
5380
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
4137
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
4138
 
}
 
5381
          my_b_safe_write(file, (uchar*) block, block_len));
 
5382
}
 
5383
#endif
 
5384
 
 
5385
 
 
5386
/*
 
5387
  Append_block_log_event::print()
 
5388
*/
 
5389
 
 
5390
#ifdef MYSQL_CLIENT  
 
5391
void Append_block_log_event::print(FILE* file,
 
5392
                                   PRINT_EVENT_INFO* print_event_info)
 
5393
{
 
5394
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5395
 
 
5396
  if (print_event_info->short_form)
 
5397
    return;
 
5398
  print_header(&cache, print_event_info, FALSE);
 
5399
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
 
5400
              get_type_str(), file_id, block_len);
 
5401
}
 
5402
#endif /* MYSQL_CLIENT */
4139
5403
 
4140
5404
 
4141
5405
/*
4142
5406
  Append_block_log_event::pack_info()
4143
5407
*/
4144
5408
 
 
5409
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4145
5410
void Append_block_log_event::pack_info(Protocol *protocol)
4146
5411
{
4147
5412
  char buf[256];
4148
 
  uint32_t length;
4149
 
  length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
4150
 
                             block_len);
 
5413
  uint length;
 
5414
  length= (uint) my_sprintf(buf,
 
5415
                            (buf, ";file_id=%u;block_len=%u", file_id,
 
5416
                             block_len));
4151
5417
  protocol->store(buf, length, &my_charset_bin);
4152
5418
}
4153
5419
 
4170
5436
  char proc_info[17+FN_REFLEN+10], *fname= proc_info+17;
4171
5437
  int fd;
4172
5438
  int error = 1;
 
5439
  DBUG_ENTER("Append_block_log_event::do_apply_event");
4173
5440
 
4174
 
  fname= my_stpcpy(proc_info, "Making temp file ");
 
5441
  fname= strmov(proc_info, "Making temp file ");
4175
5442
  slave_load_file_stem(fname, file_id, server_id, ".data");
4176
 
  thd->set_proc_info(proc_info);
 
5443
  thd_proc_info(thd, proc_info);
4177
5444
  if (get_create_or_append())
4178
5445
  {
4179
5446
    my_delete(fname, MYF(0)); // old copy may exist already
4180
5447
    if ((fd= my_create(fname, CREATE_MODE,
4181
 
                       O_WRONLY | O_EXCL,
 
5448
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4182
5449
                       MYF(MY_WME))) < 0)
4183
5450
    {
4184
5451
      rli->report(ERROR_LEVEL, my_errno,
4185
 
                  _("Error in %s event: could not create file '%s'"),
 
5452
                  "Error in %s event: could not create file '%s'",
4186
5453
                  get_type_str(), fname);
4187
5454
      goto err;
4188
5455
    }
4189
5456
  }
4190
 
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
 
5457
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
4191
5458
                         MYF(MY_WME))) < 0)
4192
5459
  {
4193
5460
    rli->report(ERROR_LEVEL, my_errno,
4194
 
                _("Error in %s event: could not open file '%s'"),
 
5461
                "Error in %s event: could not open file '%s'",
4195
5462
                get_type_str(), fname);
4196
5463
    goto err;
4197
5464
  }
4198
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5465
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4199
5466
  {
4200
5467
    rli->report(ERROR_LEVEL, my_errno,
4201
 
                _("Error in %s event: write to '%s' failed"),
 
5468
                "Error in %s event: write to '%s' failed",
4202
5469
                get_type_str(), fname);
4203
5470
    goto err;
4204
5471
  }
4207
5474
err:
4208
5475
  if (fd >= 0)
4209
5476
    my_close(fd, MYF(0));
4210
 
  thd->set_proc_info(0);
4211
 
  return(error);
 
5477
  thd_proc_info(thd, 0);
 
5478
  DBUG_RETURN(error);
4212
5479
}
 
5480
#endif
4213
5481
 
4214
5482
 
4215
5483
/**************************************************************************
4220
5488
  Delete_file_log_event ctor
4221
5489
*/
4222
5490
 
 
5491
#ifndef MYSQL_CLIENT
4223
5492
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
4224
5493
                                             bool using_trans)
4225
5494
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4226
5495
{
4227
5496
}
 
5497
#endif
4228
5498
 
4229
5499
/*
4230
5500
  Delete_file_log_event ctor
4231
5501
*/
4232
5502
 
4233
 
Delete_file_log_event::Delete_file_log_event(const char* buf, uint32_t len,
 
5503
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
4234
5504
                                             const Format_description_log_event* description_event)
4235
5505
  :Log_event(buf, description_event),file_id(0)
4236
5506
{
4237
 
  uint8_t common_header_len= description_event->common_header_len;
4238
 
  uint8_t delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
 
5507
  uint8 common_header_len= description_event->common_header_len;
 
5508
  uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
4239
5509
  if (len < (uint)(common_header_len + delete_file_header_len))
4240
5510
    return;
4241
5511
  file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
4246
5516
  Delete_file_log_event::write()
4247
5517
*/
4248
5518
 
 
5519
#ifndef MYSQL_CLIENT
4249
5520
bool Delete_file_log_event::write(IO_CACHE* file)
4250
5521
{
4251
 
 unsigned char buf[DELETE_FILE_HEADER_LEN];
 
5522
 uchar buf[DELETE_FILE_HEADER_LEN];
4252
5523
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
4253
5524
 return (write_header(file, sizeof(buf)) ||
4254
5525
         my_b_safe_write(file, buf, sizeof(buf)));
4255
5526
}
4256
 
 
 
5527
#endif
 
5528
 
 
5529
 
 
5530
/*
 
5531
  Delete_file_log_event::print()
 
5532
*/
 
5533
 
 
5534
#ifdef MYSQL_CLIENT  
 
5535
void Delete_file_log_event::print(FILE* file,
 
5536
                                  PRINT_EVENT_INFO* print_event_info)
 
5537
{
 
5538
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5539
 
 
5540
  if (print_event_info->short_form)
 
5541
    return;
 
5542
  print_header(&cache, print_event_info, FALSE);
 
5543
  my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
 
5544
}
 
5545
#endif /* MYSQL_CLIENT */
4257
5546
 
4258
5547
/*
4259
5548
  Delete_file_log_event::pack_info()
4260
5549
*/
4261
5550
 
 
5551
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4262
5552
void Delete_file_log_event::pack_info(Protocol *protocol)
4263
5553
{
4264
5554
  char buf[64];
4265
 
  uint32_t length;
4266
 
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4267
 
  protocol->store(buf, (int32_t) length, &my_charset_bin);
 
5555
  uint length;
 
5556
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5557
  protocol->store(buf, (int32) length, &my_charset_bin);
4268
5558
}
 
5559
#endif
4269
5560
 
4270
5561
/*
4271
5562
  Delete_file_log_event::do_apply_event()
4272
5563
*/
4273
5564
 
4274
 
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
5565
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5566
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli)
4275
5567
{
4276
5568
  char fname[FN_REFLEN+10];
4277
5569
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
4278
5570
  (void) my_delete(fname, MYF(MY_WME));
4279
 
  my_stpcpy(ext, ".info");
 
5571
  strmov(ext, ".info");
4280
5572
  (void) my_delete(fname, MYF(MY_WME));
4281
5573
  return 0;
4282
5574
}
 
5575
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4283
5576
 
4284
5577
 
4285
5578
/**************************************************************************
4290
5583
  Execute_load_log_event ctor
4291
5584
*/
4292
5585
 
 
5586
#ifndef MYSQL_CLIENT  
4293
5587
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
4294
5588
                                               const char* db_arg,
4295
5589
                                               bool using_trans)
4296
5590
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4297
5591
{
4298
5592
}
 
5593
#endif
4299
5594
  
4300
5595
 
4301
5596
/*
4302
5597
  Execute_load_log_event ctor
4303
5598
*/
4304
5599
 
4305
 
Execute_load_log_event::Execute_load_log_event(const char* buf, uint32_t len,
 
5600
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
4306
5601
                                               const Format_description_log_event* description_event)
4307
5602
  :Log_event(buf, description_event), file_id(0)
4308
5603
{
4309
 
  uint8_t common_header_len= description_event->common_header_len;
4310
 
  uint8_t exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
 
5604
  uint8 common_header_len= description_event->common_header_len;
 
5605
  uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
4311
5606
  if (len < (uint)(common_header_len+exec_load_header_len))
4312
5607
    return;
4313
5608
  file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
4318
5613
  Execute_load_log_event::write()
4319
5614
*/
4320
5615
 
 
5616
#ifndef MYSQL_CLIENT
4321
5617
bool Execute_load_log_event::write(IO_CACHE* file)
4322
5618
{
4323
 
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
 
5619
  uchar buf[EXEC_LOAD_HEADER_LEN];
4324
5620
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
4325
5621
  return (write_header(file, sizeof(buf)) || 
4326
5622
          my_b_safe_write(file, buf, sizeof(buf)));
4327
5623
}
4328
 
 
 
5624
#endif
 
5625
 
 
5626
 
 
5627
/*
 
5628
  Execute_load_log_event::print()
 
5629
*/
 
5630
 
 
5631
#ifdef MYSQL_CLIENT  
 
5632
void Execute_load_log_event::print(FILE* file,
 
5633
                                   PRINT_EVENT_INFO* print_event_info)
 
5634
{
 
5635
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5636
 
 
5637
  if (print_event_info->short_form)
 
5638
    return;
 
5639
  print_header(&cache, print_event_info, FALSE);
 
5640
  my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
 
5641
              file_id);
 
5642
}
 
5643
#endif
4329
5644
 
4330
5645
/*
4331
5646
  Execute_load_log_event::pack_info()
4332
5647
*/
4333
5648
 
 
5649
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4334
5650
void Execute_load_log_event::pack_info(Protocol *protocol)
4335
5651
{
4336
5652
  char buf[64];
4337
 
  uint32_t length;
4338
 
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4339
 
  protocol->store(buf, (int32_t) length, &my_charset_bin);
 
5653
  uint length;
 
5654
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5655
  protocol->store(buf, (int32) length, &my_charset_bin);
4340
5656
}
4341
5657
 
4342
5658
 
4354
5670
  Load_log_event *lev= 0;
4355
5671
 
4356
5672
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
4357
 
  if ((fd = my_open(fname, O_RDONLY,
 
5673
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
4358
5674
                    MYF(MY_WME))) < 0 ||
4359
5675
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
4360
5676
                    MYF(MY_WME|MY_NABP)))
4361
5677
  {
4362
5678
    rli->report(ERROR_LEVEL, my_errno,
4363
 
                _("Error in Exec_load event: could not open file '%s'"),
 
5679
                "Error in Exec_load event: could not open file '%s'",
4364
5680
                fname);
4365
5681
    goto err;
4366
5682
  }
4369
5685
                                                         rli->relay_log.description_event_for_exec)) ||
4370
5686
      lev->get_type_code() != NEW_LOAD_EVENT)
4371
5687
  {
4372
 
    rli->report(ERROR_LEVEL, 0,
4373
 
                _("Error in Exec_load event: "
4374
 
                  "file '%s' appears corrupted"),
4375
 
                fname);
 
5688
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
 
5689
                    "file '%s' appears corrupted", fname);
4376
5690
    goto err;
4377
5691
  }
4378
5692
 
4400
5714
    if (tmp)
4401
5715
    {
4402
5716
      rli->report(ERROR_LEVEL, rli->last_error().number,
4403
 
                  _("%s. Failed executing load from '%s'"),
4404
 
                  tmp, fname);
4405
 
      free(tmp);
 
5717
                  "%s. Failed executing load from '%s'", tmp, fname);
 
5718
      my_free(tmp,MYF(0));
4406
5719
    }
4407
5720
    goto err;
4408
5721
  }
4431
5744
  return error;
4432
5745
}
4433
5746
 
 
5747
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5748
 
4434
5749
 
4435
5750
/**************************************************************************
4436
5751
        Begin_load_query_log_event methods
4437
5752
**************************************************************************/
4438
5753
 
 
5754
#ifndef MYSQL_CLIENT
4439
5755
Begin_load_query_log_event::
4440
 
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, unsigned char* block_arg,
4441
 
                           uint32_t block_len_arg, bool using_trans)
 
5756
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
 
5757
                           uint block_len_arg, bool using_trans)
4442
5758
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4443
5759
                          using_trans)
4444
5760
{
4445
5761
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4446
5762
}
 
5763
#endif
4447
5764
 
4448
5765
 
4449
5766
Begin_load_query_log_event::
4450
 
Begin_load_query_log_event(const char* buf, uint32_t len,
 
5767
Begin_load_query_log_event(const char* buf, uint len,
4451
5768
                           const Format_description_log_event* desc_event)
4452
5769
  :Append_block_log_event(buf, len, desc_event)
4453
5770
{
4454
5771
}
4455
5772
 
4456
5773
 
 
5774
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4457
5775
int Begin_load_query_log_event::get_create_or_append() const
4458
5776
{
4459
5777
  return 1; /* create the file */
4460
5778
}
4461
 
 
4462
 
 
 
5779
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5780
 
 
5781
 
 
5782
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4463
5783
Log_event::enum_skip_reason
4464
5784
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
4465
5785
{
4469
5789
  */
4470
5790
  return continue_group(rli);
4471
5791
}
 
5792
#endif
4472
5793
 
4473
5794
 
4474
5795
/**************************************************************************
4476
5797
**************************************************************************/
4477
5798
 
4478
5799
 
 
5800
#ifndef MYSQL_CLIENT
4479
5801
Execute_load_query_log_event::
4480
5802
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
4481
 
                             ulong query_length_arg, uint32_t fn_pos_start_arg,
4482
 
                             uint32_t fn_pos_end_arg,
 
5803
                             ulong query_length_arg, uint fn_pos_start_arg,
 
5804
                             uint fn_pos_end_arg,
4483
5805
                             enum_load_dup_handling dup_handling_arg,
4484
5806
                             bool using_trans, bool suppress_use,
4485
5807
                             THD::killed_state killed_err_arg):
4489
5811
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
4490
5812
{
4491
5813
}
 
5814
#endif /* !MYSQL_CLIENT */
4492
5815
 
4493
5816
 
4494
5817
Execute_load_query_log_event::
4495
 
Execute_load_query_log_event(const char* buf, uint32_t event_len,
 
5818
Execute_load_query_log_event(const char* buf, uint event_len,
4496
5819
                             const Format_description_log_event* desc_event):
4497
5820
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
4498
5821
  file_id(0), fn_pos_start(0), fn_pos_end(0)
4520
5843
}
4521
5844
 
4522
5845
 
 
5846
#ifndef MYSQL_CLIENT
4523
5847
bool
4524
5848
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
4525
5849
{
4526
 
  unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
5850
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
4527
5851
  int4store(buf, file_id);
4528
5852
  int4store(buf + 4, fn_pos_start);
4529
5853
  int4store(buf + 4 + 4, fn_pos_end);
4530
 
  *(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
 
5854
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
4531
5855
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
4532
5856
}
4533
 
 
4534
 
 
 
5857
#endif
 
5858
 
 
5859
 
 
5860
#ifdef MYSQL_CLIENT
 
5861
void Execute_load_query_log_event::print(FILE* file,
 
5862
                                         PRINT_EVENT_INFO* print_event_info)
 
5863
{
 
5864
  print(file, print_event_info, 0);
 
5865
}
 
5866
 
 
5867
/**
 
5868
  Prints the query as LOAD DATA LOCAL and with rewritten filename.
 
5869
*/
 
5870
void Execute_load_query_log_event::print(FILE* file,
 
5871
                                         PRINT_EVENT_INFO* print_event_info,
 
5872
                                         const char *local_fname)
 
5873
{
 
5874
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5875
 
 
5876
  print_query_header(&cache, print_event_info);
 
5877
 
 
5878
  if (local_fname)
 
5879
  {
 
5880
    my_b_write(&cache, (uchar*) query, fn_pos_start);
 
5881
    my_b_printf(&cache, " LOCAL INFILE \'");
 
5882
    my_b_printf(&cache, local_fname);
 
5883
    my_b_printf(&cache, "\'");
 
5884
    if (dup_handling == LOAD_DUP_REPLACE)
 
5885
      my_b_printf(&cache, " REPLACE");
 
5886
    my_b_printf(&cache, " INTO");
 
5887
    my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
 
5888
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5889
  }
 
5890
  else
 
5891
  {
 
5892
    my_b_write(&cache, (uchar*) query, q_len);
 
5893
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5894
  }
 
5895
 
 
5896
  if (!print_event_info->short_form)
 
5897
    my_b_printf(&cache, "# file_id: %d \n", file_id);
 
5898
}
 
5899
#endif
 
5900
 
 
5901
 
 
5902
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4535
5903
void Execute_load_query_log_event::pack_info(Protocol *protocol)
4536
5904
{
4537
5905
  char *buf, *pos;
4540
5908
  pos= buf;
4541
5909
  if (db && db_len)
4542
5910
  {
4543
 
    pos= my_stpcpy(buf, "use `");
 
5911
    pos= strmov(buf, "use `");
4544
5912
    memcpy(pos, db, db_len);
4545
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
5913
    pos= strmov(pos+db_len, "`; ");
4546
5914
  }
4547
5915
  if (query && q_len)
4548
5916
  {
4549
5917
    memcpy(pos, query, q_len);
4550
5918
    pos+= q_len;
4551
5919
  }
4552
 
  pos= my_stpcpy(pos, " ;file_id=");
 
5920
  pos= strmov(pos, " ;file_id=");
4553
5921
  pos= int10_to_str((long) file_id, pos, 10);
4554
5922
  protocol->store(buf, pos-buf, &my_charset_bin);
4555
 
  free(buf);
 
5923
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4556
5924
}
4557
5925
 
4558
5926
 
4568
5936
  buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
4569
5937
                         (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
4570
5938
 
 
5939
  DBUG_EXECUTE_IF("LOAD_DATA_INFILE_has_fatal_error", my_free(buf, MYF(0)); buf= NULL;);
 
5940
 
4571
5941
  /* Replace filename and LOCAL keyword in query before executing it */
4572
5942
  if (buf == NULL)
4573
5943
  {
4574
5944
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4575
 
                ER(ER_SLAVE_FATAL_ERROR),
4576
 
                _("Not enough memory"));
 
5945
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
4577
5946
    return 1;
4578
5947
  }
4579
5948
 
4582
5951
  p+= fn_pos_start;
4583
5952
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
4584
5953
  p= slave_load_file_stem(p, file_id, server_id, ".data");
4585
 
  fname_end= p= strchr(p, '\0');                      // Safer than p=p+5
 
5954
  fname_end= p= strend(p);                      // Safer than p=p+5
4586
5955
  *(p++)='\'';
4587
5956
  switch (dup_handling) {
4588
5957
  case LOAD_DUP_IGNORE:
4610
5979
  if (!error)
4611
5980
    (void) my_delete(fname, MYF(MY_WME));
4612
5981
 
4613
 
  free(buf);
 
5982
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4614
5983
  return error;
4615
5984
}
 
5985
#endif
4616
5986
 
4617
5987
 
4618
5988
/**************************************************************************
4632
6002
            write_str(file, line_term,  (uint) line_term_len) ||
4633
6003
            write_str(file, line_start, (uint) line_start_len) ||
4634
6004
            write_str(file, escaped,    (uint) escaped_len) ||
4635
 
            my_b_safe_write(file,(unsigned char*) &opt_flags,1));
 
6005
            my_b_safe_write(file,(uchar*) &opt_flags,1));
4636
6006
  }
4637
6007
  else
4638
6008
  {
4648
6018
    old_ex.escaped=    *escaped;
4649
6019
    old_ex.opt_flags=  opt_flags;
4650
6020
    old_ex.empty_flags=empty_flags;
4651
 
    return my_b_safe_write(file, (unsigned char*) &old_ex, sizeof(old_ex)) != 0;
 
6021
    return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
4652
6022
  }
4653
6023
}
4654
6024
 
4708
6078
        Rows_log_event member functions
4709
6079
**************************************************************************/
4710
6080
 
4711
 
Rows_log_event::Rows_log_event(THD *thd_arg, Table *tbl_arg, ulong tid,
 
6081
#ifndef MYSQL_CLIENT
 
6082
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
4712
6083
                               MY_BITMAP const *cols, bool is_transactional)
4713
6084
  : Log_event(thd_arg, 0, is_transactional),
4714
6085
    m_row_count(0),
4716
6087
    m_table_id(tid),
4717
6088
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
4718
6089
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
6090
#ifdef HAVE_REPLICATION
4719
6091
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
6092
#endif
4720
6093
{
4721
6094
  /*
4722
6095
    We allow a special form of dummy event when the table, and cols
4723
 
    are null and the table id is UINT32_MAX.  This is a temporary
 
6096
    are null and the table id is ~0UL.  This is a temporary
4724
6097
    solution, to be able to terminate a started statement in the
4725
6098
    binary log: the extraneous events will be removed in the future.
4726
6099
   */
4727
 
  assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
 
6100
  DBUG_ASSERT(tbl_arg && tbl_arg->s && tid != ~0UL ||
 
6101
              !tbl_arg && !cols && tid == ~0UL);
4728
6102
 
4729
6103
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
4730
6104
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
4736
6110
                          m_width,
4737
6111
                          false)))
4738
6112
  {
 
6113
    DBUG_PRINT_BITSET("debug", "init cols: %s", cols);
4739
6114
    /* Cols can be zero if this is a dummy binrows event */
4740
6115
    if (likely(cols != NULL))
4741
6116
    {
4749
6124
    m_cols.bitmap= 0;
4750
6125
  }
4751
6126
}
4752
 
 
4753
 
 
4754
 
Rows_log_event::Rows_log_event(const char *buf, uint32_t event_len,
 
6127
#endif
 
6128
 
 
6129
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
4755
6130
                               Log_event_type event_type,
4756
6131
                               const Format_description_log_event
4757
6132
                               *description_event)
4758
6133
  : Log_event(buf, description_event),
4759
6134
    m_row_count(0),
 
6135
#ifndef MYSQL_CLIENT
4760
6136
    m_table(NULL),
 
6137
#endif
4761
6138
    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
 
6139
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4762
6140
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
6141
#endif
4763
6142
{
4764
 
  uint8_t const common_header_len= description_event->common_header_len;
4765
 
  uint8_t const post_header_len= description_event->post_header_len[event_type-1];
 
6143
  DBUG_ENTER("Rows_log_event::Rows_log_event(const char*,...)");
 
6144
  uint8 const common_header_len= description_event->common_header_len;
 
6145
  uint8 const post_header_len= description_event->post_header_len[event_type-1];
 
6146
 
 
6147
  DBUG_PRINT("enter",("event_len: %u  common_header_len: %d  "
 
6148
                      "post_header_len: %d",
 
6149
                      event_len, common_header_len,
 
6150
                      post_header_len));
4766
6151
 
4767
6152
  const char *post_start= buf + common_header_len;
4768
6153
  post_start+= RW_MAPID_OFFSET;
4780
6165
 
4781
6166
  m_flags= uint2korr(post_start);
4782
6167
 
4783
 
  unsigned char const *const var_start=
4784
 
    (const unsigned char *)buf + common_header_len + post_header_len;
4785
 
  unsigned char const *const ptr_width= var_start;
4786
 
  unsigned char *ptr_after_width= (unsigned char*) ptr_width;
 
6168
  uchar const *const var_start=
 
6169
    (const uchar *)buf + common_header_len + post_header_len;
 
6170
  uchar const *const ptr_width= var_start;
 
6171
  uchar *ptr_after_width= (uchar*) ptr_width;
 
6172
  DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
4787
6173
  m_width = net_field_length(&ptr_after_width);
 
6174
  DBUG_PRINT("debug", ("m_width=%lu", m_width));
4788
6175
  /* if bitmap_init fails, catched in is_valid() */
4789
6176
  if (likely(!bitmap_init(&m_cols,
4790
6177
                          m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
4791
6178
                          m_width,
4792
6179
                          false)))
4793
6180
  {
 
6181
    DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
4794
6182
    memcpy(m_cols.bitmap, ptr_after_width, (m_width + 7) / 8);
4795
6183
    create_last_word_mask(&m_cols);
4796
6184
    ptr_after_width+= (m_width + 7) / 8;
 
6185
    DBUG_DUMP("m_cols", (uchar*) m_cols.bitmap, no_bytes_in_map(&m_cols));
4797
6186
  }
4798
6187
  else
4799
6188
  {
4800
6189
    // Needed because bitmap_init() does not set it to null on failure
4801
6190
    m_cols.bitmap= NULL;
4802
 
    return;
 
6191
    DBUG_VOID_RETURN;
4803
6192
  }
4804
6193
 
4805
6194
  m_cols_ai.bitmap= m_cols.bitmap; /* See explanation in is_valid() */
4806
6195
 
4807
6196
  if (event_type == UPDATE_ROWS_EVENT)
4808
6197
  {
 
6198
    DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
 
6199
 
4809
6200
    /* if bitmap_init fails, caught in is_valid() */
4810
6201
    if (likely(!bitmap_init(&m_cols_ai,
4811
6202
                            m_width <= sizeof(m_bitbuf_ai)*8 ? m_bitbuf_ai : NULL,
4812
6203
                            m_width,
4813
6204
                            false)))
4814
6205
    {
 
6206
      DBUG_PRINT("debug", ("Reading from %p", ptr_after_width));
4815
6207
      memcpy(m_cols_ai.bitmap, ptr_after_width, (m_width + 7) / 8);
4816
6208
      create_last_word_mask(&m_cols_ai);
4817
6209
      ptr_after_width+= (m_width + 7) / 8;
 
6210
      DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
 
6211
                no_bytes_in_map(&m_cols_ai));
4818
6212
    }
4819
6213
    else
4820
6214
    {
4821
6215
      // Needed because bitmap_init() does not set it to null on failure
4822
6216
      m_cols_ai.bitmap= 0;
4823
 
      return;
 
6217
      DBUG_VOID_RETURN;
4824
6218
    }
4825
6219
  }
4826
6220
 
4827
 
  const unsigned char* const ptr_rows_data= (const unsigned char*) ptr_after_width;
4828
 
 
4829
 
  size_t const data_size= event_len - (ptr_rows_data - (const unsigned char *) buf);
4830
 
 
4831
 
  m_rows_buf= (unsigned char*) my_malloc(data_size, MYF(MY_WME));
 
6221
  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
 
6222
 
 
6223
  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
 
6224
  DBUG_PRINT("info",("m_table_id: %lu  m_flags: %d  m_width: %lu  data_size: %lu",
 
6225
                     m_table_id, m_flags, m_width, (ulong) data_size));
 
6226
 
 
6227
  m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
4832
6228
  if (likely((bool)m_rows_buf))
4833
6229
  {
 
6230
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4834
6231
    m_curr_row= m_rows_buf;
 
6232
#endif
4835
6233
    m_rows_end= m_rows_buf + data_size;
4836
6234
    m_rows_cur= m_rows_end;
4837
6235
    memcpy(m_rows_buf, ptr_rows_data, data_size);
4839
6237
  else
4840
6238
    m_cols.bitmap= 0; // to not free it
4841
6239
 
4842
 
  return;
 
6240
  DBUG_VOID_RETURN;
4843
6241
}
4844
6242
 
4845
6243
Rows_log_event::~Rows_log_event()
4846
6244
{
4847
6245
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
4848
 
    m_cols.bitmap= 0; // so no free in bitmap_free
 
6246
    m_cols.bitmap= 0; // so no my_free in bitmap_free
4849
6247
  bitmap_free(&m_cols); // To pair with bitmap_init().
4850
 
  free((unsigned char*)m_rows_buf);
 
6248
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
4851
6249
}
4852
6250
 
4853
6251
int Rows_log_event::get_data_size()
4854
6252
{
4855
6253
  int const type_code= get_type_code();
4856
6254
 
4857
 
  unsigned char buf[sizeof(m_width)+1];
4858
 
  unsigned char *end= net_store_length(buf, (m_width + 7) / 8);
 
6255
  uchar buf[sizeof(m_width)+1];
 
6256
  uchar *end= net_store_length(buf, (m_width + 7) / 8);
4859
6257
 
 
6258
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
6259
                  return 6 + no_bytes_in_map(&m_cols) + (end - buf) +
 
6260
                  (type_code == UPDATE_ROWS_EVENT ? no_bytes_in_map(&m_cols_ai) : 0) +
 
6261
                  (m_rows_cur - m_rows_buf););
4860
6262
  int data_size= ROWS_HEADER_LEN;
4861
6263
  data_size+= no_bytes_in_map(&m_cols);
4862
6264
  data_size+= end - buf;
4869
6271
}
4870
6272
 
4871
6273
 
4872
 
int Rows_log_event::do_add_row_data(unsigned char *row_data, size_t length)
 
6274
#ifndef MYSQL_CLIENT
 
6275
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
4873
6276
{
4874
6277
  /*
4875
6278
    When the table has a primary key, we would probably want, by default, to
4876
6279
    log only the primary key value instead of the entire "before image". This
4877
6280
    would save binlog space. TODO
4878
6281
  */
 
6282
  DBUG_ENTER("Rows_log_event::do_add_row_data");
 
6283
  DBUG_PRINT("enter", ("row_data: 0x%lx  length: %lu", (ulong) row_data,
 
6284
                       (ulong) length));
4879
6285
 
4880
6286
  /*
4881
6287
    If length is zero, there is nothing to write, so we just
4885
6291
  if (length == 0)
4886
6292
  {
4887
6293
    m_row_count++;
4888
 
    return(0);
 
6294
    DBUG_RETURN(0);
4889
6295
  }
4890
6296
 
4891
 
  assert(m_rows_buf <= m_rows_cur);
4892
 
  assert(!m_rows_buf || (m_rows_end && m_rows_buf <= m_rows_end));
4893
 
  assert(m_rows_cur <= m_rows_end);
 
6297
  /*
 
6298
    Don't print debug messages when running valgrind since they can
 
6299
    trigger false warnings.
 
6300
   */
 
6301
#ifndef HAVE_purify
 
6302
  DBUG_DUMP("row_data", row_data, min(length, 32));
 
6303
#endif
 
6304
 
 
6305
  DBUG_ASSERT(m_rows_buf <= m_rows_cur);
 
6306
  DBUG_ASSERT(!m_rows_buf || m_rows_end && m_rows_buf <= m_rows_end);
 
6307
  DBUG_ASSERT(m_rows_cur <= m_rows_end);
4894
6308
 
4895
6309
  /* The cast will always work since m_rows_cur <= m_rows_end */
4896
6310
  if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
4900
6314
    my_ptrdiff_t const new_alloc= 
4901
6315
        block_size * ((cur_size + length + block_size - 1) / block_size);
4902
6316
 
4903
 
    unsigned char* const new_buf= (unsigned char*)my_realloc((unsigned char*)m_rows_buf, (uint) new_alloc,
 
6317
    uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
4904
6318
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
4905
6319
    if (unlikely(!new_buf))
4906
 
      return(HA_ERR_OUT_OF_MEM);
 
6320
      DBUG_RETURN(HA_ERR_OUT_OF_MEM);
4907
6321
 
4908
6322
    /* If the memory moved, we need to move the pointers */
4909
6323
    if (new_buf != m_rows_buf)
4919
6333
    m_rows_end= m_rows_buf + new_alloc;
4920
6334
  }
4921
6335
 
4922
 
  assert(m_rows_cur + length <= m_rows_end);
 
6336
  DBUG_ASSERT(m_rows_cur + length <= m_rows_end);
4923
6337
  memcpy(m_rows_cur, row_data, length);
4924
6338
  m_rows_cur+= length;
4925
6339
  m_row_count++;
4926
 
  return(0);
 
6340
  DBUG_RETURN(0);
4927
6341
}
 
6342
#endif
4928
6343
 
 
6344
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4929
6345
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
4930
6346
{
 
6347
  DBUG_ENTER("Rows_log_event::do_apply_event(Relay_log_info*)");
4931
6348
  int error= 0;
4932
6349
  /*
4933
 
    If m_table_id == UINT32_MAX, then we have a dummy event that does not
 
6350
    If m_table_id == ~0UL, then we have a dummy event that does not
4934
6351
    contain any data.  In that case, we just remove all tables in the
4935
6352
    tables_to_lock list, close the thread tables, and return with
4936
6353
    success.
4937
6354
   */
4938
 
  if (m_table_id == UINT32_MAX)
 
6355
  if (m_table_id == ~0UL)
4939
6356
  {
4940
6357
    /*
4941
6358
       This one is supposed to be set: just an extra check so that
4942
6359
       nothing strange has happened.
4943
6360
     */
4944
 
    assert(get_flags(STMT_END_F));
 
6361
    DBUG_ASSERT(get_flags(STMT_END_F));
4945
6362
 
4946
6363
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4947
6364
    close_thread_tables(thd);
4948
6365
    thd->clear_error();
4949
 
    return(0);
 
6366
    DBUG_RETURN(0);
4950
6367
  }
4951
6368
 
4952
6369
  /*
4954
6371
    do_apply_event(). We still check here to prevent future coding
4955
6372
    errors.
4956
6373
  */
4957
 
  assert(rli->sql_thd == thd);
 
6374
  DBUG_ASSERT(rli->sql_thd == thd);
4958
6375
 
4959
6376
  /*
4960
6377
    If there is no locks taken, this is the first binrow event seen
4989
6406
    else
4990
6407
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4991
6408
    /* A small test to verify that objects have consistent types */
4992
 
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6409
    DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4993
6410
 
4994
6411
 
4995
6412
    while ((error= lock_tables(thd, rli->tables_to_lock,
5003
6420
            Error reporting borrowed from Query_log_event with many excessive
5004
6421
            simplifications (we don't honour --slave-skip-errors)
5005
6422
          */
5006
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6423
          uint actual_error= thd->main_da.sql_errno();
5007
6424
          rli->report(ERROR_LEVEL, actual_error,
5008
 
                      _("Error '%s' in %s event: when locking tables"),
5009
 
                      (actual_error
5010
 
                       ? thd->main_da.message()
5011
 
                       : _("unexpected success or fatal error")),
 
6425
                      "Error '%s' in %s event: when locking tables",
 
6426
                      (actual_error ? thd->main_da.message():
 
6427
                       "unexpected success or fatal error"),
5012
6428
                      get_type_str());
5013
6429
          thd->is_fatal_error= 1;
5014
6430
        }
5015
6431
        else
5016
6432
        {
5017
6433
          rli->report(ERROR_LEVEL, error,
5018
 
                      _("Error in %s event: when locking tables"),
 
6434
                      "Error in %s event: when locking tables",
5019
6435
                      get_type_str());
5020
6436
        }
5021
6437
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5022
 
        return(error);
 
6438
        DBUG_RETURN(error);
5023
6439
      }
5024
6440
 
5025
6441
      /*
5036
6452
        need to add code to assert that is the case.
5037
6453
       */
5038
6454
      thd->binlog_flush_pending_rows_event(false);
5039
 
      TableList *tables= rli->tables_to_lock;
 
6455
      TABLE_LIST *tables= rli->tables_to_lock;
5040
6456
      close_tables_for_reopen(thd, &tables);
5041
6457
 
5042
 
      uint32_t tables_count= rli->tables_to_lock_count;
 
6458
      uint tables_count= rli->tables_to_lock_count;
5043
6459
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
5044
6460
      {
5045
6461
        if (thd->is_slave_error || thd->is_fatal_error)
5048
6464
            Error reporting borrowed from Query_log_event with many excessive
5049
6465
            simplifications (we don't honour --slave-skip-errors)
5050
6466
          */
5051
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6467
          uint actual_error= thd->main_da.sql_errno();
5052
6468
          rli->report(ERROR_LEVEL, actual_error,
5053
 
                      _("Error '%s' on reopening tables"),
5054
 
                      (actual_error
5055
 
                       ? thd->main_da.message()
5056
 
                       : _("unexpected success or fatal error")));
 
6469
                      "Error '%s' on reopening tables",
 
6470
                      (actual_error ? thd->main_da.message() :
 
6471
                       "unexpected success or fatal error"));
5057
6472
          thd->is_slave_error= 1;
5058
6473
        }
5059
6474
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5060
 
        return(error);
 
6475
        DBUG_RETURN(error);
5061
6476
      }
5062
6477
    }
5063
6478
 
5066
6481
      ensure that they still have the correct type.
5067
6482
 
5068
6483
      We can use a down cast here since we know that every table added
5069
 
      to the tables_to_lock is a RPL_TableList.
 
6484
      to the tables_to_lock is a RPL_TABLE_LIST.
5070
6485
    */
5071
6486
 
5072
6487
    {
5073
 
      RPL_TableList *ptr= rli->tables_to_lock;
5074
 
      for ( ; ptr ; ptr= static_cast<RPL_TableList*>(ptr->next_global))
 
6488
      RPL_TABLE_LIST *ptr= rli->tables_to_lock;
 
6489
      for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
5075
6490
      {
5076
6491
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
5077
6492
        {
5079
6494
          thd->lock= 0;
5080
6495
          thd->is_slave_error= 1;
5081
6496
          const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5082
 
          return(ERR_BAD_TABLE_DEF);
 
6497
          DBUG_RETURN(ERR_BAD_TABLE_DEF);
5083
6498
        }
5084
6499
      }
5085
6500
    }
5098
6513
      Rows_log_event, we can invalidate the query cache for the
5099
6514
      associated table.
5100
6515
     */
5101
 
    for (TableList *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
 
6516
    for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
5102
6517
    {
5103
6518
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
5104
6519
    }
5105
6520
  }
5106
6521
 
5107
 
  Table* 
 
6522
  TABLE* 
5108
6523
    table= 
5109
6524
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
5110
6525
 
5146
6561
      thd->options&= ~OPTION_ALLOW_BATCH;
5147
6562
    
5148
6563
    /* A small test to verify that objects have consistent types */
5149
 
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6564
    DBUG_ASSERT(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
5150
6565
 
5151
6566
    /*
5152
6567
      Now we are in a statement and will stay in a statement until we
5172
6587
      longer if slave has extra columns. 
5173
6588
     */ 
5174
6589
 
 
6590
    DBUG_PRINT_BITSET("debug", "Setting table's write_set from: %s", &m_cols);
 
6591
 
5175
6592
    bitmap_set_all(table->read_set);
5176
6593
    bitmap_set_all(table->write_set);
5177
6594
    if (!get_flags(COMPLETE_ROWS_F))
5220
6637
      case HA_ERR_FOREIGN_DUPLICATE_KEY:
5221
6638
      case HA_ERR_NO_REFERENCED_ROW:
5222
6639
      case HA_ERR_ROW_IS_REFERENCED:
 
6640
 
 
6641
        DBUG_PRINT("info", ("error: %s", HA_ERR(error)));
5223
6642
        if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
5224
6643
        {
5225
6644
          if (global_system_variables.log_warnings)
5241
6660
       (i.e., error==0 at this point) we must call unpack_current_row() to set 
5242
6661
       m_curr_row_end.
5243
6662
      */ 
 
6663
   
 
6664
      DBUG_PRINT("info", ("error: %d", error));
 
6665
      DBUG_PRINT("info", ("curr_row: 0x%lu; curr_row_end: 0x%lu; rows_end: 0x%lu",
 
6666
                          (ulong) m_curr_row, (ulong) m_curr_row_end, (ulong) m_rows_end));
 
6667
 
5244
6668
      if (!m_curr_row_end && !error)
5245
6669
        unpack_current_row(rli, &m_cols);
5246
6670
  
5247
6671
      // at this moment m_curr_row_end should be set
5248
 
      assert(error || m_curr_row_end != NULL); 
5249
 
      assert(error || m_curr_row < m_curr_row_end);
5250
 
      assert(error || m_curr_row_end <= m_rows_end);
 
6672
      DBUG_ASSERT(error || m_curr_row_end != NULL); 
 
6673
      DBUG_ASSERT(error || m_curr_row < m_curr_row_end);
 
6674
      DBUG_ASSERT(error || m_curr_row_end <= m_rows_end);
5251
6675
  
5252
6676
      m_curr_row= m_curr_row_end;
5253
6677
 
5254
6678
    } // row processing loop
5255
6679
 
 
6680
    DBUG_EXECUTE_IF("STOP_SLAVE_after_first_Rows_event",
 
6681
                    const_cast<Relay_log_info*>(rli)->abort_slave= 1;);
5256
6682
    error= do_after_row_operations(rli, error);
5257
6683
    if (!cache_stmt)
5258
6684
    {
 
6685
      DBUG_PRINT("info", ("Marked that we need to keep log"));
5259
6686
      thd->options|= OPTION_KEEP_LOG;
5260
6687
    }
5261
6688
  } // if (table)
5290
6717
    thd->reset_current_stmt_binlog_row_based();
5291
6718
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
5292
6719
    thd->is_slave_error= 1;
5293
 
    return(error);
 
6720
    DBUG_RETURN(error);
5294
6721
  }
5295
6722
 
5296
6723
  /*
5320
6747
    const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
5321
6748
  }
5322
6749
 
5323
 
  return(0);
 
6750
  DBUG_RETURN(0);
5324
6751
}
5325
6752
 
5326
6753
Log_event::enum_skip_reason
5340
6767
int
5341
6768
Rows_log_event::do_update_pos(Relay_log_info *rli)
5342
6769
{
 
6770
  DBUG_ENTER("Rows_log_event::do_update_pos");
5343
6771
  int error= 0;
5344
6772
 
 
6773
  DBUG_PRINT("info", ("flags: %s",
 
6774
                      get_flags(STMT_END_F) ? "STMT_END_F " : ""));
 
6775
 
5345
6776
  if (get_flags(STMT_END_F))
5346
6777
  {
5347
6778
    /*
5406
6837
    }
5407
6838
    else
5408
6839
      rli->report(ERROR_LEVEL, error,
5409
 
                  _("Error in %s event: commit of row events failed, "
5410
 
                    "table `%s`.`%s`"),
 
6840
                  "Error in %s event: commit of row events failed, "
 
6841
                  "table `%s`.`%s`",
5411
6842
                  get_type_str(), m_table->s->db.str,
5412
6843
                  m_table->s->table_name.str);
5413
6844
  }
5416
6847
    rli->inc_event_relay_log_pos();
5417
6848
  }
5418
6849
 
5419
 
  return(error);
 
6850
  DBUG_RETURN(error);
5420
6851
}
5421
6852
 
 
6853
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
6854
 
 
6855
#ifndef MYSQL_CLIENT
5422
6856
bool Rows_log_event::write_data_header(IO_CACHE *file)
5423
6857
{
5424
 
  unsigned char buf[ROWS_HEADER_LEN];   // No need to init the buffer
5425
 
  assert(m_table_id != UINT32_MAX);
5426
 
  int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
 
6858
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
6859
  DBUG_ASSERT(m_table_id != ~0UL);
 
6860
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
6861
                  {
 
6862
                    int4store(buf + 0, m_table_id);
 
6863
                    int2store(buf + 4, m_flags);
 
6864
                    return (my_b_safe_write(file, buf, 6));
 
6865
                  });
 
6866
  int6store(buf + RW_MAPID_OFFSET, (ulonglong)m_table_id);
5427
6867
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
5428
6868
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
5429
6869
}
5434
6874
     Note that this should be the number of *bits*, not the number of
5435
6875
     bytes.
5436
6876
  */
5437
 
  unsigned char sbuf[sizeof(m_width)];
 
6877
  uchar sbuf[sizeof(m_width)];
5438
6878
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
5439
6879
  bool res= false;
5440
 
  unsigned char *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
5441
 
  assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
 
6880
  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
 
6881
  DBUG_ASSERT(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
5442
6882
 
 
6883
  DBUG_DUMP("m_width", sbuf, (size_t) (sbuf_end - sbuf));
5443
6884
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
5444
6885
 
5445
 
  res= res || my_b_safe_write(file, (unsigned char*) m_cols.bitmap,
 
6886
  DBUG_PRINT_BITSET("debug", "writing cols: %s", &m_cols);
 
6887
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
5446
6888
                              no_bytes_in_map(&m_cols));
5447
6889
  /*
5448
6890
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
5449
6891
   */
5450
6892
  if (get_type_code() == UPDATE_ROWS_EVENT)
5451
6893
  {
5452
 
    res= res || my_b_safe_write(file, (unsigned char*) m_cols_ai.bitmap,
 
6894
    DBUG_DUMP("m_cols_ai", (uchar*) m_cols_ai.bitmap,
 
6895
              no_bytes_in_map(&m_cols_ai));
 
6896
    res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
5453
6897
                                no_bytes_in_map(&m_cols_ai));
5454
6898
  }
 
6899
  DBUG_DUMP("rows", m_rows_buf, data_size);
5455
6900
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
5456
6901
 
5457
6902
  return res;
5458
6903
 
5459
6904
}
5460
 
 
5461
 
 
 
6905
#endif
 
6906
 
 
6907
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5462
6908
void Rows_log_event::pack_info(Protocol *protocol)
5463
6909
{
5464
6910
  char buf[256];
5465
6911
  char const *const flagstr=
5466
6912
    get_flags(STMT_END_F) ? " flags: STMT_END_F" : "";
5467
 
  size_t bytes= snprintf(buf, sizeof(buf),
5468
 
                         "table_id: %lu%s", m_table_id, flagstr);
 
6913
  size_t bytes= my_snprintf(buf, sizeof(buf),
 
6914
                               "table_id: %lu%s", m_table_id, flagstr);
5469
6915
  protocol->store(buf, bytes, &my_charset_bin);
5470
6916
}
5471
 
 
 
6917
#endif
 
6918
 
 
6919
#ifdef MYSQL_CLIENT
 
6920
void Rows_log_event::print_helper(FILE *file,
 
6921
                                  PRINT_EVENT_INFO *print_event_info,
 
6922
                                  char const *const name)
 
6923
{
 
6924
  IO_CACHE *const head= &print_event_info->head_cache;
 
6925
  IO_CACHE *const body= &print_event_info->body_cache;
 
6926
  if (!print_event_info->short_form)
 
6927
  {
 
6928
    bool const last_stmt_event= get_flags(STMT_END_F);
 
6929
    print_header(head, print_event_info, !last_stmt_event);
 
6930
    my_b_printf(head, "\t%s: table id %lu%s\n",
 
6931
                name, m_table_id,
 
6932
                last_stmt_event ? " flags: STMT_END_F" : "");
 
6933
    print_base64(body, print_event_info, !last_stmt_event);
 
6934
  }
 
6935
 
 
6936
  if (get_flags(STMT_END_F))
 
6937
  {
 
6938
    copy_event_cache_to_file_and_reinit(head, file);
 
6939
    copy_event_cache_to_file_and_reinit(body, file);
 
6940
  }
 
6941
}
 
6942
#endif
5472
6943
 
5473
6944
/**************************************************************************
5474
6945
        Table_map_log_event member functions and support functions
5495
6966
  same as the columns for the table on the slave.
5496
6967
 
5497
6968
  Additionally, values saved for field metadata on the master are saved as a 
5498
 
  string of bytes (unsigned char) in the binlog. A field may require 1 or more bytes
 
6969
  string of bytes (uchar) in the binlog. A field may require 1 or more bytes
5499
6970
  to store the information. In cases where values require multiple bytes 
5500
6971
  (e.g. values > 255), the endian-safe methods are used to properly encode 
5501
6972
  the values on the master and decode them on the slave. When the field
5502
6973
  metadata values are captured on the slave, they are stored in an array of
5503
 
  type uint16_t. This allows the least number of casts to prevent casting bugs
 
6974
  type uint16. This allows the least number of casts to prevent casting bugs
5504
6975
  when the field metadata is used in comparisons of field attributes. When
5505
6976
  the field metadata is used for calculating addresses in pointer math, the
5506
 
  type used is uint32_t. 
 
6977
  type used is uint32. 
5507
6978
*/
5508
6979
 
 
6980
#if !defined(MYSQL_CLIENT)
5509
6981
/**
5510
6982
  Save the field metadata based on the real_type of the field.
5511
6983
  The metadata saved depends on the type of the field. Some fields
5532
7004
*/
5533
7005
int Table_map_log_event::save_field_metadata()
5534
7006
{
 
7007
  DBUG_ENTER("Table_map_log_event::save_field_metadata");
5535
7008
  int index= 0;
5536
7009
  for (unsigned int i= 0 ; i < m_table->s->fields ; i++)
5537
7010
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
5538
 
  return(index);
 
7011
  DBUG_RETURN(index);
5539
7012
}
 
7013
#endif /* !defined(MYSQL_CLIENT) */
5540
7014
 
5541
7015
/*
5542
7016
  Constructor used to build an event for writing to the binary log.
5543
7017
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
5544
7018
  (tbl->s->db etc) and not pointer content.
5545
7019
 */
5546
 
Table_map_log_event::Table_map_log_event(THD *thd, Table *tbl, ulong tid,
5547
 
                                         bool is_transactional __attribute__((unused)),
5548
 
                                         uint16_t flags)
 
7020
#if !defined(MYSQL_CLIENT)
 
7021
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
 
7022
                                         bool is_transactional, uint16 flags)
5549
7023
  : Log_event(thd, 0, true),
5550
7024
    m_table(tbl),
5551
7025
    m_dbnam(tbl->s->db.str),
5562
7036
    m_null_bits(0),
5563
7037
    m_meta_memory(NULL)
5564
7038
{
5565
 
  assert(m_table_id != UINT32_MAX);
 
7039
  DBUG_ASSERT(m_table_id != ~0UL);
5566
7040
  /*
5567
7041
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
5568
7042
    table.cc / alloc_table_share():
5569
7043
      Use the fact the key is db/0/table_name/0
5570
7044
    As we rely on this let's assert it.
5571
7045
  */
5572
 
  assert((tbl->s->db.str == 0) ||
 
7046
  DBUG_ASSERT((tbl->s->db.str == 0) ||
5573
7047
              (tbl->s->db.str[tbl->s->db.length] == 0));
5574
 
  assert(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
 
7048
  DBUG_ASSERT(tbl->s->table_name.str[tbl->s->table_name.length] == 0);
5575
7049
 
5576
7050
 
5577
7051
  m_data_size=  TABLE_MAP_HEADER_LEN;
 
7052
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master", m_data_size= 6;);
5578
7053
  m_data_size+= m_dblen + 2;    // Include length and terminating \0
5579
7054
  m_data_size+= m_tbllen + 2;   // Include length and terminating \0
5580
7055
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
5581
7056
 
5582
7057
  /* If malloc fails, caught in is_valid() */
5583
 
  if ((m_memory= (unsigned char*) my_malloc(m_colcnt, MYF(MY_WME))))
 
7058
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
5584
7059
  {
5585
 
    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
 
7060
    m_coltype= reinterpret_cast<uchar*>(m_memory);
5586
7061
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5587
7062
      m_coltype[i]= m_table->field[i]->type();
5588
7063
  }
5593
7068
    that is not on the slave and is null and thus not in the row data during
5594
7069
    replication.
5595
7070
  */
5596
 
  uint32_t num_null_bytes= (m_table->s->fields + 7) / 8;
 
7071
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
5597
7072
  m_data_size+= num_null_bytes;
5598
 
  m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
 
7073
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5599
7074
                                 &m_null_bits, num_null_bytes,
5600
7075
                                 &m_field_metadata, (m_colcnt * 2),
5601
7076
                                 NULL);
5602
7077
 
5603
 
  memset(m_field_metadata, 0, (m_colcnt * 2));
 
7078
  bzero(m_field_metadata, (m_colcnt * 2));
5604
7079
 
5605
7080
  /*
5606
7081
    Create an array for the field metadata and store it.
5607
7082
  */
5608
7083
  m_field_metadata_size= save_field_metadata();
5609
 
  assert(m_field_metadata_size <= (m_colcnt * 2));
 
7084
  DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
5610
7085
 
5611
7086
  /*
5612
7087
    Now set the size of the data to the size of the field metadata array
5617
7092
  else
5618
7093
    m_data_size+= m_field_metadata_size + 1; 
5619
7094
 
5620
 
  memset(m_null_bits, 0, num_null_bytes);
 
7095
  bzero(m_null_bits, num_null_bytes);
5621
7096
  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5622
7097
    if (m_table->field[i]->maybe_null())
5623
7098
      m_null_bits[(i / 8)]+= 1 << (i % 8);
5624
7099
 
5625
7100
}
5626
 
 
 
7101
#endif /* !defined(MYSQL_CLIENT) */
5627
7102
 
5628
7103
/*
5629
7104
  Constructor used by slave to read the event from the binary log.
5630
7105
 */
5631
 
Table_map_log_event::Table_map_log_event(const char *buf, uint32_t event_len,
 
7106
#if defined(HAVE_REPLICATION)
 
7107
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
5632
7108
                                         const Format_description_log_event
5633
7109
                                         *description_event)
5634
7110
 
5635
7111
  : Log_event(buf, description_event),
 
7112
#ifndef MYSQL_CLIENT
5636
7113
    m_table(NULL),
 
7114
#endif
5637
7115
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
5638
7116
    m_colcnt(0), m_coltype(0),
5639
7117
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
5641
7119
    m_null_bits(0), m_meta_memory(NULL)
5642
7120
{
5643
7121
  unsigned int bytes_read= 0;
5644
 
 
5645
 
  uint8_t common_header_len= description_event->common_header_len;
5646
 
  uint8_t post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
 
7122
  DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
 
7123
 
 
7124
  uint8 common_header_len= description_event->common_header_len;
 
7125
  uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
 
7126
  DBUG_PRINT("info",("event_len: %u  common_header_len: %d  post_header_len: %d",
 
7127
                     event_len, common_header_len, post_header_len));
 
7128
 
 
7129
  /*
 
7130
    Don't print debug messages when running valgrind since they can
 
7131
    trigger false warnings.
 
7132
   */
 
7133
#ifndef HAVE_purify
 
7134
  DBUG_DUMP("event buffer", (uchar*) buf, event_len);
 
7135
#endif
5647
7136
 
5648
7137
  /* Read the post-header */
5649
7138
  const char *post_start= buf + common_header_len;
5657
7146
  }
5658
7147
  else
5659
7148
  {
5660
 
    assert(post_header_len == TABLE_MAP_HEADER_LEN);
 
7149
    DBUG_ASSERT(post_header_len == TABLE_MAP_HEADER_LEN);
5661
7150
    m_table_id= (ulong) uint6korr(post_start);
5662
7151
    post_start+= TM_FLAGS_OFFSET;
5663
7152
  }
5664
7153
 
5665
 
  assert(m_table_id != UINT32_MAX);
 
7154
  DBUG_ASSERT(m_table_id != ~0UL);
5666
7155
 
5667
7156
  m_flags= uint2korr(post_start);
5668
7157
 
5670
7159
  const char *const vpart= buf + common_header_len + post_header_len;
5671
7160
 
5672
7161
  /* Extract the length of the various parts from the buffer */
5673
 
  unsigned char const *const ptr_dblen= (unsigned char const*)vpart + 0;
5674
 
  m_dblen= *(unsigned char*) ptr_dblen;
 
7162
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
 
7163
  m_dblen= *(uchar*) ptr_dblen;
5675
7164
 
5676
7165
  /* Length of database name + counter + terminating null */
5677
 
  unsigned char const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
5678
 
  m_tbllen= *(unsigned char*) ptr_tbllen;
 
7166
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
7167
  m_tbllen= *(uchar*) ptr_tbllen;
5679
7168
 
5680
7169
  /* Length of table name + counter + terminating null */
5681
 
  unsigned char const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
5682
 
  unsigned char *ptr_after_colcnt= (unsigned char*) ptr_colcnt;
 
7170
  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
 
7171
  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
5683
7172
  m_colcnt= net_field_length(&ptr_after_colcnt);
5684
7173
 
 
7174
  DBUG_PRINT("info",("m_dblen: %lu  off: %ld  m_tbllen: %lu  off: %ld  m_colcnt: %lu  off: %ld",
 
7175
                     (ulong) m_dblen, (long) (ptr_dblen-(const uchar*)vpart), 
 
7176
                     (ulong) m_tbllen, (long) (ptr_tbllen-(const uchar*)vpart),
 
7177
                     m_colcnt, (long) (ptr_colcnt-(const uchar*)vpart)));
 
7178
 
5685
7179
  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
5686
 
  m_memory= (unsigned char*) my_multi_malloc(MYF(MY_WME),
 
7180
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
5687
7181
                                     &m_dbnam, (uint) m_dblen + 1,
5688
7182
                                     &m_tblnam, (uint) m_tbllen + 1,
5689
7183
                                     &m_coltype, (uint) m_colcnt,
5690
 
                                     NULL);
 
7184
                                     NullS);
5691
7185
 
5692
7186
  if (m_memory)
5693
7187
  {
5697
7191
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
5698
7192
 
5699
7193
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
5700
 
    bytes_read= ptr_after_colcnt - (unsigned char *)buf;
 
7194
    bytes_read= ptr_after_colcnt - (uchar *)buf;
 
7195
    DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
5701
7196
    if (bytes_read < event_len)
5702
7197
    {
5703
7198
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
5704
 
      assert(m_field_metadata_size <= (m_colcnt * 2));
5705
 
      uint32_t num_null_bytes= (m_colcnt + 7) / 8;
5706
 
      m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
 
7199
      DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
 
7200
      uint num_null_bytes= (m_colcnt + 7) / 8;
 
7201
      m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5707
7202
                                     &m_null_bits, num_null_bytes,
5708
7203
                                     &m_field_metadata, m_field_metadata_size,
5709
7204
                                     NULL);
5710
7205
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
5711
 
      ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
 
7206
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
5712
7207
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
5713
7208
    }
5714
7209
  }
5715
7210
 
5716
 
  return;
 
7211
  DBUG_VOID_RETURN;
5717
7212
}
 
7213
#endif
5718
7214
 
5719
7215
Table_map_log_event::~Table_map_log_event()
5720
7216
{
5721
 
  free(m_meta_memory);
5722
 
  free(m_memory);
 
7217
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
 
7218
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
5723
7219
}
5724
7220
 
5725
7221
/*
5733
7229
       4     Daisy-chaining RBR with SBR not possible
5734
7230
 */
5735
7231
 
 
7232
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5736
7233
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
5737
7234
{
5738
 
  RPL_TableList *table_list;
 
7235
  RPL_TABLE_LIST *table_list;
5739
7236
  char *db_mem, *tname_mem;
5740
7237
  size_t dummy_len;
5741
7238
  void *memory;
5742
 
  assert(rli->sql_thd == thd);
 
7239
  DBUG_ENTER("Table_map_log_event::do_apply_event(Relay_log_info*)");
 
7240
  DBUG_ASSERT(rli->sql_thd == thd);
5743
7241
 
5744
7242
  /* Step the query id to mark what columns that are actually used. */
5745
7243
  pthread_mutex_lock(&LOCK_thread_count);
5747
7245
  pthread_mutex_unlock(&LOCK_thread_count);
5748
7246
 
5749
7247
  if (!(memory= my_multi_malloc(MYF(MY_WME),
5750
 
                                &table_list, (uint) sizeof(RPL_TableList),
 
7248
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
5751
7249
                                &db_mem, (uint) NAME_LEN + 1,
5752
7250
                                &tname_mem, (uint) NAME_LEN + 1,
5753
 
                                NULL)))
5754
 
    return(HA_ERR_OUT_OF_MEM);
 
7251
                                NullS)))
 
7252
    DBUG_RETURN(HA_ERR_OUT_OF_MEM);
5755
7253
 
5756
 
  memset(table_list, 0, sizeof(*table_list));
 
7254
  bzero(table_list, sizeof(*table_list));
5757
7255
  table_list->db = db_mem;
5758
7256
  table_list->alias= table_list->table_name = tname_mem;
5759
7257
  table_list->lock_type= TL_WRITE;
5760
7258
  table_list->next_global= table_list->next_local= 0;
5761
7259
  table_list->table_id= m_table_id;
5762
7260
  table_list->updating= 1;
5763
 
  my_stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
5764
 
  my_stpcpy(table_list->table_name, m_tblnam);
 
7261
  strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
 
7262
  strmov(table_list->table_name, m_tblnam);
5765
7263
 
5766
7264
  int error= 0;
5767
7265
 
5768
7266
  if (!rpl_filter->db_ok(table_list->db) ||
5769
7267
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
5770
7268
  {
5771
 
    free(memory);
 
7269
    my_free(memory, MYF(MY_WME));
5772
7270
  }
5773
7271
  else
5774
7272
  {
5795
7293
      table map.  Note that for any table that should not be
5796
7294
      replicated, a filter is needed.
5797
7295
 
5798
 
      The creation of a new TableList is used to up-cast the
5799
 
      table_list consisting of RPL_TableList items. This will work
 
7296
      The creation of a new TABLE_LIST is used to up-cast the
 
7297
      table_list consisting of RPL_TABLE_LIST items. This will work
5800
7298
      since the only case where the argument to open_tables() is
5801
7299
      changed, is when thd->lex->query_tables == table_list, i.e.,
5802
7300
      when the statement requires prelocking. Since this is not
5808
7306
      internally in the open_tables() function, hence we take a copy
5809
7307
      of the pointer to make sure that it's not lost.
5810
7308
    */
5811
 
    uint32_t count;
5812
 
    assert(thd->lex->query_tables != table_list);
5813
 
    TableList *tmp_table_list= table_list;
 
7309
    uint count;
 
7310
    DBUG_ASSERT(thd->lex->query_tables != table_list);
 
7311
    TABLE_LIST *tmp_table_list= table_list;
5814
7312
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5815
7313
    {
5816
7314
      if (thd->is_slave_error || thd->is_fatal_error)
5819
7317
          Error reporting borrowed from Query_log_event with many excessive
5820
7318
          simplifications (we don't honour --slave-skip-errors)
5821
7319
        */
5822
 
        uint32_t actual_error= thd->main_da.sql_errno();
 
7320
        uint actual_error= thd->main_da.sql_errno();
5823
7321
        rli->report(ERROR_LEVEL, actual_error,
5824
 
                    _("Error '%s' on opening table `%s`.`%s`"),
5825
 
                    (actual_error
5826
 
                     ? thd->main_da.message()
5827
 
                     : _("unexpected success or fatal error")),
 
7322
                    "Error '%s' on opening table `%s`.`%s`",
 
7323
                    (actual_error ? thd->main_da.message() :
 
7324
                     "unexpected success or fatal error"),
5828
7325
                    table_list->db, table_list->table_name);
5829
7326
        thd->is_slave_error= 1;
5830
7327
      }
5837
7334
      This will fail later otherwise, the 'in_use' field should be
5838
7335
      set to the current thread.
5839
7336
    */
5840
 
    assert(m_table->in_use);
 
7337
    DBUG_ASSERT(m_table->in_use);
5841
7338
 
5842
7339
    /*
5843
7340
      Use placement new to construct the table_def instance in the
5850
7347
    */
5851
7348
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, 
5852
7349
         m_field_metadata, m_field_metadata_size, m_null_bits);
5853
 
    table_list->m_tabledef_valid= true;
 
7350
    table_list->m_tabledef_valid= TRUE;
5854
7351
 
5855
7352
    /*
5856
7353
      We record in the slave's information that the table should be
5862
7359
    /* 'memory' is freed in clear_tables_to_lock */
5863
7360
  }
5864
7361
 
5865
 
  return(error);
 
7362
  DBUG_RETURN(error);
5866
7363
 
5867
7364
err:
5868
 
  free(memory);
5869
 
  return(error);
 
7365
  my_free(memory, MYF(MY_WME));
 
7366
  DBUG_RETURN(error);
5870
7367
}
5871
7368
 
5872
7369
Log_event::enum_skip_reason
5885
7382
  return 0;
5886
7383
}
5887
7384
 
 
7385
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
5888
7386
 
 
7387
#ifndef MYSQL_CLIENT
5889
7388
bool Table_map_log_event::write_data_header(IO_CACHE *file)
5890
7389
{
5891
 
  assert(m_table_id != UINT32_MAX);
5892
 
  unsigned char buf[TABLE_MAP_HEADER_LEN];
5893
 
  int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
 
7390
  DBUG_ASSERT(m_table_id != ~0UL);
 
7391
  uchar buf[TABLE_MAP_HEADER_LEN];
 
7392
  DBUG_EXECUTE_IF("old_row_based_repl_4_byte_map_id_master",
 
7393
                  {
 
7394
                    int4store(buf + 0, m_table_id);
 
7395
                    int2store(buf + 4, m_flags);
 
7396
                    return (my_b_safe_write(file, buf, 6));
 
7397
                  });
 
7398
  int6store(buf + TM_MAPID_OFFSET, (ulonglong)m_table_id);
5894
7399
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
5895
7400
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
5896
7401
}
5897
7402
 
5898
7403
bool Table_map_log_event::write_data_body(IO_CACHE *file)
5899
7404
{
5900
 
  assert(m_dbnam != NULL);
5901
 
  assert(m_tblnam != NULL);
 
7405
  DBUG_ASSERT(m_dbnam != NULL);
 
7406
  DBUG_ASSERT(m_tblnam != NULL);
5902
7407
  /* We use only one byte per length for storage in event: */
5903
 
  assert(m_dblen < 128);
5904
 
  assert(m_tbllen < 128);
5905
 
 
5906
 
  unsigned char const dbuf[]= { (unsigned char) m_dblen };
5907
 
  unsigned char const tbuf[]= { (unsigned char) m_tbllen };
5908
 
 
5909
 
  unsigned char cbuf[sizeof(m_colcnt)];
5910
 
  unsigned char *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
5911
 
  assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
 
7408
  DBUG_ASSERT(m_dblen < 128);
 
7409
  DBUG_ASSERT(m_tbllen < 128);
 
7410
 
 
7411
  uchar const dbuf[]= { (uchar) m_dblen };
 
7412
  uchar const tbuf[]= { (uchar) m_tbllen };
 
7413
 
 
7414
  uchar cbuf[sizeof(m_colcnt)];
 
7415
  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
 
7416
  DBUG_ASSERT(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
5912
7417
 
5913
7418
  /*
5914
7419
    Store the size of the field metadata.
5915
7420
  */
5916
 
  unsigned char mbuf[sizeof(m_field_metadata_size)];
5917
 
  unsigned char *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
 
7421
  uchar mbuf[sizeof(m_field_metadata_size)];
 
7422
  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
5918
7423
 
5919
7424
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
5920
 
          my_b_safe_write(file, (const unsigned char*)m_dbnam,   m_dblen+1) ||
 
7425
          my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
5921
7426
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
5922
 
          my_b_safe_write(file, (const unsigned char*)m_tblnam,  m_tbllen+1) ||
 
7427
          my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
5923
7428
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
5924
7429
          my_b_safe_write(file, m_coltype, m_colcnt) ||
5925
7430
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
5926
7431
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
5927
7432
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
5928
7433
 }
 
7434
#endif
5929
7435
 
 
7436
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5930
7437
 
5931
7438
/*
5932
7439
  Print some useful information for the SHOW BINARY LOG information
5933
7440
  field.
5934
7441
 */
5935
7442
 
 
7443
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5936
7444
void Table_map_log_event::pack_info(Protocol *protocol)
5937
7445
{
5938
7446
    char buf[256];
5939
 
    size_t bytes= snprintf(buf, sizeof(buf),
5940
 
                           "table_id: %lu (%s.%s)",
5941
 
                           m_table_id, m_dbnam, m_tblnam);
 
7447
    size_t bytes= my_snprintf(buf, sizeof(buf),
 
7448
                                 "table_id: %lu (%s.%s)",
 
7449
                              m_table_id, m_dbnam, m_tblnam);
5942
7450
    protocol->store(buf, bytes, &my_charset_bin);
5943
7451
}
5944
 
 
 
7452
#endif
 
7453
 
 
7454
 
 
7455
#endif
 
7456
 
 
7457
 
 
7458
#ifdef MYSQL_CLIENT
 
7459
void Table_map_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
 
7460
{
 
7461
  if (!print_event_info->short_form)
 
7462
  {
 
7463
    print_header(&print_event_info->head_cache, print_event_info, TRUE);
 
7464
    my_b_printf(&print_event_info->head_cache,
 
7465
                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
 
7466
                m_dbnam, m_tblnam, m_table_id);
 
7467
    print_base64(&print_event_info->body_cache, print_event_info, TRUE);
 
7468
  }
 
7469
}
 
7470
#endif
5945
7471
 
5946
7472
/**************************************************************************
5947
7473
        Write_rows_log_event member functions
5950
7476
/*
5951
7477
  Constructor used to build an event for writing to the binary log.
5952
7478
 */
5953
 
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7479
#if !defined(MYSQL_CLIENT)
 
7480
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
5954
7481
                                           ulong tid_arg,
5955
7482
                                           bool is_transactional)
5956
7483
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
5957
7484
{
5958
7485
}
 
7486
#endif
5959
7487
 
5960
7488
/*
5961
7489
  Constructor used by slave to read the event from the binary log.
5962
7490
 */
5963
 
Write_rows_log_event::Write_rows_log_event(const char *buf, uint32_t event_len,
 
7491
#ifdef HAVE_REPLICATION
 
7492
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
5964
7493
                                           const Format_description_log_event
5965
7494
                                           *description_event)
5966
7495
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
5967
7496
{
5968
7497
}
 
7498
#endif
5969
7499
 
 
7500
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5970
7501
int 
5971
7502
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5972
7503
{
6044
7575
  return error? error : local_error;
6045
7576
}
6046
7577
 
 
7578
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6047
7579
 
6048
7580
/*
6049
7581
  Check if there are more UNIQUE keys after the given key.
6050
7582
*/
6051
7583
static int
6052
 
last_uniq_key(Table *table, uint32_t keyno)
 
7584
last_uniq_key(TABLE *table, uint keyno)
6053
7585
{
6054
7586
  while (++keyno < table->s->keys)
6055
7587
    if (table->key_info[keyno].flags & HA_NOSAME)
6121
7653
Rows_log_event::write_row(const Relay_log_info *const rli,
6122
7654
                          const bool overwrite)
6123
7655
{
6124
 
  assert(m_table != NULL && thd != NULL);
 
7656
  DBUG_ENTER("write_row");
 
7657
  DBUG_ASSERT(m_table != NULL && thd != NULL);
6125
7658
 
6126
 
  Table *table= m_table;  // pointer to event's table
 
7659
  TABLE *table= m_table;  // pointer to event's table
6127
7660
  int error;
6128
7661
  int keynum;
6129
7662
  auto_afree_ptr<char> key(NULL);
6140
7673
     values filled in and one flag to handle the case that the default
6141
7674
     values should be checked. Maybe these two flags can be combined.
6142
7675
  */
6143
 
  if ((error= prepare_record(table, &m_cols, m_width, true)))
6144
 
    return(error);
 
7676
  if ((error= prepare_record(table, &m_cols, m_width,
 
7677
                             table->file->ht->db_type != DB_TYPE_NDBCLUSTER)))
 
7678
    DBUG_RETURN(error);
6145
7679
  
6146
7680
  /* unpack row into table->record[0] */
6147
7681
  error= unpack_current_row(rli, &m_cols);
6149
7683
  // Temporary fix to find out why it fails [/Matz]
6150
7684
  memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
6151
7685
 
 
7686
#ifndef DBUG_OFF
 
7687
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
7688
  DBUG_PRINT_BITSET("debug", "write_set = %s", table->write_set);
 
7689
  DBUG_PRINT_BITSET("debug", "read_set = %s", table->read_set);
 
7690
#endif
 
7691
 
6152
7692
  /* 
6153
7693
    Try to write record. If a corresponding record already exists in the table,
6154
7694
    we try to change it using ha_update_row() if possible. Otherwise we delete
6164
7704
        (keynum= table->file->get_dup_key(error)) < 0 ||
6165
7705
        !overwrite)
6166
7706
    {
 
7707
      DBUG_PRINT("info",("get_dup_key returns %d)", keynum));
6167
7708
      /*
6168
7709
        Deadlock, waiting for lock or just an error from the handler
6169
7710
        such as HA_ERR_FOUND_DUPP_KEY when overwrite is false.
6172
7713
        - or because the information which key is not available
6173
7714
      */
6174
7715
      table->file->print_error(error, MYF(0));
6175
 
      return(error);
 
7716
      DBUG_RETURN(error);
6176
7717
    }
6177
7718
    /*
6178
7719
       We need to retrieve the old row into record[1] to be able to
6186
7727
     */
6187
7728
    if (table->file->ha_table_flags() & HA_DUPLICATE_POS)
6188
7729
    {
 
7730
      DBUG_PRINT("info",("Locating offending record using rnd_pos()"));
6189
7731
      if (table->file->inited && (error= table->file->ha_index_end()))
6190
 
        return(error);
6191
 
      if ((error= table->file->ha_rnd_init(false)))
6192
 
        return(error);
 
7732
        DBUG_RETURN(error);
 
7733
      if ((error= table->file->ha_rnd_init(FALSE)))
 
7734
        DBUG_RETURN(error);
6193
7735
 
6194
7736
      error= table->file->rnd_pos(table->record[1], table->file->dup_ref);
6195
7737
      table->file->ha_rnd_end();
6196
7738
      if (error)
6197
7739
      {
 
7740
        DBUG_PRINT("info",("rnd_pos() returns error %d",error));
6198
7741
        table->file->print_error(error, MYF(0));
6199
 
        return(error);
 
7742
        DBUG_RETURN(error);
6200
7743
      }
6201
7744
    }
6202
7745
    else
6203
7746
    {
 
7747
      DBUG_PRINT("info",("Locating offending record using index_read_idx()"));
 
7748
 
6204
7749
      if (table->file->extra(HA_EXTRA_FLUSH_CACHE))
6205
7750
      {
6206
 
        return(my_errno);
 
7751
        DBUG_PRINT("info",("Error when setting HA_EXTRA_FLUSH_CACHE"));
 
7752
        DBUG_RETURN(my_errno);
6207
7753
      }
6208
7754
 
6209
7755
      if (key.get() == NULL)
6211
7757
        key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
6212
7758
        if (key.get() == NULL)
6213
7759
        {
6214
 
          return(ENOMEM);
 
7760
          DBUG_PRINT("info",("Can't allocate key buffer"));
 
7761
          DBUG_RETURN(ENOMEM);
6215
7762
        }
6216
7763
      }
6217
7764
 
6218
 
      key_copy((unsigned char*)key.get(), table->record[0], table->key_info + keynum,
 
7765
      key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
6219
7766
               0);
6220
7767
      error= table->file->index_read_idx_map(table->record[1], keynum,
6221
 
                                             (const unsigned char*)key.get(),
 
7768
                                             (const uchar*)key.get(),
6222
7769
                                             HA_WHOLE_KEY,
6223
7770
                                             HA_READ_KEY_EXACT);
6224
7771
      if (error)
6225
7772
      {
 
7773
        DBUG_PRINT("info",("index_read_idx() returns error %d",error)); 
6226
7774
        table->file->print_error(error, MYF(0));
6227
 
        return(error);
 
7775
        DBUG_RETURN(error);
6228
7776
      }
6229
7777
    }
6230
7778
 
6244
7792
      error= unpack_current_row(rli, &m_cols);
6245
7793
    }
6246
7794
 
 
7795
#ifndef DBUG_OFF
 
7796
    DBUG_PRINT("debug",("preparing for update: before and after image"));
 
7797
    DBUG_DUMP("record[1] (before)", table->record[1], table->s->reclength);
 
7798
    DBUG_DUMP("record[0] (after)", table->record[0], table->s->reclength);
 
7799
#endif
 
7800
 
6247
7801
    /*
6248
7802
       REPLACE is defined as either INSERT or DELETE + INSERT.  If
6249
7803
       possible, we can replace it with an UPDATE, but that will not
6262
7816
    if (last_uniq_key(table, keynum) &&
6263
7817
        !table->file->referenced_by_foreign_key())
6264
7818
    {
 
7819
      DBUG_PRINT("info",("Updating row using ha_update_row()"));
6265
7820
      error=table->file->ha_update_row(table->record[1],
6266
7821
                                       table->record[0]);
6267
7822
      switch (error) {
6268
7823
                
6269
7824
      case HA_ERR_RECORD_IS_THE_SAME:
 
7825
        DBUG_PRINT("info",("ignoring HA_ERR_RECORD_IS_THE_SAME error from"
 
7826
                           " ha_update_row()"));
6270
7827
        error= 0;
6271
7828
      
6272
7829
      case 0:
6273
7830
        break;
6274
7831
        
6275
7832
      default:    
 
7833
        DBUG_PRINT("info",("ha_update_row() returns error %d",error));
6276
7834
        table->file->print_error(error, MYF(0));
6277
7835
      }
6278
7836
      
6279
 
      return(error);
 
7837
      DBUG_RETURN(error);
6280
7838
    }
6281
7839
    else
6282
7840
    {
 
7841
      DBUG_PRINT("info",("Deleting offending row and trying to write new one again"));
6283
7842
      if ((error= table->file->ha_delete_row(table->record[1])))
6284
7843
      {
 
7844
        DBUG_PRINT("info",("ha_delete_row() returns error %d",error));
6285
7845
        table->file->print_error(error, MYF(0));
6286
 
        return(error);
 
7846
        DBUG_RETURN(error);
6287
7847
      }
6288
7848
      /* Will retry ha_write_row() with the offending row removed. */
6289
7849
    }
6290
7850
  }
6291
7851
 
6292
 
  return(error);
 
7852
  DBUG_RETURN(error);
6293
7853
}
6294
7854
 
 
7855
#endif
6295
7856
 
6296
7857
int 
6297
7858
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6298
7859
{
6299
 
  assert(m_table != NULL);
 
7860
  DBUG_ASSERT(m_table != NULL);
6300
7861
  int error=
6301
7862
    write_row(rli,        /* if 1 then overwrite */
6302
7863
              bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
6303
7864
    
6304
7865
  if (error && !thd->is_error())
6305
7866
  {
6306
 
    assert(0);
 
7867
    DBUG_ASSERT(0);
6307
7868
    my_error(ER_UNKNOWN_ERROR, MYF(0));
6308
7869
  }
6309
7870
  
6310
7871
  return error; 
6311
7872
}
6312
7873
 
 
7874
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7875
 
 
7876
#ifdef MYSQL_CLIENT
 
7877
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
 
7878
{
 
7879
  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
 
7880
}
 
7881
#endif
6313
7882
 
6314
7883
/**************************************************************************
6315
7884
        Delete_rows_log_event member functions
6316
7885
**************************************************************************/
6317
7886
 
 
7887
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6318
7888
/*
6319
7889
  Compares table->record[0] and table->record[1]
6320
7890
 
6321
7891
  Returns TRUE if different.
6322
7892
*/
6323
 
static bool record_compare(Table *table)
 
7893
static bool record_compare(TABLE *table)
6324
7894
{
6325
7895
  /*
6326
7896
    Need to set the X bit and the filler bits in both records since
6333
7903
    TODO[record format ndb]: Remove it once NDB returns correct
6334
7904
    records. Check that the other engines also return correct records.
6335
7905
   */
6336
 
  bool result= false;
6337
 
  unsigned char saved_x[2], saved_filler[2];
 
7906
 
 
7907
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
7908
  DBUG_DUMP("record[1]", table->record[1], table->s->reclength);
 
7909
 
 
7910
  bool result= FALSE;
 
7911
  uchar saved_x[2], saved_filler[2];
6338
7912
 
6339
7913
  if (table->s->null_bytes > 0)
6340
7914
  {
6359
7933
             table->null_flags+table->s->rec_buff_length,
6360
7934
             table->s->null_bytes))
6361
7935
  {
6362
 
    result= true;                               // Diff in NULL value
 
7936
    result= TRUE;                               // Diff in NULL value
6363
7937
    goto record_compare_exit;
6364
7938
  }
6365
7939
 
6368
7942
  {
6369
7943
    if ((*ptr)->cmp_binary_offset(table->s->rec_buff_length))
6370
7944
    {
6371
 
      result= true;
 
7945
      result= TRUE;
6372
7946
      goto record_compare_exit;
6373
7947
    }
6374
7948
  }
6421
7995
 
6422
7996
int Rows_log_event::find_row(const Relay_log_info *rli)
6423
7997
{
6424
 
  assert(m_table && m_table->in_use != NULL);
6425
 
 
6426
 
  Table *table= m_table;
 
7998
  DBUG_ENTER("Rows_log_event::find_row");
 
7999
 
 
8000
  DBUG_ASSERT(m_table && m_table->in_use != NULL);
 
8001
 
 
8002
  TABLE *table= m_table;
6427
8003
  int error;
6428
8004
 
6429
8005
  /* unpack row - missing fields get default values */
6430
 
  prepare_record(table, &m_cols, m_width, false/* don't check errors */); 
 
8006
  prepare_record(table, &m_cols, m_width, FALSE /* don't check errors */); 
6431
8007
  error= unpack_current_row(rli, &m_cols);
6432
8008
 
6433
8009
  // Temporary fix to find out why it fails [/Matz]
6434
8010
  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
6435
8011
 
 
8012
#ifndef DBUG_OFF
 
8013
  DBUG_PRINT("info",("looking for the following record"));
 
8014
  DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
8015
  DBUG_DUMP("read_set", (uchar*) table->read_set->bitmap, (table->read_set->n_bits + 7) / 8);
 
8016
#endif
 
8017
 
6436
8018
  if ((table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
6437
8019
      table->s->primary_key < MAX_KEY)
6438
8020
  {
6450
8032
 
6451
8033
      ADD>>>  store_record(table,record[1]);
6452
8034
              int error= table->file->rnd_pos(table->record[0], table->file->ref);
6453
 
      ADD>>>  assert(memcmp(table->record[1], table->record[0],
 
8035
      ADD>>>  DBUG_ASSERT(memcmp(table->record[1], table->record[0],
6454
8036
                                 table->s->reclength) == 0);
6455
8037
    */
6456
8038
 
 
8039
    DBUG_PRINT("info",("locating record using primary key (position)"));
6457
8040
    int error= table->file->rnd_pos_by_record(table->record[0]);
6458
8041
    table->file->ha_rnd_end();
6459
8042
    if (error)
6460
8043
    {
 
8044
      DBUG_PRINT("info",("rnd_pos returns error %d",error));
6461
8045
      table->file->print_error(error, MYF(0));
6462
8046
    }
6463
 
    return(error);
 
8047
    DBUG_RETURN(error);
6464
8048
  }
6465
8049
 
6466
8050
  // We can't use position() - try other methods.
6473
8057
 
6474
8058
  if (table->s->keys > 0)
6475
8059
  {
 
8060
    DBUG_PRINT("info",("locating record using primary key (index_read)"));
 
8061
 
6476
8062
    /* We have a key: search the table using the index */
6477
 
    if (!table->file->inited && (error= table->file->ha_index_init(0, false)))
 
8063
    if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE)))
6478
8064
    {
 
8065
      DBUG_PRINT("info",("ha_index_init returns error %d",error));
6479
8066
      table->file->print_error(error, MYF(0));
6480
8067
      goto err;
6481
8068
    }
6482
8069
 
6483
8070
    /* Fill key data for the row */
6484
8071
 
6485
 
    assert(m_key);
 
8072
    DBUG_ASSERT(m_key);
6486
8073
    key_copy(m_key, table->record[0], table->key_info, 0);
6487
8074
 
6488
8075
    /*
 
8076
      Don't print debug messages when running valgrind since they can
 
8077
      trigger false warnings.
 
8078
     */
 
8079
#ifndef HAVE_purify
 
8080
    DBUG_DUMP("key data", m_key, table->key_info->key_length);
 
8081
#endif
 
8082
 
 
8083
    /*
6489
8084
      We need to set the null bytes to ensure that the filler bit are
6490
8085
      all set when returning.  There are storage engines that just set
6491
8086
      the necessary bits on the bytes and don't set the filler bits
6499
8094
                                            HA_WHOLE_KEY,
6500
8095
                                            HA_READ_KEY_EXACT)))
6501
8096
    {
 
8097
      DBUG_PRINT("info",("no record matching the key found in the table"));
6502
8098
      table->file->print_error(error, MYF(0));
6503
8099
      table->file->ha_index_end();
6504
8100
      goto err;
6505
8101
    }
6506
8102
 
 
8103
  /*
 
8104
    Don't print debug messages when running valgrind since they can
 
8105
    trigger false warnings.
 
8106
   */
 
8107
#ifndef HAVE_purify
 
8108
    DBUG_PRINT("info",("found first matching record")); 
 
8109
    DBUG_DUMP("record[0]", table->record[0], table->s->reclength);
 
8110
#endif
6507
8111
    /*
6508
8112
      Below is a minor "optimization".  If the key (i.e., key number
6509
8113
      0) has the HA_NOSAME flag set, we know that we have found the
6529
8133
      and find the one which is identical to the row given. A copy of the 
6530
8134
      record we are looking for is stored in record[1].
6531
8135
     */ 
 
8136
    DBUG_PRINT("info",("non-unique index, scanning it to find matching record")); 
 
8137
 
6532
8138
    while (record_compare(table))
6533
8139
    {
6534
8140
      /*
6548
8154
 
6549
8155
      if ((error= table->file->index_next(table->record[0])))
6550
8156
      {
 
8157
        DBUG_PRINT("info",("no record matching the given row found"));
6551
8158
        table->file->print_error(error, MYF(0));
6552
8159
        table->file->ha_index_end();
6553
8160
        goto err;
6561
8168
  }
6562
8169
  else
6563
8170
  {
 
8171
    DBUG_PRINT("info",("locating record using table scan (rnd_next)"));
 
8172
 
6564
8173
    int restart_count= 0; // Number of times scanning has restarted from top
6565
8174
 
6566
8175
    /* We don't have a key: search the table using rnd_next() */
6567
8176
    if ((error= table->file->ha_rnd_init(1)))
6568
8177
    {
 
8178
      DBUG_PRINT("info",("error initializing table scan"
 
8179
                         " (ha_rnd_init returns %d)",error));
6569
8180
      table->file->print_error(error, MYF(0));
6570
8181
      goto err;
6571
8182
    }
6587
8198
        break;
6588
8199
 
6589
8200
      default:
 
8201
        DBUG_PRINT("info", ("Failed to get next record"
 
8202
                            " (rnd_next returns %d)",error));
6590
8203
        table->file->print_error(error, MYF(0));
6591
8204
        table->file->ha_rnd_end();
6592
8205
        goto err;
6598
8211
      Note: above record_compare will take into accout all record fields 
6599
8212
      which might be incorrect in case a partial row was given in the event
6600
8213
     */
 
8214
 
 
8215
    /*
 
8216
      Have to restart the scan to be able to fetch the next row.
 
8217
    */
 
8218
    if (restart_count == 2)
 
8219
    {
 
8220
      DBUG_PRINT("info", ("Record not found"));
 
8221
    }
 
8222
    else
 
8223
    {
 
8224
      DBUG_DUMP("record found", table->record[0], table->s->reclength);
 
8225
    }
6601
8226
    table->file->ha_rnd_end();
6602
8227
 
6603
 
    assert(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
 
8228
    DBUG_ASSERT(error == HA_ERR_END_OF_FILE || error == HA_ERR_RECORD_DELETED || error == 0);
6604
8229
    goto err;
6605
8230
  }
6606
8231
ok:
6607
8232
  table->default_column_bitmaps();
6608
 
  return(0);
 
8233
  DBUG_RETURN(0);
6609
8234
err:
6610
8235
  table->default_column_bitmaps();
6611
 
  return(error);
 
8236
  DBUG_RETURN(error);
6612
8237
}
6613
8238
 
 
8239
#endif
6614
8240
 
6615
8241
/*
6616
8242
  Constructor used to build an event for writing to the binary log.
6617
8243
 */
6618
8244
 
6619
 
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
8245
#ifndef MYSQL_CLIENT
 
8246
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6620
8247
                                             ulong tid,
6621
8248
                                             bool is_transactional)
6622
8249
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6623
8250
{
6624
8251
}
 
8252
#endif /* #if !defined(MYSQL_CLIENT) */
6625
8253
 
6626
8254
/*
6627
8255
  Constructor used by slave to read the event from the binary log.
6628
8256
 */
6629
 
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint32_t event_len,
 
8257
#ifdef HAVE_REPLICATION
 
8258
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
6630
8259
                                             const Format_description_log_event
6631
8260
                                             *description_event)
6632
8261
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
6633
8262
{
6634
8263
}
 
8264
#endif
6635
8265
 
 
8266
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6636
8267
 
6637
8268
int 
6638
8269
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6649
8280
  if (m_table->s->keys > 0)
6650
8281
  {
6651
8282
    // Allocate buffer for key searches
6652
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8283
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6653
8284
    if (!m_key)
6654
8285
      return HA_ERR_OUT_OF_MEM;
6655
8286
  }
6663
8294
{
6664
8295
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6665
8296
  m_table->file->ha_index_or_rnd_end();
6666
 
  free(m_key);
 
8297
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
6667
8298
  m_key= NULL;
6668
8299
 
6669
8300
  return error;
6672
8303
int Delete_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6673
8304
{
6674
8305
  int error;
6675
 
  assert(m_table != NULL);
 
8306
  DBUG_ASSERT(m_table != NULL);
6676
8307
 
6677
8308
  if (!(error= find_row(rli))) 
6678
8309
  { 
6684
8315
  return error;
6685
8316
}
6686
8317
 
 
8318
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8319
 
 
8320
#ifdef MYSQL_CLIENT
 
8321
void Delete_rows_log_event::print(FILE *file,
 
8322
                                  PRINT_EVENT_INFO* print_event_info)
 
8323
{
 
8324
  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
 
8325
}
 
8326
#endif
 
8327
 
6687
8328
 
6688
8329
/**************************************************************************
6689
8330
        Update_rows_log_event member functions
6692
8333
/*
6693
8334
  Constructor used to build an event for writing to the binary log.
6694
8335
 */
6695
 
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
8336
#if !defined(MYSQL_CLIENT)
 
8337
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6696
8338
                                             ulong tid,
6697
8339
                                             bool is_transactional)
6698
8340
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6716
8358
    }
6717
8359
  }
6718
8360
}
 
8361
#endif /* !defined(MYSQL_CLIENT) */
6719
8362
 
6720
8363
 
6721
8364
Update_rows_log_event::~Update_rows_log_event()
6722
8365
{
6723
8366
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
6724
 
    m_cols_ai.bitmap= 0; // so no free in bitmap_free
 
8367
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
6725
8368
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
6726
8369
}
6727
8370
 
6729
8372
/*
6730
8373
  Constructor used by slave to read the event from the binary log.
6731
8374
 */
6732
 
Update_rows_log_event::Update_rows_log_event(const char *buf, uint32_t event_len,
 
8375
#ifdef HAVE_REPLICATION
 
8376
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
6733
8377
                                             const
6734
8378
                                             Format_description_log_event
6735
8379
                                             *description_event)
6736
8380
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
6737
8381
{
6738
8382
}
 
8383
#endif
6739
8384
 
 
8385
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6740
8386
 
6741
8387
int 
6742
8388
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6744
8390
  if (m_table->s->keys > 0)
6745
8391
  {
6746
8392
    // Allocate buffer for key searches
6747
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8393
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6748
8394
    if (!m_key)
6749
8395
      return HA_ERR_OUT_OF_MEM;
6750
8396
  }
6760
8406
{
6761
8407
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6762
8408
  m_table->file->ha_index_or_rnd_end();
6763
 
  free(m_key); // Free for multi_malloc
 
8409
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
6764
8410
  m_key= NULL;
6765
8411
 
6766
8412
  return error;
6769
8415
int 
6770
8416
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6771
8417
{
6772
 
  assert(m_table != NULL);
 
8418
  DBUG_ASSERT(m_table != NULL);
6773
8419
 
6774
8420
  int error= find_row(rli); 
6775
8421
  if (error)
6803
8449
    Now we have the right row to update.  The old row (the one we're
6804
8450
    looking for) is in record[1] and the new row is in record[0].
6805
8451
  */
 
8452
#ifndef HAVE_purify
 
8453
  /*
 
8454
    Don't print debug messages when running valgrind since they can
 
8455
    trigger false warnings.
 
8456
   */
 
8457
  DBUG_PRINT("info",("Updating row in table"));
 
8458
  DBUG_DUMP("old record", m_table->record[1], m_table->s->reclength);
 
8459
  DBUG_DUMP("new values", m_table->record[0], m_table->s->reclength);
 
8460
#endif
6806
8461
 
6807
8462
  // Temporary fix to find out why it fails [/Matz]
6808
8463
  memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
6815
8470
  return error;
6816
8471
}
6817
8472
 
6818
 
 
6819
 
Incident_log_event::Incident_log_event(const char *buf, uint32_t event_len,
 
8473
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8474
 
 
8475
#ifdef MYSQL_CLIENT
 
8476
void Update_rows_log_event::print(FILE *file,
 
8477
                                  PRINT_EVENT_INFO* print_event_info)
 
8478
{
 
8479
  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
 
8480
}
 
8481
#endif
 
8482
 
 
8483
 
 
8484
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
6820
8485
                                       const Format_description_log_event *descr_event)
6821
8486
  : Log_event(buf, descr_event)
6822
8487
{
6823
 
  uint8_t const common_header_len=
 
8488
  DBUG_ENTER("Incident_log_event::Incident_log_event");
 
8489
  uint8 const common_header_len=
6824
8490
    descr_event->common_header_len;
6825
 
  uint8_t const post_header_len=
 
8491
  uint8 const post_header_len=
6826
8492
    descr_event->post_header_len[INCIDENT_EVENT-1];
6827
8493
 
 
8494
  DBUG_PRINT("info",("event_len: %u; common_header_len: %d; post_header_len: %d",
 
8495
                     event_len, common_header_len, post_header_len));
 
8496
 
6828
8497
  m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
6829
8498
  char const *ptr= buf + common_header_len + post_header_len;
6830
8499
  char const *const str_end= buf + event_len;
6831
 
  uint8_t len= 0;                   // Assignment to keep compiler happy
 
8500
  uint8 len= 0;                   // Assignment to keep compiler happy
6832
8501
  const char *str= NULL;          // Assignment to keep compiler happy
6833
8502
  read_str(&ptr, str_end, &str, &len);
6834
8503
  m_message.str= const_cast<char*>(str);
6835
8504
  m_message.length= len;
6836
 
  return;
 
8505
  DBUG_PRINT("info", ("m_incident: %d", m_incident));
 
8506
  DBUG_VOID_RETURN;
6837
8507
}
6838
8508
 
6839
8509
 
6850
8520
    "LOST_EVENTS"
6851
8521
  };
6852
8522
 
6853
 
  assert(0 <= m_incident);
6854
 
  assert((size_t) m_incident <= sizeof(description)/sizeof(*description));
 
8523
  DBUG_PRINT("info", ("m_incident: %d", m_incident));
 
8524
 
 
8525
  DBUG_ASSERT(0 <= m_incident);
 
8526
  DBUG_ASSERT((size_t) m_incident <= sizeof(description)/sizeof(*description));
6855
8527
 
6856
8528
  return description[m_incident];
6857
8529
}
6858
8530
 
6859
8531
 
 
8532
#ifndef MYSQL_CLIENT
6860
8533
void Incident_log_event::pack_info(Protocol *protocol)
6861
8534
{
6862
8535
  char buf[256];
6863
8536
  size_t bytes;
6864
8537
  if (m_message.length > 0)
6865
 
    bytes= snprintf(buf, sizeof(buf), "#%d (%s)",
6866
 
                    m_incident, description());
 
8538
    bytes= my_snprintf(buf, sizeof(buf), "#%d (%s)",
 
8539
                       m_incident, description());
6867
8540
  else
6868
 
    bytes= snprintf(buf, sizeof(buf), "#%d (%s): %s",
6869
 
                    m_incident, description(), m_message.str);
 
8541
    bytes= my_snprintf(buf, sizeof(buf), "#%d (%s): %s",
 
8542
                       m_incident, description(), m_message.str);
6870
8543
  protocol->store(buf, bytes, &my_charset_bin);
6871
8544
}
6872
 
 
6873
 
 
 
8545
#endif
 
8546
 
 
8547
 
 
8548
#ifdef MYSQL_CLIENT
 
8549
void
 
8550
Incident_log_event::print(FILE *file,
 
8551
                          PRINT_EVENT_INFO *print_event_info)
 
8552
{
 
8553
  if (print_event_info->short_form)
 
8554
    return;
 
8555
 
 
8556
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
8557
  print_header(&cache, print_event_info, FALSE);
 
8558
  my_b_printf(&cache, "\n# Incident: %s", description());
 
8559
}
 
8560
#endif
 
8561
 
 
8562
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6874
8563
int
6875
8564
Incident_log_event::do_apply_event(Relay_log_info const *rli)
6876
8565
{
 
8566
  DBUG_ENTER("Incident_log_event::do_apply_event");
6877
8567
  rli->report(ERROR_LEVEL, ER_SLAVE_INCIDENT,
6878
8568
              ER(ER_SLAVE_INCIDENT),
6879
8569
              description(),
6880
8570
              m_message.length > 0 ? m_message.str : "<none>");
6881
 
  return(1);
 
8571
  DBUG_RETURN(1);
6882
8572
}
6883
 
 
 
8573
#endif
6884
8574
 
6885
8575
bool
6886
8576
Incident_log_event::write_data_header(IO_CACHE *file)
6887
8577
{
6888
 
  unsigned char buf[sizeof(int16_t)];
6889
 
  int2store(buf, (int16_t) m_incident);
6890
 
  return(my_b_safe_write(file, buf, sizeof(buf)));
 
8578
  DBUG_ENTER("Incident_log_event::write_data_header");
 
8579
  DBUG_PRINT("enter", ("m_incident: %d", m_incident));
 
8580
  uchar buf[sizeof(int16)];
 
8581
  int2store(buf, (int16) m_incident);
 
8582
  DBUG_RETURN(my_b_safe_write(file, buf, sizeof(buf)));
6891
8583
}
6892
8584
 
6893
8585
bool
6894
8586
Incident_log_event::write_data_body(IO_CACHE *file)
6895
8587
{
6896
 
  return(write_str(file, m_message.str, m_message.length));
 
8588
  DBUG_ENTER("Incident_log_event::write_data_body");
 
8589
  DBUG_RETURN(write_str(file, m_message.str, m_message.length));
6897
8590
}
6898
8591
 
6899
 
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint32_t event_len,
 
8592
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
8593
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
6900
8594
                    const Format_description_log_event* description_event)
6901
8595
  :Log_event(buf, description_event)
6902
8596
{
6903
 
  uint8_t header_size= description_event->common_header_len;
 
8597
  uint8 header_size= description_event->common_header_len;
6904
8598
  ident_len = event_len - header_size;
6905
8599
  set_if_smaller(ident_len,FN_REFLEN-1);
6906
8600
  log_ident= buf + header_size;
6907
8601
}
 
8602
#endif
 
8603
 
 
8604
 
 
8605
#ifdef MYSQL_CLIENT
 
8606
/**
 
8607
  The default values for these variables should be values that are
 
8608
  *incorrect*, i.e., values that cannot occur in an event.  This way,
 
8609
  they will always be printed for the first event.
 
8610
*/
 
8611
st_print_event_info::st_print_event_info()
 
8612
  :flags2_inited(0), sql_mode_inited(0),
 
8613
   auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
 
8614
   lc_time_names_number(~0),
 
8615
   charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
 
8616
   thread_id(0), thread_id_printed(false),
 
8617
   base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(FALSE)
 
8618
{
 
8619
  /*
 
8620
    Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
 
8621
    program's startup, but these explicit bzero() is for the day someone
 
8622
    creates dynamic instances.
 
8623
  */
 
8624
  bzero(db, sizeof(db));
 
8625
  bzero(charset, sizeof(charset));
 
8626
  bzero(time_zone_str, sizeof(time_zone_str));
 
8627
  delimiter[0]= ';';
 
8628
  delimiter[1]= 0;
 
8629
  myf const flags = MYF(MY_WME | MY_NABP);
 
8630
  open_cached_file(&head_cache, NULL, NULL, 0, flags);
 
8631
  open_cached_file(&body_cache, NULL, NULL, 0, flags);
 
8632
}
 
8633
#endif