~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

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