~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/log_event.cc

  • Committer: Brian Aker
  • Date: 2008-07-14 22:40:46 UTC
  • Revision ID: brian@tangent.org-20080714224046-x183907w9wp1txwv
Removed sql_manager. Ever heard of just setting up the OS to sync when you
want it to?

Show diffs side-by-side

added added

removed removed

Lines of Context:
14
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
 
#include <drizzled/server_includes.h>
 
17
#ifdef MYSQL_CLIENT
 
18
 
 
19
#include "mysql_priv.h"
 
20
 
 
21
#else
 
22
 
 
23
#ifdef USE_PRAGMA_IMPLEMENTATION
 
24
#pragma implementation                          // gcc: Class implementation
 
25
#endif
 
26
 
 
27
#include "mysql_priv.h"
 
28
#include "slave.h"
18
29
#include "rpl_rli.h"
19
30
#include "rpl_mi.h"
20
31
#include "rpl_filter.h"
21
32
#include "rpl_utility.h"
22
33
#include "rpl_record.h"
23
 
#include <mysys/my_dir.h>
24
 
#include <drizzled/drizzled_error_messages.h>
25
 
 
26
 
#include <algorithm>
27
 
 
28
 
#include <mysys/base64.h>
29
 
#include <mysys/my_bitmap.h>
30
 
 
31
 
#include <libdrizzle/gettext.h>
32
 
#include <libdrizzle/libdrizzle.h>
33
 
 
34
 
#define log_cs  &my_charset_utf8_general_ci
 
34
#include <my_dir.h>
 
35
 
 
36
#endif /* MYSQL_CLIENT */
 
37
 
 
38
#include <base64.h>
 
39
#include <my_bitmap.h>
 
40
 
 
41
#define log_cs  &my_charset_latin1
35
42
 
36
43
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
37
44
 
45
52
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
46
53
 
47
54
 
 
55
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
48
56
static const char *HA_ERR(int i)
49
57
{
50
58
  switch (i) {
117
125
*/
118
126
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
119
127
                                           Relay_log_info const *rli, THD *thd,
120
 
                                           Table *table, const char * type,
 
128
                                           TABLE *table, const char * type,
121
129
                                           const char *log_name, ulong pos)
122
130
{
123
131
  const char *handler_error= HA_ERR(ha_error);
124
132
  char buff[MAX_SLAVE_ERRMSG], *slider;
125
133
  const char *buff_end= buff + sizeof(buff);
126
 
  uint32_t len;
127
 
  List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
128
 
  DRIZZLE_ERROR *err;
 
134
  uint len;
 
135
  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
136
  MYSQL_ERROR *err;
129
137
  buff[0]= 0;
130
138
 
131
139
  for (err= it++, slider= buff; err && slider < buff_end - 1;
132
140
       slider += len, err= it++)
133
141
  {
134
142
    len= snprintf(slider, buff_end - slider,
135
 
                  _(" %s, Error_code: %d;"), err->msg, err->code);
 
143
                  " %s, Error_code: %d;", err->msg, err->code);
136
144
  }
137
145
  
138
146
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
139
 
              _("Could not execute %s event on table %s.%s;"
140
 
                "%s handler error %s; "
141
 
                "the event's master log %s, end_log_pos %lu"),
 
147
              "Could not execute %s event on table %s.%s;"
 
148
              "%s handler error %s; "
 
149
              "the event's master log %s, end_log_pos %lu",
142
150
              type, table->s->db.str,
143
151
              table->s->table_name.str,
144
152
              buff,
145
 
              handler_error == NULL? _("<unknown>") : handler_error,
 
153
              handler_error == NULL? "<unknown>" : handler_error,
146
154
              log_name, pos);
147
155
}
148
 
 
 
156
#endif
149
157
 
150
158
/*
151
159
  Cache that will automatically be written to a dedicated file on
225
233
  flag_set m_flags;
226
234
};
227
235
 
228
 
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
236
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
229
237
 
230
238
/*
231
239
  pretty_print_str()
232
240
*/
233
241
 
 
242
#ifdef MYSQL_CLIENT
 
243
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
 
244
{
 
245
  const char* end = str + len;
 
246
  my_b_printf(cache, "\'");
 
247
  while (str < end)
 
248
  {
 
249
    char c;
 
250
    switch ((c=*str++)) {
 
251
    case '\n': my_b_printf(cache, "\\n"); break;
 
252
    case '\r': my_b_printf(cache, "\\r"); break;
 
253
    case '\\': my_b_printf(cache, "\\\\"); break;
 
254
    case '\b': my_b_printf(cache, "\\b"); break;
 
255
    case '\t': my_b_printf(cache, "\\t"); break;
 
256
    case '\'': my_b_printf(cache, "\\'"); break;
 
257
    case 0   : my_b_printf(cache, "\\0"); break;
 
258
    default:
 
259
      my_b_printf(cache, "%c", c);
 
260
      break;
 
261
    }
 
262
  }
 
263
  my_b_printf(cache, "\'");
 
264
}
 
265
#endif /* MYSQL_CLIENT */
 
266
 
 
267
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
268
 
234
269
static void clear_all_errors(THD *thd, Relay_log_info *rli)
235
270
{
236
271
  thd->is_slave_error = 0;
248
283
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
249
284
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
250
285
}
 
286
#endif
251
287
 
252
288
 
253
289
/*
254
290
  pretty_print_str()
255
291
*/
256
292
 
 
293
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
257
294
static char *pretty_print_str(char *packet, const char *str, int len)
258
295
{
259
296
  const char *end= str + len;
278
315
  *pos++= '\'';
279
316
  return pos;
280
317
}
281
 
 
 
318
#endif /* !MYSQL_CLIENT */
 
319
 
 
320
 
 
321
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
282
322
 
283
323
/**
284
324
  Creates a temporary name for load data infile:.
292
332
    Pointer to start of extension
293
333
*/
294
334
 
295
 
static char *slave_load_file_stem(char *buf, uint32_t file_id,
 
335
static char *slave_load_file_stem(char *buf, uint file_id,
296
336
                                  int event_server_id, const char *ext)
297
337
{
298
338
  char *res;
299
339
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
300
340
  to_unix_path(buf);
301
341
 
302
 
  buf= strchr(buf, '\0');
303
 
  buf= int10_to_str(::server_id, buf, 10);
 
342
  buf = strend(buf);
 
343
  buf = int10_to_str(::server_id, buf, 10);
304
344
  *buf++ = '-';
305
 
  buf= int10_to_str(event_server_id, buf, 10);
 
345
  buf = int10_to_str(event_server_id, buf, 10);
306
346
  *buf++ = '-';
307
347
  res= int10_to_str(file_id, buf, 10);
308
 
  my_stpcpy(res, ext);                             // Add extension last
 
348
  strmov(res, ext);                             // Add extension last
309
349
  return res;                                   // Pointer to extension
310
350
}
311
 
 
 
351
#endif
 
352
 
 
353
 
 
354
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
312
355
 
313
356
/**
314
357
  Delete all temporary files used for SQL_LOAD.
318
361
{
319
362
  MY_DIR *dirp;
320
363
  FILEINFO *file;
321
 
  uint32_t i;
 
364
  uint i;
322
365
  char fname[FN_REFLEN], prefbuf[31], *p;
323
366
 
324
367
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
349
392
 
350
393
  my_dirend(dirp);
351
394
}
 
395
#endif
352
396
 
353
397
 
354
398
/*
355
399
  write_str()
356
400
*/
357
401
 
358
 
static bool write_str(IO_CACHE *file, const char *str, uint32_t length)
 
402
static bool write_str(IO_CACHE *file, const char *str, uint length)
359
403
{
360
 
  unsigned char tmp[1];
361
 
  tmp[0]= (unsigned char) length;
 
404
  uchar tmp[1];
 
405
  tmp[0]= (uchar) length;
362
406
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
363
 
          my_b_safe_write(file, (unsigned char*) str, length));
 
407
          my_b_safe_write(file, (uchar*) str, length));
364
408
}
365
409
 
366
410
 
369
413
*/
370
414
 
371
415
static inline int read_str(const char **buf, const char *buf_end,
372
 
                           const char **str, uint8_t *len)
 
416
                           const char **str, uint8 *len)
373
417
{
374
 
  if (*buf + ((uint) (unsigned char) **buf) >= buf_end)
 
418
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
375
419
    return 1;
376
 
  *len= (uint8_t) **buf;
 
420
  *len= (uint8) **buf;
377
421
  *str= (*buf)+1;
378
422
  (*buf)+= (uint) *len+1;
379
423
  return 0;
384
428
  Transforms a string into "" or its expression in 0x... form.
385
429
*/
386
430
 
387
 
char *str_to_hex(char *to, const char *from, uint32_t len)
 
431
char *str_to_hex(char *to, const char *from, uint len)
388
432
{
389
433
  if (len)
390
434
  {
393
437
    to= octet2hex(to, from, len);
394
438
  }
395
439
  else
396
 
    to= my_stpcpy(to, "\"\"");
 
440
    to= strmov(to, "\"\"");
397
441
  return to;                               // pointer to end 0 of 'to'
398
442
}
399
443
 
 
444
#ifndef MYSQL_CLIENT
400
445
 
401
446
/**
402
447
  Append a version of the 'from' string suitable for use in a query to
405
450
*/
406
451
 
407
452
int
408
 
append_query_string(const CHARSET_INFO * const csinfo,
 
453
append_query_string(CHARSET_INFO *csinfo,
409
454
                    String const *from, String *to)
410
455
{
411
456
  char *beg, *ptr;
412
 
  uint32_t const orig_len= to->length();
 
457
  uint32 const orig_len= to->length();
413
458
  if (to->reserve(orig_len + from->length()*2+3))
414
459
    return 1;
415
460
 
420
465
  else
421
466
  {
422
467
    *ptr++= '\'';
423
 
    ptr+= drizzle_escape_string(ptr, from->ptr(), from->length());
 
468
    ptr+= escape_string_for_mysql(csinfo, ptr, 0,
 
469
                                  from->ptr(), from->length());
424
470
    *ptr++='\'';
425
471
  }
426
472
  to->length(orig_len + ptr - beg);
427
473
  return 0;
428
474
}
429
 
 
 
475
#endif
 
476
 
 
477
 
 
478
/**
 
479
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
 
480
  commands just before it prints a query.
 
481
*/
 
482
 
 
483
#ifdef MYSQL_CLIENT
 
484
 
 
485
static void print_set_option(IO_CACHE* file, uint32 bits_changed,
 
486
                             uint32 option, uint32 flags, const char* name,
 
487
                             bool* need_comma)
 
488
{
 
489
  if (bits_changed & option)
 
490
  {
 
491
    if (*need_comma)
 
492
      my_b_printf(file,", ");
 
493
    my_b_printf(file,"%s=%d", name, test(flags & option));
 
494
    *need_comma= 1;
 
495
  }
 
496
}
 
497
#endif
430
498
 
431
499
/**************************************************************************
432
500
        Log_event methods (= the parent class of all events)
480
548
  Log_event::Log_event()
481
549
*/
482
550
 
483
 
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
 
551
#ifndef MYSQL_CLIENT
 
552
Log_event::Log_event(THD* thd_arg, uint16 flags_arg, bool using_trans)
484
553
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
485
554
{
486
555
  server_id=    thd->server_id;
508
577
  when=         0;
509
578
  log_pos=      0;
510
579
}
 
580
#endif /* !MYSQL_CLIENT */
511
581
 
512
582
 
513
583
/*
518
588
                     const Format_description_log_event* description_event)
519
589
  :temp_buf(0), cache_stmt(0)
520
590
{
521
 
  thd= 0;
522
 
  when= uint4korr(buf);
523
 
  server_id= uint4korr(buf + SERVER_ID_OFFSET);
 
591
#ifndef MYSQL_CLIENT
 
592
  thd = 0;
 
593
#endif
 
594
  when = uint4korr(buf);
 
595
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
524
596
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
525
597
  if (description_event->binlog_version==1)
526
598
  {
579
651
  /* otherwise, go on with reading the header from buf (nothing now) */
580
652
}
581
653
 
 
654
#ifndef MYSQL_CLIENT
 
655
#ifdef HAVE_REPLICATION
582
656
 
583
657
int Log_event::do_update_pos(Relay_log_info *rli)
584
658
{
638
712
 
639
713
 
640
714
/**
 
715
  Only called by SHOW BINLOG EVENTS
 
716
*/
 
717
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
 
718
{
 
719
  const char *p= strrchr(log_name, FN_LIBCHAR);
 
720
  const char *event_type;
 
721
  if (p)
 
722
    log_name = p + 1;
 
723
 
 
724
  protocol->prepare_for_resend();
 
725
  protocol->store(log_name, &my_charset_bin);
 
726
  protocol->store((uint64_t) pos);
 
727
  event_type = get_type_str();
 
728
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
 
729
  protocol->store((uint32) server_id);
 
730
  protocol->store((uint64_t) log_pos);
 
731
  pack_info(protocol);
 
732
  return protocol->write();
 
733
}
 
734
#endif /* HAVE_REPLICATION */
 
735
 
 
736
 
 
737
/**
641
738
  init_show_field_list() prepares the column names and types for the
642
739
  output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
643
740
  EVENTS.
647
744
{
648
745
  field_list->push_back(new Item_empty_string("Log_name", 20));
649
746
  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
650
 
                                            DRIZZLE_TYPE_LONGLONG));
 
747
                                            MYSQL_TYPE_LONGLONG));
651
748
  field_list->push_back(new Item_empty_string("Event_type", 20));
652
749
  field_list->push_back(new Item_return_int("Server_id", 10,
653
 
                                            DRIZZLE_TYPE_LONG));
 
750
                                            MYSQL_TYPE_LONG));
654
751
  field_list->push_back(new Item_return_int("End_log_pos",
655
752
                                            MY_INT32_NUM_DECIMAL_DIGITS,
656
 
                                            DRIZZLE_TYPE_LONGLONG));
 
753
                                            MYSQL_TYPE_LONGLONG));
657
754
  field_list->push_back(new Item_empty_string("Info", 20));
658
755
}
659
756
 
663
760
 
664
761
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
665
762
{
666
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
763
  uchar header[LOG_EVENT_HEADER_LEN];
667
764
  ulong now;
668
765
 
669
766
  /* Store number of bytes that will be written by this event */
748
845
 
749
846
  if (log_lock)
750
847
    pthread_mutex_lock(log_lock);
751
 
  if (my_b_read(file, (unsigned char*) buf, sizeof(buf)))
 
848
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
752
849
  {
753
850
    /*
754
851
      If the read hits eof, we must report it as eof so the caller
806
903
    pthread_mutex_unlock(log_lock);
807
904
  return(result);
808
905
}
 
906
#endif /* !MYSQL_CLIENT */
809
907
 
 
908
#ifndef MYSQL_CLIENT
810
909
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
811
910
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
 
911
#else
 
912
#define UNLOCK_MUTEX
 
913
#define LOCK_MUTEX
 
914
#endif
812
915
 
 
916
#ifndef MYSQL_CLIENT
813
917
/**
814
918
  @note
815
919
    Allocates memory;  The caller is responsible for clean-up.
818
922
                                     pthread_mutex_t* log_lock,
819
923
                                     const Format_description_log_event
820
924
                                     *description_event)
 
925
#else
 
926
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
927
                                     const Format_description_log_event
 
928
                                     *description_event)
 
929
#endif
821
930
{
822
931
  assert(description_event != 0);
823
932
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
828
937
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
829
938
    "minimal" over the set {MySQL >=4.0}).
830
939
  */
831
 
  uint32_t header_size= cmin(description_event->common_header_len,
 
940
  uint header_size= min(description_event->common_header_len,
832
941
                        LOG_EVENT_MINIMAL_HEADER_LEN);
833
942
 
834
943
  LOCK_MUTEX;
835
 
  if (my_b_read(file, (unsigned char *) head, header_size))
 
944
  if (my_b_read(file, (uchar *) head, header_size))
836
945
  {
837
946
    UNLOCK_MUTEX;
838
947
    /*
842
951
    */
843
952
    return(0);
844
953
  }
845
 
  uint32_t data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
954
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
846
955
  char *buf= 0;
847
956
  const char *error= 0;
848
957
  Log_event *res=  0;
849
958
#ifndef max_allowed_packet
850
959
  THD *thd=current_thd;
851
 
  uint32_t max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
 
960
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
852
961
#endif
853
962
 
854
963
  if (data_len > max_allowed_packet)
871
980
  }
872
981
  buf[data_len] = 0;
873
982
  memcpy(buf, head, header_size);
874
 
  if (my_b_read(file, (unsigned char*) buf + header_size, data_len - header_size))
 
983
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
875
984
  {
876
985
    error = "read error";
877
986
    goto err;
884
993
  if (!res)
885
994
  {
886
995
    assert(error != 0);
887
 
    sql_print_error(_("Error in Log_event::read_log_event(): "
888
 
                    "'%s', data_len: %d, event_type: %d"),
 
996
    sql_print_error("Error in Log_event::read_log_event(): "
 
997
                    "'%s', data_len: %d, event_type: %d",
889
998
                    error,data_len,head[EVENT_TYPE_OFFSET]);
890
 
    free(buf);
 
999
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
891
1000
    /*
892
1001
      The SQL slave thread will check if file->error<0 to know
893
1002
      if there was an I/O error. Even if there is no "low-level" I/O errors
907
1016
  constructors.
908
1017
*/
909
1018
 
910
 
Log_event* Log_event::read_log_event(const char* buf, uint32_t event_len,
 
1019
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
911
1020
                                     const char **error,
912
1021
                                     const Format_description_log_event *description_event)
913
1022
{
923
1032
    return(NULL); // general sanity check - will fail on a partial read
924
1033
  }
925
1034
 
926
 
  uint32_t event_type= buf[EVENT_TYPE_OFFSET];
 
1035
  uint event_type= buf[EVENT_TYPE_OFFSET];
927
1036
  if (event_type > description_event->number_of_event_types &&
928
1037
      event_type != FORMAT_DESCRIPTION_EVENT)
929
1038
  {
961
1070
    case ROTATE_EVENT:
962
1071
      ev = new Rotate_log_event(buf, event_len, description_event);
963
1072
      break;
 
1073
    case SLAVE_EVENT: /* can never happen (unused event) */
 
1074
      ev = new Slave_log_event(buf, event_len);
 
1075
      break;
964
1076
    case CREATE_FILE_EVENT:
965
1077
      ev = new Create_file_log_event(buf, event_len, description_event);
966
1078
      break;
994
1106
    case FORMAT_DESCRIPTION_EVENT:
995
1107
      ev = new Format_description_log_event(buf, event_len, description_event);
996
1108
      break;
 
1109
#if defined(HAVE_REPLICATION) 
997
1110
    case WRITE_ROWS_EVENT:
998
1111
      ev = new Write_rows_log_event(buf, event_len, description_event);
999
1112
      break;
1006
1119
    case TABLE_MAP_EVENT:
1007
1120
      ev = new Table_map_log_event(buf, event_len, description_event);
1008
1121
      break;
 
1122
#endif
1009
1123
    case BEGIN_LOAD_QUERY_EVENT:
1010
1124
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
1011
1125
      break;
1033
1147
  if (!ev || !ev->is_valid())
1034
1148
  {
1035
1149
    delete ev;
 
1150
#ifdef MYSQL_CLIENT
 
1151
    if (!force_opt) /* then mysqlbinlog dies */
 
1152
    {
 
1153
      *error= "Found invalid event in binary log";
 
1154
      return(0);
 
1155
    }
 
1156
    ev= new Unknown_log_event(buf, description_event);
 
1157
#else
1036
1158
    *error= "Found invalid event in binary log";
1037
1159
    return(0);
 
1160
#endif
1038
1161
  }
1039
1162
  return(ev);  
1040
1163
}
1041
1164
 
 
1165
#ifdef MYSQL_CLIENT
 
1166
 
 
1167
/*
 
1168
  Log_event::print_header()
 
1169
*/
 
1170
 
 
1171
void Log_event::print_header(IO_CACHE* file,
 
1172
                             PRINT_EVENT_INFO* print_event_info,
 
1173
                             bool is_more __attribute__((unused)))
 
1174
{
 
1175
  char llbuff[22];
 
1176
  my_off_t hexdump_from= print_event_info->hexdump_from;
 
1177
 
 
1178
  my_b_printf(file, "#");
 
1179
  print_timestamp(file);
 
1180
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
 
1181
              llstr(log_pos,llbuff));
 
1182
 
 
1183
  /* mysqlbinlog --hexdump */
 
1184
  if (print_event_info->hexdump_from)
 
1185
  {
 
1186
    my_b_printf(file, "\n");
 
1187
    uchar *ptr= (uchar*)temp_buf;
 
1188
    my_off_t size=
 
1189
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
 
1190
    my_off_t i;
 
1191
 
 
1192
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
 
1193
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
 
1194
    char *c, char_string[16+1]= {0};
 
1195
 
 
1196
    /* Pretty-print event common header if header is exactly 19 bytes */
 
1197
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
 
1198
    {
 
1199
      char emit_buf[256];               // Enough for storing one line
 
1200
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
 
1201
                  "Size      Master Pos    Flags \n");
 
1202
      int const bytes_written=
 
1203
        snprintf(emit_buf, sizeof(emit_buf),
 
1204
                 "# %8.8lx %02x %02x %02x %02x   %02x   "
 
1205
                 "%02x %02x %02x %02x   %02x %02x %02x %02x   "
 
1206
                 "%02x %02x %02x %02x   %02x %02x\n",
 
1207
                 (unsigned long) hexdump_from,
 
1208
                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
 
1209
                 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
 
1210
                 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
 
1211
      assert(bytes_written >= 0);
 
1212
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1213
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1214
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1215
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1216
    }
 
1217
 
 
1218
    /* Rest of event (without common header) */
 
1219
    for (i= 0, c= char_string, h=hex_string;
 
1220
         i < size;
 
1221
         i++, ptr++)
 
1222
    {
 
1223
      snprintf(h, 4, "%02x ", *ptr);
 
1224
      h += 3;
 
1225
 
 
1226
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
 
1227
 
 
1228
      if (i % 16 == 15)
 
1229
      {
 
1230
        /*
 
1231
          my_b_printf() does not support full printf() formats, so we
 
1232
          have to do it this way.
 
1233
 
 
1234
          TODO: Rewrite my_b_printf() to support full printf() syntax.
 
1235
         */
 
1236
        char emit_buf[256];
 
1237
        int const bytes_written=
 
1238
          snprintf(emit_buf, sizeof(emit_buf),
 
1239
                   "# %8.8lx %-48.48s |%16s|\n",
 
1240
                   (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1241
                   hex_string, char_string);
 
1242
        assert(bytes_written >= 0);
 
1243
        assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1244
        my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1245
        hex_string[0]= 0;
 
1246
        char_string[0]= 0;
 
1247
        c= char_string;
 
1248
        h= hex_string;
 
1249
      }
 
1250
      else if (i % 8 == 7) *h++ = ' ';
 
1251
    }
 
1252
    *c= '\0';
 
1253
 
 
1254
    if (hex_string[0])
 
1255
    {
 
1256
      char emit_buf[256];
 
1257
      int const bytes_written=
 
1258
        snprintf(emit_buf, sizeof(emit_buf),
 
1259
                    "# %8.8lx %-48.48s |%s|\n",
 
1260
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1261
                    hex_string, char_string);
 
1262
      assert(bytes_written >= 0);
 
1263
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1264
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1265
    }
 
1266
    /*
 
1267
      need a # to prefix the rest of printouts for example those of
 
1268
      Rows_log_event::print_helper().
 
1269
    */
 
1270
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
 
1271
  }
 
1272
  return;
 
1273
}
 
1274
 
 
1275
 
 
1276
void Log_event::print_base64(IO_CACHE* file,
 
1277
                             PRINT_EVENT_INFO* print_event_info,
 
1278
                             bool more)
 
1279
{
 
1280
  const uchar *ptr= (const uchar *)temp_buf;
 
1281
  uint32 size= uint4korr(ptr + EVENT_LEN_OFFSET);
 
1282
 
 
1283
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
 
1284
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
 
1285
  if (!tmp_str) {
 
1286
    fprintf(stderr, "\nError: Out of memory. "
 
1287
            "Could not print correct binlog event.\n");
 
1288
    return;
 
1289
  }
 
1290
 
 
1291
  if (base64_encode(ptr, (size_t) size, tmp_str))
 
1292
  {
 
1293
    assert(0);
 
1294
  }
 
1295
 
 
1296
  if (my_b_tell(file) == 0)
 
1297
    my_b_printf(file, "\nBINLOG '\n");
 
1298
 
 
1299
  my_b_printf(file, "%s\n", tmp_str);
 
1300
 
 
1301
  if (!more)
 
1302
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
 
1303
 
 
1304
  my_free(tmp_str, MYF(0));
 
1305
  return;
 
1306
}
 
1307
 
 
1308
 
 
1309
/*
 
1310
  Log_event::print_timestamp()
 
1311
*/
 
1312
 
 
1313
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
 
1314
{
 
1315
  struct tm *res;
 
1316
  if (!ts)
 
1317
    ts = &when;
 
1318
#ifdef MYSQL_SERVER                             // This is always false
 
1319
  struct tm tm_tmp;
 
1320
  localtime_r(ts,(res= &tm_tmp));
 
1321
#else
 
1322
  res=localtime(ts);
 
1323
#endif
 
1324
 
 
1325
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
 
1326
              res->tm_year % 100,
 
1327
              res->tm_mon+1,
 
1328
              res->tm_mday,
 
1329
              res->tm_hour,
 
1330
              res->tm_min,
 
1331
              res->tm_sec);
 
1332
  return;
 
1333
}
 
1334
 
 
1335
#endif /* MYSQL_CLIENT */
 
1336
 
 
1337
 
 
1338
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1042
1339
inline Log_event::enum_skip_reason
1043
1340
Log_event::continue_group(Relay_log_info *rli)
1044
1341
{
1046
1343
    return Log_event::EVENT_SKIP_IGNORE;
1047
1344
  return Log_event::do_shall_skip(rli);
1048
1345
}
 
1346
#endif
1049
1347
 
1050
1348
/**************************************************************************
1051
1349
        Query_log_event methods
1052
1350
**************************************************************************/
1053
1351
 
 
1352
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
1353
 
1054
1354
/**
1055
1355
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
1056
1356
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1070
1370
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1071
1371
      && db && db_len)
1072
1372
  {
1073
 
    pos= my_stpcpy(buf, "use `");
 
1373
    pos= strmov(buf, "use `");
1074
1374
    memcpy(pos, db, db_len);
1075
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
1375
    pos= strmov(pos+db_len, "`; ");
1076
1376
  }
1077
1377
  if (query && q_len)
1078
1378
  {
1080
1380
    pos+= q_len;
1081
1381
  }
1082
1382
  protocol->store(buf, pos-buf, &my_charset_bin);
1083
 
  free(buf);
 
1383
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1084
1384
}
 
1385
#endif
1085
1386
 
 
1387
#ifndef MYSQL_CLIENT
1086
1388
 
1087
1389
/**
1088
1390
  Utility function for the next method (Query_log_event::write()) .
1089
1391
*/
1090
1392
static void write_str_with_code_and_len(char **dst, const char *src,
1091
 
                                        int len, uint32_t code)
 
1393
                                        int len, uint code)
1092
1394
{
1093
1395
  assert(src);
1094
1396
  *((*dst)++)= code;
1095
 
  *((*dst)++)= (unsigned char) len;
1096
 
  memcpy(*dst, src, len);
 
1397
  *((*dst)++)= (uchar) len;
 
1398
  bmove(*dst, src, len);
1097
1399
  (*dst)+= len;
1098
1400
}
1099
1401
 
1114
1416
    replicating it correctly, since the length is stored in a byte
1115
1417
    /sven
1116
1418
  */
1117
 
  unsigned char buf[QUERY_HEADER_LEN+
 
1419
  uchar buf[QUERY_HEADER_LEN+
1118
1420
            1+4+           // code of flags2 and flags2
1119
1421
            1+8+           // code of sql_mode and sql_mode
1120
1422
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1270
1572
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1271
1573
 
1272
1574
  return (write_header(file, event_length) ||
1273
 
          my_b_safe_write(file, (unsigned char*) buf, QUERY_HEADER_LEN) ||
 
1575
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1274
1576
          write_post_header_for_derived(file) ||
1275
 
          my_b_safe_write(file, (unsigned char*) start_of_status,
 
1577
          my_b_safe_write(file, (uchar*) start_of_status,
1276
1578
                          (uint) (start-start_of_status)) ||
1277
 
          my_b_safe_write(file, (db) ? (unsigned char*) db : (unsigned char*)"", db_len + 1) ||
1278
 
          my_b_safe_write(file, (unsigned char*) query, q_len)) ? 1 : 0;
 
1579
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
 
1580
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1279
1581
}
1280
1582
 
1281
1583
/**
1316
1618
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1317
1619
             using_trans),
1318
1620
   data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1319
 
   db(thd_arg->db), q_len((uint32_t) query_length),
 
1621
   db(thd_arg->db), q_len((uint32) query_length),
1320
1622
   thread_id(thd_arg->thread_id),
1321
1623
   /* save the original thread id; we already know the server id */
1322
1624
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1343
1645
    @todo this means that if we have no catalog, then it is replicated
1344
1646
    as an existing catalog of length zero. is that safe? /sven
1345
1647
  */
1346
 
  catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
 
1648
  catalog_len = (catalog) ? (uint32) strlen(catalog) : 0;
1347
1649
  /* status_vars_len is set just before writing the event */
1348
 
  db_len = (db) ? (uint32_t) strlen(db) : 0;
 
1650
  db_len = (db) ? (uint32) strlen(db) : 0;
1349
1651
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
1350
1652
    charset_database_number= thd_arg->variables.collation_database->number;
1351
1653
  
1356
1658
    But it's likely that we don't want to use 32 bits for 3 bits; in the future
1357
1659
    we will probably want to reclaim the 29 bits. So we need the &.
1358
1660
  */
1359
 
  flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
 
1661
  flags2= (uint32) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1360
1662
  assert(thd_arg->variables.character_set_client->number < 256*256);
1361
1663
  assert(thd_arg->variables.collation_connection->number < 256*256);
1362
1664
  assert(thd_arg->variables.collation_server->number < 256*256);
1377
1679
  else
1378
1680
    time_zone_len= 0;
1379
1681
}
 
1682
#endif /* MYSQL_CLIENT */
1380
1683
 
1381
1684
 
1382
1685
/* 2 utility functions for the next method */
1408
1711
static int
1409
1712
get_str_len_and_pointer(const Log_event::Byte **src,
1410
1713
                        const char **dst,
1411
 
                        uint32_t *len,
 
1714
                        uint *len,
1412
1715
                        const Log_event::Byte *end)
1413
1716
{
1414
1717
  if (*src >= end)
1415
1718
    return -1;       // Will be UINT_MAX in two-complement arithmetics
1416
 
  uint32_t length= **src;
 
1719
  uint length= **src;
1417
1720
  if (length > 0)
1418
1721
  {
1419
1722
    if (*src + length >= end)
1427
1730
 
1428
1731
static void copy_str_and_move(const char **src, 
1429
1732
                              Log_event::Byte **dst, 
1430
 
                              uint32_t len)
 
1733
                              uint len)
1431
1734
{
1432
1735
  memcpy(*dst, *src, len);
1433
1736
  *src= (const char *)*dst;
1445
1748
 */
1446
1749
#define CHECK_SPACE(PTR,END,CNT)                      \
1447
1750
  do {                                                \
1448
 
    assert((PTR) + (CNT) <= (END));                   \
 
1751
    assert((PTR) + (CNT) <= (END));              \
1449
1752
    if ((PTR) + (CNT) > (END)) {                      \
1450
1753
      query= 0;                                       \
1451
 
      return;                                         \
 
1754
      return;                               \
1452
1755
    }                                                 \
1453
1756
  } while (0)
1454
1757
 
1456
1759
/**
1457
1760
  This is used by the SQL slave thread to prepare the event before execution.
1458
1761
*/
1459
 
Query_log_event::Query_log_event(const char* buf, uint32_t event_len,
 
1762
Query_log_event::Query_log_event(const char* buf, uint event_len,
1460
1763
                                 const Format_description_log_event
1461
1764
                                 *description_event,
1462
1765
                                 Log_event_type event_type)
1463
 
  :Log_event(buf, description_event), data_buf(0), query(NULL),
1464
 
   db(NULL), catalog_len(0), status_vars_len(0),
 
1766
  :Log_event(buf, description_event), data_buf(0), query(NullS),
 
1767
   db(NullS), catalog_len(0), status_vars_len(0),
1465
1768
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1466
1769
   auto_increment_increment(1), auto_increment_offset(1),
1467
1770
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1468
1771
{
1469
 
  uint32_t data_len;
1470
 
  uint32_t tmp;
1471
 
  uint8_t common_header_len, post_header_len;
 
1772
  ulong data_len;
 
1773
  uint32 tmp;
 
1774
  uint8 common_header_len, post_header_len;
1472
1775
  Log_event::Byte *start;
1473
1776
  const Log_event::Byte *end;
1474
1777
  bool catalog_nz= 1;
1506
1809
      be even bigger, but this will suffice to catch most corruption
1507
1810
      errors that can lead to a crash.
1508
1811
    */
1509
 
    if (status_vars_len > cmin(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
 
1812
    if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
1510
1813
    {
1511
1814
      query= 0;
1512
1815
      return;
1554
1857
      auto_increment_offset=    uint2korr(pos+2);
1555
1858
      pos+= 4;
1556
1859
      break;
 
1860
    case Q_CHARSET_CODE:
 
1861
    {
 
1862
      CHECK_SPACE(pos, end, 6);
 
1863
      charset_inited= 1;
 
1864
      memcpy(charset, pos, 6);
 
1865
      pos+= 6;
 
1866
      break;
 
1867
    }
1557
1868
    case Q_TIME_ZONE_CODE:
1558
1869
    {
1559
1870
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1583
1894
      break;
1584
1895
    default:
1585
1896
      /* That's why you must write status vars in growing order of code */
1586
 
      pos= (const unsigned char*) end;                         // Break loop
 
1897
      pos= (const uchar*) end;                         // Break loop
1587
1898
    }
1588
1899
  }
1589
1900
  
1619
1930
  */
1620
1931
 
1621
1932
  /* A 2nd variable part; this is common to all versions */ 
1622
 
  memcpy(start, end, data_len);          // Copy db and query
 
1933
  memcpy((char*) start, end, data_len);          // Copy db and query
1623
1934
  start[data_len]= '\0';              // End query with \0 (For safetly)
1624
1935
  db= (char *)start;
1625
1936
  query= (char *)(start + db_len + 1);
1628
1939
}
1629
1940
 
1630
1941
 
 
1942
#ifdef MYSQL_CLIENT
 
1943
/**
 
1944
  Query_log_event::print().
 
1945
 
 
1946
  @todo
 
1947
    print the catalog ??
 
1948
*/
 
1949
void Query_log_event::print_query_header(IO_CACHE* file,
 
1950
                                         PRINT_EVENT_INFO* print_event_info)
 
1951
{
 
1952
  // TODO: print the catalog ??
 
1953
  char buff[40],*end;                           // Enough for SET TIMESTAMP
 
1954
  bool different_db= 1;
 
1955
  uint32 tmp;
 
1956
 
 
1957
  if (!print_event_info->short_form)
 
1958
  {
 
1959
    print_header(file, print_event_info, false);
 
1960
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 
1961
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
 
1962
                error_code);
 
1963
  }
 
1964
 
 
1965
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
 
1966
  {
 
1967
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
 
1968
      memcpy(print_event_info->db, db, db_len + 1);
 
1969
    if (db[0] && different_db) 
 
1970
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
 
1971
  }
 
1972
 
 
1973
  end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
 
1974
  end= strmov(end, print_event_info->delimiter);
 
1975
  *end++='\n';
 
1976
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
 
1977
  if ((!print_event_info->thread_id_printed ||
 
1978
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
 
1979
        thread_id != print_event_info->thread_id)))
 
1980
  {
 
1981
    // If --short-form, print deterministic value instead of pseudo_thread_id.
 
1982
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
 
1983
                short_form ? 999999999 : (ulong)thread_id,
 
1984
                print_event_info->delimiter);
 
1985
    print_event_info->thread_id= thread_id;
 
1986
    print_event_info->thread_id_printed= 1;
 
1987
  }
 
1988
 
 
1989
  /*
 
1990
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
 
1991
    print (remember we don't produce mixed relay logs so there cannot be
 
1992
    5.0 events before that one so there is nothing to reset).
 
1993
  */
 
1994
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
 
1995
  {
 
1996
    /* tmp is a bitmask of bits which have changed. */
 
1997
    if (likely(print_event_info->flags2_inited)) 
 
1998
      /* All bits which have changed */
 
1999
      tmp= (print_event_info->flags2) ^ flags2;
 
2000
    else /* that's the first Query event we read */
 
2001
    {
 
2002
      print_event_info->flags2_inited= 1;
 
2003
      tmp= ~((uint32)0); /* all bits have changed */
 
2004
    }
 
2005
 
 
2006
    if (unlikely(tmp)) /* some bits have changed */
 
2007
    {
 
2008
      bool need_comma= 0;
 
2009
      my_b_printf(file, "SET ");
 
2010
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
 
2011
                   "@@session.foreign_key_checks", &need_comma);
 
2012
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
 
2013
                   "@@session.sql_auto_is_null", &need_comma);
 
2014
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
 
2015
                   "@@session.unique_checks", &need_comma);
 
2016
      my_b_printf(file,"%s\n", print_event_info->delimiter);
 
2017
      print_event_info->flags2= flags2;
 
2018
    }
 
2019
  }
 
2020
 
 
2021
  /*
 
2022
    Now the session variables;
 
2023
    it's more efficient to pass SQL_MODE as a number instead of a
 
2024
    comma-separated list.
 
2025
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
 
2026
    variables (they have no global version; they're not listed in
 
2027
    sql_class.h), The tests below work for pure binlogs or pure relay
 
2028
    logs. Won't work for mixed relay logs but we don't create mixed
 
2029
    relay logs (that is, there is no relay log with a format change
 
2030
    except within the 3 first events, which mysqlbinlog handles
 
2031
    gracefully). So this code should always be good.
 
2032
  */
 
2033
 
 
2034
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
 
2035
      print_event_info->auto_increment_offset != auto_increment_offset)
 
2036
  {
 
2037
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
 
2038
                auto_increment_increment,auto_increment_offset,
 
2039
                print_event_info->delimiter);
 
2040
    print_event_info->auto_increment_increment= auto_increment_increment;
 
2041
    print_event_info->auto_increment_offset=    auto_increment_offset;
 
2042
  }
 
2043
 
 
2044
  /* TODO: print the catalog when we feature SET CATALOG */
 
2045
 
 
2046
  if (likely(charset_inited) &&
 
2047
      (unlikely(!print_event_info->charset_inited ||
 
2048
                bcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
 
2049
  {
 
2050
    CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
 
2051
    if (cs_info)
 
2052
    {
 
2053
      /* for mysql client */
 
2054
      my_b_printf(file, "/*!\\C %s */%s\n",
 
2055
                  cs_info->csname, print_event_info->delimiter);
 
2056
    }
 
2057
    my_b_printf(file,"SET "
 
2058
                "@@session.character_set_client=%d,"
 
2059
                "@@session.collation_connection=%d,"
 
2060
                "@@session.collation_server=%d"
 
2061
                "%s\n",
 
2062
                uint2korr(charset),
 
2063
                uint2korr(charset+2),
 
2064
                uint2korr(charset+4),
 
2065
                print_event_info->delimiter);
 
2066
    memcpy(print_event_info->charset, charset, 6);
 
2067
    print_event_info->charset_inited= 1;
 
2068
  }
 
2069
  if (time_zone_len)
 
2070
  {
 
2071
    if (bcmp((uchar*) print_event_info->time_zone_str,
 
2072
             (uchar*) time_zone_str, time_zone_len+1))
 
2073
    {
 
2074
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
 
2075
                  time_zone_str, print_event_info->delimiter);
 
2076
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
 
2077
    }
 
2078
  }
 
2079
  if (lc_time_names_number != print_event_info->lc_time_names_number)
 
2080
  {
 
2081
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
 
2082
                lc_time_names_number, print_event_info->delimiter);
 
2083
    print_event_info->lc_time_names_number= lc_time_names_number;
 
2084
  }
 
2085
  if (charset_database_number != print_event_info->charset_database_number)
 
2086
  {
 
2087
    if (charset_database_number)
 
2088
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
 
2089
                  charset_database_number, print_event_info->delimiter);
 
2090
    else
 
2091
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
2092
                  print_event_info->delimiter);
 
2093
    print_event_info->charset_database_number= charset_database_number;
 
2094
  }
 
2095
}
 
2096
 
 
2097
 
 
2098
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2099
{
 
2100
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
2101
 
 
2102
  print_query_header(&cache, print_event_info);
 
2103
  my_b_write(&cache, (uchar*) query, q_len);
 
2104
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
2105
}
 
2106
#endif /* MYSQL_CLIENT */
 
2107
 
 
2108
 
1631
2109
/*
1632
2110
  Query_log_event::do_apply_event()
1633
2111
*/
 
2112
 
 
2113
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2114
 
1634
2115
int Query_log_event::do_apply_event(Relay_log_info const *rli)
1635
2116
{
1636
2117
  return do_apply_event(rli, query, q_len);
1642
2123
  Compare the values of "affected rows" around here. Something
1643
2124
  like:
1644
2125
  @code
1645
 
     if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
 
2126
     if ((uint32) affected_in_event != (uint32) affected_on_slave)
1646
2127
     {
1647
2128
     sql_print_error("Slave: did not get the expected number of affected \
1648
2129
     rows running query from master - expected %d, got %d (this numbers \
1655
2136
  to ignore it you would use --slave-skip-errors...
1656
2137
*/
1657
2138
int Query_log_event::do_apply_event(Relay_log_info const *rli,
1658
 
                                      const char *query_arg, uint32_t q_len_arg)
 
2139
                                      const char *query_arg, uint32 q_len_arg)
1659
2140
{
1660
2141
  LEX_STRING new_db;
1661
2142
  int expected_error,actual_error= 0;
1703
2184
    thd->set_time((time_t)when);
1704
2185
    thd->query_length= q_len_arg;
1705
2186
    thd->query= (char*)query_arg;
1706
 
    pthread_mutex_lock(&LOCK_thread_count);
 
2187
    VOID(pthread_mutex_lock(&LOCK_thread_count));
1707
2188
    thd->query_id = next_query_id();
1708
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
2189
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
1709
2190
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
1710
2191
 
1711
2192
    if (ignored_error_code((expected_error= error_code)) ||
1717
2198
          must take their value from flags2.
1718
2199
        */
1719
2200
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2201
      /*
 
2202
        else, we are in a 3.23/4.0 binlog; we previously received a
 
2203
        Rotate_log_event which reset thd->options and sql_mode etc, so
 
2204
        nothing to do.
 
2205
      */
 
2206
      if (charset_inited)
 
2207
      {
 
2208
        if (rli->cached_charset_compare(charset))
 
2209
        {
 
2210
          /* Verify that we support the charsets found in the event. */
 
2211
          if (!(thd->variables.character_set_client=
 
2212
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
 
2213
              !(thd->variables.collation_connection=
 
2214
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
 
2215
              !(thd->variables.collation_server=
 
2216
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
 
2217
          {
 
2218
            /*
 
2219
              We updated the thd->variables with nonsensical values (0). Let's
 
2220
              set them to something safe (i.e. which avoids crash), and we'll
 
2221
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
 
2222
              ignore this error).
 
2223
            */
 
2224
            set_slave_thread_default_charset(thd, rli);
 
2225
            goto compare_errors;
 
2226
          }
 
2227
          thd->update_charset(); // for the charset change to take effect
 
2228
        }
 
2229
      }
1720
2230
      if (time_zone_len)
1721
2231
      {
1722
2232
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1742
2252
        thd->variables.lc_time_names= &my_locale_en_US;
1743
2253
      if (charset_database_number)
1744
2254
      {
1745
 
        const CHARSET_INFO *cs;
 
2255
        CHARSET_INFO *cs;
1746
2256
        if (!(cs= get_charset(charset_database_number, MYF(0))))
1747
2257
        {
1748
2258
          char buf[20];
1773
2283
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
1774
2284
      else
1775
2285
      {
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);
 
2286
        rli->report(ERROR_LEVEL, expected_error, 
 
2287
                          "\
 
2288
Query partially completed on the master (error on master: %d) \
 
2289
and was aborted. There is a chance that your master is inconsistent at this \
 
2290
point. If you are sure that your master is ok, run this query manually on the \
 
2291
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
 
2292
START SLAVE; . Query: '%s'", expected_error, thd->query);
1785
2293
        thd->is_slave_error= 1;
1786
2294
      }
1787
2295
      goto end;
1788
2296
    }
1789
2297
 
 
2298
    /* If the query was not ignored, it is printed to the general log */
 
2299
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
 
2300
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
 
2301
 
1790
2302
compare_errors:
1791
2303
 
1792
2304
     /*
1795
2307
    */
1796
2308
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
1797
2309
    if ((expected_error != actual_error) &&
1798
 
        expected_error &&
1799
 
        !ignored_error_code(actual_error) &&
1800
 
        !ignored_error_code(expected_error))
 
2310
        expected_error &&
 
2311
        !ignored_error_code(actual_error) &&
 
2312
        !ignored_error_code(expected_error))
1801
2313
    {
1802
2314
      rli->report(ERROR_LEVEL, 0,
1803
 
                  _("Query caused differenxt errors on master and slave.\n"
1804
 
                    "Error on master: '%s' (%d), Error on slave: '%s' (%d).\n"
1805
 
                    "Default database: '%s'. Query: '%s'"),
1806
 
                  ER_SAFE(expected_error),
1807
 
                  expected_error,
1808
 
                  actual_error ? thd->main_da.message() : _("no error"),
1809
 
                  actual_error,
1810
 
                  print_slave_db_safe(db), query_arg);
 
2315
                      "\
 
2316
Query caused different errors on master and slave.     \
 
2317
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
 
2318
Default database: '%s'. Query: '%s'",
 
2319
                      ER_SAFE(expected_error),
 
2320
                      expected_error,
 
2321
                      actual_error ? thd->main_da.message() : "no error",
 
2322
                      actual_error,
 
2323
                      print_slave_db_safe(db), query_arg);
1811
2324
      thd->is_slave_error= 1;
1812
2325
    }
1813
2326
    /*
1825
2338
    else if (thd->is_slave_error || thd->is_fatal_error)
1826
2339
    {
1827
2340
      rli->report(ERROR_LEVEL, actual_error,
1828
 
                  _("Error '%s' on query. Default database: '%s'. Query: '%s'"),
1829
 
                  (actual_error ? thd->main_da.message() :
1830
 
                   _("unexpected success or fatal error")),
 
2341
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
 
2342
                      (actual_error ? thd->main_da.message() :
 
2343
                       "unexpected success or fatal error"),
1831
2344
                      print_slave_db_safe(thd->db), query_arg);
1832
2345
      thd->is_slave_error= 1;
1833
2346
    }
1835
2348
    /*
1836
2349
      TODO: compare the values of "affected rows" around here. Something
1837
2350
      like:
1838
 
      if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
 
2351
      if ((uint32) affected_in_event != (uint32) affected_on_slave)
1839
2352
      {
1840
2353
      sql_print_error("Slave: did not get the expected number of affected \
1841
2354
      rows running query from master - expected %d, got %d (this numbers \
1856
2369
  } /* End of if (db_ok(... */
1857
2370
 
1858
2371
end:
1859
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2372
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1860
2373
  /*
1861
2374
    Probably we have set thd->query, thd->db, thd->catalog to point to places
1862
2375
    in the data_buf of this event. Now the event is going to be deleted
1863
2376
    probably, so data_buf will be freed, so the thd->... listed above will be
1864
2377
    pointers to freed memory. 
1865
2378
    So we must set them to 0, so that those bad pointers values are not later
1866
 
    used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
 
2379
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
1867
2380
    don't suffer from these assignments to 0 as DROP TEMPORARY
1868
 
    Table uses the db.table syntax.
 
2381
    TABLE uses the db.table syntax.
1869
2382
  */
1870
2383
  thd->catalog= 0;
1871
2384
  thd->set_db(NULL, 0);                 /* will free the current database */
1872
2385
  thd->query= 0;                        // just to be sure
1873
2386
  thd->query_length= 0;
1874
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2387
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1875
2388
  close_thread_tables(thd);      
1876
2389
  /*
1877
2390
    As a disk space optimization, future masters will not log an event for
1926
2439
  return(Log_event::do_shall_skip(rli));
1927
2440
}
1928
2441
 
 
2442
#endif
 
2443
 
1929
2444
 
1930
2445
/**************************************************************************
1931
2446
        Start_log_event_v3 methods
1932
2447
**************************************************************************/
1933
2448
 
 
2449
#ifndef MYSQL_CLIENT
1934
2450
Start_log_event_v3::Start_log_event_v3()
1935
2451
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
1936
2452
   artificial_event(0), dont_set_created(0)
1937
2453
{
1938
2454
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
1939
2455
}
 
2456
#endif
1940
2457
 
1941
2458
/*
1942
2459
  Start_log_event_v3::pack_info()
1943
2460
*/
1944
2461
 
 
2462
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1945
2463
void Start_log_event_v3::pack_info(Protocol *protocol)
1946
2464
{
1947
2465
  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
1948
 
  pos= my_stpcpy(buf, "Server ver: ");
1949
 
  pos= my_stpcpy(pos, server_version);
1950
 
  pos= my_stpcpy(pos, ", Binlog ver: ");
 
2466
  pos= strmov(buf, "Server ver: ");
 
2467
  pos= strmov(pos, server_version);
 
2468
  pos= strmov(pos, ", Binlog ver: ");
1951
2469
  pos= int10_to_str(binlog_version, pos, 10);
1952
2470
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
1953
2471
}
1954
 
 
 
2472
#endif
 
2473
 
 
2474
 
 
2475
/*
 
2476
  Start_log_event_v3::print()
 
2477
*/
 
2478
 
 
2479
#ifdef MYSQL_CLIENT
 
2480
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2481
{
 
2482
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
2483
                               Write_on_release_cache::FLUSH_F);
 
2484
 
 
2485
  if (!print_event_info->short_form)
 
2486
  {
 
2487
    print_header(&cache, print_event_info, false);
 
2488
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
 
2489
                binlog_version, server_version);
 
2490
    print_timestamp(&cache);
 
2491
    if (created)
 
2492
      my_b_printf(&cache," at startup");
 
2493
    my_b_printf(&cache, "\n");
 
2494
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
 
2495
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
 
2496
                  "Most probably mysqld crashed writing it.\n");
 
2497
  }
 
2498
  if (!artificial_event && created)
 
2499
  {
 
2500
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
 
2501
    /*
 
2502
      This is for mysqlbinlog: like in replication, we want to delete the stale
 
2503
      tmp files left by an unclean shutdown of mysqld (temporary tables)
 
2504
      and rollback unfinished transaction.
 
2505
      Probably this can be done with RESET CONNECTION (syntax to be defined).
 
2506
    */
 
2507
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
 
2508
#else
 
2509
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
 
2510
#endif
 
2511
  }
 
2512
  if (temp_buf &&
 
2513
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
 
2514
      !print_event_info->short_form)
 
2515
  {
 
2516
    my_b_printf(&cache, "BINLOG '\n");
 
2517
    print_base64(&cache, print_event_info, false);
 
2518
    print_event_info->printed_fd_event= true;
 
2519
  }
 
2520
  return;
 
2521
}
 
2522
#endif /* MYSQL_CLIENT */
1955
2523
 
1956
2524
/*
1957
2525
  Start_log_event_v3::Start_log_event_v3()
1979
2547
  Start_log_event_v3::write()
1980
2548
*/
1981
2549
 
 
2550
#ifndef MYSQL_CLIENT
1982
2551
bool Start_log_event_v3::write(IO_CACHE* file)
1983
2552
{
1984
2553
  char buff[START_V3_HEADER_LEN];
1988
2557
    created= when= get_time();
1989
2558
  int4store(buff + ST_CREATED_OFFSET,created);
1990
2559
  return (write_header(file, sizeof(buff)) ||
1991
 
          my_b_safe_write(file, (unsigned char*) buff, sizeof(buff)));
 
2560
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
1992
2561
}
1993
 
 
 
2562
#endif
 
2563
 
 
2564
 
 
2565
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1994
2566
 
1995
2567
/**
1996
2568
  Start_log_event_v3::do_apply_event() .
1998
2570
 
1999
2571
    IMPLEMENTATION
2000
2572
    - To handle the case where the master died without having time to write
2001
 
    DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
 
2573
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
2002
2574
    TODO), we clean up all temporary tables that we got, if we are sure we
2003
2575
    can (see below).
2004
2576
 
2055
2627
  }
2056
2628
  return(0);
2057
2629
}
 
2630
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
2058
2631
 
2059
2632
/***************************************************************************
2060
2633
       Format_description_log_event methods
2077
2650
*/
2078
2651
 
2079
2652
Format_description_log_event::
2080
 
Format_description_log_event(uint8_t binlog_ver, const char* server_ver)
 
2653
Format_description_log_event(uint8 binlog_ver, const char* server_ver)
2081
2654
  :Start_log_event_v3(), event_type_permutation(0)
2082
2655
{
2083
2656
  binlog_version= binlog_ver;
2087
2660
    common_header_len= LOG_EVENT_HEADER_LEN;
2088
2661
    number_of_event_types= LOG_EVENT_TYPES;
2089
2662
    /* we'll catch my_malloc() error in is_valid() */
2090
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
 
2663
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2091
2664
                                       MYF(MY_ZEROFILL));
2092
2665
    /*
2093
2666
      This long list of assignments is not beautiful, but I see no way to
2124
2697
      describes what those old master versions send.
2125
2698
    */
2126
2699
    if (binlog_ver==1)
2127
 
      my_stpcpy(server_version, server_ver ? server_ver : "3.23");
 
2700
      strmov(server_version, server_ver ? server_ver : "3.23");
2128
2701
    else
2129
 
      my_stpcpy(server_version, server_ver ? server_ver : "4.0");
 
2702
      strmov(server_version, server_ver ? server_ver : "4.0");
2130
2703
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2131
2704
      LOG_EVENT_MINIMAL_HEADER_LEN;
2132
2705
    /*
2137
2710
      make the slave detect less corruptions).
2138
2711
    */
2139
2712
    number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
2140
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
 
2713
    post_header_len=(uint8*) my_malloc(number_of_event_types*sizeof(uint8),
2141
2714
                                       MYF(0));
2142
2715
    if (post_header_len)
2143
2716
    {
2185
2758
 
2186
2759
Format_description_log_event::
2187
2760
Format_description_log_event(const char* buf,
2188
 
                             uint32_t event_len,
 
2761
                             uint event_len,
2189
2762
                             const
2190
2763
                             Format_description_log_event*
2191
2764
                             description_event)
2197
2770
  number_of_event_types=
2198
2771
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
2199
2772
  /* If alloc fails, we'll detect it in is_valid() */
2200
 
  post_header_len= (uint8_t*) my_memdup((unsigned char*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
 
2773
  post_header_len= (uint8*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2201
2774
                                      number_of_event_types*
2202
2775
                                      sizeof(*post_header_len), MYF(0));
2203
2776
  calc_server_version_split();
2272
2845
    if (number_of_event_types != 22)
2273
2846
    {
2274
2847
      /* this makes is_valid() return false. */
2275
 
      free(post_header_len);
 
2848
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2276
2849
      post_header_len= NULL;
2277
2850
      return;
2278
2851
    }
2279
 
    static const uint8_t perm[23]=
 
2852
    static const uint8 perm[23]=
2280
2853
      {
2281
2854
        UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
2282
2855
        INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
2297
2870
      Since we use (permuted) event id's to index the post_header_len
2298
2871
      array, we need to permute the post_header_len array too.
2299
2872
    */
2300
 
    uint8_t post_header_len_temp[23];
 
2873
    uint8 post_header_len_temp[23];
2301
2874
    for (int i= 1; i < 23; i++)
2302
2875
      post_header_len_temp[perm[i] - 1]= post_header_len[i - 1];
2303
2876
    for (int i= 0; i < 22; i++)
2306
2879
  return;
2307
2880
}
2308
2881
 
 
2882
#ifndef MYSQL_CLIENT
2309
2883
bool Format_description_log_event::write(IO_CACHE* file)
2310
2884
{
2311
2885
  /*
2312
2886
    We don't call Start_log_event_v3::write() because this would make 2
2313
2887
    my_b_safe_write().
2314
2888
  */
2315
 
  unsigned char buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
2889
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
2316
2890
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2317
 
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
 
2891
  memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2318
2892
  if (!dont_set_created)
2319
2893
    created= when= get_time();
2320
2894
  int4store(buff + ST_CREATED_OFFSET,created);
2321
2895
  buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
2322
 
  memcpy(buff+ST_COMMON_HEADER_LEN_OFFSET+1, post_header_len,
 
2896
  memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
2323
2897
         LOG_EVENT_TYPES);
2324
2898
  return (write_header(file, sizeof(buff)) ||
2325
2899
          my_b_safe_write(file, buff, sizeof(buff)));
2326
2900
}
2327
 
 
2328
 
 
 
2901
#endif
 
2902
 
 
2903
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2329
2904
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2330
2905
{
2331
2906
  /*
2343
2918
  {
2344
2919
    /* This is not an error (XA is safe), just an information */
2345
2920
    rli->report(INFORMATION_LEVEL, 0,
2346
 
                _("Rolling back unfinished transaction (no COMMIT "
2347
 
                  "or ROLLBACK in relay log). A probable cause is that "
2348
 
                  "the master died while writing the transaction to "
2349
 
                  "its binary log, thus rolled back too."));
 
2921
                "Rolling back unfinished transaction (no COMMIT "
 
2922
                "or ROLLBACK in relay log). A probable cause is that "
 
2923
                "the master died while writing the transaction to "
 
2924
                "its binary log, thus rolled back too."); 
2350
2925
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2351
2926
  }
2352
2927
  /*
2354
2929
    perform, we don't call Start_log_event_v3::do_apply_event()
2355
2930
    (this was just to update the log's description event).
2356
2931
  */
2357
 
  if (server_id != (uint32_t) ::server_id)
 
2932
  if (server_id != (uint32) ::server_id)
2358
2933
  {
2359
2934
    /*
2360
2935
      If the event was not requested by the slave i.e. the master sent
2376
2951
  delete rli->relay_log.description_event_for_exec;
2377
2952
  rli->relay_log.description_event_for_exec= this;
2378
2953
 
2379
 
  if (server_id == (uint32_t) ::server_id)
 
2954
  if (server_id == (uint32) ::server_id)
2380
2955
  {
2381
2956
    /*
2382
2957
      We only increase the relay log position if we are skipping
2401
2976
}
2402
2977
 
2403
2978
Log_event::enum_skip_reason
2404
 
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((unused)))
 
2979
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((__unused__)))
2405
2980
{
2406
2981
  return Log_event::EVENT_SKIP_NOT;
2407
2982
}
2408
2983
 
 
2984
#endif
 
2985
 
2409
2986
 
2410
2987
/**
2411
2988
   Splits the event's 'server_version' string into three numeric pieces stored
2420
2997
{
2421
2998
  char *p= server_version, *r;
2422
2999
  ulong number;
2423
 
  for (uint32_t i= 0; i<=2; i++)
 
3000
  for (uint i= 0; i<=2; i++)
2424
3001
  {
2425
3002
    number= strtoul(p, &r, 10);
2426
 
    server_version_split[i]= (unsigned char)number;
2427
 
    assert(number < 256); // fit in unsigned char
 
3003
    server_version_split[i]= (uchar)number;
 
3004
    assert(number < 256); // fit in uchar
2428
3005
    p= r;
2429
3006
    assert(!((i == 0) && (*r != '.'))); // should be true in practice
2430
3007
    if (*r == '.')
2454
3031
  Load_log_event::pack_info()
2455
3032
*/
2456
3033
 
2457
 
uint32_t Load_log_event::get_query_buffer_length()
 
3034
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3035
uint Load_log_event::get_query_buffer_length()
2458
3036
{
2459
3037
  return
2460
3038
    5 + db_len + 3 +                        // "use DB; "
2461
3039
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
2462
3040
    7 +                                     // LOCAL
2463
3041
    9 +                                     // " REPLACE or IGNORE "
2464
 
    13 + table_name_len*2 +                 // "INTO Table `table`"
 
3042
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
2465
3043
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
2466
3044
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
2467
3045
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
2479
3057
 
2480
3058
  if (need_db && db && db_len)
2481
3059
  {
2482
 
    pos= my_stpcpy(pos, "use `");
 
3060
    pos= strmov(pos, "use `");
2483
3061
    memcpy(pos, db, db_len);
2484
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
3062
    pos= strmov(pos+db_len, "`; ");
2485
3063
  }
2486
3064
 
2487
 
  pos= my_stpcpy(pos, "LOAD DATA ");
 
3065
  pos= strmov(pos, "LOAD DATA ");
2488
3066
 
2489
3067
  if (fn_start)
2490
3068
    *fn_start= pos;
2491
3069
 
2492
3070
  if (check_fname_outside_temp_buf())
2493
 
    pos= my_stpcpy(pos, "LOCAL ");
2494
 
  pos= my_stpcpy(pos, "INFILE '");
 
3071
    pos= strmov(pos, "LOCAL ");
 
3072
  pos= strmov(pos, "INFILE '");
2495
3073
  memcpy(pos, fname, fname_len);
2496
 
  pos= my_stpcpy(pos+fname_len, "' ");
 
3074
  pos= strmov(pos+fname_len, "' ");
2497
3075
 
2498
3076
  if (sql_ex.opt_flags & REPLACE_FLAG)
2499
 
    pos= my_stpcpy(pos, " REPLACE ");
 
3077
    pos= strmov(pos, " REPLACE ");
2500
3078
  else if (sql_ex.opt_flags & IGNORE_FLAG)
2501
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3079
    pos= strmov(pos, " IGNORE ");
2502
3080
 
2503
 
  pos= my_stpcpy(pos ,"INTO");
 
3081
  pos= strmov(pos ,"INTO");
2504
3082
 
2505
3083
  if (fn_end)
2506
3084
    *fn_end= pos;
2507
3085
 
2508
 
  pos= my_stpcpy(pos ," Table `");
 
3086
  pos= strmov(pos ," TABLE `");
2509
3087
  memcpy(pos, table_name, table_name_len);
2510
3088
  pos+= table_name_len;
2511
3089
 
2512
3090
  /* We have to create all optinal fields as the default is not empty */
2513
 
  pos= my_stpcpy(pos, "` FIELDS TERMINATED BY ");
 
3091
  pos= strmov(pos, "` FIELDS TERMINATED BY ");
2514
3092
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
2515
3093
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
2516
 
    pos= my_stpcpy(pos, " OPTIONALLY ");
2517
 
  pos= my_stpcpy(pos, " ENCLOSED BY ");
 
3094
    pos= strmov(pos, " OPTIONALLY ");
 
3095
  pos= strmov(pos, " ENCLOSED BY ");
2518
3096
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
2519
3097
 
2520
 
  pos= my_stpcpy(pos, " ESCAPED BY ");
 
3098
  pos= strmov(pos, " ESCAPED BY ");
2521
3099
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
2522
3100
 
2523
 
  pos= my_stpcpy(pos, " LINES TERMINATED BY ");
 
3101
  pos= strmov(pos, " LINES TERMINATED BY ");
2524
3102
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
2525
3103
  if (sql_ex.line_start_len)
2526
3104
  {
2527
 
    pos= my_stpcpy(pos, " STARTING BY ");
 
3105
    pos= strmov(pos, " STARTING BY ");
2528
3106
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
2529
3107
  }
2530
3108
 
2531
3109
  if ((long) skip_lines > 0)
2532
3110
  {
2533
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3111
    pos= strmov(pos, " IGNORE ");
2534
3112
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2535
 
    pos= my_stpcpy(pos," LINES ");    
 
3113
    pos= strmov(pos," LINES ");    
2536
3114
  }
2537
3115
 
2538
3116
  if (num_fields)
2539
3117
  {
2540
 
    uint32_t i;
 
3118
    uint i;
2541
3119
    const char *field= fields;
2542
 
    pos= my_stpcpy(pos, " (");
 
3120
    pos= strmov(pos, " (");
2543
3121
    for (i = 0; i < num_fields; i++)
2544
3122
    {
2545
3123
      if (i)
2566
3144
    return;
2567
3145
  print_query(true, buf, &end, 0, 0);
2568
3146
  protocol->store(buf, end-buf, &my_charset_bin);
2569
 
  free(buf);
 
3147
  my_free(buf, MYF(0));
2570
3148
}
2571
 
 
 
3149
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
3150
 
 
3151
 
 
3152
#ifndef MYSQL_CLIENT
2572
3153
 
2573
3154
/*
2574
3155
  Load_log_event::write_data_header()
2583
3164
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
2584
3165
  buf[L_DB_LEN_OFFSET] = (char)db_len;
2585
3166
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
2586
 
  return my_b_safe_write(file, (unsigned char*)buf, LOAD_HEADER_LEN) != 0;
 
3167
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
2587
3168
}
2588
3169
 
2589
3170
 
2597
3178
    return 1;
2598
3179
  if (num_fields && fields && field_lens)
2599
3180
  {
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))
 
3181
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
 
3182
        my_b_safe_write(file, (uchar*)fields, field_block_len))
2602
3183
      return 1;
2603
3184
  }
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));
 
3185
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
 
3186
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
 
3187
          my_b_safe_write(file, (uchar*)fname, fname_len));
2607
3188
}
2608
3189
 
2609
3190
 
2630
3211
  time(&end_time);
2631
3212
  exec_time = (ulong) (end_time  - thd_arg->start_time);
2632
3213
  /* db can never be a zero pointer in 4.0 */
2633
 
  db_len = (uint32_t) strlen(db);
2634
 
  table_name_len = (uint32_t) strlen(table_name);
 
3214
  db_len = (uint32) strlen(db);
 
3215
  table_name_len = (uint32) strlen(table_name);
2635
3216
  fname_len = (fname) ? (uint) strlen(fname) : 0;
2636
3217
  sql_ex.field_term = (char*) ex->field_term->ptr();
2637
 
  sql_ex.field_term_len = (uint8_t) ex->field_term->length();
 
3218
  sql_ex.field_term_len = (uint8) ex->field_term->length();
2638
3219
  sql_ex.enclosed = (char*) ex->enclosed->ptr();
2639
 
  sql_ex.enclosed_len = (uint8_t) ex->enclosed->length();
 
3220
  sql_ex.enclosed_len = (uint8) ex->enclosed->length();
2640
3221
  sql_ex.line_term = (char*) ex->line_term->ptr();
2641
 
  sql_ex.line_term_len = (uint8_t) ex->line_term->length();
 
3222
  sql_ex.line_term_len = (uint8) ex->line_term->length();
2642
3223
  sql_ex.line_start = (char*) ex->line_start->ptr();
2643
 
  sql_ex.line_start_len = (uint8_t) ex->line_start->length();
 
3224
  sql_ex.line_start_len = (uint8) ex->line_start->length();
2644
3225
  sql_ex.escaped = (char*) ex->escaped->ptr();
2645
 
  sql_ex.escaped_len = (uint8_t) ex->escaped->length();
 
3226
  sql_ex.escaped_len = (uint8) ex->escaped->length();
2646
3227
  sql_ex.opt_flags = 0;
2647
3228
  sql_ex.cached_new_format = -1;
2648
3229
    
2684
3265
  while ((item = li++))
2685
3266
  {
2686
3267
    num_fields++;
2687
 
    unsigned char len = (unsigned char) strlen(item->name);
 
3268
    uchar len = (uchar) strlen(item->name);
2688
3269
    field_block_len += len + 1;
2689
3270
    fields_buf.append(item->name, len + 1);
2690
3271
    field_lens_buf.append((char*)&len, 1);
2691
3272
  }
2692
3273
 
2693
 
  field_lens = (const unsigned char*)field_lens_buf.ptr();
 
3274
  field_lens = (const uchar*)field_lens_buf.ptr();
2694
3275
  fields = fields_buf.ptr();
2695
3276
}
 
3277
#endif /* !MYSQL_CLIENT */
2696
3278
 
2697
3279
 
2698
3280
/**
2700
3282
    The caller must do buf[event_len] = 0 before he starts using the
2701
3283
    constructed event.
2702
3284
*/
2703
 
Load_log_event::Load_log_event(const char *buf, uint32_t event_len,
 
3285
Load_log_event::Load_log_event(const char *buf, uint event_len,
2704
3286
                               const Format_description_log_event *description_event)
2705
3287
  :Log_event(buf, description_event), num_fields(0), fields(0),
2706
3288
   field_lens(0),field_block_len(0),
2730
3312
                                   int body_offset,
2731
3313
                                   const Format_description_log_event *description_event)
2732
3314
{
2733
 
  uint32_t data_len;
 
3315
  uint data_len;
2734
3316
  char* buf_end = (char*)buf + event_len;
2735
3317
  /* this is the beginning of the post-header */
2736
3318
  const char* data_head = buf + description_event->common_header_len;
2747
3329
    Sql_ex.init() on success returns the pointer to the first byte after
2748
3330
    the sql_ex structure, which is the start of field lengths array.
2749
3331
  */
2750
 
  if (!(field_lens= (unsigned char*)sql_ex.init((char*)buf + body_offset,
 
3332
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
2751
3333
                                        buf_end,
2752
3334
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
2753
3335
    return(1);
2755
3337
  data_len = event_len - body_offset;
2756
3338
  if (num_fields > data_len) // simple sanity check against corruption
2757
3339
    return(1);
2758
 
  for (uint32_t i = 0; i < num_fields; i++)
 
3340
  for (uint i = 0; i < num_fields; i++)
2759
3341
    field_block_len += (uint)field_lens[i] + 1;
2760
3342
 
2761
3343
  fields = (char*)field_lens + num_fields;
2769
3351
}
2770
3352
 
2771
3353
 
 
3354
/*
 
3355
  Load_log_event::print()
 
3356
*/
 
3357
 
 
3358
#ifdef MYSQL_CLIENT
 
3359
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3360
{
 
3361
  print(file, print_event_info, 0);
 
3362
}
 
3363
 
 
3364
 
 
3365
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 
3366
                           bool commented)
 
3367
{
 
3368
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
3369
 
 
3370
  if (!print_event_info->short_form)
 
3371
  {
 
3372
    print_header(&cache, print_event_info, false);
 
3373
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 
3374
                thread_id, exec_time);
 
3375
  }
 
3376
 
 
3377
  bool different_db= 1;
 
3378
  if (db)
 
3379
  {
 
3380
    /*
 
3381
      If the database is different from the one of the previous statement, we
 
3382
      need to print the "use" command, and we update the last_db.
 
3383
      But if commented, the "use" is going to be commented so we should not
 
3384
      update the last_db.
 
3385
    */
 
3386
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
 
3387
        !commented)
 
3388
      memcpy(print_event_info->db, db, db_len + 1);
 
3389
  }
 
3390
  
 
3391
  if (db && db[0] && different_db)
 
3392
    my_b_printf(&cache, "%suse %s%s\n", 
 
3393
            commented ? "# " : "",
 
3394
            db, print_event_info->delimiter);
 
3395
 
 
3396
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
 
3397
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
 
3398
            commented ? "# " : "", (ulong)thread_id,
 
3399
            print_event_info->delimiter);
 
3400
  my_b_printf(&cache, "%sLOAD DATA ",
 
3401
              commented ? "# " : "");
 
3402
  if (check_fname_outside_temp_buf())
 
3403
    my_b_printf(&cache, "LOCAL ");
 
3404
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
 
3405
 
 
3406
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3407
    my_b_printf(&cache," REPLACE ");
 
3408
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3409
    my_b_printf(&cache," IGNORE ");
 
3410
  
 
3411
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
 
3412
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
 
3413
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
 
3414
 
 
3415
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3416
    my_b_printf(&cache," OPTIONALLY ");
 
3417
  my_b_printf(&cache, " ENCLOSED BY ");
 
3418
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
 
3419
     
 
3420
  my_b_printf(&cache, " ESCAPED BY ");
 
3421
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
 
3422
     
 
3423
  my_b_printf(&cache," LINES TERMINATED BY ");
 
3424
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
 
3425
 
 
3426
 
 
3427
  if (sql_ex.line_start)
 
3428
  {
 
3429
    my_b_printf(&cache," STARTING BY ");
 
3430
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
 
3431
  }
 
3432
  if ((long) skip_lines > 0)
 
3433
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
 
3434
 
 
3435
  if (num_fields)
 
3436
  {
 
3437
    uint i;
 
3438
    const char* field = fields;
 
3439
    my_b_printf(&cache, " (");
 
3440
    for (i = 0; i < num_fields; i++)
 
3441
    {
 
3442
      if (i)
 
3443
        my_b_printf(&cache, ",");
 
3444
      my_b_printf(&cache, field);
 
3445
          
 
3446
      field += field_lens[i]  + 1;
 
3447
    }
 
3448
    my_b_printf(&cache, ")");
 
3449
  }
 
3450
 
 
3451
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
 
3452
  return;
 
3453
}
 
3454
#endif /* MYSQL_CLIENT */
 
3455
 
 
3456
#ifndef MYSQL_CLIENT
 
3457
 
2772
3458
/**
2773
3459
  Load_log_event::set_fields()
2774
3460
 
2783
3469
                                List<Item> &field_list,
2784
3470
                                Name_resolution_context *context)
2785
3471
{
2786
 
  uint32_t i;
 
3472
  uint i;
2787
3473
  const char* field = fields;
2788
3474
  for (i= 0; i < num_fields; i++)
2789
3475
  {
2792
3478
    field+= field_lens[i]  + 1;
2793
3479
  }
2794
3480
}
2795
 
 
2796
 
 
 
3481
#endif /* !MYSQL_CLIENT */
 
3482
 
 
3483
 
 
3484
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2797
3485
/**
2798
3486
  Does the data loading job when executing a LOAD DATA on the slave.
2799
3487
 
2879
3567
  if (rpl_filter->db_ok(thd->db))
2880
3568
  {
2881
3569
    thd->set_time((time_t)when);
2882
 
    pthread_mutex_lock(&LOCK_thread_count);
 
3570
    VOID(pthread_mutex_lock(&LOCK_thread_count));
2883
3571
    thd->query_id = next_query_id();
2884
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
3572
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
2885
3573
    /*
2886
3574
      Initing thd->row_count is not necessary in theory as this variable has no
2887
3575
      influence in the case of the slave SQL thread (it is used to generate a
2888
3576
      "data truncated" warning but which is absorbed and never gets to the
2889
3577
      error log); still we init it to avoid a Valgrind message.
2890
3578
    */
2891
 
    drizzle_reset_errors(thd, 0);
 
3579
    mysql_reset_errors(thd, 0);
2892
3580
 
2893
 
    TableList tables;
2894
 
    memset(&tables, 0, sizeof(tables));
 
3581
    TABLE_LIST tables;
 
3582
    bzero((char*) &tables,sizeof(tables));
2895
3583
    tables.db= thd->strmake(thd->db, thd->db_length);
2896
3584
    tables.alias = tables.table_name = (char*) table_name;
2897
3585
    tables.lock_type = TL_WRITE;
3009
3697
      if (thd->cuted_fields)
3010
3698
      {
3011
3699
        /* log_pos is the position of the LOAD event in the master log */
3012
 
        sql_print_warning(_("Slave: load data infile on table '%s' at "
 
3700
        sql_print_warning("Slave: load data infile on table '%s' at "
3013
3701
                          "log position %s in log '%s' produced %ld "
3014
 
                          "warning(s). Default database: '%s'"),
 
3702
                          "warning(s). Default database: '%s'",
3015
3703
                          (char*) table_name,
3016
3704
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
3017
3705
                          (ulong) thd->cuted_fields,
3035
3723
error:
3036
3724
  thd->net.vio = 0; 
3037
3725
  const char *remember_db= thd->db;
3038
 
  pthread_mutex_lock(&LOCK_thread_count);
 
3726
  VOID(pthread_mutex_lock(&LOCK_thread_count));
3039
3727
  thd->catalog= 0;
3040
3728
  thd->set_db(NULL, 0);                   /* will free the current database */
3041
3729
  thd->query= 0;
3042
3730
  thd->query_length= 0;
3043
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
3731
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
3044
3732
  close_thread_tables(thd);
3045
3733
 
3046
3734
  if (thd->is_slave_error)
3056
3744
    else
3057
3745
    {
3058
3746
      sql_errno=ER_UNKNOWN_ERROR;
3059
 
      err=ER(sql_errno);
 
3747
      err=ER(sql_errno);       
3060
3748
    }
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));
 
3749
    rli->report(ERROR_LEVEL, sql_errno,"\
 
3750
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
 
3751
                    err, (char*)table_name, print_slave_db_safe(remember_db));
3065
3752
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3066
3753
    return 1;
3067
3754
  }
3071
3758
  {
3072
3759
    char buf[256];
3073
3760
    snprintf(buf, sizeof(buf),
3074
 
             _("Running LOAD DATA INFILE on table '%-.64s'."
3075
 
               " Default database: '%-.64s'"),
 
3761
             "Running LOAD DATA INFILE on table '%-.64s'."
 
3762
             " Default database: '%-.64s'",
3076
3763
             (char*)table_name,
3077
3764
             print_slave_db_safe(remember_db));
3078
3765
 
3081
3768
    return 1;
3082
3769
  }
3083
3770
 
3084
 
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
 
3771
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
3085
3772
}
 
3773
#endif
3086
3774
 
3087
3775
 
3088
3776
/**************************************************************************
3093
3781
  Rotate_log_event::pack_info()
3094
3782
*/
3095
3783
 
 
3784
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3096
3785
void Rotate_log_event::pack_info(Protocol *protocol)
3097
3786
{
3098
3787
  char buf1[256], buf[22];
3103
3792
  tmp.append(llstr(pos,buf));
3104
3793
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3105
3794
}
 
3795
#endif
 
3796
 
 
3797
 
 
3798
/*
 
3799
  Rotate_log_event::print()
 
3800
*/
 
3801
 
 
3802
#ifdef MYSQL_CLIENT
 
3803
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3804
{
 
3805
  char buf[22];
 
3806
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
3807
                               Write_on_release_cache::FLUSH_F);
 
3808
 
 
3809
  if (print_event_info->short_form)
 
3810
    return;
 
3811
  print_header(&cache, print_event_info, false);
 
3812
  my_b_printf(&cache, "\tRotate to ");
 
3813
  if (new_log_ident)
 
3814
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
 
3815
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
 
3816
}
 
3817
#endif /* MYSQL_CLIENT */
 
3818
 
3106
3819
 
3107
3820
 
3108
3821
/*
3110
3823
*/
3111
3824
 
3112
3825
 
 
3826
#ifndef MYSQL_CLIENT
3113
3827
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
3114
 
                                   uint32_t ident_len_arg, uint64_t pos_arg,
3115
 
                                   uint32_t flags_arg)
 
3828
                                   uint ident_len_arg, uint64_t pos_arg,
 
3829
                                   uint flags_arg)
3116
3830
  :Log_event(), new_log_ident(new_log_ident_arg),
3117
3831
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3118
3832
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
3121
3835
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
3122
3836
  return;
3123
3837
}
3124
 
 
3125
 
 
3126
 
Rotate_log_event::Rotate_log_event(const char* buf, uint32_t event_len,
 
3838
#endif
 
3839
 
 
3840
 
 
3841
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
3127
3842
                                   const Format_description_log_event* description_event)
3128
3843
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
3129
3844
{
3130
3845
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
3131
 
  uint8_t header_size= description_event->common_header_len;
3132
 
  uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
3133
 
  uint32_t ident_offset;
 
3846
  uint8 header_size= description_event->common_header_len;
 
3847
  uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
 
3848
  uint ident_offset;
3134
3849
  if (event_len < header_size)
3135
3850
    return;
3136
3851
  buf += header_size;
3148
3863
  Rotate_log_event::write()
3149
3864
*/
3150
3865
 
 
3866
#ifndef MYSQL_CLIENT
3151
3867
bool Rotate_log_event::write(IO_CACHE* file)
3152
3868
{
3153
3869
  char buf[ROTATE_HEADER_LEN];
3154
3870
  int8store(buf + R_POS_OFFSET, pos);
3155
3871
  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
3156
 
          my_b_safe_write(file, (unsigned char*)buf, ROTATE_HEADER_LEN) ||
3157
 
          my_b_safe_write(file, (unsigned char*)new_log_ident, (uint) ident_len));
 
3872
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
 
3873
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
3158
3874
}
3159
 
 
 
3875
#endif
 
3876
 
 
3877
 
 
3878
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3160
3879
 
3161
3880
/*
3162
3881
  Got a rotate log event from the master.
3194
3913
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3195
3914
      !rli->is_in_group())
3196
3915
  {
3197
 
    rli->group_master_log_name.assign(new_log_ident, ident_len+1);
 
3916
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3198
3917
    rli->notify_group_master_log_name_update();
3199
3918
    rli->group_master_log_pos= pos;
3200
 
    rli->group_relay_log_name.assign(rli->event_relay_log_name);
 
3919
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
 
3920
            sizeof(rli->group_relay_log_name) - 1);
3201
3921
    rli->notify_group_relay_log_name_update();
3202
3922
    rli->group_relay_log_pos= rli->event_relay_log_pos;
3203
3923
    /*
3208
3928
      master is 4.0 then the events are in the slave's format (conversion).
3209
3929
    */
3210
3930
    set_slave_thread_options(thd);
 
3931
    set_slave_thread_default_charset(thd, rli);
3211
3932
    thd->variables.auto_increment_increment=
3212
3933
      thd->variables.auto_increment_offset= 1;
3213
3934
  }
3236
3957
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
3237
3958
}
3238
3959
 
 
3960
#endif
 
3961
 
3239
3962
 
3240
3963
/**************************************************************************
3241
3964
        Intvar_log_event methods
3245
3968
  Intvar_log_event::pack_info()
3246
3969
*/
3247
3970
 
 
3971
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3248
3972
void Intvar_log_event::pack_info(Protocol *protocol)
3249
3973
{
3250
3974
  char buf[256], *pos;
3253
3977
  pos= int64_t10_to_str(val, pos, -10);
3254
3978
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3255
3979
}
 
3980
#endif
3256
3981
 
3257
3982
 
3258
3983
/*
3287
4012
  Intvar_log_event::write()
3288
4013
*/
3289
4014
 
 
4015
#ifndef MYSQL_CLIENT
3290
4016
bool Intvar_log_event::write(IO_CACHE* file)
3291
4017
{
3292
 
  unsigned char buf[9];
3293
 
  buf[I_TYPE_OFFSET]= (unsigned char) type;
 
4018
  uchar buf[9];
 
4019
  buf[I_TYPE_OFFSET]= (uchar) type;
3294
4020
  int8store(buf + I_VAL_OFFSET, val);
3295
4021
  return (write_header(file, sizeof(buf)) ||
3296
4022
          my_b_safe_write(file, buf, sizeof(buf)));
3297
4023
}
 
4024
#endif
3298
4025
 
3299
4026
 
3300
4027
/*
3301
4028
  Intvar_log_event::print()
3302
4029
*/
3303
4030
 
 
4031
#ifdef MYSQL_CLIENT
 
4032
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4033
{
 
4034
  char llbuff[22];
 
4035
  const char *msg;
 
4036
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4037
                               Write_on_release_cache::FLUSH_F);
 
4038
 
 
4039
  if (!print_event_info->short_form)
 
4040
  {
 
4041
    print_header(&cache, print_event_info, false);
 
4042
    my_b_printf(&cache, "\tIntvar\n");
 
4043
  }
 
4044
 
 
4045
  my_b_printf(&cache, "SET ");
 
4046
  switch (type) {
 
4047
  case LAST_INSERT_ID_EVENT:
 
4048
    msg="LAST_INSERT_ID";
 
4049
    break;
 
4050
  case INSERT_ID_EVENT:
 
4051
    msg="INSERT_ID";
 
4052
    break;
 
4053
  case INVALID_INT_EVENT:
 
4054
  default: // cannot happen
 
4055
    msg="INVALID_INT";
 
4056
    break;
 
4057
  }
 
4058
  my_b_printf(&cache, "%s=%s%s\n",
 
4059
              msg, llstr(val,llbuff), print_event_info->delimiter);
 
4060
}
 
4061
#endif
 
4062
 
 
4063
 
3304
4064
/*
3305
4065
  Intvar_log_event::do_apply_event()
3306
4066
*/
3307
4067
 
 
4068
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
3308
4069
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
3309
4070
{
3310
4071
  /*
3346
4107
  return continue_group(rli);
3347
4108
}
3348
4109
 
 
4110
#endif
 
4111
 
3349
4112
 
3350
4113
/**************************************************************************
3351
4114
  Rand_log_event methods
3352
4115
**************************************************************************/
3353
4116
 
 
4117
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3354
4118
void Rand_log_event::pack_info(Protocol *protocol)
3355
4119
{
3356
4120
  char buf1[256], *pos;
3357
 
  pos= my_stpcpy(buf1,"rand_seed1=");
 
4121
  pos= strmov(buf1,"rand_seed1=");
3358
4122
  pos= int10_to_str((long) seed1, pos, 10);
3359
 
  pos= my_stpcpy(pos, ",rand_seed2=");
 
4123
  pos= strmov(pos, ",rand_seed2=");
3360
4124
  pos= int10_to_str((long) seed2, pos, 10);
3361
4125
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
3362
4126
}
 
4127
#endif
3363
4128
 
3364
4129
 
3365
4130
Rand_log_event::Rand_log_event(const char* buf,
3372
4137
}
3373
4138
 
3374
4139
 
 
4140
#ifndef MYSQL_CLIENT
3375
4141
bool Rand_log_event::write(IO_CACHE* file)
3376
4142
{
3377
 
  unsigned char buf[16];
 
4143
  uchar buf[16];
3378
4144
  int8store(buf + RAND_SEED1_OFFSET, seed1);
3379
4145
  int8store(buf + RAND_SEED2_OFFSET, seed2);
3380
4146
  return (write_header(file, sizeof(buf)) ||
3381
4147
          my_b_safe_write(file, buf, sizeof(buf)));
3382
4148
}
3383
 
 
3384
 
 
 
4149
#endif
 
4150
 
 
4151
 
 
4152
#ifdef MYSQL_CLIENT
 
4153
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4154
{
 
4155
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4156
                               Write_on_release_cache::FLUSH_F);
 
4157
 
 
4158
  char llbuff[22],llbuff2[22];
 
4159
  if (!print_event_info->short_form)
 
4160
  {
 
4161
    print_header(&cache, print_event_info, false);
 
4162
    my_b_printf(&cache, "\tRand\n");
 
4163
  }
 
4164
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
 
4165
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
 
4166
              print_event_info->delimiter);
 
4167
}
 
4168
#endif /* MYSQL_CLIENT */
 
4169
 
 
4170
 
 
4171
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3385
4172
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
3386
4173
{
3387
4174
  /*
3416
4203
  return continue_group(rli);
3417
4204
}
3418
4205
 
 
4206
#endif /* !MYSQL_CLIENT */
 
4207
 
3419
4208
 
3420
4209
/**************************************************************************
3421
4210
  Xid_log_event methods
3422
4211
**************************************************************************/
3423
4212
 
 
4213
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3424
4214
void Xid_log_event::pack_info(Protocol *protocol)
3425
4215
{
3426
4216
  char buf[128], *pos;
3427
 
  pos= my_stpcpy(buf, "COMMIT /* xid=");
 
4217
  pos= strmov(buf, "COMMIT /* xid=");
3428
4218
  pos= int64_t10_to_str(xid, pos, 10);
3429
 
  pos= my_stpcpy(pos, " */");
 
4219
  pos= strmov(pos, " */");
3430
4220
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3431
4221
}
 
4222
#endif
3432
4223
 
3433
4224
/**
3434
4225
  @note
3445
4236
  :Log_event(buf, description_event)
3446
4237
{
3447
4238
  buf+= description_event->common_header_len;
3448
 
  memcpy(&xid, buf, sizeof(xid));
 
4239
  memcpy((char*) &xid, buf, sizeof(xid));
3449
4240
}
3450
4241
 
3451
4242
 
 
4243
#ifndef MYSQL_CLIENT
3452
4244
bool Xid_log_event::write(IO_CACHE* file)
3453
4245
{
3454
4246
  return write_header(file, sizeof(xid)) ||
3455
 
         my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
3456
 
}
3457
 
 
3458
 
 
3459
 
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
3460
 
{
 
4247
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
 
4248
}
 
4249
#endif
 
4250
 
 
4251
 
 
4252
#ifdef MYSQL_CLIENT
 
4253
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4254
{
 
4255
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4256
                               Write_on_release_cache::FLUSH_F);
 
4257
 
 
4258
  if (!print_event_info->short_form)
 
4259
  {
 
4260
    char buf[64];
 
4261
    int64_t10_to_str(xid, buf, 10);
 
4262
 
 
4263
    print_header(&cache, print_event_info, false);
 
4264
    my_b_printf(&cache, "\tXid = %s\n", buf);
 
4265
  }
 
4266
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
 
4267
}
 
4268
#endif /* MYSQL_CLIENT */
 
4269
 
 
4270
 
 
4271
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4272
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((__unused__)))
 
4273
{
 
4274
  /* For a slave Xid_log_event is COMMIT */
 
4275
  general_log_print(thd, COM_QUERY,
 
4276
                    "COMMIT /* implicit, from Xid_log_event */");
3461
4277
  return end_trans(thd, COMMIT);
3462
4278
}
3463
4279
 
3470
4286
  }
3471
4287
  return(Log_event::do_shall_skip(rli));
3472
4288
}
 
4289
#endif /* !MYSQL_CLIENT */
3473
4290
 
3474
4291
 
3475
4292
/**************************************************************************
3476
4293
  User_var_log_event methods
3477
4294
**************************************************************************/
3478
4295
 
 
4296
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3479
4297
void User_var_log_event::pack_info(Protocol* protocol)
3480
4298
{
3481
4299
  char *buf= 0;
3482
 
  uint32_t val_offset= 4 + name_len;
3483
 
  uint32_t event_len= val_offset;
 
4300
  uint val_offset= 4 + name_len;
 
4301
  uint event_len= val_offset;
3484
4302
 
3485
4303
  if (is_null)
3486
4304
  {
3487
4305
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
3488
4306
      return;
3489
 
    my_stpcpy(buf + val_offset, "NULL");
 
4307
    strmov(buf + val_offset, "NULL");
3490
4308
    event_len= val_offset + 4;
3491
4309
  }
3492
4310
  else
3513
4331
        return;
3514
4332
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
3515
4333
      my_decimal dec;
3516
 
      binary2my_decimal(E_DEC_FATAL_ERROR, (unsigned char*) (val+2), &dec, val[0],
 
4334
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
3517
4335
                        val[1]);
3518
4336
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
3519
4337
      event_len= str.length() + val_offset;
3523
4341
      /* 15 is for 'COLLATE' and other chars */
3524
4342
      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
3525
4343
                             MYF(MY_WME));
3526
 
      const CHARSET_INFO *cs;
 
4344
      CHARSET_INFO *cs;
3527
4345
      if (!buf)
3528
4346
        return;
3529
4347
      if (!(cs= get_charset(charset_number, MYF(0))))
3530
4348
      {
3531
 
        my_stpcpy(buf+val_offset, "???");
 
4349
        strmov(buf+val_offset, "???");
3532
4350
        event_len+= 3;
3533
4351
      }
3534
4352
      else
3535
4353
      {
3536
 
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NULL);
 
4354
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
3537
4355
        p= str_to_hex(p, val, val_len);
3538
 
        p= strxmov(p, " COLLATE ", cs->name, NULL);
 
4356
        p= strxmov(p, " COLLATE ", cs->name, NullS);
3539
4357
        event_len= p-buf;
3540
4358
      }
3541
4359
      break;
3551
4369
  buf[2+name_len]= '`';
3552
4370
  buf[3+name_len]= '=';
3553
4371
  protocol->store(buf, event_len, &my_charset_bin);
3554
 
  free(buf);
 
4372
  my_free(buf, MYF(0));
3555
4373
}
 
4374
#endif /* !MYSQL_CLIENT */
3556
4375
 
3557
4376
 
3558
4377
User_var_log_event::
3584
4403
}
3585
4404
 
3586
4405
 
 
4406
#ifndef MYSQL_CLIENT
3587
4407
bool User_var_log_event::write(IO_CACHE* file)
3588
4408
{
3589
4409
  char buf[UV_NAME_LEN_SIZE];
3590
4410
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
3591
4411
            UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
3592
 
  unsigned char buf2[(8 > DECIMAL_MAX_FIELD_SIZE + 2) ? 8 : DECIMAL_MAX_FIELD_SIZE +2], *pos= buf2;
3593
 
  uint32_t buf1_length;
 
4412
  uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
 
4413
  uint buf1_length;
3594
4414
  ulong event_length;
3595
4415
 
3596
4416
  int4store(buf, name_len);
3623
4443
      break;
3624
4444
    }
3625
4445
    case STRING_RESULT:
3626
 
      pos= (unsigned char*) val;
 
4446
      pos= (uchar*) val;
3627
4447
      break;
3628
4448
    case ROW_RESULT:
3629
4449
    default:
3638
4458
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
3639
4459
 
3640
4460
  return (write_header(file, event_length) ||
3641
 
          my_b_safe_write(file, (unsigned char*) buf, sizeof(buf))   ||
3642
 
          my_b_safe_write(file, (unsigned char*) name, name_len)     ||
3643
 
          my_b_safe_write(file, (unsigned char*) buf1, buf1_length) ||
 
4461
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
 
4462
          my_b_safe_write(file, (uchar*) name, name_len)     ||
 
4463
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
3644
4464
          my_b_safe_write(file, pos, val_len));
3645
4465
}
3646
 
 
 
4466
#endif
 
4467
 
 
4468
 
 
4469
/*
 
4470
  User_var_log_event::print()
 
4471
*/
 
4472
 
 
4473
#ifdef MYSQL_CLIENT
 
4474
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4475
{
 
4476
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4477
                               Write_on_release_cache::FLUSH_F);
 
4478
 
 
4479
  if (!print_event_info->short_form)
 
4480
  {
 
4481
    print_header(&cache, print_event_info, false);
 
4482
    my_b_printf(&cache, "\tUser_var\n");
 
4483
  }
 
4484
 
 
4485
  my_b_printf(&cache, "SET @`");
 
4486
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
 
4487
  my_b_printf(&cache, "`");
 
4488
 
 
4489
  if (is_null)
 
4490
  {
 
4491
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
 
4492
  }
 
4493
  else
 
4494
  {
 
4495
    switch (type) {
 
4496
    case REAL_RESULT:
 
4497
      double real_val;
 
4498
      char real_buf[FMT_G_BUFSIZE(14)];
 
4499
      float8get(real_val, val);
 
4500
      my_sprintf(real_buf, (real_buf, "%.14g", real_val));
 
4501
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
 
4502
      break;
 
4503
    case INT_RESULT:
 
4504
      char int_buf[22];
 
4505
      int64_t10_to_str(uint8korr(val), int_buf, -10);
 
4506
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
 
4507
      break;
 
4508
    case DECIMAL_RESULT:
 
4509
    {
 
4510
      char str_buf[200];
 
4511
      int str_len= sizeof(str_buf) - 1;
 
4512
      int precision= (int)val[0];
 
4513
      int scale= (int)val[1];
 
4514
      decimal_digit_t dec_buf[10];
 
4515
      decimal_t dec;
 
4516
      dec.len= 10;
 
4517
      dec.buf= dec_buf;
 
4518
 
 
4519
      bin2decimal((uchar*) val+2, &dec, precision, scale);
 
4520
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
 
4521
      str_buf[str_len]= 0;
 
4522
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
 
4523
      break;
 
4524
    }
 
4525
    case STRING_RESULT:
 
4526
    {
 
4527
      /*
 
4528
        Let's express the string in hex. That's the most robust way. If we
 
4529
        print it in character form instead, we need to escape it with
 
4530
        character_set_client which we don't know (we will know it in 5.0, but
 
4531
        in 4.1 we don't know it easily when we are printing
 
4532
        User_var_log_event). Explanation why we would need to bother with
 
4533
        character_set_client (quoting Bar):
 
4534
        > Note, the parser doesn't switch to another unescaping mode after
 
4535
        > it has met a character set introducer.
 
4536
        > For example, if an SJIS client says something like:
 
4537
        > SET @a= _ucs2 \0a\0b'
 
4538
        > the string constant is still unescaped according to SJIS, not
 
4539
        > according to UCS2.
 
4540
      */
 
4541
      char *hex_str;
 
4542
      CHARSET_INFO *cs;
 
4543
 
 
4544
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
 
4545
        break; // no error, as we are 'void'
 
4546
      str_to_hex(hex_str, val, val_len);
 
4547
      /*
 
4548
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
 
4549
        specify the variable's collation. It will however cause problems when
 
4550
        people want to mysqlbinlog|mysql into another server not supporting the
 
4551
        character set. But there's not much to do about this and it's unlikely.
 
4552
      */
 
4553
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4554
        /*
 
4555
          Generate an unusable command (=> syntax error) is probably the best
 
4556
          thing we can do here.
 
4557
        */
 
4558
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
 
4559
      else
 
4560
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
 
4561
                    cs->csname, hex_str, cs->name,
 
4562
                    print_event_info->delimiter);
 
4563
      my_afree(hex_str);
 
4564
    }
 
4565
      break;
 
4566
    case ROW_RESULT:
 
4567
    default:
 
4568
      assert(1);
 
4569
      return;
 
4570
    }
 
4571
  }
 
4572
}
 
4573
#endif
3647
4574
 
3648
4575
 
3649
4576
/*
3650
4577
  User_var_log_event::do_apply_event()
3651
4578
*/
3652
4579
 
 
4580
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3653
4581
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
3654
4582
{
3655
4583
  Item *it= 0;
3656
 
  const CHARSET_INFO *charset;
 
4584
  CHARSET_INFO *charset;
3657
4585
  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
3658
4586
    return 1;
3659
4587
  LEX_STRING user_var_name;
3689
4617
      break;
3690
4618
    case DECIMAL_RESULT:
3691
4619
    {
3692
 
      Item_decimal *dec= new Item_decimal((unsigned char*) val+2, val[0], val[1]);
 
4620
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
3693
4621
      it= dec;
3694
4622
      val= (char *)dec->val_decimal(NULL);
3695
4623
      val_len= sizeof(my_decimal);
3740
4668
  */
3741
4669
  return continue_group(rli);
3742
4670
}
 
4671
#endif /* !MYSQL_CLIENT */
3743
4672
 
3744
4673
 
3745
4674
/**************************************************************************
3746
4675
  Slave_log_event methods
3747
4676
**************************************************************************/
3748
4677
 
 
4678
#ifdef HAVE_REPLICATION
 
4679
#ifdef MYSQL_CLIENT
 
4680
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
 
4681
{
 
4682
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
4683
 
 
4684
  if (print_event_info->short_form)
 
4685
    return;
 
4686
  print_header(&cache, print_event_info, false);
 
4687
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
 
4688
}
 
4689
#endif  
 
4690
 
 
4691
#ifndef MYSQL_CLIENT
3749
4692
void Slave_log_event::pack_info(Protocol *protocol)
3750
4693
{
3751
4694
  char buf[256+HOSTNAME_LENGTH], *pos;
3752
 
  pos= my_stpcpy(buf, "host=");
3753
 
  pos= my_stpncpy(pos, master_host.c_str(), HOSTNAME_LENGTH);
3754
 
  pos= my_stpcpy(pos, ",port=");
 
4695
  pos= strmov(buf, "host=");
 
4696
  pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
 
4697
  pos= strmov(pos, ",port=");
3755
4698
  pos= int10_to_str((long) master_port, pos, 10);
3756
 
  pos= my_stpcpy(pos, ",log=");
3757
 
  pos= my_stpcpy(pos, master_log.c_str());
3758
 
  pos= my_stpcpy(pos, ",pos=");
 
4699
  pos= strmov(pos, ",log=");
 
4700
  pos= strmov(pos, master_log);
 
4701
  pos= strmov(pos, ",pos=");
3759
4702
  pos= int64_t10_to_str(master_pos, pos, 10);
3760
4703
  protocol->store(buf, pos-buf, &my_charset_bin);
3761
4704
}
3762
 
 
3763
 
 
 
4705
#endif /* !MYSQL_CLIENT */
 
4706
 
 
4707
 
 
4708
#ifndef MYSQL_CLIENT
3764
4709
/**
3765
4710
  @todo
3766
4711
  re-write this better without holding both locks at the same time
3776
4721
  // TODO: re-write this better without holding both locks at the same time
3777
4722
  pthread_mutex_lock(&mi->data_lock);
3778
4723
  pthread_mutex_lock(&rli->data_lock);
 
4724
  master_host_len = strlen(mi->host);
 
4725
  master_log_len = strlen(rli->group_master_log_name);
3779
4726
  // on OOM, just do not initialize the structure and print the error
3780
4727
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
3781
4728
                                   MYF(MY_WME))))
3782
4729
  {
3783
 
    master_host.assign(mi->getHostname());
3784
 
    master_log.assign(rli->group_master_log_name);
3785
 
    master_port = mi->getPort();
 
4730
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
 
4731
    memcpy(master_host, mi->host, master_host_len + 1);
 
4732
    master_log = master_host + master_host_len + 1;
 
4733
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
 
4734
    master_port = mi->port;
3786
4735
    master_pos = rli->group_master_log_pos;
3787
4736
  }
3788
4737
  else
3789
 
    sql_print_error(_("Out of memory while recording slave event"));
 
4738
    sql_print_error("Out of memory while recording slave event");
3790
4739
  pthread_mutex_unlock(&rli->data_lock);
3791
4740
  pthread_mutex_unlock(&mi->data_lock);
3792
4741
  return;
3793
4742
}
 
4743
#endif /* !MYSQL_CLIENT */
3794
4744
 
3795
4745
 
3796
4746
Slave_log_event::~Slave_log_event()
3797
4747
{
3798
 
  free(mem_pool);
3799
 
}
 
4748
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 
4749
}
 
4750
 
 
4751
 
 
4752
#ifdef MYSQL_CLIENT
 
4753
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4754
{
 
4755
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
4756
 
 
4757
  char llbuff[22];
 
4758
  if (print_event_info->short_form)
 
4759
    return;
 
4760
  print_header(&cache, print_event_info, false);
 
4761
  my_b_printf(&cache, "\n\
 
4762
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 
4763
          master_host, master_port, master_log, llstr(master_pos, llbuff));
 
4764
}
 
4765
#endif /* MYSQL_CLIENT */
3800
4766
 
3801
4767
 
3802
4768
int Slave_log_event::get_data_size()
3803
4769
{
3804
 
  return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
 
4770
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
3805
4771
}
3806
4772
 
3807
4773
 
 
4774
#ifndef MYSQL_CLIENT
3808
4775
bool Slave_log_event::write(IO_CACHE* file)
3809
4776
{
3810
4777
  ulong event_length= get_data_size();
3813
4780
  // log and host are already there
3814
4781
 
3815
4782
  return (write_header(file, event_length) ||
3816
 
          my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
 
4783
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
3817
4784
}
3818
 
 
3819
 
 
3820
 
void Slave_log_event::init_from_mem_pool()
 
4785
#endif
 
4786
 
 
4787
 
 
4788
void Slave_log_event::init_from_mem_pool(int data_size)
3821
4789
{
3822
4790
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
3823
4791
  master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
3824
 
#ifdef FIXME
3825
 
  /* Assign these correctly */
3826
 
  master_host.assign(mem_pool + SL_MASTER_HOST_OFFSET);
3827
 
  master_log.assign();
3828
 
#endif
3829
 
}
3830
 
 
3831
 
 
3832
 
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
4792
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
 
4793
  master_host_len = strlen(master_host);
 
4794
  // safety
 
4795
  master_log = master_host + master_host_len + 1;
 
4796
  if (master_log > mem_pool + data_size)
 
4797
  {
 
4798
    master_host = 0;
 
4799
    return;
 
4800
  }
 
4801
  master_log_len = strlen(master_log);
 
4802
}
 
4803
 
 
4804
 
 
4805
/** This code is not used, so has not been updated to be format-tolerant. */
 
4806
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
 
4807
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
 
4808
{
 
4809
  if (event_len < LOG_EVENT_HEADER_LEN)
 
4810
    return;
 
4811
  event_len -= LOG_EVENT_HEADER_LEN;
 
4812
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
 
4813
    return;
 
4814
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
 
4815
  mem_pool[event_len] = 0;
 
4816
  init_from_mem_pool(event_len);
 
4817
}
 
4818
 
 
4819
 
 
4820
#ifndef MYSQL_CLIENT
 
4821
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((__unused__)))
3833
4822
{
3834
4823
  if (mysql_bin_log.is_open())
3835
4824
    mysql_bin_log.write(this);
3836
4825
  return 0;
3837
4826
}
 
4827
#endif /* !MYSQL_CLIENT */
3838
4828
 
3839
4829
 
3840
4830
/**************************************************************************
3842
4832
**************************************************************************/
3843
4833
 
3844
4834
/*
 
4835
  Stop_log_event::print()
 
4836
*/
 
4837
 
 
4838
#ifdef MYSQL_CLIENT
 
4839
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4840
{
 
4841
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4842
                               Write_on_release_cache::FLUSH_F);
 
4843
 
 
4844
  if (print_event_info->short_form)
 
4845
    return;
 
4846
 
 
4847
  print_header(&cache, print_event_info, false);
 
4848
  my_b_printf(&cache, "\tStop\n");
 
4849
}
 
4850
#endif /* MYSQL_CLIENT */
 
4851
 
 
4852
 
 
4853
#ifndef MYSQL_CLIENT
 
4854
/*
3845
4855
  The master stopped.  We used to clean up all temporary tables but
3846
4856
  this is useless as, as the master has shut down properly, it has
3847
 
  written all DROP TEMPORARY Table (prepared statements' deletion is
 
4857
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
3848
4858
  TODO only when we binlog prep stmts).  We used to clean up
3849
4859
  slave_load_tmpdir, but this is useless as it has been cleared at the
3850
4860
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
3871
4881
  return 0;
3872
4882
}
3873
4883
 
 
4884
#endif /* !MYSQL_CLIENT */
 
4885
#endif /* HAVE_REPLICATION */
 
4886
 
3874
4887
 
3875
4888
/**************************************************************************
3876
4889
        Create_file_log_event methods
3880
4893
  Create_file_log_event ctor
3881
4894
*/
3882
4895
 
 
4896
#ifndef MYSQL_CLIENT
3883
4897
Create_file_log_event::
3884
4898
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3885
4899
                      const char* db_arg, const char* table_name_arg,
3886
4900
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
3887
4901
                      bool ignore,
3888
 
                      unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
 
4902
                      uchar* block_arg, uint block_len_arg, bool using_trans)
3889
4903
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3890
4904
                  using_trans),
3891
4905
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3905
4919
  bool res;
3906
4920
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
3907
4921
    return res;
3908
 
  return (my_b_safe_write(file, (unsigned char*) "", 1) ||
3909
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
 
4922
  return (my_b_safe_write(file, (uchar*) "", 1) ||
 
4923
          my_b_safe_write(file, (uchar*) block, block_len));
3910
4924
}
3911
4925
 
3912
4926
 
3917
4931
bool Create_file_log_event::write_data_header(IO_CACHE* file)
3918
4932
{
3919
4933
  bool res;
3920
 
  unsigned char buf[CREATE_FILE_HEADER_LEN];
 
4934
  uchar buf[CREATE_FILE_HEADER_LEN];
3921
4935
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
3922
4936
    return res;
3923
4937
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
3938
4952
  return res;
3939
4953
}
3940
4954
 
 
4955
#endif /* !MYSQL_CLIENT */
 
4956
 
3941
4957
/*
3942
4958
  Create_file_log_event ctor
3943
4959
*/
3944
4960
 
3945
 
Create_file_log_event::Create_file_log_event(const char* buf, uint32_t len,
 
4961
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
3946
4962
                                             const Format_description_log_event* description_event)
3947
4963
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
3948
4964
{
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];
 
4965
  uint block_offset;
 
4966
  uint header_len= description_event->common_header_len;
 
4967
  uint8 load_header_len= description_event->post_header_len[LOAD_EVENT-1];
 
4968
  uint8 create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
3953
4969
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
3954
4970
      copy_log_event(event_buf,len,
3955
4971
                     ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
3980
4996
                   create_file_header_len + 1);
3981
4997
    if (len < block_offset)
3982
4998
      return;
3983
 
    block = (unsigned char*)buf + block_offset;
 
4999
    block = (uchar*)buf + block_offset;
3984
5000
    block_len = len - block_offset;
3985
5001
  }
3986
5002
  else
3993
5009
 
3994
5010
 
3995
5011
/*
 
5012
  Create_file_log_event::print()
 
5013
*/
 
5014
 
 
5015
#ifdef MYSQL_CLIENT
 
5016
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
 
5017
                                  bool enable_local)
 
5018
{
 
5019
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5020
 
 
5021
  if (print_event_info->short_form)
 
5022
  {
 
5023
    if (enable_local && check_fname_outside_temp_buf())
 
5024
      Load_log_event::print(file, print_event_info);
 
5025
    return;
 
5026
  }
 
5027
 
 
5028
  if (enable_local)
 
5029
  {
 
5030
    Load_log_event::print(file, print_event_info,
 
5031
                          !check_fname_outside_temp_buf());
 
5032
    /* 
 
5033
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
 
5034
       SHOW BINLOG EVENTS we don't.
 
5035
    */
 
5036
    my_b_printf(&cache, "#"); 
 
5037
  }
 
5038
 
 
5039
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
 
5040
}
 
5041
 
 
5042
 
 
5043
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5044
{
 
5045
  print(file, print_event_info, 0);
 
5046
}
 
5047
#endif /* MYSQL_CLIENT */
 
5048
 
 
5049
 
 
5050
/*
3996
5051
  Create_file_log_event::pack_info()
3997
5052
*/
3998
5053
 
 
5054
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3999
5055
void Create_file_log_event::pack_info(Protocol *protocol)
4000
5056
{
4001
5057
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
4002
 
  pos= my_stpcpy(buf, "db=");
 
5058
  pos= strmov(buf, "db=");
4003
5059
  memcpy(pos, db, db_len);
4004
 
  pos= my_stpcpy(pos + db_len, ";table=");
 
5060
  pos= strmov(pos + db_len, ";table=");
4005
5061
  memcpy(pos, table_name, table_name_len);
4006
 
  pos= my_stpcpy(pos + table_name_len, ";file_id=");
 
5062
  pos= strmov(pos + table_name_len, ";file_id=");
4007
5063
  pos= int10_to_str((long) file_id, pos, 10);
4008
 
  pos= my_stpcpy(pos, ";block_len=");
 
5064
  pos= strmov(pos, ";block_len=");
4009
5065
  pos= int10_to_str((long) block_len, pos, 10);
4010
5066
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4011
5067
}
 
5068
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4012
5069
 
4013
5070
 
4014
5071
/*
4015
5072
  Create_file_log_event::do_apply_event()
4016
5073
*/
4017
5074
 
 
5075
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4018
5076
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
4019
5077
{
4020
5078
  char proc_info[17+FN_REFLEN+10], *fname_buf;
4023
5081
  IO_CACHE file;
4024
5082
  int error = 1;
4025
5083
 
4026
 
  memset(&file, 0, sizeof(file));
4027
 
  fname_buf= my_stpcpy(proc_info, "Making temp file ");
 
5084
  bzero((char*)&file, sizeof(file));
 
5085
  fname_buf= strmov(proc_info, "Making temp file ");
4028
5086
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
4029
 
  thd->set_proc_info(proc_info);
 
5087
  thd_proc_info(thd, proc_info);
4030
5088
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4031
5089
  if ((fd= my_create(fname_buf, CREATE_MODE,
4032
 
                     O_WRONLY | O_EXCL,
 
5090
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4033
5091
                     MYF(MY_WME))) < 0 ||
4034
5092
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
4035
5093
                    MYF(MY_WME|MY_NABP)))
4036
5094
  {
4037
5095
    rli->report(ERROR_LEVEL, my_errno,
4038
 
                _("Error in Create_file event: could not open file '%s'"),
 
5096
                "Error in Create_file event: could not open file '%s'",
4039
5097
                fname_buf);
4040
5098
    goto err;
4041
5099
  }
4042
5100
  
4043
5101
  // a trick to avoid allocating another buffer
4044
5102
  fname= fname_buf;
4045
 
  fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
 
5103
  fname_len= (uint) (strmov(ext, ".data") - fname);
4046
5104
  if (write_base(&file))
4047
5105
  {
4048
 
    my_stpcpy(ext, ".info"); // to have it right in the error message
 
5106
    strmov(ext, ".info"); // to have it right in the error message
4049
5107
    rli->report(ERROR_LEVEL, my_errno,
4050
 
                _("Error in Create_file event: could not write to file '%s'"),
 
5108
                "Error in Create_file event: could not write to file '%s'",
4051
5109
                fname_buf);
4052
5110
    goto err;
4053
5111
  }
4054
5112
  end_io_cache(&file);
4055
5113
  my_close(fd, MYF(0));
4056
 
 
 
5114
  
4057
5115
  // fname_buf now already has .data, not .info, because we did our trick
4058
5116
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4059
5117
  if ((fd= my_create(fname_buf, CREATE_MODE,
4060
 
                     O_WRONLY | O_EXCL,
4061
 
                     MYF(MY_WME))) < 0)
 
5118
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5119
                     MYF(MY_WME))) < 0)
4062
5120
  {
4063
5121
    rli->report(ERROR_LEVEL, my_errno,
4064
 
                _("Error in Create_file event: could not open file '%s'"),
 
5122
                "Error in Create_file event: could not open file '%s'",
4065
5123
                fname_buf);
4066
5124
    goto err;
4067
5125
  }
4068
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5126
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4069
5127
  {
4070
5128
    rli->report(ERROR_LEVEL, my_errno,
4071
 
                _("Error in Create_file event: write to '%s' failed"),
 
5129
                "Error in Create_file event: write to '%s' failed",
4072
5130
                fname_buf);
4073
5131
    goto err;
4074
5132
  }
4079
5137
    end_io_cache(&file);
4080
5138
  if (fd >= 0)
4081
5139
    my_close(fd, MYF(0));
4082
 
  thd->set_proc_info(0);
 
5140
  thd_proc_info(thd, 0);
4083
5141
  return error == 0;
4084
5142
}
 
5143
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4085
5144
 
4086
5145
 
4087
5146
/**************************************************************************
4092
5151
  Append_block_log_event ctor
4093
5152
*/
4094
5153
 
 
5154
#ifndef MYSQL_CLIENT  
4095
5155
Append_block_log_event::Append_block_log_event(THD *thd_arg,
4096
5156
                                               const char *db_arg,
4097
 
                                               unsigned char *block_arg,
4098
 
                                               uint32_t block_len_arg,
 
5157
                                               uchar *block_arg,
 
5158
                                               uint block_len_arg,
4099
5159
                                               bool using_trans)
4100
5160
  :Log_event(thd_arg,0, using_trans), block(block_arg),
4101
5161
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
4102
5162
{
4103
5163
}
 
5164
#endif
4104
5165
 
4105
5166
 
4106
5167
/*
4107
5168
  Append_block_log_event ctor
4108
5169
*/
4109
5170
 
4110
 
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
 
5171
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
4111
5172
                                               const Format_description_log_event* description_event)
4112
5173
  :Log_event(buf, description_event),block(0)
4113
5174
{
4114
 
  uint8_t common_header_len= description_event->common_header_len; 
4115
 
  uint8_t append_block_header_len=
 
5175
  uint8 common_header_len= description_event->common_header_len; 
 
5176
  uint8 append_block_header_len=
4116
5177
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
4117
 
  uint32_t total_header_len= common_header_len+append_block_header_len;
 
5178
  uint total_header_len= common_header_len+append_block_header_len;
4118
5179
  if (len < total_header_len)
4119
5180
    return;
4120
5181
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
4121
 
  block= (unsigned char*)buf + total_header_len;
 
5182
  block= (uchar*)buf + total_header_len;
4122
5183
  block_len= len - total_header_len;
4123
5184
  return;
4124
5185
}
4128
5189
  Append_block_log_event::write()
4129
5190
*/
4130
5191
 
 
5192
#ifndef MYSQL_CLIENT
4131
5193
bool Append_block_log_event::write(IO_CACHE* file)
4132
5194
{
4133
 
  unsigned char buf[APPEND_BLOCK_HEADER_LEN];
 
5195
  uchar buf[APPEND_BLOCK_HEADER_LEN];
4134
5196
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
4135
5197
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
4136
5198
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
4137
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
4138
 
}
 
5199
          my_b_safe_write(file, (uchar*) block, block_len));
 
5200
}
 
5201
#endif
 
5202
 
 
5203
 
 
5204
/*
 
5205
  Append_block_log_event::print()
 
5206
*/
 
5207
 
 
5208
#ifdef MYSQL_CLIENT  
 
5209
void Append_block_log_event::print(FILE* file,
 
5210
                                   PRINT_EVENT_INFO* print_event_info)
 
5211
{
 
5212
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5213
 
 
5214
  if (print_event_info->short_form)
 
5215
    return;
 
5216
  print_header(&cache, print_event_info, false);
 
5217
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
 
5218
              get_type_str(), file_id, block_len);
 
5219
}
 
5220
#endif /* MYSQL_CLIENT */
4139
5221
 
4140
5222
 
4141
5223
/*
4142
5224
  Append_block_log_event::pack_info()
4143
5225
*/
4144
5226
 
 
5227
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4145
5228
void Append_block_log_event::pack_info(Protocol *protocol)
4146
5229
{
4147
5230
  char buf[256];
4148
 
  uint32_t length;
4149
 
  length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
4150
 
                             block_len);
 
5231
  uint length;
 
5232
  length= (uint) my_sprintf(buf,
 
5233
                            (buf, ";file_id=%u;block_len=%u", file_id,
 
5234
                             block_len));
4151
5235
  protocol->store(buf, length, &my_charset_bin);
4152
5236
}
4153
5237
 
4171
5255
  int fd;
4172
5256
  int error = 1;
4173
5257
 
4174
 
  fname= my_stpcpy(proc_info, "Making temp file ");
 
5258
  fname= strmov(proc_info, "Making temp file ");
4175
5259
  slave_load_file_stem(fname, file_id, server_id, ".data");
4176
 
  thd->set_proc_info(proc_info);
 
5260
  thd_proc_info(thd, proc_info);
4177
5261
  if (get_create_or_append())
4178
5262
  {
4179
5263
    my_delete(fname, MYF(0)); // old copy may exist already
4180
5264
    if ((fd= my_create(fname, CREATE_MODE,
4181
 
                       O_WRONLY | O_EXCL,
 
5265
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4182
5266
                       MYF(MY_WME))) < 0)
4183
5267
    {
4184
5268
      rli->report(ERROR_LEVEL, my_errno,
4185
 
                  _("Error in %s event: could not create file '%s'"),
 
5269
                  "Error in %s event: could not create file '%s'",
4186
5270
                  get_type_str(), fname);
4187
5271
      goto err;
4188
5272
    }
4189
5273
  }
4190
 
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
 
5274
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
4191
5275
                         MYF(MY_WME))) < 0)
4192
5276
  {
4193
5277
    rli->report(ERROR_LEVEL, my_errno,
4194
 
                _("Error in %s event: could not open file '%s'"),
 
5278
                "Error in %s event: could not open file '%s'",
4195
5279
                get_type_str(), fname);
4196
5280
    goto err;
4197
5281
  }
4198
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5282
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4199
5283
  {
4200
5284
    rli->report(ERROR_LEVEL, my_errno,
4201
 
                _("Error in %s event: write to '%s' failed"),
 
5285
                "Error in %s event: write to '%s' failed",
4202
5286
                get_type_str(), fname);
4203
5287
    goto err;
4204
5288
  }
4207
5291
err:
4208
5292
  if (fd >= 0)
4209
5293
    my_close(fd, MYF(0));
4210
 
  thd->set_proc_info(0);
 
5294
  thd_proc_info(thd, 0);
4211
5295
  return(error);
4212
5296
}
 
5297
#endif
4213
5298
 
4214
5299
 
4215
5300
/**************************************************************************
4220
5305
  Delete_file_log_event ctor
4221
5306
*/
4222
5307
 
 
5308
#ifndef MYSQL_CLIENT
4223
5309
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
4224
5310
                                             bool using_trans)
4225
5311
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4226
5312
{
4227
5313
}
 
5314
#endif
4228
5315
 
4229
5316
/*
4230
5317
  Delete_file_log_event ctor
4231
5318
*/
4232
5319
 
4233
 
Delete_file_log_event::Delete_file_log_event(const char* buf, uint32_t len,
 
5320
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
4234
5321
                                             const Format_description_log_event* description_event)
4235
5322
  :Log_event(buf, description_event),file_id(0)
4236
5323
{
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];
 
5324
  uint8 common_header_len= description_event->common_header_len;
 
5325
  uint8 delete_file_header_len= description_event->post_header_len[DELETE_FILE_EVENT-1];
4239
5326
  if (len < (uint)(common_header_len + delete_file_header_len))
4240
5327
    return;
4241
5328
  file_id= uint4korr(buf + common_header_len + DF_FILE_ID_OFFSET);
4246
5333
  Delete_file_log_event::write()
4247
5334
*/
4248
5335
 
 
5336
#ifndef MYSQL_CLIENT
4249
5337
bool Delete_file_log_event::write(IO_CACHE* file)
4250
5338
{
4251
 
 unsigned char buf[DELETE_FILE_HEADER_LEN];
 
5339
 uchar buf[DELETE_FILE_HEADER_LEN];
4252
5340
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
4253
5341
 return (write_header(file, sizeof(buf)) ||
4254
5342
         my_b_safe_write(file, buf, sizeof(buf)));
4255
5343
}
4256
 
 
 
5344
#endif
 
5345
 
 
5346
 
 
5347
/*
 
5348
  Delete_file_log_event::print()
 
5349
*/
 
5350
 
 
5351
#ifdef MYSQL_CLIENT  
 
5352
void Delete_file_log_event::print(FILE* file,
 
5353
                                  PRINT_EVENT_INFO* print_event_info)
 
5354
{
 
5355
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5356
 
 
5357
  if (print_event_info->short_form)
 
5358
    return;
 
5359
  print_header(&cache, print_event_info, false);
 
5360
  my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
 
5361
}
 
5362
#endif /* MYSQL_CLIENT */
4257
5363
 
4258
5364
/*
4259
5365
  Delete_file_log_event::pack_info()
4260
5366
*/
4261
5367
 
 
5368
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4262
5369
void Delete_file_log_event::pack_info(Protocol *protocol)
4263
5370
{
4264
5371
  char buf[64];
4265
 
  uint32_t length;
4266
 
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4267
 
  protocol->store(buf, (int32_t) length, &my_charset_bin);
 
5372
  uint length;
 
5373
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5374
  protocol->store(buf, (int32) length, &my_charset_bin);
4268
5375
}
 
5376
#endif
4269
5377
 
4270
5378
/*
4271
5379
  Delete_file_log_event::do_apply_event()
4272
5380
*/
4273
5381
 
4274
 
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
5382
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5383
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((__unused__)))
4275
5384
{
4276
5385
  char fname[FN_REFLEN+10];
4277
5386
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
4278
5387
  (void) my_delete(fname, MYF(MY_WME));
4279
 
  my_stpcpy(ext, ".info");
 
5388
  strmov(ext, ".info");
4280
5389
  (void) my_delete(fname, MYF(MY_WME));
4281
5390
  return 0;
4282
5391
}
 
5392
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4283
5393
 
4284
5394
 
4285
5395
/**************************************************************************
4290
5400
  Execute_load_log_event ctor
4291
5401
*/
4292
5402
 
 
5403
#ifndef MYSQL_CLIENT  
4293
5404
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
4294
5405
                                               const char* db_arg,
4295
5406
                                               bool using_trans)
4296
5407
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4297
5408
{
4298
5409
}
 
5410
#endif
4299
5411
  
4300
5412
 
4301
5413
/*
4302
5414
  Execute_load_log_event ctor
4303
5415
*/
4304
5416
 
4305
 
Execute_load_log_event::Execute_load_log_event(const char* buf, uint32_t len,
 
5417
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
4306
5418
                                               const Format_description_log_event* description_event)
4307
5419
  :Log_event(buf, description_event), file_id(0)
4308
5420
{
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];
 
5421
  uint8 common_header_len= description_event->common_header_len;
 
5422
  uint8 exec_load_header_len= description_event->post_header_len[EXEC_LOAD_EVENT-1];
4311
5423
  if (len < (uint)(common_header_len+exec_load_header_len))
4312
5424
    return;
4313
5425
  file_id= uint4korr(buf + common_header_len + EL_FILE_ID_OFFSET);
4318
5430
  Execute_load_log_event::write()
4319
5431
*/
4320
5432
 
 
5433
#ifndef MYSQL_CLIENT
4321
5434
bool Execute_load_log_event::write(IO_CACHE* file)
4322
5435
{
4323
 
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
 
5436
  uchar buf[EXEC_LOAD_HEADER_LEN];
4324
5437
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
4325
5438
  return (write_header(file, sizeof(buf)) || 
4326
5439
          my_b_safe_write(file, buf, sizeof(buf)));
4327
5440
}
4328
 
 
 
5441
#endif
 
5442
 
 
5443
 
 
5444
/*
 
5445
  Execute_load_log_event::print()
 
5446
*/
 
5447
 
 
5448
#ifdef MYSQL_CLIENT  
 
5449
void Execute_load_log_event::print(FILE* file,
 
5450
                                   PRINT_EVENT_INFO* print_event_info)
 
5451
{
 
5452
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5453
 
 
5454
  if (print_event_info->short_form)
 
5455
    return;
 
5456
  print_header(&cache, print_event_info, false);
 
5457
  my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
 
5458
              file_id);
 
5459
}
 
5460
#endif
4329
5461
 
4330
5462
/*
4331
5463
  Execute_load_log_event::pack_info()
4332
5464
*/
4333
5465
 
 
5466
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4334
5467
void Execute_load_log_event::pack_info(Protocol *protocol)
4335
5468
{
4336
5469
  char buf[64];
4337
 
  uint32_t length;
4338
 
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4339
 
  protocol->store(buf, (int32_t) length, &my_charset_bin);
 
5470
  uint length;
 
5471
  length= (uint) my_sprintf(buf, (buf, ";file_id=%u", (uint) file_id));
 
5472
  protocol->store(buf, (int32) length, &my_charset_bin);
4340
5473
}
4341
5474
 
4342
5475
 
4354
5487
  Load_log_event *lev= 0;
4355
5488
 
4356
5489
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
4357
 
  if ((fd = my_open(fname, O_RDONLY,
 
5490
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
4358
5491
                    MYF(MY_WME))) < 0 ||
4359
5492
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
4360
5493
                    MYF(MY_WME|MY_NABP)))
4361
5494
  {
4362
5495
    rli->report(ERROR_LEVEL, my_errno,
4363
 
                _("Error in Exec_load event: could not open file '%s'"),
 
5496
                "Error in Exec_load event: could not open file '%s'",
4364
5497
                fname);
4365
5498
    goto err;
4366
5499
  }
4369
5502
                                                         rli->relay_log.description_event_for_exec)) ||
4370
5503
      lev->get_type_code() != NEW_LOAD_EVENT)
4371
5504
  {
4372
 
    rli->report(ERROR_LEVEL, 0,
4373
 
                _("Error in Exec_load event: "
4374
 
                  "file '%s' appears corrupted"),
4375
 
                fname);
 
5505
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
 
5506
                    "file '%s' appears corrupted", fname);
4376
5507
    goto err;
4377
5508
  }
4378
5509
 
4400
5531
    if (tmp)
4401
5532
    {
4402
5533
      rli->report(ERROR_LEVEL, rli->last_error().number,
4403
 
                  _("%s. Failed executing load from '%s'"),
4404
 
                  tmp, fname);
4405
 
      free(tmp);
 
5534
                  "%s. Failed executing load from '%s'", tmp, fname);
 
5535
      my_free(tmp,MYF(0));
4406
5536
    }
4407
5537
    goto err;
4408
5538
  }
4431
5561
  return error;
4432
5562
}
4433
5563
 
 
5564
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5565
 
4434
5566
 
4435
5567
/**************************************************************************
4436
5568
        Begin_load_query_log_event methods
4437
5569
**************************************************************************/
4438
5570
 
 
5571
#ifndef MYSQL_CLIENT
4439
5572
Begin_load_query_log_event::
4440
 
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, unsigned char* block_arg,
4441
 
                           uint32_t block_len_arg, bool using_trans)
 
5573
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
 
5574
                           uint block_len_arg, bool using_trans)
4442
5575
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4443
5576
                          using_trans)
4444
5577
{
4445
5578
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4446
5579
}
 
5580
#endif
4447
5581
 
4448
5582
 
4449
5583
Begin_load_query_log_event::
4450
 
Begin_load_query_log_event(const char* buf, uint32_t len,
 
5584
Begin_load_query_log_event(const char* buf, uint len,
4451
5585
                           const Format_description_log_event* desc_event)
4452
5586
  :Append_block_log_event(buf, len, desc_event)
4453
5587
{
4454
5588
}
4455
5589
 
4456
5590
 
 
5591
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4457
5592
int Begin_load_query_log_event::get_create_or_append() const
4458
5593
{
4459
5594
  return 1; /* create the file */
4460
5595
}
4461
 
 
4462
 
 
 
5596
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5597
 
 
5598
 
 
5599
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4463
5600
Log_event::enum_skip_reason
4464
5601
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
4465
5602
{
4469
5606
  */
4470
5607
  return continue_group(rli);
4471
5608
}
 
5609
#endif
4472
5610
 
4473
5611
 
4474
5612
/**************************************************************************
4476
5614
**************************************************************************/
4477
5615
 
4478
5616
 
 
5617
#ifndef MYSQL_CLIENT
4479
5618
Execute_load_query_log_event::
4480
5619
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
4481
 
                             ulong query_length_arg, uint32_t fn_pos_start_arg,
4482
 
                             uint32_t fn_pos_end_arg,
 
5620
                             ulong query_length_arg, uint fn_pos_start_arg,
 
5621
                             uint fn_pos_end_arg,
4483
5622
                             enum_load_dup_handling dup_handling_arg,
4484
5623
                             bool using_trans, bool suppress_use,
4485
5624
                             THD::killed_state killed_err_arg):
4489
5628
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
4490
5629
{
4491
5630
}
 
5631
#endif /* !MYSQL_CLIENT */
4492
5632
 
4493
5633
 
4494
5634
Execute_load_query_log_event::
4495
 
Execute_load_query_log_event(const char* buf, uint32_t event_len,
 
5635
Execute_load_query_log_event(const char* buf, uint event_len,
4496
5636
                             const Format_description_log_event* desc_event):
4497
5637
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
4498
5638
  file_id(0), fn_pos_start(0), fn_pos_end(0)
4520
5660
}
4521
5661
 
4522
5662
 
 
5663
#ifndef MYSQL_CLIENT
4523
5664
bool
4524
5665
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
4525
5666
{
4526
 
  unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
5667
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
4527
5668
  int4store(buf, file_id);
4528
5669
  int4store(buf + 4, fn_pos_start);
4529
5670
  int4store(buf + 4 + 4, fn_pos_end);
4530
 
  *(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
 
5671
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
4531
5672
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
4532
5673
}
4533
 
 
4534
 
 
 
5674
#endif
 
5675
 
 
5676
 
 
5677
#ifdef MYSQL_CLIENT
 
5678
void Execute_load_query_log_event::print(FILE* file,
 
5679
                                         PRINT_EVENT_INFO* print_event_info)
 
5680
{
 
5681
  print(file, print_event_info, 0);
 
5682
}
 
5683
 
 
5684
/**
 
5685
  Prints the query as LOAD DATA LOCAL and with rewritten filename.
 
5686
*/
 
5687
void Execute_load_query_log_event::print(FILE* file,
 
5688
                                         PRINT_EVENT_INFO* print_event_info,
 
5689
                                         const char *local_fname)
 
5690
{
 
5691
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5692
 
 
5693
  print_query_header(&cache, print_event_info);
 
5694
 
 
5695
  if (local_fname)
 
5696
  {
 
5697
    my_b_write(&cache, (uchar*) query, fn_pos_start);
 
5698
    my_b_printf(&cache, " LOCAL INFILE \'");
 
5699
    my_b_printf(&cache, local_fname);
 
5700
    my_b_printf(&cache, "\'");
 
5701
    if (dup_handling == LOAD_DUP_REPLACE)
 
5702
      my_b_printf(&cache, " REPLACE");
 
5703
    my_b_printf(&cache, " INTO");
 
5704
    my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
 
5705
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5706
  }
 
5707
  else
 
5708
  {
 
5709
    my_b_write(&cache, (uchar*) query, q_len);
 
5710
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5711
  }
 
5712
 
 
5713
  if (!print_event_info->short_form)
 
5714
    my_b_printf(&cache, "# file_id: %d \n", file_id);
 
5715
}
 
5716
#endif
 
5717
 
 
5718
 
 
5719
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4535
5720
void Execute_load_query_log_event::pack_info(Protocol *protocol)
4536
5721
{
4537
5722
  char *buf, *pos;
4540
5725
  pos= buf;
4541
5726
  if (db && db_len)
4542
5727
  {
4543
 
    pos= my_stpcpy(buf, "use `");
 
5728
    pos= strmov(buf, "use `");
4544
5729
    memcpy(pos, db, db_len);
4545
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
5730
    pos= strmov(pos+db_len, "`; ");
4546
5731
  }
4547
5732
  if (query && q_len)
4548
5733
  {
4549
5734
    memcpy(pos, query, q_len);
4550
5735
    pos+= q_len;
4551
5736
  }
4552
 
  pos= my_stpcpy(pos, " ;file_id=");
 
5737
  pos= strmov(pos, " ;file_id=");
4553
5738
  pos= int10_to_str((long) file_id, pos, 10);
4554
5739
  protocol->store(buf, pos-buf, &my_charset_bin);
4555
 
  free(buf);
 
5740
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4556
5741
}
4557
5742
 
4558
5743
 
4572
5757
  if (buf == NULL)
4573
5758
  {
4574
5759
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4575
 
                ER(ER_SLAVE_FATAL_ERROR),
4576
 
                _("Not enough memory"));
 
5760
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
4577
5761
    return 1;
4578
5762
  }
4579
5763
 
4582
5766
  p+= fn_pos_start;
4583
5767
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
4584
5768
  p= slave_load_file_stem(p, file_id, server_id, ".data");
4585
 
  fname_end= p= strchr(p, '\0');                      // Safer than p=p+5
 
5769
  fname_end= p= strend(p);                      // Safer than p=p+5
4586
5770
  *(p++)='\'';
4587
5771
  switch (dup_handling) {
4588
5772
  case LOAD_DUP_IGNORE:
4610
5794
  if (!error)
4611
5795
    (void) my_delete(fname, MYF(MY_WME));
4612
5796
 
4613
 
  free(buf);
 
5797
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4614
5798
  return error;
4615
5799
}
 
5800
#endif
4616
5801
 
4617
5802
 
4618
5803
/**************************************************************************
4632
5817
            write_str(file, line_term,  (uint) line_term_len) ||
4633
5818
            write_str(file, line_start, (uint) line_start_len) ||
4634
5819
            write_str(file, escaped,    (uint) escaped_len) ||
4635
 
            my_b_safe_write(file,(unsigned char*) &opt_flags,1));
 
5820
            my_b_safe_write(file,(uchar*) &opt_flags,1));
4636
5821
  }
4637
5822
  else
4638
5823
  {
4648
5833
    old_ex.escaped=    *escaped;
4649
5834
    old_ex.opt_flags=  opt_flags;
4650
5835
    old_ex.empty_flags=empty_flags;
4651
 
    return my_b_safe_write(file, (unsigned char*) &old_ex, sizeof(old_ex)) != 0;
 
5836
    return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
4652
5837
  }
4653
5838
}
4654
5839
 
4708
5893
        Rows_log_event member functions
4709
5894
**************************************************************************/
4710
5895
 
4711
 
Rows_log_event::Rows_log_event(THD *thd_arg, Table *tbl_arg, ulong tid,
 
5896
#ifndef MYSQL_CLIENT
 
5897
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
4712
5898
                               MY_BITMAP const *cols, bool is_transactional)
4713
5899
  : Log_event(thd_arg, 0, is_transactional),
4714
5900
    m_row_count(0),
4716
5902
    m_table_id(tid),
4717
5903
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
4718
5904
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
5905
#ifdef HAVE_REPLICATION
4719
5906
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5907
#endif
4720
5908
{
4721
5909
  /*
4722
5910
    We allow a special form of dummy event when the table, and cols
4723
 
    are null and the table id is UINT32_MAX.  This is a temporary
 
5911
    are null and the table id is ~0UL.  This is a temporary
4724
5912
    solution, to be able to terminate a started statement in the
4725
5913
    binary log: the extraneous events will be removed in the future.
4726
5914
   */
4727
 
  assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
 
5915
  assert((tbl_arg && tbl_arg->s && tid != ~0UL) || (!tbl_arg && !cols && tid == ~0UL));
4728
5916
 
4729
5917
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
4730
5918
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
4749
5937
    m_cols.bitmap= 0;
4750
5938
  }
4751
5939
}
4752
 
 
4753
 
 
4754
 
Rows_log_event::Rows_log_event(const char *buf, uint32_t event_len,
 
5940
#endif
 
5941
 
 
5942
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
4755
5943
                               Log_event_type event_type,
4756
5944
                               const Format_description_log_event
4757
5945
                               *description_event)
4758
5946
  : Log_event(buf, description_event),
4759
5947
    m_row_count(0),
 
5948
#ifndef MYSQL_CLIENT
4760
5949
    m_table(NULL),
 
5950
#endif
4761
5951
    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
 
5952
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4762
5953
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5954
#endif
4763
5955
{
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];
 
5956
  uint8 const common_header_len= description_event->common_header_len;
 
5957
  uint8 const post_header_len= description_event->post_header_len[event_type-1];
4766
5958
 
4767
5959
  const char *post_start= buf + common_header_len;
4768
5960
  post_start+= RW_MAPID_OFFSET;
4780
5972
 
4781
5973
  m_flags= uint2korr(post_start);
4782
5974
 
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;
 
5975
  uchar const *const var_start=
 
5976
    (const uchar *)buf + common_header_len + post_header_len;
 
5977
  uchar const *const ptr_width= var_start;
 
5978
  uchar *ptr_after_width= (uchar*) ptr_width;
4787
5979
  m_width = net_field_length(&ptr_after_width);
4788
5980
  /* if bitmap_init fails, catched in is_valid() */
4789
5981
  if (likely(!bitmap_init(&m_cols,
4824
6016
    }
4825
6017
  }
4826
6018
 
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));
 
6019
  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
 
6020
 
 
6021
  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
 
6022
 
 
6023
  m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
4832
6024
  if (likely((bool)m_rows_buf))
4833
6025
  {
 
6026
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4834
6027
    m_curr_row= m_rows_buf;
 
6028
#endif
4835
6029
    m_rows_end= m_rows_buf + data_size;
4836
6030
    m_rows_cur= m_rows_end;
4837
6031
    memcpy(m_rows_buf, ptr_rows_data, data_size);
4845
6039
Rows_log_event::~Rows_log_event()
4846
6040
{
4847
6041
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
4848
 
    m_cols.bitmap= 0; // so no free in bitmap_free
 
6042
    m_cols.bitmap= 0; // so no my_free in bitmap_free
4849
6043
  bitmap_free(&m_cols); // To pair with bitmap_init().
4850
 
  free((unsigned char*)m_rows_buf);
 
6044
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
4851
6045
}
4852
6046
 
4853
6047
int Rows_log_event::get_data_size()
4854
6048
{
4855
6049
  int const type_code= get_type_code();
4856
6050
 
4857
 
  unsigned char buf[sizeof(m_width)+1];
4858
 
  unsigned char *end= net_store_length(buf, (m_width + 7) / 8);
 
6051
  uchar buf[sizeof(m_width)+1];
 
6052
  uchar *end= net_store_length(buf, (m_width + 7) / 8);
4859
6053
 
4860
6054
  int data_size= ROWS_HEADER_LEN;
4861
6055
  data_size+= no_bytes_in_map(&m_cols);
4869
6063
}
4870
6064
 
4871
6065
 
4872
 
int Rows_log_event::do_add_row_data(unsigned char *row_data, size_t length)
 
6066
#ifndef MYSQL_CLIENT
 
6067
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
4873
6068
{
4874
6069
  /*
4875
6070
    When the table has a primary key, we would probably want, by default, to
4900
6095
    my_ptrdiff_t const new_alloc= 
4901
6096
        block_size * ((cur_size + length + block_size - 1) / block_size);
4902
6097
 
4903
 
    unsigned char* const new_buf= (unsigned char*)my_realloc((unsigned char*)m_rows_buf, (uint) new_alloc,
 
6098
    uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
4904
6099
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
4905
6100
    if (unlikely(!new_buf))
4906
6101
      return(HA_ERR_OUT_OF_MEM);
4925
6120
  m_row_count++;
4926
6121
  return(0);
4927
6122
}
 
6123
#endif
4928
6124
 
 
6125
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4929
6126
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
4930
6127
{
4931
6128
  int error= 0;
4932
6129
  /*
4933
 
    If m_table_id == UINT32_MAX, then we have a dummy event that does not
 
6130
    If m_table_id == ~0UL, then we have a dummy event that does not
4934
6131
    contain any data.  In that case, we just remove all tables in the
4935
6132
    tables_to_lock list, close the thread tables, and return with
4936
6133
    success.
4937
6134
   */
4938
 
  if (m_table_id == UINT32_MAX)
 
6135
  if (m_table_id == ~0UL)
4939
6136
  {
4940
6137
    /*
4941
6138
       This one is supposed to be set: just an extra check so that
5003
6200
            Error reporting borrowed from Query_log_event with many excessive
5004
6201
            simplifications (we don't honour --slave-skip-errors)
5005
6202
          */
5006
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6203
          uint actual_error= thd->main_da.sql_errno();
5007
6204
          rli->report(ERROR_LEVEL, actual_error,
5008
 
                      _("Error '%s' in %s event: when locking tables"),
5009
 
                      (actual_error
5010
 
                       ? thd->main_da.message()
5011
 
                       : _("unexpected success or fatal error")),
 
6205
                      "Error '%s' in %s event: when locking tables",
 
6206
                      (actual_error ? thd->main_da.message():
 
6207
                       "unexpected success or fatal error"),
5012
6208
                      get_type_str());
5013
6209
          thd->is_fatal_error= 1;
5014
6210
        }
5015
6211
        else
5016
6212
        {
5017
6213
          rli->report(ERROR_LEVEL, error,
5018
 
                      _("Error in %s event: when locking tables"),
 
6214
                      "Error in %s event: when locking tables",
5019
6215
                      get_type_str());
5020
6216
        }
5021
6217
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5036
6232
        need to add code to assert that is the case.
5037
6233
       */
5038
6234
      thd->binlog_flush_pending_rows_event(false);
5039
 
      TableList *tables= rli->tables_to_lock;
 
6235
      TABLE_LIST *tables= rli->tables_to_lock;
5040
6236
      close_tables_for_reopen(thd, &tables);
5041
6237
 
5042
 
      uint32_t tables_count= rli->tables_to_lock_count;
 
6238
      uint tables_count= rli->tables_to_lock_count;
5043
6239
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
5044
6240
      {
5045
6241
        if (thd->is_slave_error || thd->is_fatal_error)
5048
6244
            Error reporting borrowed from Query_log_event with many excessive
5049
6245
            simplifications (we don't honour --slave-skip-errors)
5050
6246
          */
5051
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6247
          uint actual_error= thd->main_da.sql_errno();
5052
6248
          rli->report(ERROR_LEVEL, actual_error,
5053
 
                      _("Error '%s' on reopening tables"),
5054
 
                      (actual_error
5055
 
                       ? thd->main_da.message()
5056
 
                       : _("unexpected success or fatal error")));
 
6249
                      "Error '%s' on reopening tables",
 
6250
                      (actual_error ? thd->main_da.message() :
 
6251
                       "unexpected success or fatal error"));
5057
6252
          thd->is_slave_error= 1;
5058
6253
        }
5059
6254
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5066
6261
      ensure that they still have the correct type.
5067
6262
 
5068
6263
      We can use a down cast here since we know that every table added
5069
 
      to the tables_to_lock is a RPL_TableList.
 
6264
      to the tables_to_lock is a RPL_TABLE_LIST.
5070
6265
    */
5071
6266
 
5072
6267
    {
5073
 
      RPL_TableList *ptr= rli->tables_to_lock;
5074
 
      for ( ; ptr ; ptr= static_cast<RPL_TableList*>(ptr->next_global))
 
6268
      RPL_TABLE_LIST *ptr= rli->tables_to_lock;
 
6269
      for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
5075
6270
      {
5076
6271
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
5077
6272
        {
5098
6293
      Rows_log_event, we can invalidate the query cache for the
5099
6294
      associated table.
5100
6295
     */
5101
 
    for (TableList *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
 
6296
    for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
5102
6297
    {
5103
6298
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
5104
6299
    }
5105
6300
  }
5106
6301
 
5107
 
  Table* 
 
6302
  TABLE* 
5108
6303
    table= 
5109
6304
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
5110
6305
 
5406
6601
    }
5407
6602
    else
5408
6603
      rli->report(ERROR_LEVEL, error,
5409
 
                  _("Error in %s event: commit of row events failed, "
5410
 
                    "table `%s`.`%s`"),
 
6604
                  "Error in %s event: commit of row events failed, "
 
6605
                  "table `%s`.`%s`",
5411
6606
                  get_type_str(), m_table->s->db.str,
5412
6607
                  m_table->s->table_name.str);
5413
6608
  }
5419
6614
  return(error);
5420
6615
}
5421
6616
 
 
6617
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
6618
 
 
6619
#ifndef MYSQL_CLIENT
5422
6620
bool Rows_log_event::write_data_header(IO_CACHE *file)
5423
6621
{
5424
 
  unsigned char buf[ROWS_HEADER_LEN];   // No need to init the buffer
5425
 
  assert(m_table_id != UINT32_MAX);
 
6622
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
6623
  assert(m_table_id != ~0UL);
5426
6624
  int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
5427
6625
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
5428
6626
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
5434
6632
     Note that this should be the number of *bits*, not the number of
5435
6633
     bytes.
5436
6634
  */
5437
 
  unsigned char sbuf[sizeof(m_width)];
 
6635
  uchar sbuf[sizeof(m_width)];
5438
6636
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
5439
6637
  bool res= false;
5440
 
  unsigned char *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
 
6638
  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
5441
6639
  assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
5442
6640
 
5443
6641
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
5444
6642
 
5445
 
  res= res || my_b_safe_write(file, (unsigned char*) m_cols.bitmap,
 
6643
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
5446
6644
                              no_bytes_in_map(&m_cols));
5447
6645
  /*
5448
6646
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
5449
6647
   */
5450
6648
  if (get_type_code() == UPDATE_ROWS_EVENT)
5451
6649
  {
5452
 
    res= res || my_b_safe_write(file, (unsigned char*) m_cols_ai.bitmap,
 
6650
    res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
5453
6651
                                no_bytes_in_map(&m_cols_ai));
5454
6652
  }
5455
6653
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
5457
6655
  return res;
5458
6656
 
5459
6657
}
5460
 
 
5461
 
 
 
6658
#endif
 
6659
 
 
6660
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5462
6661
void Rows_log_event::pack_info(Protocol *protocol)
5463
6662
{
5464
6663
  char buf[256];
5468
6667
                         "table_id: %lu%s", m_table_id, flagstr);
5469
6668
  protocol->store(buf, bytes, &my_charset_bin);
5470
6669
}
5471
 
 
 
6670
#endif
 
6671
 
 
6672
#ifdef MYSQL_CLIENT
 
6673
void Rows_log_event::print_helper(FILE *file,
 
6674
                                  PRINT_EVENT_INFO *print_event_info,
 
6675
                                  char const *const name)
 
6676
{
 
6677
  IO_CACHE *const head= &print_event_info->head_cache;
 
6678
  IO_CACHE *const body= &print_event_info->body_cache;
 
6679
  if (!print_event_info->short_form)
 
6680
  {
 
6681
    bool const last_stmt_event= get_flags(STMT_END_F);
 
6682
    print_header(head, print_event_info, !last_stmt_event);
 
6683
    my_b_printf(head, "\t%s: table id %lu%s\n",
 
6684
                name, m_table_id,
 
6685
                last_stmt_event ? " flags: STMT_END_F" : "");
 
6686
    print_base64(body, print_event_info, !last_stmt_event);
 
6687
  }
 
6688
 
 
6689
  if (get_flags(STMT_END_F))
 
6690
  {
 
6691
    copy_event_cache_to_file_and_reinit(head, file);
 
6692
    copy_event_cache_to_file_and_reinit(body, file);
 
6693
  }
 
6694
}
 
6695
#endif
5472
6696
 
5473
6697
/**************************************************************************
5474
6698
        Table_map_log_event member functions and support functions
5495
6719
  same as the columns for the table on the slave.
5496
6720
 
5497
6721
  Additionally, values saved for field metadata on the master are saved as a 
5498
 
  string of bytes (unsigned char) in the binlog. A field may require 1 or more bytes
 
6722
  string of bytes (uchar) in the binlog. A field may require 1 or more bytes
5499
6723
  to store the information. In cases where values require multiple bytes 
5500
6724
  (e.g. values > 255), the endian-safe methods are used to properly encode 
5501
6725
  the values on the master and decode them on the slave. When the field
5502
6726
  metadata values are captured on the slave, they are stored in an array of
5503
 
  type uint16_t. This allows the least number of casts to prevent casting bugs
 
6727
  type uint16. This allows the least number of casts to prevent casting bugs
5504
6728
  when the field metadata is used in comparisons of field attributes. When
5505
6729
  the field metadata is used for calculating addresses in pointer math, the
5506
 
  type used is uint32_t. 
 
6730
  type used is uint32. 
5507
6731
*/
5508
6732
 
 
6733
#if !defined(MYSQL_CLIENT)
5509
6734
/**
5510
6735
  Save the field metadata based on the real_type of the field.
5511
6736
  The metadata saved depends on the type of the field. Some fields
5537
6762
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
5538
6763
  return(index);
5539
6764
}
 
6765
#endif /* !defined(MYSQL_CLIENT) */
5540
6766
 
5541
6767
/*
5542
6768
  Constructor used to build an event for writing to the binary log.
5543
6769
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
5544
6770
  (tbl->s->db etc) and not pointer content.
5545
6771
 */
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)
 
6772
#if !defined(MYSQL_CLIENT)
 
6773
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
 
6774
                                         bool is_transactional __attribute__((__unused__)),
 
6775
                                         uint16 flags)
5549
6776
  : Log_event(thd, 0, true),
5550
6777
    m_table(tbl),
5551
6778
    m_dbnam(tbl->s->db.str),
5562
6789
    m_null_bits(0),
5563
6790
    m_meta_memory(NULL)
5564
6791
{
5565
 
  assert(m_table_id != UINT32_MAX);
 
6792
  assert(m_table_id != ~0UL);
5566
6793
  /*
5567
6794
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
5568
6795
    table.cc / alloc_table_share():
5580
6807
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
5581
6808
 
5582
6809
  /* If malloc fails, caught in is_valid() */
5583
 
  if ((m_memory= (unsigned char*) my_malloc(m_colcnt, MYF(MY_WME))))
 
6810
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
5584
6811
  {
5585
 
    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
 
6812
    m_coltype= reinterpret_cast<uchar*>(m_memory);
5586
6813
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5587
6814
      m_coltype[i]= m_table->field[i]->type();
5588
6815
  }
5593
6820
    that is not on the slave and is null and thus not in the row data during
5594
6821
    replication.
5595
6822
  */
5596
 
  uint32_t num_null_bytes= (m_table->s->fields + 7) / 8;
 
6823
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
5597
6824
  m_data_size+= num_null_bytes;
5598
 
  m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
 
6825
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5599
6826
                                 &m_null_bits, num_null_bytes,
5600
6827
                                 &m_field_metadata, (m_colcnt * 2),
5601
6828
                                 NULL);
5602
6829
 
5603
 
  memset(m_field_metadata, 0, (m_colcnt * 2));
 
6830
  bzero(m_field_metadata, (m_colcnt * 2));
5604
6831
 
5605
6832
  /*
5606
6833
    Create an array for the field metadata and store it.
5617
6844
  else
5618
6845
    m_data_size+= m_field_metadata_size + 1; 
5619
6846
 
5620
 
  memset(m_null_bits, 0, num_null_bytes);
 
6847
  bzero(m_null_bits, num_null_bytes);
5621
6848
  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5622
6849
    if (m_table->field[i]->maybe_null())
5623
6850
      m_null_bits[(i / 8)]+= 1 << (i % 8);
5624
6851
 
5625
6852
}
5626
 
 
 
6853
#endif /* !defined(MYSQL_CLIENT) */
5627
6854
 
5628
6855
/*
5629
6856
  Constructor used by slave to read the event from the binary log.
5630
6857
 */
5631
 
Table_map_log_event::Table_map_log_event(const char *buf, uint32_t event_len,
 
6858
#if defined(HAVE_REPLICATION)
 
6859
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
5632
6860
                                         const Format_description_log_event
5633
6861
                                         *description_event)
5634
6862
 
5635
6863
  : Log_event(buf, description_event),
 
6864
#ifndef MYSQL_CLIENT
5636
6865
    m_table(NULL),
 
6866
#endif
5637
6867
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
5638
6868
    m_colcnt(0), m_coltype(0),
5639
6869
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
5642
6872
{
5643
6873
  unsigned int bytes_read= 0;
5644
6874
 
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];
 
6875
  uint8 common_header_len= description_event->common_header_len;
 
6876
  uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
5647
6877
 
5648
6878
  /* Read the post-header */
5649
6879
  const char *post_start= buf + common_header_len;
5662
6892
    post_start+= TM_FLAGS_OFFSET;
5663
6893
  }
5664
6894
 
5665
 
  assert(m_table_id != UINT32_MAX);
 
6895
  assert(m_table_id != ~0UL);
5666
6896
 
5667
6897
  m_flags= uint2korr(post_start);
5668
6898
 
5670
6900
  const char *const vpart= buf + common_header_len + post_header_len;
5671
6901
 
5672
6902
  /* Extract the length of the various parts from the buffer */
5673
 
  unsigned char const *const ptr_dblen= (unsigned char const*)vpart + 0;
5674
 
  m_dblen= *(unsigned char*) ptr_dblen;
 
6903
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
 
6904
  m_dblen= *(uchar*) ptr_dblen;
5675
6905
 
5676
6906
  /* Length of database name + counter + terminating null */
5677
 
  unsigned char const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
5678
 
  m_tbllen= *(unsigned char*) ptr_tbllen;
 
6907
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
6908
  m_tbllen= *(uchar*) ptr_tbllen;
5679
6909
 
5680
6910
  /* Length of table name + counter + terminating null */
5681
 
  unsigned char const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
5682
 
  unsigned char *ptr_after_colcnt= (unsigned char*) ptr_colcnt;
 
6911
  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
 
6912
  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
5683
6913
  m_colcnt= net_field_length(&ptr_after_colcnt);
5684
6914
 
5685
6915
  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
5686
 
  m_memory= (unsigned char*) my_multi_malloc(MYF(MY_WME),
 
6916
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
5687
6917
                                     &m_dbnam, (uint) m_dblen + 1,
5688
6918
                                     &m_tblnam, (uint) m_tbllen + 1,
5689
6919
                                     &m_coltype, (uint) m_colcnt,
5690
 
                                     NULL);
 
6920
                                     NullS);
5691
6921
 
5692
6922
  if (m_memory)
5693
6923
  {
5697
6927
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
5698
6928
 
5699
6929
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
5700
 
    bytes_read= ptr_after_colcnt - (unsigned char *)buf;
 
6930
    bytes_read= ptr_after_colcnt - (uchar *)buf;
5701
6931
    if (bytes_read < event_len)
5702
6932
    {
5703
6933
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
5704
6934
      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),
 
6935
      uint num_null_bytes= (m_colcnt + 7) / 8;
 
6936
      m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5707
6937
                                     &m_null_bits, num_null_bytes,
5708
6938
                                     &m_field_metadata, m_field_metadata_size,
5709
6939
                                     NULL);
5710
6940
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
5711
 
      ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
 
6941
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
5712
6942
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
5713
6943
    }
5714
6944
  }
5715
6945
 
5716
6946
  return;
5717
6947
}
 
6948
#endif
5718
6949
 
5719
6950
Table_map_log_event::~Table_map_log_event()
5720
6951
{
5721
 
  free(m_meta_memory);
5722
 
  free(m_memory);
 
6952
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
 
6953
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
5723
6954
}
5724
6955
 
5725
6956
/*
5733
6964
       4     Daisy-chaining RBR with SBR not possible
5734
6965
 */
5735
6966
 
 
6967
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5736
6968
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
5737
6969
{
5738
 
  RPL_TableList *table_list;
 
6970
  RPL_TABLE_LIST *table_list;
5739
6971
  char *db_mem, *tname_mem;
5740
6972
  size_t dummy_len;
5741
6973
  void *memory;
5747
6979
  pthread_mutex_unlock(&LOCK_thread_count);
5748
6980
 
5749
6981
  if (!(memory= my_multi_malloc(MYF(MY_WME),
5750
 
                                &table_list, (uint) sizeof(RPL_TableList),
 
6982
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
5751
6983
                                &db_mem, (uint) NAME_LEN + 1,
5752
6984
                                &tname_mem, (uint) NAME_LEN + 1,
5753
 
                                NULL)))
 
6985
                                NullS)))
5754
6986
    return(HA_ERR_OUT_OF_MEM);
5755
6987
 
5756
 
  memset(table_list, 0, sizeof(*table_list));
 
6988
  bzero(table_list, sizeof(*table_list));
5757
6989
  table_list->db = db_mem;
5758
6990
  table_list->alias= table_list->table_name = tname_mem;
5759
6991
  table_list->lock_type= TL_WRITE;
5760
6992
  table_list->next_global= table_list->next_local= 0;
5761
6993
  table_list->table_id= m_table_id;
5762
6994
  table_list->updating= 1;
5763
 
  my_stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
5764
 
  my_stpcpy(table_list->table_name, m_tblnam);
 
6995
  strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
 
6996
  strmov(table_list->table_name, m_tblnam);
5765
6997
 
5766
6998
  int error= 0;
5767
6999
 
5768
7000
  if (!rpl_filter->db_ok(table_list->db) ||
5769
7001
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
5770
7002
  {
5771
 
    free(memory);
 
7003
    my_free(memory, MYF(MY_WME));
5772
7004
  }
5773
7005
  else
5774
7006
  {
5795
7027
      table map.  Note that for any table that should not be
5796
7028
      replicated, a filter is needed.
5797
7029
 
5798
 
      The creation of a new TableList is used to up-cast the
5799
 
      table_list consisting of RPL_TableList items. This will work
 
7030
      The creation of a new TABLE_LIST is used to up-cast the
 
7031
      table_list consisting of RPL_TABLE_LIST items. This will work
5800
7032
      since the only case where the argument to open_tables() is
5801
7033
      changed, is when thd->lex->query_tables == table_list, i.e.,
5802
7034
      when the statement requires prelocking. Since this is not
5808
7040
      internally in the open_tables() function, hence we take a copy
5809
7041
      of the pointer to make sure that it's not lost.
5810
7042
    */
5811
 
    uint32_t count;
 
7043
    uint count;
5812
7044
    assert(thd->lex->query_tables != table_list);
5813
 
    TableList *tmp_table_list= table_list;
 
7045
    TABLE_LIST *tmp_table_list= table_list;
5814
7046
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5815
7047
    {
5816
7048
      if (thd->is_slave_error || thd->is_fatal_error)
5819
7051
          Error reporting borrowed from Query_log_event with many excessive
5820
7052
          simplifications (we don't honour --slave-skip-errors)
5821
7053
        */
5822
 
        uint32_t actual_error= thd->main_da.sql_errno();
 
7054
        uint actual_error= thd->main_da.sql_errno();
5823
7055
        rli->report(ERROR_LEVEL, actual_error,
5824
 
                    _("Error '%s' on opening table `%s`.`%s`"),
5825
 
                    (actual_error
5826
 
                     ? thd->main_da.message()
5827
 
                     : _("unexpected success or fatal error")),
 
7056
                    "Error '%s' on opening table `%s`.`%s`",
 
7057
                    (actual_error ? thd->main_da.message() :
 
7058
                     "unexpected success or fatal error"),
5828
7059
                    table_list->db, table_list->table_name);
5829
7060
        thd->is_slave_error= 1;
5830
7061
      }
5865
7096
  return(error);
5866
7097
 
5867
7098
err:
5868
 
  free(memory);
 
7099
  my_free(memory, MYF(MY_WME));
5869
7100
  return(error);
5870
7101
}
5871
7102
 
5885
7116
  return 0;
5886
7117
}
5887
7118
 
 
7119
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
5888
7120
 
 
7121
#ifndef MYSQL_CLIENT
5889
7122
bool Table_map_log_event::write_data_header(IO_CACHE *file)
5890
7123
{
5891
 
  assert(m_table_id != UINT32_MAX);
5892
 
  unsigned char buf[TABLE_MAP_HEADER_LEN];
 
7124
  assert(m_table_id != ~0UL);
 
7125
  uchar buf[TABLE_MAP_HEADER_LEN];
5893
7126
  int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
5894
7127
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
5895
7128
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
5903
7136
  assert(m_dblen < 128);
5904
7137
  assert(m_tbllen < 128);
5905
7138
 
5906
 
  unsigned char const dbuf[]= { (unsigned char) m_dblen };
5907
 
  unsigned char const tbuf[]= { (unsigned char) m_tbllen };
 
7139
  uchar const dbuf[]= { (uchar) m_dblen };
 
7140
  uchar const tbuf[]= { (uchar) m_tbllen };
5908
7141
 
5909
 
  unsigned char cbuf[sizeof(m_colcnt)];
5910
 
  unsigned char *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
 
7142
  uchar cbuf[sizeof(m_colcnt)];
 
7143
  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
5911
7144
  assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
5912
7145
 
5913
7146
  /*
5914
7147
    Store the size of the field metadata.
5915
7148
  */
5916
 
  unsigned char mbuf[sizeof(m_field_metadata_size)];
5917
 
  unsigned char *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
 
7149
  uchar mbuf[sizeof(m_field_metadata_size)];
 
7150
  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
5918
7151
 
5919
7152
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
5920
 
          my_b_safe_write(file, (const unsigned char*)m_dbnam,   m_dblen+1) ||
 
7153
          my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
5921
7154
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
5922
 
          my_b_safe_write(file, (const unsigned char*)m_tblnam,  m_tbllen+1) ||
 
7155
          my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
5923
7156
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
5924
7157
          my_b_safe_write(file, m_coltype, m_colcnt) ||
5925
7158
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
5926
7159
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
5927
7160
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
5928
7161
 }
 
7162
#endif
5929
7163
 
 
7164
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5930
7165
 
5931
7166
/*
5932
7167
  Print some useful information for the SHOW BINARY LOG information
5933
7168
  field.
5934
7169
 */
5935
7170
 
 
7171
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5936
7172
void Table_map_log_event::pack_info(Protocol *protocol)
5937
7173
{
5938
7174
    char buf[256];
5941
7177
                           m_table_id, m_dbnam, m_tblnam);
5942
7178
    protocol->store(buf, bytes, &my_charset_bin);
5943
7179
}
5944
 
 
 
7180
#endif
 
7181
 
 
7182
 
 
7183
#endif
 
7184
 
 
7185
 
 
7186
#ifdef MYSQL_CLIENT
 
7187
void Table_map_log_event::print(FILE * /* unused */,
 
7188
                                PRINT_EVENT_INFO *print_event_info)
 
7189
{
 
7190
  if (!print_event_info->short_form)
 
7191
  {
 
7192
    print_header(&print_event_info->head_cache, print_event_info, true);
 
7193
    my_b_printf(&print_event_info->head_cache,
 
7194
                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
 
7195
                m_dbnam, m_tblnam, m_table_id);
 
7196
    print_base64(&print_event_info->body_cache, print_event_info, true);
 
7197
  }
 
7198
}
 
7199
#endif
5945
7200
 
5946
7201
/**************************************************************************
5947
7202
        Write_rows_log_event member functions
5950
7205
/*
5951
7206
  Constructor used to build an event for writing to the binary log.
5952
7207
 */
5953
 
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7208
#if !defined(MYSQL_CLIENT)
 
7209
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
5954
7210
                                           ulong tid_arg,
5955
7211
                                           bool is_transactional)
5956
7212
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
5957
7213
{
5958
7214
}
 
7215
#endif
5959
7216
 
5960
7217
/*
5961
7218
  Constructor used by slave to read the event from the binary log.
5962
7219
 */
5963
 
Write_rows_log_event::Write_rows_log_event(const char *buf, uint32_t event_len,
 
7220
#ifdef HAVE_REPLICATION
 
7221
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
5964
7222
                                           const Format_description_log_event
5965
7223
                                           *description_event)
5966
7224
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
5967
7225
{
5968
7226
}
 
7227
#endif
5969
7228
 
 
7229
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5970
7230
int 
5971
7231
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5972
7232
{
6044
7304
  return error? error : local_error;
6045
7305
}
6046
7306
 
 
7307
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6047
7308
 
6048
7309
/*
6049
7310
  Check if there are more UNIQUE keys after the given key.
6050
7311
*/
6051
7312
static int
6052
 
last_uniq_key(Table *table, uint32_t keyno)
 
7313
last_uniq_key(TABLE *table, uint keyno)
6053
7314
{
6054
7315
  while (++keyno < table->s->keys)
6055
7316
    if (table->key_info[keyno].flags & HA_NOSAME)
6123
7384
{
6124
7385
  assert(m_table != NULL && thd != NULL);
6125
7386
 
6126
 
  Table *table= m_table;  // pointer to event's table
 
7387
  TABLE *table= m_table;  // pointer to event's table
6127
7388
  int error;
6128
7389
  int keynum;
6129
7390
  auto_afree_ptr<char> key(NULL);
6140
7401
     values filled in and one flag to handle the case that the default
6141
7402
     values should be checked. Maybe these two flags can be combined.
6142
7403
  */
6143
 
  if ((error= prepare_record(table, &m_cols, m_width, true)))
 
7404
  if ((error= prepare_record(table, &m_cols, m_width,
 
7405
                             table->file->ht->db_type != DB_TYPE_NDBCLUSTER)))
6144
7406
    return(error);
6145
7407
  
6146
7408
  /* unpack row into table->record[0] */
6215
7477
        }
6216
7478
      }
6217
7479
 
6218
 
      key_copy((unsigned char*)key.get(), table->record[0], table->key_info + keynum,
 
7480
      key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
6219
7481
               0);
6220
7482
      error= table->file->index_read_idx_map(table->record[1], keynum,
6221
 
                                             (const unsigned char*)key.get(),
 
7483
                                             (const uchar*)key.get(),
6222
7484
                                             HA_WHOLE_KEY,
6223
7485
                                             HA_READ_KEY_EXACT);
6224
7486
      if (error)
6292
7554
  return(error);
6293
7555
}
6294
7556
 
 
7557
#endif
6295
7558
 
6296
7559
int 
6297
7560
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6310
7573
  return error; 
6311
7574
}
6312
7575
 
 
7576
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7577
 
 
7578
#ifdef MYSQL_CLIENT
 
7579
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
 
7580
{
 
7581
  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
 
7582
}
 
7583
#endif
6313
7584
 
6314
7585
/**************************************************************************
6315
7586
        Delete_rows_log_event member functions
6316
7587
**************************************************************************/
6317
7588
 
 
7589
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6318
7590
/*
6319
7591
  Compares table->record[0] and table->record[1]
6320
7592
 
6321
7593
  Returns TRUE if different.
6322
7594
*/
6323
 
static bool record_compare(Table *table)
 
7595
static bool record_compare(TABLE *table)
6324
7596
{
6325
7597
  /*
6326
7598
    Need to set the X bit and the filler bits in both records since
6334
7606
    records. Check that the other engines also return correct records.
6335
7607
   */
6336
7608
  bool result= false;
6337
 
  unsigned char saved_x[2], saved_filler[2];
 
7609
  uchar saved_x[2], saved_filler[2];
6338
7610
 
6339
7611
  if (table->s->null_bytes > 0)
6340
7612
  {
6423
7695
{
6424
7696
  assert(m_table && m_table->in_use != NULL);
6425
7697
 
6426
 
  Table *table= m_table;
 
7698
  TABLE *table= m_table;
6427
7699
  int error;
6428
7700
 
6429
7701
  /* unpack row - missing fields get default values */
6611
7883
  return(error);
6612
7884
}
6613
7885
 
 
7886
#endif
6614
7887
 
6615
7888
/*
6616
7889
  Constructor used to build an event for writing to the binary log.
6617
7890
 */
6618
7891
 
6619
 
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7892
#ifndef MYSQL_CLIENT
 
7893
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6620
7894
                                             ulong tid,
6621
7895
                                             bool is_transactional)
6622
7896
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6623
7897
{
6624
7898
}
 
7899
#endif /* #if !defined(MYSQL_CLIENT) */
6625
7900
 
6626
7901
/*
6627
7902
  Constructor used by slave to read the event from the binary log.
6628
7903
 */
6629
 
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint32_t event_len,
 
7904
#ifdef HAVE_REPLICATION
 
7905
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
6630
7906
                                             const Format_description_log_event
6631
7907
                                             *description_event)
6632
7908
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
6633
7909
{
6634
7910
}
 
7911
#endif
6635
7912
 
 
7913
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6636
7914
 
6637
7915
int 
6638
7916
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6649
7927
  if (m_table->s->keys > 0)
6650
7928
  {
6651
7929
    // Allocate buffer for key searches
6652
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
7930
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6653
7931
    if (!m_key)
6654
7932
      return HA_ERR_OUT_OF_MEM;
6655
7933
  }
6663
7941
{
6664
7942
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6665
7943
  m_table->file->ha_index_or_rnd_end();
6666
 
  free(m_key);
 
7944
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
6667
7945
  m_key= NULL;
6668
7946
 
6669
7947
  return error;
6684
7962
  return error;
6685
7963
}
6686
7964
 
 
7965
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7966
 
 
7967
#ifdef MYSQL_CLIENT
 
7968
void Delete_rows_log_event::print(FILE *file,
 
7969
                                  PRINT_EVENT_INFO* print_event_info)
 
7970
{
 
7971
  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
 
7972
}
 
7973
#endif
 
7974
 
6687
7975
 
6688
7976
/**************************************************************************
6689
7977
        Update_rows_log_event member functions
6692
7980
/*
6693
7981
  Constructor used to build an event for writing to the binary log.
6694
7982
 */
6695
 
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7983
#if !defined(MYSQL_CLIENT)
 
7984
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6696
7985
                                             ulong tid,
6697
7986
                                             bool is_transactional)
6698
7987
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6716
8005
    }
6717
8006
  }
6718
8007
}
 
8008
#endif /* !defined(MYSQL_CLIENT) */
6719
8009
 
6720
8010
 
6721
8011
Update_rows_log_event::~Update_rows_log_event()
6722
8012
{
6723
8013
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
6724
 
    m_cols_ai.bitmap= 0; // so no free in bitmap_free
 
8014
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
6725
8015
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
6726
8016
}
6727
8017
 
6729
8019
/*
6730
8020
  Constructor used by slave to read the event from the binary log.
6731
8021
 */
6732
 
Update_rows_log_event::Update_rows_log_event(const char *buf, uint32_t event_len,
 
8022
#ifdef HAVE_REPLICATION
 
8023
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
6733
8024
                                             const
6734
8025
                                             Format_description_log_event
6735
8026
                                             *description_event)
6736
8027
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
6737
8028
{
6738
8029
}
 
8030
#endif
6739
8031
 
 
8032
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6740
8033
 
6741
8034
int 
6742
8035
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6744
8037
  if (m_table->s->keys > 0)
6745
8038
  {
6746
8039
    // Allocate buffer for key searches
6747
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8040
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6748
8041
    if (!m_key)
6749
8042
      return HA_ERR_OUT_OF_MEM;
6750
8043
  }
6760
8053
{
6761
8054
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6762
8055
  m_table->file->ha_index_or_rnd_end();
6763
 
  free(m_key); // Free for multi_malloc
 
8056
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
6764
8057
  m_key= NULL;
6765
8058
 
6766
8059
  return error;
6815
8108
  return error;
6816
8109
}
6817
8110
 
6818
 
 
6819
 
Incident_log_event::Incident_log_event(const char *buf, uint32_t event_len,
 
8111
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8112
 
 
8113
#ifdef MYSQL_CLIENT
 
8114
void Update_rows_log_event::print(FILE *file,
 
8115
                                  PRINT_EVENT_INFO* print_event_info)
 
8116
{
 
8117
  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
 
8118
}
 
8119
#endif
 
8120
 
 
8121
 
 
8122
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
6820
8123
                                       const Format_description_log_event *descr_event)
6821
8124
  : Log_event(buf, descr_event)
6822
8125
{
6823
 
  uint8_t const common_header_len=
 
8126
  uint8 const common_header_len=
6824
8127
    descr_event->common_header_len;
6825
 
  uint8_t const post_header_len=
 
8128
  uint8 const post_header_len=
6826
8129
    descr_event->post_header_len[INCIDENT_EVENT-1];
6827
8130
 
6828
8131
  m_incident= static_cast<Incident>(uint2korr(buf + common_header_len));
6829
8132
  char const *ptr= buf + common_header_len + post_header_len;
6830
8133
  char const *const str_end= buf + event_len;
6831
 
  uint8_t len= 0;                   // Assignment to keep compiler happy
 
8134
  uint8 len= 0;                   // Assignment to keep compiler happy
6832
8135
  const char *str= NULL;          // Assignment to keep compiler happy
6833
8136
  read_str(&ptr, str_end, &str, &len);
6834
8137
  m_message.str= const_cast<char*>(str);
6857
8160
}
6858
8161
 
6859
8162
 
 
8163
#ifndef MYSQL_CLIENT
6860
8164
void Incident_log_event::pack_info(Protocol *protocol)
6861
8165
{
6862
8166
  char buf[256];
6869
8173
                    m_incident, description(), m_message.str);
6870
8174
  protocol->store(buf, bytes, &my_charset_bin);
6871
8175
}
6872
 
 
6873
 
 
 
8176
#endif
 
8177
 
 
8178
 
 
8179
#ifdef MYSQL_CLIENT
 
8180
void
 
8181
Incident_log_event::print(FILE *file,
 
8182
                          PRINT_EVENT_INFO *print_event_info)
 
8183
{
 
8184
  if (print_event_info->short_form)
 
8185
    return;
 
8186
 
 
8187
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
8188
  print_header(&cache, print_event_info, false);
 
8189
  my_b_printf(&cache, "\n# Incident: %s", description());
 
8190
}
 
8191
#endif
 
8192
 
 
8193
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6874
8194
int
6875
8195
Incident_log_event::do_apply_event(Relay_log_info const *rli)
6876
8196
{
6880
8200
              m_message.length > 0 ? m_message.str : "<none>");
6881
8201
  return(1);
6882
8202
}
6883
 
 
 
8203
#endif
6884
8204
 
6885
8205
bool
6886
8206
Incident_log_event::write_data_header(IO_CACHE *file)
6887
8207
{
6888
 
  unsigned char buf[sizeof(int16_t)];
6889
 
  int2store(buf, (int16_t) m_incident);
 
8208
  uchar buf[sizeof(int16)];
 
8209
  int2store(buf, (int16) m_incident);
6890
8210
  return(my_b_safe_write(file, buf, sizeof(buf)));
6891
8211
}
6892
8212
 
6896
8216
  return(write_str(file, m_message.str, m_message.length));
6897
8217
}
6898
8218
 
6899
 
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint32_t event_len,
 
8219
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
8220
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
6900
8221
                    const Format_description_log_event* description_event)
6901
8222
  :Log_event(buf, description_event)
6902
8223
{
6903
 
  uint8_t header_size= description_event->common_header_len;
 
8224
  uint8 header_size= description_event->common_header_len;
6904
8225
  ident_len = event_len - header_size;
6905
8226
  set_if_smaller(ident_len,FN_REFLEN-1);
6906
8227
  log_ident= buf + header_size;
6907
8228
}
 
8229
#endif
 
8230
 
 
8231
 
 
8232
#ifdef MYSQL_CLIENT
 
8233
/**
 
8234
  The default values for these variables should be values that are
 
8235
  *incorrect*, i.e., values that cannot occur in an event.  This way,
 
8236
  they will always be printed for the first event.
 
8237
*/
 
8238
st_print_event_info::st_print_event_info()
 
8239
  :flags2_inited(0), sql_mode_inited(0),
 
8240
   auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
 
8241
   lc_time_names_number(~0),
 
8242
   charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
 
8243
   thread_id(0), thread_id_printed(false),
 
8244
   base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(false)
 
8245
{
 
8246
  /*
 
8247
    Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
 
8248
    program's startup, but these explicit bzero() is for the day someone
 
8249
    creates dynamic instances.
 
8250
  */
 
8251
  bzero(db, sizeof(db));
 
8252
  bzero(charset, sizeof(charset));
 
8253
  bzero(time_zone_str, sizeof(time_zone_str));
 
8254
  delimiter[0]= ';';
 
8255
  delimiter[1]= 0;
 
8256
  myf const flags = MYF(MY_WME | MY_NABP);
 
8257
  open_cached_file(&head_cache, NULL, NULL, 0, flags);
 
8258
  open_cached_file(&body_cache, NULL, NULL, 0, flags);
 
8259
}
 
8260
#endif