~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Andy Lester
  • Date: 2008-08-09 05:13:22 UTC
  • mto: (266.1.29 use-replace-funcs)
  • mto: This revision was merged to the branch mainline in revision 287.
  • Revision ID: andy@petdance.com-20080809051322-dzas70no2mv6c9i5
removed incorrect comment

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
#ifndef MYSQL_CLIENT
 
18
 
17
19
#include <drizzled/server_includes.h>
18
20
#include "rpl_rli.h"
19
21
#include "rpl_mi.h"
23
25
#include <mysys/my_dir.h>
24
26
#include <drizzled/drizzled_error_messages.h>
25
27
 
26
 
#include <algorithm>
 
28
#endif /* !MYSQL_CLIENT */
27
29
 
28
30
#include <mysys/base64.h>
29
31
#include <mysys/my_bitmap.h>
30
32
 
31
 
#include <libdrizzle/gettext.h>
32
 
#include <libdrizzle/libdrizzle.h>
33
 
 
34
 
#define log_cs  &my_charset_utf8_general_ci
 
33
#define log_cs  &my_charset_latin1
35
34
 
36
35
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
37
36
 
45
44
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
46
45
 
47
46
 
 
47
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
48
48
static const char *HA_ERR(int i)
49
49
{
50
50
  switch (i) {
117
117
*/
118
118
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
119
119
                                           Relay_log_info const *rli, THD *thd,
120
 
                                           Table *table, const char * type,
 
120
                                           TABLE *table, const char * type,
121
121
                                           const char *log_name, ulong pos)
122
122
{
123
123
  const char *handler_error= HA_ERR(ha_error);
124
124
  char buff[MAX_SLAVE_ERRMSG], *slider;
125
125
  const char *buff_end= buff + sizeof(buff);
126
 
  uint32_t len;
 
126
  uint len;
127
127
  List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
128
128
  DRIZZLE_ERROR *err;
129
129
  buff[0]= 0;
132
132
       slider += len, err= it++)
133
133
  {
134
134
    len= snprintf(slider, buff_end - slider,
135
 
                  _(" %s, Error_code: %d;"), err->msg, err->code);
 
135
                  " %s, Error_code: %d;", err->msg, err->code);
136
136
  }
137
137
  
138
138
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
139
 
              _("Could not execute %s event on table %s.%s;"
140
 
                "%s handler error %s; "
141
 
                "the event's master log %s, end_log_pos %lu"),
 
139
              "Could not execute %s event on table %s.%s;"
 
140
              "%s handler error %s; "
 
141
              "the event's master log %s, end_log_pos %lu",
142
142
              type, table->s->db.str,
143
143
              table->s->table_name.str,
144
144
              buff,
145
 
              handler_error == NULL? _("<unknown>") : handler_error,
 
145
              handler_error == NULL? "<unknown>" : handler_error,
146
146
              log_name, pos);
147
147
}
148
 
 
 
148
#endif
149
149
 
150
150
/*
151
151
  Cache that will automatically be written to a dedicated file on
225
225
  flag_set m_flags;
226
226
};
227
227
 
228
 
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
228
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
229
229
 
230
230
/*
231
231
  pretty_print_str()
232
232
*/
233
233
 
 
234
#ifdef MYSQL_CLIENT
 
235
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
 
236
{
 
237
  const char* end = str + len;
 
238
  my_b_printf(cache, "\'");
 
239
  while (str < end)
 
240
  {
 
241
    char c;
 
242
    switch ((c=*str++)) {
 
243
    case '\n': my_b_printf(cache, "\\n"); break;
 
244
    case '\r': my_b_printf(cache, "\\r"); break;
 
245
    case '\\': my_b_printf(cache, "\\\\"); break;
 
246
    case '\b': my_b_printf(cache, "\\b"); break;
 
247
    case '\t': my_b_printf(cache, "\\t"); break;
 
248
    case '\'': my_b_printf(cache, "\\'"); break;
 
249
    case 0   : my_b_printf(cache, "\\0"); break;
 
250
    default:
 
251
      my_b_printf(cache, "%c", c);
 
252
      break;
 
253
    }
 
254
  }
 
255
  my_b_printf(cache, "\'");
 
256
}
 
257
#endif /* MYSQL_CLIENT */
 
258
 
 
259
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
260
 
234
261
static void clear_all_errors(THD *thd, Relay_log_info *rli)
235
262
{
236
263
  thd->is_slave_error = 0;
248
275
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
249
276
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
250
277
}
 
278
#endif
251
279
 
252
280
 
253
281
/*
254
282
  pretty_print_str()
255
283
*/
256
284
 
 
285
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
257
286
static char *pretty_print_str(char *packet, const char *str, int len)
258
287
{
259
288
  const char *end= str + len;
278
307
  *pos++= '\'';
279
308
  return pos;
280
309
}
281
 
 
 
310
#endif /* !MYSQL_CLIENT */
 
311
 
 
312
 
 
313
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
282
314
 
283
315
/**
284
316
  Creates a temporary name for load data infile:.
292
324
    Pointer to start of extension
293
325
*/
294
326
 
295
 
static char *slave_load_file_stem(char *buf, uint32_t file_id,
 
327
static char *slave_load_file_stem(char *buf, uint file_id,
296
328
                                  int event_server_id, const char *ext)
297
329
{
298
330
  char *res;
299
331
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
300
332
  to_unix_path(buf);
301
333
 
302
 
  buf= strchr(buf, '\0');
303
 
  buf= int10_to_str(::server_id, buf, 10);
 
334
  buf = strend(buf);
 
335
  buf = int10_to_str(::server_id, buf, 10);
304
336
  *buf++ = '-';
305
 
  buf= int10_to_str(event_server_id, buf, 10);
 
337
  buf = int10_to_str(event_server_id, buf, 10);
306
338
  *buf++ = '-';
307
339
  res= int10_to_str(file_id, buf, 10);
308
 
  my_stpcpy(res, ext);                             // Add extension last
 
340
  strmov(res, ext);                             // Add extension last
309
341
  return res;                                   // Pointer to extension
310
342
}
311
 
 
 
343
#endif
 
344
 
 
345
 
 
346
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
312
347
 
313
348
/**
314
349
  Delete all temporary files used for SQL_LOAD.
318
353
{
319
354
  MY_DIR *dirp;
320
355
  FILEINFO *file;
321
 
  uint32_t i;
 
356
  uint i;
322
357
  char fname[FN_REFLEN], prefbuf[31], *p;
323
358
 
324
359
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
349
384
 
350
385
  my_dirend(dirp);
351
386
}
 
387
#endif
352
388
 
353
389
 
354
390
/*
355
391
  write_str()
356
392
*/
357
393
 
358
 
static bool write_str(IO_CACHE *file, const char *str, uint32_t length)
 
394
static bool write_str(IO_CACHE *file, const char *str, uint length)
359
395
{
360
 
  unsigned char tmp[1];
361
 
  tmp[0]= (unsigned char) length;
 
396
  uchar tmp[1];
 
397
  tmp[0]= (uchar) length;
362
398
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
363
 
          my_b_safe_write(file, (unsigned char*) str, length));
 
399
          my_b_safe_write(file, (uchar*) str, length));
364
400
}
365
401
 
366
402
 
371
407
static inline int read_str(const char **buf, const char *buf_end,
372
408
                           const char **str, uint8_t *len)
373
409
{
374
 
  if (*buf + ((uint) (unsigned char) **buf) >= buf_end)
 
410
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
375
411
    return 1;
376
412
  *len= (uint8_t) **buf;
377
413
  *str= (*buf)+1;
384
420
  Transforms a string into "" or its expression in 0x... form.
385
421
*/
386
422
 
387
 
char *str_to_hex(char *to, const char *from, uint32_t len)
 
423
char *str_to_hex(char *to, const char *from, uint len)
388
424
{
389
425
  if (len)
390
426
  {
393
429
    to= octet2hex(to, from, len);
394
430
  }
395
431
  else
396
 
    to= my_stpcpy(to, "\"\"");
 
432
    to= strmov(to, "\"\"");
397
433
  return to;                               // pointer to end 0 of 'to'
398
434
}
399
435
 
 
436
#ifndef MYSQL_CLIENT
400
437
 
401
438
/**
402
439
  Append a version of the 'from' string suitable for use in a query to
420
457
  else
421
458
  {
422
459
    *ptr++= '\'';
423
 
    ptr+= drizzle_escape_string(ptr, from->ptr(), from->length());
 
460
    ptr+= escape_string_for_drizzle(csinfo, ptr, 0,
 
461
                                    from->ptr(), from->length());
424
462
    *ptr++='\'';
425
463
  }
426
464
  to->length(orig_len + ptr - beg);
427
465
  return 0;
428
466
}
429
 
 
 
467
#endif
 
468
 
 
469
 
 
470
/**
 
471
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
 
472
  commands just before it prints a query.
 
473
*/
 
474
 
 
475
#ifdef MYSQL_CLIENT
 
476
 
 
477
static void print_set_option(IO_CACHE* file, uint32_t bits_changed,
 
478
                             uint32_t option, uint32_t flags, const char* name,
 
479
                             bool* need_comma)
 
480
{
 
481
  if (bits_changed & option)
 
482
  {
 
483
    if (*need_comma)
 
484
      my_b_printf(file,", ");
 
485
    my_b_printf(file,"%s=%d", name, test(flags & option));
 
486
    *need_comma= 1;
 
487
  }
 
488
}
 
489
#endif
430
490
 
431
491
/**************************************************************************
432
492
        Log_event methods (= the parent class of all events)
480
540
  Log_event::Log_event()
481
541
*/
482
542
 
 
543
#ifndef MYSQL_CLIENT
483
544
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
484
545
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
485
546
{
508
569
  when=         0;
509
570
  log_pos=      0;
510
571
}
 
572
#endif /* !MYSQL_CLIENT */
511
573
 
512
574
 
513
575
/*
518
580
                     const Format_description_log_event* description_event)
519
581
  :temp_buf(0), cache_stmt(0)
520
582
{
521
 
  thd= 0;
522
 
  when= uint4korr(buf);
523
 
  server_id= uint4korr(buf + SERVER_ID_OFFSET);
 
583
#ifndef MYSQL_CLIENT
 
584
  thd = 0;
 
585
#endif
 
586
  when = uint4korr(buf);
 
587
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
524
588
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
525
589
  if (description_event->binlog_version==1)
526
590
  {
579
643
  /* otherwise, go on with reading the header from buf (nothing now) */
580
644
}
581
645
 
 
646
#ifndef MYSQL_CLIENT
 
647
#ifdef HAVE_REPLICATION
582
648
 
583
649
int Log_event::do_update_pos(Relay_log_info *rli)
584
650
{
638
704
 
639
705
 
640
706
/**
 
707
  Only called by SHOW BINLOG EVENTS
 
708
*/
 
709
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
 
710
{
 
711
  const char *p= strrchr(log_name, FN_LIBCHAR);
 
712
  const char *event_type;
 
713
  if (p)
 
714
    log_name = p + 1;
 
715
 
 
716
  protocol->prepare_for_resend();
 
717
  protocol->store(log_name, &my_charset_bin);
 
718
  protocol->store((uint64_t) pos);
 
719
  event_type = get_type_str();
 
720
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
 
721
  protocol->store((uint32_t) server_id);
 
722
  protocol->store((uint64_t) log_pos);
 
723
  pack_info(protocol);
 
724
  return protocol->write();
 
725
}
 
726
#endif /* HAVE_REPLICATION */
 
727
 
 
728
 
 
729
/**
641
730
  init_show_field_list() prepares the column names and types for the
642
731
  output of SHOW BINLOG EVENTS; it is used only by SHOW BINLOG
643
732
  EVENTS.
663
752
 
664
753
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
665
754
{
666
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
755
  uchar header[LOG_EVENT_HEADER_LEN];
667
756
  ulong now;
668
757
 
669
758
  /* Store number of bytes that will be written by this event */
748
837
 
749
838
  if (log_lock)
750
839
    pthread_mutex_lock(log_lock);
751
 
  if (my_b_read(file, (unsigned char*) buf, sizeof(buf)))
 
840
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
752
841
  {
753
842
    /*
754
843
      If the read hits eof, we must report it as eof so the caller
806
895
    pthread_mutex_unlock(log_lock);
807
896
  return(result);
808
897
}
 
898
#endif /* !MYSQL_CLIENT */
809
899
 
 
900
#ifndef MYSQL_CLIENT
810
901
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
811
902
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
 
903
#else
 
904
#define UNLOCK_MUTEX
 
905
#define LOCK_MUTEX
 
906
#endif
812
907
 
 
908
#ifndef MYSQL_CLIENT
813
909
/**
814
910
  @note
815
911
    Allocates memory;  The caller is responsible for clean-up.
818
914
                                     pthread_mutex_t* log_lock,
819
915
                                     const Format_description_log_event
820
916
                                     *description_event)
 
917
#else
 
918
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
919
                                     const Format_description_log_event
 
920
                                     *description_event)
 
921
#endif
821
922
{
822
923
  assert(description_event != 0);
823
924
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
828
929
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
829
930
    "minimal" over the set {MySQL >=4.0}).
830
931
  */
831
 
  uint32_t header_size= cmin(description_event->common_header_len,
 
932
  uint header_size= min(description_event->common_header_len,
832
933
                        LOG_EVENT_MINIMAL_HEADER_LEN);
833
934
 
834
935
  LOCK_MUTEX;
835
 
  if (my_b_read(file, (unsigned char *) head, header_size))
 
936
  if (my_b_read(file, (uchar *) head, header_size))
836
937
  {
837
938
    UNLOCK_MUTEX;
838
939
    /*
842
943
    */
843
944
    return(0);
844
945
  }
845
 
  uint32_t data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
946
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
846
947
  char *buf= 0;
847
948
  const char *error= 0;
848
949
  Log_event *res=  0;
849
950
#ifndef max_allowed_packet
850
951
  THD *thd=current_thd;
851
 
  uint32_t max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
 
952
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
852
953
#endif
853
954
 
854
955
  if (data_len > max_allowed_packet)
871
972
  }
872
973
  buf[data_len] = 0;
873
974
  memcpy(buf, head, header_size);
874
 
  if (my_b_read(file, (unsigned char*) buf + header_size, data_len - header_size))
 
975
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
875
976
  {
876
977
    error = "read error";
877
978
    goto err;
884
985
  if (!res)
885
986
  {
886
987
    assert(error != 0);
887
 
    sql_print_error(_("Error in Log_event::read_log_event(): "
888
 
                    "'%s', data_len: %d, event_type: %d"),
 
988
    sql_print_error("Error in Log_event::read_log_event(): "
 
989
                    "'%s', data_len: %d, event_type: %d",
889
990
                    error,data_len,head[EVENT_TYPE_OFFSET]);
890
 
    free(buf);
 
991
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
891
992
    /*
892
993
      The SQL slave thread will check if file->error<0 to know
893
994
      if there was an I/O error. Even if there is no "low-level" I/O errors
907
1008
  constructors.
908
1009
*/
909
1010
 
910
 
Log_event* Log_event::read_log_event(const char* buf, uint32_t event_len,
 
1011
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
911
1012
                                     const char **error,
912
1013
                                     const Format_description_log_event *description_event)
913
1014
{
923
1024
    return(NULL); // general sanity check - will fail on a partial read
924
1025
  }
925
1026
 
926
 
  uint32_t event_type= buf[EVENT_TYPE_OFFSET];
 
1027
  uint event_type= buf[EVENT_TYPE_OFFSET];
927
1028
  if (event_type > description_event->number_of_event_types &&
928
1029
      event_type != FORMAT_DESCRIPTION_EVENT)
929
1030
  {
961
1062
    case ROTATE_EVENT:
962
1063
      ev = new Rotate_log_event(buf, event_len, description_event);
963
1064
      break;
 
1065
    case SLAVE_EVENT: /* can never happen (unused event) */
 
1066
      ev = new Slave_log_event(buf, event_len);
 
1067
      break;
964
1068
    case CREATE_FILE_EVENT:
965
1069
      ev = new Create_file_log_event(buf, event_len, description_event);
966
1070
      break;
994
1098
    case FORMAT_DESCRIPTION_EVENT:
995
1099
      ev = new Format_description_log_event(buf, event_len, description_event);
996
1100
      break;
 
1101
#if defined(HAVE_REPLICATION) 
997
1102
    case WRITE_ROWS_EVENT:
998
1103
      ev = new Write_rows_log_event(buf, event_len, description_event);
999
1104
      break;
1006
1111
    case TABLE_MAP_EVENT:
1007
1112
      ev = new Table_map_log_event(buf, event_len, description_event);
1008
1113
      break;
 
1114
#endif
1009
1115
    case BEGIN_LOAD_QUERY_EVENT:
1010
1116
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
1011
1117
      break;
1033
1139
  if (!ev || !ev->is_valid())
1034
1140
  {
1035
1141
    delete ev;
 
1142
#ifdef MYSQL_CLIENT
 
1143
    if (!force_opt) /* then mysqlbinlog dies */
 
1144
    {
 
1145
      *error= "Found invalid event in binary log";
 
1146
      return(0);
 
1147
    }
 
1148
    ev= new Unknown_log_event(buf, description_event);
 
1149
#else
1036
1150
    *error= "Found invalid event in binary log";
1037
1151
    return(0);
 
1152
#endif
1038
1153
  }
1039
1154
  return(ev);  
1040
1155
}
1041
1156
 
 
1157
#ifdef MYSQL_CLIENT
 
1158
 
 
1159
/*
 
1160
  Log_event::print_header()
 
1161
*/
 
1162
 
 
1163
void Log_event::print_header(IO_CACHE* file,
 
1164
                             PRINT_EVENT_INFO* print_event_info,
 
1165
                             bool is_more __attribute__((unused)))
 
1166
{
 
1167
  char llbuff[22];
 
1168
  my_off_t hexdump_from= print_event_info->hexdump_from;
 
1169
 
 
1170
  my_b_printf(file, "#");
 
1171
  print_timestamp(file);
 
1172
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
 
1173
              llstr(log_pos,llbuff));
 
1174
 
 
1175
  /* mysqlbinlog --hexdump */
 
1176
  if (print_event_info->hexdump_from)
 
1177
  {
 
1178
    my_b_printf(file, "\n");
 
1179
    uchar *ptr= (uchar*)temp_buf;
 
1180
    my_off_t size=
 
1181
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
 
1182
    my_off_t i;
 
1183
 
 
1184
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
 
1185
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
 
1186
    char *c, char_string[16+1]= {0};
 
1187
 
 
1188
    /* Pretty-print event common header if header is exactly 19 bytes */
 
1189
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
 
1190
    {
 
1191
      char emit_buf[256];               // Enough for storing one line
 
1192
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
 
1193
                  "Size      Master Pos    Flags \n");
 
1194
      int const bytes_written=
 
1195
        snprintf(emit_buf, sizeof(emit_buf),
 
1196
                 "# %8.8lx %02x %02x %02x %02x   %02x   "
 
1197
                 "%02x %02x %02x %02x   %02x %02x %02x %02x   "
 
1198
                 "%02x %02x %02x %02x   %02x %02x\n",
 
1199
                 (unsigned long) hexdump_from,
 
1200
                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
 
1201
                 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
 
1202
                 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
 
1203
      assert(bytes_written >= 0);
 
1204
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1205
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1206
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1207
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1208
    }
 
1209
 
 
1210
    /* Rest of event (without common header) */
 
1211
    for (i= 0, c= char_string, h=hex_string;
 
1212
         i < size;
 
1213
         i++, ptr++)
 
1214
    {
 
1215
      snprintf(h, 4, "%02x ", *ptr);
 
1216
      h += 3;
 
1217
 
 
1218
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
 
1219
 
 
1220
      if (i % 16 == 15)
 
1221
      {
 
1222
        /*
 
1223
          my_b_printf() does not support full printf() formats, so we
 
1224
          have to do it this way.
 
1225
 
 
1226
          TODO: Rewrite my_b_printf() to support full printf() syntax.
 
1227
         */
 
1228
        char emit_buf[256];
 
1229
        int const bytes_written=
 
1230
          snprintf(emit_buf, sizeof(emit_buf),
 
1231
                   "# %8.8lx %-48.48s |%16s|\n",
 
1232
                   (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1233
                   hex_string, char_string);
 
1234
        assert(bytes_written >= 0);
 
1235
        assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1236
        my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1237
        hex_string[0]= 0;
 
1238
        char_string[0]= 0;
 
1239
        c= char_string;
 
1240
        h= hex_string;
 
1241
      }
 
1242
      else if (i % 8 == 7) *h++ = ' ';
 
1243
    }
 
1244
    *c= '\0';
 
1245
 
 
1246
    if (hex_string[0])
 
1247
    {
 
1248
      char emit_buf[256];
 
1249
      int const bytes_written=
 
1250
        snprintf(emit_buf, sizeof(emit_buf),
 
1251
                    "# %8.8lx %-48.48s |%s|\n",
 
1252
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1253
                    hex_string, char_string);
 
1254
      assert(bytes_written >= 0);
 
1255
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1256
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1257
    }
 
1258
    /*
 
1259
      need a # to prefix the rest of printouts for example those of
 
1260
      Rows_log_event::print_helper().
 
1261
    */
 
1262
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
 
1263
  }
 
1264
  return;
 
1265
}
 
1266
 
 
1267
 
 
1268
void Log_event::print_base64(IO_CACHE* file,
 
1269
                             PRINT_EVENT_INFO* print_event_info,
 
1270
                             bool more)
 
1271
{
 
1272
  const uchar *ptr= (const uchar *)temp_buf;
 
1273
  uint32_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
 
1274
 
 
1275
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
 
1276
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
 
1277
  if (!tmp_str) {
 
1278
    fprintf(stderr, "\nError: Out of memory. "
 
1279
            "Could not print correct binlog event.\n");
 
1280
    return;
 
1281
  }
 
1282
 
 
1283
  if (base64_encode(ptr, (size_t) size, tmp_str))
 
1284
  {
 
1285
    assert(0);
 
1286
  }
 
1287
 
 
1288
  if (my_b_tell(file) == 0)
 
1289
    my_b_printf(file, "\nBINLOG '\n");
 
1290
 
 
1291
  my_b_printf(file, "%s\n", tmp_str);
 
1292
 
 
1293
  if (!more)
 
1294
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
 
1295
 
 
1296
  my_free(tmp_str, MYF(0));
 
1297
  return;
 
1298
}
 
1299
 
 
1300
 
 
1301
/*
 
1302
  Log_event::print_timestamp()
 
1303
*/
 
1304
 
 
1305
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
 
1306
{
 
1307
  struct tm *res;
 
1308
  if (!ts)
 
1309
    ts = &when;
 
1310
#ifdef MYSQL_SERVER                             // This is always false
 
1311
  struct tm tm_tmp;
 
1312
  localtime_r(ts,(res= &tm_tmp));
 
1313
#else
 
1314
  res=localtime(ts);
 
1315
#endif
 
1316
 
 
1317
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
 
1318
              res->tm_year % 100,
 
1319
              res->tm_mon+1,
 
1320
              res->tm_mday,
 
1321
              res->tm_hour,
 
1322
              res->tm_min,
 
1323
              res->tm_sec);
 
1324
  return;
 
1325
}
 
1326
 
 
1327
#endif /* MYSQL_CLIENT */
 
1328
 
 
1329
 
 
1330
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1042
1331
inline Log_event::enum_skip_reason
1043
1332
Log_event::continue_group(Relay_log_info *rli)
1044
1333
{
1046
1335
    return Log_event::EVENT_SKIP_IGNORE;
1047
1336
  return Log_event::do_shall_skip(rli);
1048
1337
}
 
1338
#endif
1049
1339
 
1050
1340
/**************************************************************************
1051
1341
        Query_log_event methods
1052
1342
**************************************************************************/
1053
1343
 
 
1344
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
1345
 
1054
1346
/**
1055
1347
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
1056
1348
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1070
1362
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1071
1363
      && db && db_len)
1072
1364
  {
1073
 
    pos= my_stpcpy(buf, "use `");
 
1365
    pos= strmov(buf, "use `");
1074
1366
    memcpy(pos, db, db_len);
1075
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
1367
    pos= strmov(pos+db_len, "`; ");
1076
1368
  }
1077
1369
  if (query && q_len)
1078
1370
  {
1080
1372
    pos+= q_len;
1081
1373
  }
1082
1374
  protocol->store(buf, pos-buf, &my_charset_bin);
1083
 
  free(buf);
 
1375
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1084
1376
}
 
1377
#endif
1085
1378
 
 
1379
#ifndef MYSQL_CLIENT
1086
1380
 
1087
1381
/**
1088
1382
  Utility function for the next method (Query_log_event::write()) .
1089
1383
*/
1090
1384
static void write_str_with_code_and_len(char **dst, const char *src,
1091
 
                                        int len, uint32_t code)
 
1385
                                        int len, uint code)
1092
1386
{
1093
1387
  assert(src);
1094
1388
  *((*dst)++)= code;
1095
 
  *((*dst)++)= (unsigned char) len;
 
1389
  *((*dst)++)= (uchar) len;
1096
1390
  memcpy(*dst, src, len);
1097
1391
  (*dst)+= len;
1098
1392
}
1114
1408
    replicating it correctly, since the length is stored in a byte
1115
1409
    /sven
1116
1410
  */
1117
 
  unsigned char buf[QUERY_HEADER_LEN+
 
1411
  uchar buf[QUERY_HEADER_LEN+
1118
1412
            1+4+           // code of flags2 and flags2
1119
1413
            1+8+           // code of sql_mode and sql_mode
1120
1414
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1270
1564
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1271
1565
 
1272
1566
  return (write_header(file, event_length) ||
1273
 
          my_b_safe_write(file, (unsigned char*) buf, QUERY_HEADER_LEN) ||
 
1567
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1274
1568
          write_post_header_for_derived(file) ||
1275
 
          my_b_safe_write(file, (unsigned char*) start_of_status,
 
1569
          my_b_safe_write(file, (uchar*) start_of_status,
1276
1570
                          (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;
 
1571
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
 
1572
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1279
1573
}
1280
1574
 
1281
1575
/**
1377
1671
  else
1378
1672
    time_zone_len= 0;
1379
1673
}
 
1674
#endif /* MYSQL_CLIENT */
1380
1675
 
1381
1676
 
1382
1677
/* 2 utility functions for the next method */
1408
1703
static int
1409
1704
get_str_len_and_pointer(const Log_event::Byte **src,
1410
1705
                        const char **dst,
1411
 
                        uint32_t *len,
 
1706
                        uint *len,
1412
1707
                        const Log_event::Byte *end)
1413
1708
{
1414
1709
  if (*src >= end)
1415
1710
    return -1;       // Will be UINT_MAX in two-complement arithmetics
1416
 
  uint32_t length= **src;
 
1711
  uint length= **src;
1417
1712
  if (length > 0)
1418
1713
  {
1419
1714
    if (*src + length >= end)
1427
1722
 
1428
1723
static void copy_str_and_move(const char **src, 
1429
1724
                              Log_event::Byte **dst, 
1430
 
                              uint32_t len)
 
1725
                              uint len)
1431
1726
{
1432
1727
  memcpy(*dst, *src, len);
1433
1728
  *src= (const char *)*dst;
1445
1740
 */
1446
1741
#define CHECK_SPACE(PTR,END,CNT)                      \
1447
1742
  do {                                                \
1448
 
    assert((PTR) + (CNT) <= (END));                   \
 
1743
    assert((PTR) + (CNT) <= (END));              \
1449
1744
    if ((PTR) + (CNT) > (END)) {                      \
1450
1745
      query= 0;                                       \
1451
 
      return;                                         \
 
1746
      return;                               \
1452
1747
    }                                                 \
1453
1748
  } while (0)
1454
1749
 
1456
1751
/**
1457
1752
  This is used by the SQL slave thread to prepare the event before execution.
1458
1753
*/
1459
 
Query_log_event::Query_log_event(const char* buf, uint32_t event_len,
 
1754
Query_log_event::Query_log_event(const char* buf, uint event_len,
1460
1755
                                 const Format_description_log_event
1461
1756
                                 *description_event,
1462
1757
                                 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),
 
1758
  :Log_event(buf, description_event), data_buf(0), query(NullS),
 
1759
   db(NullS), catalog_len(0), status_vars_len(0),
1465
1760
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1466
1761
   auto_increment_increment(1), auto_increment_offset(1),
1467
1762
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1468
1763
{
1469
 
  uint32_t data_len;
 
1764
  ulong data_len;
1470
1765
  uint32_t tmp;
1471
1766
  uint8_t common_header_len, post_header_len;
1472
1767
  Log_event::Byte *start;
1506
1801
      be even bigger, but this will suffice to catch most corruption
1507
1802
      errors that can lead to a crash.
1508
1803
    */
1509
 
    if (status_vars_len > cmin(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
 
1804
    if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
1510
1805
    {
1511
1806
      query= 0;
1512
1807
      return;
1554
1849
      auto_increment_offset=    uint2korr(pos+2);
1555
1850
      pos+= 4;
1556
1851
      break;
 
1852
    case Q_CHARSET_CODE:
 
1853
    {
 
1854
      CHECK_SPACE(pos, end, 6);
 
1855
      charset_inited= 1;
 
1856
      memcpy(charset, pos, 6);
 
1857
      pos+= 6;
 
1858
      break;
 
1859
    }
1557
1860
    case Q_TIME_ZONE_CODE:
1558
1861
    {
1559
1862
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1583
1886
      break;
1584
1887
    default:
1585
1888
      /* That's why you must write status vars in growing order of code */
1586
 
      pos= (const unsigned char*) end;                         // Break loop
 
1889
      pos= (const uchar*) end;                         // Break loop
1587
1890
    }
1588
1891
  }
1589
1892
  
1628
1931
}
1629
1932
 
1630
1933
 
 
1934
#ifdef MYSQL_CLIENT
 
1935
/**
 
1936
  Query_log_event::print().
 
1937
 
 
1938
  @todo
 
1939
    print the catalog ??
 
1940
*/
 
1941
void Query_log_event::print_query_header(IO_CACHE* file,
 
1942
                                         PRINT_EVENT_INFO* print_event_info)
 
1943
{
 
1944
  // TODO: print the catalog ??
 
1945
  char buff[40],*end;                           // Enough for SET TIMESTAMP
 
1946
  bool different_db= 1;
 
1947
  uint32_t tmp;
 
1948
 
 
1949
  if (!print_event_info->short_form)
 
1950
  {
 
1951
    print_header(file, print_event_info, false);
 
1952
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 
1953
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
 
1954
                error_code);
 
1955
  }
 
1956
 
 
1957
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
 
1958
  {
 
1959
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
 
1960
      memcpy(print_event_info->db, db, db_len + 1);
 
1961
    if (db[0] && different_db) 
 
1962
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
 
1963
  }
 
1964
 
 
1965
  end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
 
1966
  end= strmov(end, print_event_info->delimiter);
 
1967
  *end++='\n';
 
1968
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
 
1969
  if ((!print_event_info->thread_id_printed ||
 
1970
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
 
1971
        thread_id != print_event_info->thread_id)))
 
1972
  {
 
1973
    // If --short-form, print deterministic value instead of pseudo_thread_id.
 
1974
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
 
1975
                short_form ? 999999999 : (ulong)thread_id,
 
1976
                print_event_info->delimiter);
 
1977
    print_event_info->thread_id= thread_id;
 
1978
    print_event_info->thread_id_printed= 1;
 
1979
  }
 
1980
 
 
1981
  /*
 
1982
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
 
1983
    print (remember we don't produce mixed relay logs so there cannot be
 
1984
    5.0 events before that one so there is nothing to reset).
 
1985
  */
 
1986
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
 
1987
  {
 
1988
    /* tmp is a bitmask of bits which have changed. */
 
1989
    if (likely(print_event_info->flags2_inited)) 
 
1990
      /* All bits which have changed */
 
1991
      tmp= (print_event_info->flags2) ^ flags2;
 
1992
    else /* that's the first Query event we read */
 
1993
    {
 
1994
      print_event_info->flags2_inited= 1;
 
1995
      tmp= ~((uint32_t)0); /* all bits have changed */
 
1996
    }
 
1997
 
 
1998
    if (unlikely(tmp)) /* some bits have changed */
 
1999
    {
 
2000
      bool need_comma= 0;
 
2001
      my_b_printf(file, "SET ");
 
2002
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
 
2003
                   "@@session.foreign_key_checks", &need_comma);
 
2004
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
 
2005
                   "@@session.sql_auto_is_null", &need_comma);
 
2006
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
 
2007
                   "@@session.unique_checks", &need_comma);
 
2008
      my_b_printf(file,"%s\n", print_event_info->delimiter);
 
2009
      print_event_info->flags2= flags2;
 
2010
    }
 
2011
  }
 
2012
 
 
2013
  /*
 
2014
    Now the session variables;
 
2015
    it's more efficient to pass SQL_MODE as a number instead of a
 
2016
    comma-separated list.
 
2017
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
 
2018
    variables (they have no global version; they're not listed in
 
2019
    sql_class.h), The tests below work for pure binlogs or pure relay
 
2020
    logs. Won't work for mixed relay logs but we don't create mixed
 
2021
    relay logs (that is, there is no relay log with a format change
 
2022
    except within the 3 first events, which mysqlbinlog handles
 
2023
    gracefully). So this code should always be good.
 
2024
  */
 
2025
 
 
2026
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
 
2027
      print_event_info->auto_increment_offset != auto_increment_offset)
 
2028
  {
 
2029
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
 
2030
                auto_increment_increment,auto_increment_offset,
 
2031
                print_event_info->delimiter);
 
2032
    print_event_info->auto_increment_increment= auto_increment_increment;
 
2033
    print_event_info->auto_increment_offset=    auto_increment_offset;
 
2034
  }
 
2035
 
 
2036
  /* TODO: print the catalog when we feature SET CATALOG */
 
2037
 
 
2038
  if (likely(charset_inited) &&
 
2039
      (unlikely(!print_event_info->charset_inited ||
 
2040
                memcmp(print_event_info->charset, charset, 6))))
 
2041
  {
 
2042
    const CHARSET_INFO * const cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
 
2043
    if (cs_info)
 
2044
    {
 
2045
      /* for mysql client */
 
2046
      my_b_printf(file, "/*!\\C %s */%s\n",
 
2047
                  cs_info->csname, print_event_info->delimiter);
 
2048
    }
 
2049
    my_b_printf(file,"SET "
 
2050
                "@@session.character_set_client=%d,"
 
2051
                "@@session.collation_connection=%d,"
 
2052
                "@@session.collation_server=%d"
 
2053
                "%s\n",
 
2054
                uint2korr(charset),
 
2055
                uint2korr(charset+2),
 
2056
                uint2korr(charset+4),
 
2057
                print_event_info->delimiter);
 
2058
    memcpy(print_event_info->charset, charset, 6);
 
2059
    print_event_info->charset_inited= 1;
 
2060
  }
 
2061
  if (time_zone_len)
 
2062
  {
 
2063
    if (memcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
 
2064
    {
 
2065
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
 
2066
                  time_zone_str, print_event_info->delimiter);
 
2067
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
 
2068
    }
 
2069
  }
 
2070
  if (lc_time_names_number != print_event_info->lc_time_names_number)
 
2071
  {
 
2072
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
 
2073
                lc_time_names_number, print_event_info->delimiter);
 
2074
    print_event_info->lc_time_names_number= lc_time_names_number;
 
2075
  }
 
2076
  if (charset_database_number != print_event_info->charset_database_number)
 
2077
  {
 
2078
    if (charset_database_number)
 
2079
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
 
2080
                  charset_database_number, print_event_info->delimiter);
 
2081
    else
 
2082
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
2083
                  print_event_info->delimiter);
 
2084
    print_event_info->charset_database_number= charset_database_number;
 
2085
  }
 
2086
}
 
2087
 
 
2088
 
 
2089
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2090
{
 
2091
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
2092
 
 
2093
  print_query_header(&cache, print_event_info);
 
2094
  my_b_write(&cache, (uchar*) query, q_len);
 
2095
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
2096
}
 
2097
#endif /* MYSQL_CLIENT */
 
2098
 
 
2099
 
1631
2100
/*
1632
2101
  Query_log_event::do_apply_event()
1633
2102
*/
 
2103
 
 
2104
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2105
 
1634
2106
int Query_log_event::do_apply_event(Relay_log_info const *rli)
1635
2107
{
1636
2108
  return do_apply_event(rli, query, q_len);
1703
2175
    thd->set_time((time_t)when);
1704
2176
    thd->query_length= q_len_arg;
1705
2177
    thd->query= (char*)query_arg;
1706
 
    pthread_mutex_lock(&LOCK_thread_count);
 
2178
    VOID(pthread_mutex_lock(&LOCK_thread_count));
1707
2179
    thd->query_id = next_query_id();
1708
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
2180
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
1709
2181
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
1710
2182
 
1711
2183
    if (ignored_error_code((expected_error= error_code)) ||
1717
2189
          must take their value from flags2.
1718
2190
        */
1719
2191
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2192
      /*
 
2193
        else, we are in a 3.23/4.0 binlog; we previously received a
 
2194
        Rotate_log_event which reset thd->options and sql_mode etc, so
 
2195
        nothing to do.
 
2196
      */
 
2197
      if (charset_inited)
 
2198
      {
 
2199
        if (rli->cached_charset_compare(charset))
 
2200
        {
 
2201
          /* Verify that we support the charsets found in the event. */
 
2202
          if (!(thd->variables.character_set_client=
 
2203
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
 
2204
              !(thd->variables.collation_connection=
 
2205
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
 
2206
              !(thd->variables.collation_server=
 
2207
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
 
2208
          {
 
2209
            /*
 
2210
              We updated the thd->variables with nonsensical values (0). Let's
 
2211
              set them to something safe (i.e. which avoids crash), and we'll
 
2212
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
 
2213
              ignore this error).
 
2214
            */
 
2215
            set_slave_thread_default_charset(thd, rli);
 
2216
            goto compare_errors;
 
2217
          }
 
2218
          thd->update_charset(); // for the charset change to take effect
 
2219
        }
 
2220
      }
1720
2221
      if (time_zone_len)
1721
2222
      {
1722
2223
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1773
2274
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
1774
2275
      else
1775
2276
      {
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);
 
2277
        rli->report(ERROR_LEVEL, expected_error, 
 
2278
                          "\
 
2279
Query partially completed on the master (error on master: %d) \
 
2280
and was aborted. There is a chance that your master is inconsistent at this \
 
2281
point. If you are sure that your master is ok, run this query manually on the \
 
2282
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
 
2283
START SLAVE; . Query: '%s'", expected_error, thd->query);
1785
2284
        thd->is_slave_error= 1;
1786
2285
      }
1787
2286
      goto end;
1788
2287
    }
1789
2288
 
 
2289
    /* If the query was not ignored, it is printed to the general log */
 
2290
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
 
2291
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
 
2292
 
1790
2293
compare_errors:
1791
2294
 
1792
2295
     /*
1795
2298
    */
1796
2299
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
1797
2300
    if ((expected_error != actual_error) &&
1798
 
        expected_error &&
1799
 
        !ignored_error_code(actual_error) &&
1800
 
        !ignored_error_code(expected_error))
 
2301
        expected_error &&
 
2302
        !ignored_error_code(actual_error) &&
 
2303
        !ignored_error_code(expected_error))
1801
2304
    {
1802
2305
      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);
 
2306
                      "\
 
2307
Query caused different errors on master and slave.     \
 
2308
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
 
2309
Default database: '%s'. Query: '%s'",
 
2310
                      ER_SAFE(expected_error),
 
2311
                      expected_error,
 
2312
                      actual_error ? thd->main_da.message() : "no error",
 
2313
                      actual_error,
 
2314
                      print_slave_db_safe(db), query_arg);
1811
2315
      thd->is_slave_error= 1;
1812
2316
    }
1813
2317
    /*
1825
2329
    else if (thd->is_slave_error || thd->is_fatal_error)
1826
2330
    {
1827
2331
      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")),
 
2332
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
 
2333
                      (actual_error ? thd->main_da.message() :
 
2334
                       "unexpected success or fatal error"),
1831
2335
                      print_slave_db_safe(thd->db), query_arg);
1832
2336
      thd->is_slave_error= 1;
1833
2337
    }
1856
2360
  } /* End of if (db_ok(... */
1857
2361
 
1858
2362
end:
1859
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2363
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1860
2364
  /*
1861
2365
    Probably we have set thd->query, thd->db, thd->catalog to point to places
1862
2366
    in the data_buf of this event. Now the event is going to be deleted
1863
2367
    probably, so data_buf will be freed, so the thd->... listed above will be
1864
2368
    pointers to freed memory. 
1865
2369
    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
 
2370
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
1867
2371
    don't suffer from these assignments to 0 as DROP TEMPORARY
1868
 
    Table uses the db.table syntax.
 
2372
    TABLE uses the db.table syntax.
1869
2373
  */
1870
2374
  thd->catalog= 0;
1871
2375
  thd->set_db(NULL, 0);                 /* will free the current database */
1872
2376
  thd->query= 0;                        // just to be sure
1873
2377
  thd->query_length= 0;
1874
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
2378
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
1875
2379
  close_thread_tables(thd);      
1876
2380
  /*
1877
2381
    As a disk space optimization, future masters will not log an event for
1926
2430
  return(Log_event::do_shall_skip(rli));
1927
2431
}
1928
2432
 
 
2433
#endif
 
2434
 
1929
2435
 
1930
2436
/**************************************************************************
1931
2437
        Start_log_event_v3 methods
1932
2438
**************************************************************************/
1933
2439
 
 
2440
#ifndef MYSQL_CLIENT
1934
2441
Start_log_event_v3::Start_log_event_v3()
1935
2442
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
1936
2443
   artificial_event(0), dont_set_created(0)
1937
2444
{
1938
2445
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
1939
2446
}
 
2447
#endif
1940
2448
 
1941
2449
/*
1942
2450
  Start_log_event_v3::pack_info()
1943
2451
*/
1944
2452
 
 
2453
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1945
2454
void Start_log_event_v3::pack_info(Protocol *protocol)
1946
2455
{
1947
2456
  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: ");
 
2457
  pos= strmov(buf, "Server ver: ");
 
2458
  pos= strmov(pos, server_version);
 
2459
  pos= strmov(pos, ", Binlog ver: ");
1951
2460
  pos= int10_to_str(binlog_version, pos, 10);
1952
2461
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
1953
2462
}
1954
 
 
 
2463
#endif
 
2464
 
 
2465
 
 
2466
/*
 
2467
  Start_log_event_v3::print()
 
2468
*/
 
2469
 
 
2470
#ifdef MYSQL_CLIENT
 
2471
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2472
{
 
2473
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
2474
                               Write_on_release_cache::FLUSH_F);
 
2475
 
 
2476
  if (!print_event_info->short_form)
 
2477
  {
 
2478
    print_header(&cache, print_event_info, false);
 
2479
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
 
2480
                binlog_version, server_version);
 
2481
    print_timestamp(&cache);
 
2482
    if (created)
 
2483
      my_b_printf(&cache," at startup");
 
2484
    my_b_printf(&cache, "\n");
 
2485
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
 
2486
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
 
2487
                  "Most probably mysqld crashed writing it.\n");
 
2488
  }
 
2489
  if (!artificial_event && created)
 
2490
  {
 
2491
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
 
2492
    /*
 
2493
      This is for mysqlbinlog: like in replication, we want to delete the stale
 
2494
      tmp files left by an unclean shutdown of mysqld (temporary tables)
 
2495
      and rollback unfinished transaction.
 
2496
      Probably this can be done with RESET CONNECTION (syntax to be defined).
 
2497
    */
 
2498
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
 
2499
#else
 
2500
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
 
2501
#endif
 
2502
  }
 
2503
  if (temp_buf &&
 
2504
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
 
2505
      !print_event_info->short_form)
 
2506
  {
 
2507
    my_b_printf(&cache, "BINLOG '\n");
 
2508
    print_base64(&cache, print_event_info, false);
 
2509
    print_event_info->printed_fd_event= true;
 
2510
  }
 
2511
  return;
 
2512
}
 
2513
#endif /* MYSQL_CLIENT */
1955
2514
 
1956
2515
/*
1957
2516
  Start_log_event_v3::Start_log_event_v3()
1979
2538
  Start_log_event_v3::write()
1980
2539
*/
1981
2540
 
 
2541
#ifndef MYSQL_CLIENT
1982
2542
bool Start_log_event_v3::write(IO_CACHE* file)
1983
2543
{
1984
2544
  char buff[START_V3_HEADER_LEN];
1988
2548
    created= when= get_time();
1989
2549
  int4store(buff + ST_CREATED_OFFSET,created);
1990
2550
  return (write_header(file, sizeof(buff)) ||
1991
 
          my_b_safe_write(file, (unsigned char*) buff, sizeof(buff)));
 
2551
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
1992
2552
}
1993
 
 
 
2553
#endif
 
2554
 
 
2555
 
 
2556
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1994
2557
 
1995
2558
/**
1996
2559
  Start_log_event_v3::do_apply_event() .
1998
2561
 
1999
2562
    IMPLEMENTATION
2000
2563
    - To handle the case where the master died without having time to write
2001
 
    DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
 
2564
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
2002
2565
    TODO), we clean up all temporary tables that we got, if we are sure we
2003
2566
    can (see below).
2004
2567
 
2055
2618
  }
2056
2619
  return(0);
2057
2620
}
 
2621
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
2058
2622
 
2059
2623
/***************************************************************************
2060
2624
       Format_description_log_event methods
2124
2688
      describes what those old master versions send.
2125
2689
    */
2126
2690
    if (binlog_ver==1)
2127
 
      my_stpcpy(server_version, server_ver ? server_ver : "3.23");
 
2691
      strmov(server_version, server_ver ? server_ver : "3.23");
2128
2692
    else
2129
 
      my_stpcpy(server_version, server_ver ? server_ver : "4.0");
 
2693
      strmov(server_version, server_ver ? server_ver : "4.0");
2130
2694
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2131
2695
      LOG_EVENT_MINIMAL_HEADER_LEN;
2132
2696
    /*
2185
2749
 
2186
2750
Format_description_log_event::
2187
2751
Format_description_log_event(const char* buf,
2188
 
                             uint32_t event_len,
 
2752
                             uint event_len,
2189
2753
                             const
2190
2754
                             Format_description_log_event*
2191
2755
                             description_event)
2197
2761
  number_of_event_types=
2198
2762
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
2199
2763
  /* 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,
 
2764
  post_header_len= (uint8_t*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2201
2765
                                      number_of_event_types*
2202
2766
                                      sizeof(*post_header_len), MYF(0));
2203
2767
  calc_server_version_split();
2272
2836
    if (number_of_event_types != 22)
2273
2837
    {
2274
2838
      /* this makes is_valid() return false. */
2275
 
      free(post_header_len);
 
2839
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2276
2840
      post_header_len= NULL;
2277
2841
      return;
2278
2842
    }
2306
2870
  return;
2307
2871
}
2308
2872
 
 
2873
#ifndef MYSQL_CLIENT
2309
2874
bool Format_description_log_event::write(IO_CACHE* file)
2310
2875
{
2311
2876
  /*
2312
2877
    We don't call Start_log_event_v3::write() because this would make 2
2313
2878
    my_b_safe_write().
2314
2879
  */
2315
 
  unsigned char buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
2880
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
2316
2881
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2317
2882
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2318
2883
  if (!dont_set_created)
2324
2889
  return (write_header(file, sizeof(buff)) ||
2325
2890
          my_b_safe_write(file, buff, sizeof(buff)));
2326
2891
}
2327
 
 
2328
 
 
 
2892
#endif
 
2893
 
 
2894
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2329
2895
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2330
2896
{
2331
2897
  /*
2343
2909
  {
2344
2910
    /* This is not an error (XA is safe), just an information */
2345
2911
    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."));
 
2912
                "Rolling back unfinished transaction (no COMMIT "
 
2913
                "or ROLLBACK in relay log). A probable cause is that "
 
2914
                "the master died while writing the transaction to "
 
2915
                "its binary log, thus rolled back too."); 
2350
2916
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2351
2917
  }
2352
2918
  /*
2406
2972
  return Log_event::EVENT_SKIP_NOT;
2407
2973
}
2408
2974
 
 
2975
#endif
 
2976
 
2409
2977
 
2410
2978
/**
2411
2979
   Splits the event's 'server_version' string into three numeric pieces stored
2420
2988
{
2421
2989
  char *p= server_version, *r;
2422
2990
  ulong number;
2423
 
  for (uint32_t i= 0; i<=2; i++)
 
2991
  for (uint i= 0; i<=2; i++)
2424
2992
  {
2425
2993
    number= strtoul(p, &r, 10);
2426
 
    server_version_split[i]= (unsigned char)number;
2427
 
    assert(number < 256); // fit in unsigned char
 
2994
    server_version_split[i]= (uchar)number;
 
2995
    assert(number < 256); // fit in uchar
2428
2996
    p= r;
2429
2997
    assert(!((i == 0) && (*r != '.'))); // should be true in practice
2430
2998
    if (*r == '.')
2454
3022
  Load_log_event::pack_info()
2455
3023
*/
2456
3024
 
2457
 
uint32_t Load_log_event::get_query_buffer_length()
 
3025
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3026
uint Load_log_event::get_query_buffer_length()
2458
3027
{
2459
3028
  return
2460
3029
    5 + db_len + 3 +                        // "use DB; "
2461
3030
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
2462
3031
    7 +                                     // LOCAL
2463
3032
    9 +                                     // " REPLACE or IGNORE "
2464
 
    13 + table_name_len*2 +                 // "INTO Table `table`"
 
3033
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
2465
3034
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
2466
3035
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
2467
3036
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
2479
3048
 
2480
3049
  if (need_db && db && db_len)
2481
3050
  {
2482
 
    pos= my_stpcpy(pos, "use `");
 
3051
    pos= strmov(pos, "use `");
2483
3052
    memcpy(pos, db, db_len);
2484
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
3053
    pos= strmov(pos+db_len, "`; ");
2485
3054
  }
2486
3055
 
2487
 
  pos= my_stpcpy(pos, "LOAD DATA ");
 
3056
  pos= strmov(pos, "LOAD DATA ");
2488
3057
 
2489
3058
  if (fn_start)
2490
3059
    *fn_start= pos;
2491
3060
 
2492
3061
  if (check_fname_outside_temp_buf())
2493
 
    pos= my_stpcpy(pos, "LOCAL ");
2494
 
  pos= my_stpcpy(pos, "INFILE '");
 
3062
    pos= strmov(pos, "LOCAL ");
 
3063
  pos= strmov(pos, "INFILE '");
2495
3064
  memcpy(pos, fname, fname_len);
2496
 
  pos= my_stpcpy(pos+fname_len, "' ");
 
3065
  pos= strmov(pos+fname_len, "' ");
2497
3066
 
2498
3067
  if (sql_ex.opt_flags & REPLACE_FLAG)
2499
 
    pos= my_stpcpy(pos, " REPLACE ");
 
3068
    pos= strmov(pos, " REPLACE ");
2500
3069
  else if (sql_ex.opt_flags & IGNORE_FLAG)
2501
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3070
    pos= strmov(pos, " IGNORE ");
2502
3071
 
2503
 
  pos= my_stpcpy(pos ,"INTO");
 
3072
  pos= strmov(pos ,"INTO");
2504
3073
 
2505
3074
  if (fn_end)
2506
3075
    *fn_end= pos;
2507
3076
 
2508
 
  pos= my_stpcpy(pos ," Table `");
 
3077
  pos= strmov(pos ," TABLE `");
2509
3078
  memcpy(pos, table_name, table_name_len);
2510
3079
  pos+= table_name_len;
2511
3080
 
2512
3081
  /* We have to create all optinal fields as the default is not empty */
2513
 
  pos= my_stpcpy(pos, "` FIELDS TERMINATED BY ");
 
3082
  pos= strmov(pos, "` FIELDS TERMINATED BY ");
2514
3083
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
2515
3084
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
2516
 
    pos= my_stpcpy(pos, " OPTIONALLY ");
2517
 
  pos= my_stpcpy(pos, " ENCLOSED BY ");
 
3085
    pos= strmov(pos, " OPTIONALLY ");
 
3086
  pos= strmov(pos, " ENCLOSED BY ");
2518
3087
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
2519
3088
 
2520
 
  pos= my_stpcpy(pos, " ESCAPED BY ");
 
3089
  pos= strmov(pos, " ESCAPED BY ");
2521
3090
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
2522
3091
 
2523
 
  pos= my_stpcpy(pos, " LINES TERMINATED BY ");
 
3092
  pos= strmov(pos, " LINES TERMINATED BY ");
2524
3093
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
2525
3094
  if (sql_ex.line_start_len)
2526
3095
  {
2527
 
    pos= my_stpcpy(pos, " STARTING BY ");
 
3096
    pos= strmov(pos, " STARTING BY ");
2528
3097
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
2529
3098
  }
2530
3099
 
2531
3100
  if ((long) skip_lines > 0)
2532
3101
  {
2533
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3102
    pos= strmov(pos, " IGNORE ");
2534
3103
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2535
 
    pos= my_stpcpy(pos," LINES ");    
 
3104
    pos= strmov(pos," LINES ");    
2536
3105
  }
2537
3106
 
2538
3107
  if (num_fields)
2539
3108
  {
2540
 
    uint32_t i;
 
3109
    uint i;
2541
3110
    const char *field= fields;
2542
 
    pos= my_stpcpy(pos, " (");
 
3111
    pos= strmov(pos, " (");
2543
3112
    for (i = 0; i < num_fields; i++)
2544
3113
    {
2545
3114
      if (i)
2566
3135
    return;
2567
3136
  print_query(true, buf, &end, 0, 0);
2568
3137
  protocol->store(buf, end-buf, &my_charset_bin);
2569
 
  free(buf);
 
3138
  my_free(buf, MYF(0));
2570
3139
}
2571
 
 
 
3140
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
3141
 
 
3142
 
 
3143
#ifndef MYSQL_CLIENT
2572
3144
 
2573
3145
/*
2574
3146
  Load_log_event::write_data_header()
2583
3155
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
2584
3156
  buf[L_DB_LEN_OFFSET] = (char)db_len;
2585
3157
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
2586
 
  return my_b_safe_write(file, (unsigned char*)buf, LOAD_HEADER_LEN) != 0;
 
3158
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
2587
3159
}
2588
3160
 
2589
3161
 
2597
3169
    return 1;
2598
3170
  if (num_fields && fields && field_lens)
2599
3171
  {
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))
 
3172
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
 
3173
        my_b_safe_write(file, (uchar*)fields, field_block_len))
2602
3174
      return 1;
2603
3175
  }
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));
 
3176
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
 
3177
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
 
3178
          my_b_safe_write(file, (uchar*)fname, fname_len));
2607
3179
}
2608
3180
 
2609
3181
 
2684
3256
  while ((item = li++))
2685
3257
  {
2686
3258
    num_fields++;
2687
 
    unsigned char len = (unsigned char) strlen(item->name);
 
3259
    uchar len = (uchar) strlen(item->name);
2688
3260
    field_block_len += len + 1;
2689
3261
    fields_buf.append(item->name, len + 1);
2690
3262
    field_lens_buf.append((char*)&len, 1);
2691
3263
  }
2692
3264
 
2693
 
  field_lens = (const unsigned char*)field_lens_buf.ptr();
 
3265
  field_lens = (const uchar*)field_lens_buf.ptr();
2694
3266
  fields = fields_buf.ptr();
2695
3267
}
 
3268
#endif /* !MYSQL_CLIENT */
2696
3269
 
2697
3270
 
2698
3271
/**
2700
3273
    The caller must do buf[event_len] = 0 before he starts using the
2701
3274
    constructed event.
2702
3275
*/
2703
 
Load_log_event::Load_log_event(const char *buf, uint32_t event_len,
 
3276
Load_log_event::Load_log_event(const char *buf, uint event_len,
2704
3277
                               const Format_description_log_event *description_event)
2705
3278
  :Log_event(buf, description_event), num_fields(0), fields(0),
2706
3279
   field_lens(0),field_block_len(0),
2730
3303
                                   int body_offset,
2731
3304
                                   const Format_description_log_event *description_event)
2732
3305
{
2733
 
  uint32_t data_len;
 
3306
  uint data_len;
2734
3307
  char* buf_end = (char*)buf + event_len;
2735
3308
  /* this is the beginning of the post-header */
2736
3309
  const char* data_head = buf + description_event->common_header_len;
2747
3320
    Sql_ex.init() on success returns the pointer to the first byte after
2748
3321
    the sql_ex structure, which is the start of field lengths array.
2749
3322
  */
2750
 
  if (!(field_lens= (unsigned char*)sql_ex.init((char*)buf + body_offset,
 
3323
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
2751
3324
                                        buf_end,
2752
3325
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
2753
3326
    return(1);
2755
3328
  data_len = event_len - body_offset;
2756
3329
  if (num_fields > data_len) // simple sanity check against corruption
2757
3330
    return(1);
2758
 
  for (uint32_t i = 0; i < num_fields; i++)
 
3331
  for (uint i = 0; i < num_fields; i++)
2759
3332
    field_block_len += (uint)field_lens[i] + 1;
2760
3333
 
2761
3334
  fields = (char*)field_lens + num_fields;
2769
3342
}
2770
3343
 
2771
3344
 
 
3345
/*
 
3346
  Load_log_event::print()
 
3347
*/
 
3348
 
 
3349
#ifdef MYSQL_CLIENT
 
3350
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3351
{
 
3352
  print(file, print_event_info, 0);
 
3353
}
 
3354
 
 
3355
 
 
3356
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 
3357
                           bool commented)
 
3358
{
 
3359
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
3360
 
 
3361
  if (!print_event_info->short_form)
 
3362
  {
 
3363
    print_header(&cache, print_event_info, false);
 
3364
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 
3365
                thread_id, exec_time);
 
3366
  }
 
3367
 
 
3368
  bool different_db= 1;
 
3369
  if (db)
 
3370
  {
 
3371
    /*
 
3372
      If the database is different from the one of the previous statement, we
 
3373
      need to print the "use" command, and we update the last_db.
 
3374
      But if commented, the "use" is going to be commented so we should not
 
3375
      update the last_db.
 
3376
    */
 
3377
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
 
3378
        !commented)
 
3379
      memcpy(print_event_info->db, db, db_len + 1);
 
3380
  }
 
3381
  
 
3382
  if (db && db[0] && different_db)
 
3383
    my_b_printf(&cache, "%suse %s%s\n", 
 
3384
            commented ? "# " : "",
 
3385
            db, print_event_info->delimiter);
 
3386
 
 
3387
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
 
3388
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
 
3389
            commented ? "# " : "", (ulong)thread_id,
 
3390
            print_event_info->delimiter);
 
3391
  my_b_printf(&cache, "%sLOAD DATA ",
 
3392
              commented ? "# " : "");
 
3393
  if (check_fname_outside_temp_buf())
 
3394
    my_b_printf(&cache, "LOCAL ");
 
3395
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
 
3396
 
 
3397
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3398
    my_b_printf(&cache," REPLACE ");
 
3399
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3400
    my_b_printf(&cache," IGNORE ");
 
3401
  
 
3402
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
 
3403
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
 
3404
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
 
3405
 
 
3406
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3407
    my_b_printf(&cache," OPTIONALLY ");
 
3408
  my_b_printf(&cache, " ENCLOSED BY ");
 
3409
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
 
3410
     
 
3411
  my_b_printf(&cache, " ESCAPED BY ");
 
3412
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
 
3413
     
 
3414
  my_b_printf(&cache," LINES TERMINATED BY ");
 
3415
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
 
3416
 
 
3417
 
 
3418
  if (sql_ex.line_start)
 
3419
  {
 
3420
    my_b_printf(&cache," STARTING BY ");
 
3421
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
 
3422
  }
 
3423
  if ((long) skip_lines > 0)
 
3424
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
 
3425
 
 
3426
  if (num_fields)
 
3427
  {
 
3428
    uint i;
 
3429
    const char* field = fields;
 
3430
    my_b_printf(&cache, " (");
 
3431
    for (i = 0; i < num_fields; i++)
 
3432
    {
 
3433
      if (i)
 
3434
        my_b_printf(&cache, ",");
 
3435
      my_b_printf(&cache, field);
 
3436
          
 
3437
      field += field_lens[i]  + 1;
 
3438
    }
 
3439
    my_b_printf(&cache, ")");
 
3440
  }
 
3441
 
 
3442
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
 
3443
  return;
 
3444
}
 
3445
#endif /* MYSQL_CLIENT */
 
3446
 
 
3447
#ifndef MYSQL_CLIENT
 
3448
 
2772
3449
/**
2773
3450
  Load_log_event::set_fields()
2774
3451
 
2783
3460
                                List<Item> &field_list,
2784
3461
                                Name_resolution_context *context)
2785
3462
{
2786
 
  uint32_t i;
 
3463
  uint i;
2787
3464
  const char* field = fields;
2788
3465
  for (i= 0; i < num_fields; i++)
2789
3466
  {
2792
3469
    field+= field_lens[i]  + 1;
2793
3470
  }
2794
3471
}
2795
 
 
2796
 
 
 
3472
#endif /* !MYSQL_CLIENT */
 
3473
 
 
3474
 
 
3475
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2797
3476
/**
2798
3477
  Does the data loading job when executing a LOAD DATA on the slave.
2799
3478
 
2879
3558
  if (rpl_filter->db_ok(thd->db))
2880
3559
  {
2881
3560
    thd->set_time((time_t)when);
2882
 
    pthread_mutex_lock(&LOCK_thread_count);
 
3561
    VOID(pthread_mutex_lock(&LOCK_thread_count));
2883
3562
    thd->query_id = next_query_id();
2884
 
    pthread_mutex_unlock(&LOCK_thread_count);
 
3563
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
2885
3564
    /*
2886
3565
      Initing thd->row_count is not necessary in theory as this variable has no
2887
3566
      influence in the case of the slave SQL thread (it is used to generate a
2890
3569
    */
2891
3570
    drizzle_reset_errors(thd, 0);
2892
3571
 
2893
 
    TableList tables;
 
3572
    TABLE_LIST tables;
2894
3573
    memset(&tables, 0, sizeof(tables));
2895
3574
    tables.db= thd->strmake(thd->db, thd->db_length);
2896
3575
    tables.alias = tables.table_name = (char*) table_name;
3009
3688
      if (thd->cuted_fields)
3010
3689
      {
3011
3690
        /* 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 "
 
3691
        sql_print_warning("Slave: load data infile on table '%s' at "
3013
3692
                          "log position %s in log '%s' produced %ld "
3014
 
                          "warning(s). Default database: '%s'"),
 
3693
                          "warning(s). Default database: '%s'",
3015
3694
                          (char*) table_name,
3016
3695
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
3017
3696
                          (ulong) thd->cuted_fields,
3035
3714
error:
3036
3715
  thd->net.vio = 0; 
3037
3716
  const char *remember_db= thd->db;
3038
 
  pthread_mutex_lock(&LOCK_thread_count);
 
3717
  VOID(pthread_mutex_lock(&LOCK_thread_count));
3039
3718
  thd->catalog= 0;
3040
3719
  thd->set_db(NULL, 0);                   /* will free the current database */
3041
3720
  thd->query= 0;
3042
3721
  thd->query_length= 0;
3043
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
3722
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
3044
3723
  close_thread_tables(thd);
3045
3724
 
3046
3725
  if (thd->is_slave_error)
3056
3735
    else
3057
3736
    {
3058
3737
      sql_errno=ER_UNKNOWN_ERROR;
3059
 
      err=ER(sql_errno);
 
3738
      err=ER(sql_errno);       
3060
3739
    }
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));
 
3740
    rli->report(ERROR_LEVEL, sql_errno,"\
 
3741
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
 
3742
                    err, (char*)table_name, print_slave_db_safe(remember_db));
3065
3743
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
3066
3744
    return 1;
3067
3745
  }
3071
3749
  {
3072
3750
    char buf[256];
3073
3751
    snprintf(buf, sizeof(buf),
3074
 
             _("Running LOAD DATA INFILE on table '%-.64s'."
3075
 
               " Default database: '%-.64s'"),
 
3752
             "Running LOAD DATA INFILE on table '%-.64s'."
 
3753
             " Default database: '%-.64s'",
3076
3754
             (char*)table_name,
3077
3755
             print_slave_db_safe(remember_db));
3078
3756
 
3081
3759
    return 1;
3082
3760
  }
3083
3761
 
3084
 
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
 
3762
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
3085
3763
}
 
3764
#endif
3086
3765
 
3087
3766
 
3088
3767
/**************************************************************************
3093
3772
  Rotate_log_event::pack_info()
3094
3773
*/
3095
3774
 
 
3775
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3096
3776
void Rotate_log_event::pack_info(Protocol *protocol)
3097
3777
{
3098
3778
  char buf1[256], buf[22];
3103
3783
  tmp.append(llstr(pos,buf));
3104
3784
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3105
3785
}
 
3786
#endif
 
3787
 
 
3788
 
 
3789
/*
 
3790
  Rotate_log_event::print()
 
3791
*/
 
3792
 
 
3793
#ifdef MYSQL_CLIENT
 
3794
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3795
{
 
3796
  char buf[22];
 
3797
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
3798
                               Write_on_release_cache::FLUSH_F);
 
3799
 
 
3800
  if (print_event_info->short_form)
 
3801
    return;
 
3802
  print_header(&cache, print_event_info, false);
 
3803
  my_b_printf(&cache, "\tRotate to ");
 
3804
  if (new_log_ident)
 
3805
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
 
3806
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
 
3807
}
 
3808
#endif /* MYSQL_CLIENT */
 
3809
 
3106
3810
 
3107
3811
 
3108
3812
/*
3110
3814
*/
3111
3815
 
3112
3816
 
 
3817
#ifndef MYSQL_CLIENT
3113
3818
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)
 
3819
                                   uint ident_len_arg, uint64_t pos_arg,
 
3820
                                   uint flags_arg)
3116
3821
  :Log_event(), new_log_ident(new_log_ident_arg),
3117
3822
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3118
3823
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
3121
3826
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
3122
3827
  return;
3123
3828
}
3124
 
 
3125
 
 
3126
 
Rotate_log_event::Rotate_log_event(const char* buf, uint32_t event_len,
 
3829
#endif
 
3830
 
 
3831
 
 
3832
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
3127
3833
                                   const Format_description_log_event* description_event)
3128
3834
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
3129
3835
{
3130
3836
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
3131
3837
  uint8_t header_size= description_event->common_header_len;
3132
3838
  uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
3133
 
  uint32_t ident_offset;
 
3839
  uint ident_offset;
3134
3840
  if (event_len < header_size)
3135
3841
    return;
3136
3842
  buf += header_size;
3148
3854
  Rotate_log_event::write()
3149
3855
*/
3150
3856
 
 
3857
#ifndef MYSQL_CLIENT
3151
3858
bool Rotate_log_event::write(IO_CACHE* file)
3152
3859
{
3153
3860
  char buf[ROTATE_HEADER_LEN];
3154
3861
  int8store(buf + R_POS_OFFSET, pos);
3155
3862
  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));
 
3863
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
 
3864
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
3158
3865
}
3159
 
 
 
3866
#endif
 
3867
 
 
3868
 
 
3869
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3160
3870
 
3161
3871
/*
3162
3872
  Got a rotate log event from the master.
3194
3904
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3195
3905
      !rli->is_in_group())
3196
3906
  {
3197
 
    rli->group_master_log_name.assign(new_log_ident, ident_len+1);
 
3907
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3198
3908
    rli->notify_group_master_log_name_update();
3199
3909
    rli->group_master_log_pos= pos;
3200
 
    rli->group_relay_log_name.assign(rli->event_relay_log_name);
 
3910
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
 
3911
            sizeof(rli->group_relay_log_name) - 1);
3201
3912
    rli->notify_group_relay_log_name_update();
3202
3913
    rli->group_relay_log_pos= rli->event_relay_log_pos;
3203
3914
    /*
3208
3919
      master is 4.0 then the events are in the slave's format (conversion).
3209
3920
    */
3210
3921
    set_slave_thread_options(thd);
 
3922
    set_slave_thread_default_charset(thd, rli);
3211
3923
    thd->variables.auto_increment_increment=
3212
3924
      thd->variables.auto_increment_offset= 1;
3213
3925
  }
3236
3948
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
3237
3949
}
3238
3950
 
 
3951
#endif
 
3952
 
3239
3953
 
3240
3954
/**************************************************************************
3241
3955
        Intvar_log_event methods
3245
3959
  Intvar_log_event::pack_info()
3246
3960
*/
3247
3961
 
 
3962
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3248
3963
void Intvar_log_event::pack_info(Protocol *protocol)
3249
3964
{
3250
3965
  char buf[256], *pos;
3253
3968
  pos= int64_t10_to_str(val, pos, -10);
3254
3969
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3255
3970
}
 
3971
#endif
3256
3972
 
3257
3973
 
3258
3974
/*
3287
4003
  Intvar_log_event::write()
3288
4004
*/
3289
4005
 
 
4006
#ifndef MYSQL_CLIENT
3290
4007
bool Intvar_log_event::write(IO_CACHE* file)
3291
4008
{
3292
 
  unsigned char buf[9];
3293
 
  buf[I_TYPE_OFFSET]= (unsigned char) type;
 
4009
  uchar buf[9];
 
4010
  buf[I_TYPE_OFFSET]= (uchar) type;
3294
4011
  int8store(buf + I_VAL_OFFSET, val);
3295
4012
  return (write_header(file, sizeof(buf)) ||
3296
4013
          my_b_safe_write(file, buf, sizeof(buf)));
3297
4014
}
 
4015
#endif
3298
4016
 
3299
4017
 
3300
4018
/*
3301
4019
  Intvar_log_event::print()
3302
4020
*/
3303
4021
 
 
4022
#ifdef MYSQL_CLIENT
 
4023
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4024
{
 
4025
  char llbuff[22];
 
4026
  const char *msg;
 
4027
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4028
                               Write_on_release_cache::FLUSH_F);
 
4029
 
 
4030
  if (!print_event_info->short_form)
 
4031
  {
 
4032
    print_header(&cache, print_event_info, false);
 
4033
    my_b_printf(&cache, "\tIntvar\n");
 
4034
  }
 
4035
 
 
4036
  my_b_printf(&cache, "SET ");
 
4037
  switch (type) {
 
4038
  case LAST_INSERT_ID_EVENT:
 
4039
    msg="LAST_INSERT_ID";
 
4040
    break;
 
4041
  case INSERT_ID_EVENT:
 
4042
    msg="INSERT_ID";
 
4043
    break;
 
4044
  case INVALID_INT_EVENT:
 
4045
  default: // cannot happen
 
4046
    msg="INVALID_INT";
 
4047
    break;
 
4048
  }
 
4049
  my_b_printf(&cache, "%s=%s%s\n",
 
4050
              msg, llstr(val,llbuff), print_event_info->delimiter);
 
4051
}
 
4052
#endif
 
4053
 
 
4054
 
3304
4055
/*
3305
4056
  Intvar_log_event::do_apply_event()
3306
4057
*/
3307
4058
 
 
4059
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
3308
4060
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
3309
4061
{
3310
4062
  /*
3346
4098
  return continue_group(rli);
3347
4099
}
3348
4100
 
 
4101
#endif
 
4102
 
3349
4103
 
3350
4104
/**************************************************************************
3351
4105
  Rand_log_event methods
3352
4106
**************************************************************************/
3353
4107
 
 
4108
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3354
4109
void Rand_log_event::pack_info(Protocol *protocol)
3355
4110
{
3356
4111
  char buf1[256], *pos;
3357
 
  pos= my_stpcpy(buf1,"rand_seed1=");
 
4112
  pos= strmov(buf1,"rand_seed1=");
3358
4113
  pos= int10_to_str((long) seed1, pos, 10);
3359
 
  pos= my_stpcpy(pos, ",rand_seed2=");
 
4114
  pos= strmov(pos, ",rand_seed2=");
3360
4115
  pos= int10_to_str((long) seed2, pos, 10);
3361
4116
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
3362
4117
}
 
4118
#endif
3363
4119
 
3364
4120
 
3365
4121
Rand_log_event::Rand_log_event(const char* buf,
3372
4128
}
3373
4129
 
3374
4130
 
 
4131
#ifndef MYSQL_CLIENT
3375
4132
bool Rand_log_event::write(IO_CACHE* file)
3376
4133
{
3377
 
  unsigned char buf[16];
 
4134
  uchar buf[16];
3378
4135
  int8store(buf + RAND_SEED1_OFFSET, seed1);
3379
4136
  int8store(buf + RAND_SEED2_OFFSET, seed2);
3380
4137
  return (write_header(file, sizeof(buf)) ||
3381
4138
          my_b_safe_write(file, buf, sizeof(buf)));
3382
4139
}
3383
 
 
3384
 
 
 
4140
#endif
 
4141
 
 
4142
 
 
4143
#ifdef MYSQL_CLIENT
 
4144
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4145
{
 
4146
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4147
                               Write_on_release_cache::FLUSH_F);
 
4148
 
 
4149
  char llbuff[22],llbuff2[22];
 
4150
  if (!print_event_info->short_form)
 
4151
  {
 
4152
    print_header(&cache, print_event_info, false);
 
4153
    my_b_printf(&cache, "\tRand\n");
 
4154
  }
 
4155
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
 
4156
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
 
4157
              print_event_info->delimiter);
 
4158
}
 
4159
#endif /* MYSQL_CLIENT */
 
4160
 
 
4161
 
 
4162
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3385
4163
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
3386
4164
{
3387
4165
  /*
3416
4194
  return continue_group(rli);
3417
4195
}
3418
4196
 
 
4197
#endif /* !MYSQL_CLIENT */
 
4198
 
3419
4199
 
3420
4200
/**************************************************************************
3421
4201
  Xid_log_event methods
3422
4202
**************************************************************************/
3423
4203
 
 
4204
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3424
4205
void Xid_log_event::pack_info(Protocol *protocol)
3425
4206
{
3426
4207
  char buf[128], *pos;
3427
 
  pos= my_stpcpy(buf, "COMMIT /* xid=");
 
4208
  pos= strmov(buf, "COMMIT /* xid=");
3428
4209
  pos= int64_t10_to_str(xid, pos, 10);
3429
 
  pos= my_stpcpy(pos, " */");
 
4210
  pos= strmov(pos, " */");
3430
4211
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3431
4212
}
 
4213
#endif
3432
4214
 
3433
4215
/**
3434
4216
  @note
3449
4231
}
3450
4232
 
3451
4233
 
 
4234
#ifndef MYSQL_CLIENT
3452
4235
bool Xid_log_event::write(IO_CACHE* file)
3453
4236
{
3454
4237
  return write_header(file, sizeof(xid)) ||
3455
 
         my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
3456
 
}
3457
 
 
3458
 
 
 
4238
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
 
4239
}
 
4240
#endif
 
4241
 
 
4242
 
 
4243
#ifdef MYSQL_CLIENT
 
4244
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4245
{
 
4246
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4247
                               Write_on_release_cache::FLUSH_F);
 
4248
 
 
4249
  if (!print_event_info->short_form)
 
4250
  {
 
4251
    char buf[64];
 
4252
    int64_t10_to_str(xid, buf, 10);
 
4253
 
 
4254
    print_header(&cache, print_event_info, false);
 
4255
    my_b_printf(&cache, "\tXid = %s\n", buf);
 
4256
  }
 
4257
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
 
4258
}
 
4259
#endif /* MYSQL_CLIENT */
 
4260
 
 
4261
 
 
4262
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3459
4263
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
3460
4264
{
 
4265
  /* For a slave Xid_log_event is COMMIT */
 
4266
  general_log_print(thd, COM_QUERY,
 
4267
                    "COMMIT /* implicit, from Xid_log_event */");
3461
4268
  return end_trans(thd, COMMIT);
3462
4269
}
3463
4270
 
3470
4277
  }
3471
4278
  return(Log_event::do_shall_skip(rli));
3472
4279
}
 
4280
#endif /* !MYSQL_CLIENT */
3473
4281
 
3474
4282
 
3475
4283
/**************************************************************************
3476
4284
  User_var_log_event methods
3477
4285
**************************************************************************/
3478
4286
 
 
4287
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3479
4288
void User_var_log_event::pack_info(Protocol* protocol)
3480
4289
{
3481
4290
  char *buf= 0;
3482
 
  uint32_t val_offset= 4 + name_len;
3483
 
  uint32_t event_len= val_offset;
 
4291
  uint val_offset= 4 + name_len;
 
4292
  uint event_len= val_offset;
3484
4293
 
3485
4294
  if (is_null)
3486
4295
  {
3487
4296
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
3488
4297
      return;
3489
 
    my_stpcpy(buf + val_offset, "NULL");
 
4298
    strmov(buf + val_offset, "NULL");
3490
4299
    event_len= val_offset + 4;
3491
4300
  }
3492
4301
  else
3513
4322
        return;
3514
4323
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
3515
4324
      my_decimal dec;
3516
 
      binary2my_decimal(E_DEC_FATAL_ERROR, (unsigned char*) (val+2), &dec, val[0],
 
4325
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
3517
4326
                        val[1]);
3518
4327
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
3519
4328
      event_len= str.length() + val_offset;
3528
4337
        return;
3529
4338
      if (!(cs= get_charset(charset_number, MYF(0))))
3530
4339
      {
3531
 
        my_stpcpy(buf+val_offset, "???");
 
4340
        strmov(buf+val_offset, "???");
3532
4341
        event_len+= 3;
3533
4342
      }
3534
4343
      else
3535
4344
      {
3536
 
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NULL);
 
4345
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
3537
4346
        p= str_to_hex(p, val, val_len);
3538
 
        p= strxmov(p, " COLLATE ", cs->name, NULL);
 
4347
        p= strxmov(p, " COLLATE ", cs->name, NullS);
3539
4348
        event_len= p-buf;
3540
4349
      }
3541
4350
      break;
3551
4360
  buf[2+name_len]= '`';
3552
4361
  buf[3+name_len]= '=';
3553
4362
  protocol->store(buf, event_len, &my_charset_bin);
3554
 
  free(buf);
 
4363
  my_free(buf, MYF(0));
3555
4364
}
 
4365
#endif /* !MYSQL_CLIENT */
3556
4366
 
3557
4367
 
3558
4368
User_var_log_event::
3584
4394
}
3585
4395
 
3586
4396
 
 
4397
#ifndef MYSQL_CLIENT
3587
4398
bool User_var_log_event::write(IO_CACHE* file)
3588
4399
{
3589
4400
  char buf[UV_NAME_LEN_SIZE];
3590
4401
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
3591
4402
            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;
 
4403
  uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
 
4404
  uint buf1_length;
3594
4405
  ulong event_length;
3595
4406
 
3596
4407
  int4store(buf, name_len);
3623
4434
      break;
3624
4435
    }
3625
4436
    case STRING_RESULT:
3626
 
      pos= (unsigned char*) val;
 
4437
      pos= (uchar*) val;
3627
4438
      break;
3628
4439
    case ROW_RESULT:
3629
4440
    default:
3638
4449
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
3639
4450
 
3640
4451
  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) ||
 
4452
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
 
4453
          my_b_safe_write(file, (uchar*) name, name_len)     ||
 
4454
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
3644
4455
          my_b_safe_write(file, pos, val_len));
3645
4456
}
3646
 
 
 
4457
#endif
 
4458
 
 
4459
 
 
4460
/*
 
4461
  User_var_log_event::print()
 
4462
*/
 
4463
 
 
4464
#ifdef MYSQL_CLIENT
 
4465
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4466
{
 
4467
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4468
                               Write_on_release_cache::FLUSH_F);
 
4469
 
 
4470
  if (!print_event_info->short_form)
 
4471
  {
 
4472
    print_header(&cache, print_event_info, false);
 
4473
    my_b_printf(&cache, "\tUser_var\n");
 
4474
  }
 
4475
 
 
4476
  my_b_printf(&cache, "SET @`");
 
4477
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
 
4478
  my_b_printf(&cache, "`");
 
4479
 
 
4480
  if (is_null)
 
4481
  {
 
4482
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
 
4483
  }
 
4484
  else
 
4485
  {
 
4486
    switch (type) {
 
4487
    case REAL_RESULT:
 
4488
      double real_val;
 
4489
      char real_buf[FMT_G_BUFSIZE(14)];
 
4490
      float8get(real_val, val);
 
4491
      sprintf(real_buf, "%.14g", real_val);
 
4492
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
 
4493
      break;
 
4494
    case INT_RESULT:
 
4495
      char int_buf[22];
 
4496
      int64_t10_to_str(uint8korr(val), int_buf, -10);
 
4497
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
 
4498
      break;
 
4499
    case DECIMAL_RESULT:
 
4500
    {
 
4501
      char str_buf[200];
 
4502
      int str_len= sizeof(str_buf) - 1;
 
4503
      int precision= (int)val[0];
 
4504
      int scale= (int)val[1];
 
4505
      decimal_digit_t dec_buf[10];
 
4506
      decimal_t dec;
 
4507
      dec.len= 10;
 
4508
      dec.buf= dec_buf;
 
4509
 
 
4510
      bin2decimal((uchar*) val+2, &dec, precision, scale);
 
4511
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
 
4512
      str_buf[str_len]= 0;
 
4513
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
 
4514
      break;
 
4515
    }
 
4516
    case STRING_RESULT:
 
4517
    {
 
4518
      /*
 
4519
        Let's express the string in hex. That's the most robust way. If we
 
4520
        print it in character form instead, we need to escape it with
 
4521
        character_set_client which we don't know (we will know it in 5.0, but
 
4522
        in 4.1 we don't know it easily when we are printing
 
4523
        User_var_log_event). Explanation why we would need to bother with
 
4524
        character_set_client (quoting Bar):
 
4525
        > Note, the parser doesn't switch to another unescaping mode after
 
4526
        > it has met a character set introducer.
 
4527
        > For example, if an SJIS client says something like:
 
4528
        > SET @a= _ucs2 \0a\0b'
 
4529
        > the string constant is still unescaped according to SJIS, not
 
4530
        > according to UCS2.
 
4531
      */
 
4532
      char *hex_str;
 
4533
      const CHARSET_INFO *cs;
 
4534
 
 
4535
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
 
4536
        break; // no error, as we are 'void'
 
4537
      str_to_hex(hex_str, val, val_len);
 
4538
      /*
 
4539
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
 
4540
        specify the variable's collation. It will however cause problems when
 
4541
        people want to mysqlbinlog|mysql into another server not supporting the
 
4542
        character set. But there's not much to do about this and it's unlikely.
 
4543
      */
 
4544
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4545
        /*
 
4546
          Generate an unusable command (=> syntax error) is probably the best
 
4547
          thing we can do here.
 
4548
        */
 
4549
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
 
4550
      else
 
4551
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
 
4552
                    cs->csname, hex_str, cs->name,
 
4553
                    print_event_info->delimiter);
 
4554
      my_afree(hex_str);
 
4555
    }
 
4556
      break;
 
4557
    case ROW_RESULT:
 
4558
    default:
 
4559
      assert(1);
 
4560
      return;
 
4561
    }
 
4562
  }
 
4563
}
 
4564
#endif
3647
4565
 
3648
4566
 
3649
4567
/*
3650
4568
  User_var_log_event::do_apply_event()
3651
4569
*/
3652
4570
 
 
4571
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3653
4572
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
3654
4573
{
3655
4574
  Item *it= 0;
3689
4608
      break;
3690
4609
    case DECIMAL_RESULT:
3691
4610
    {
3692
 
      Item_decimal *dec= new Item_decimal((unsigned char*) val+2, val[0], val[1]);
 
4611
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
3693
4612
      it= dec;
3694
4613
      val= (char *)dec->val_decimal(NULL);
3695
4614
      val_len= sizeof(my_decimal);
3740
4659
  */
3741
4660
  return continue_group(rli);
3742
4661
}
 
4662
#endif /* !MYSQL_CLIENT */
3743
4663
 
3744
4664
 
3745
4665
/**************************************************************************
3746
4666
  Slave_log_event methods
3747
4667
**************************************************************************/
3748
4668
 
 
4669
#ifdef HAVE_REPLICATION
 
4670
#ifdef MYSQL_CLIENT
 
4671
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
 
4672
{
 
4673
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
4674
 
 
4675
  if (print_event_info->short_form)
 
4676
    return;
 
4677
  print_header(&cache, print_event_info, false);
 
4678
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
 
4679
}
 
4680
#endif  
 
4681
 
 
4682
#ifndef MYSQL_CLIENT
3749
4683
void Slave_log_event::pack_info(Protocol *protocol)
3750
4684
{
3751
4685
  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=");
 
4686
  pos= strmov(buf, "host=");
 
4687
  pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
 
4688
  pos= strmov(pos, ",port=");
3755
4689
  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=");
 
4690
  pos= strmov(pos, ",log=");
 
4691
  pos= strmov(pos, master_log);
 
4692
  pos= strmov(pos, ",pos=");
3759
4693
  pos= int64_t10_to_str(master_pos, pos, 10);
3760
4694
  protocol->store(buf, pos-buf, &my_charset_bin);
3761
4695
}
3762
 
 
3763
 
 
 
4696
#endif /* !MYSQL_CLIENT */
 
4697
 
 
4698
 
 
4699
#ifndef MYSQL_CLIENT
3764
4700
/**
3765
4701
  @todo
3766
4702
  re-write this better without holding both locks at the same time
3776
4712
  // TODO: re-write this better without holding both locks at the same time
3777
4713
  pthread_mutex_lock(&mi->data_lock);
3778
4714
  pthread_mutex_lock(&rli->data_lock);
 
4715
  master_host_len = strlen(mi->host);
 
4716
  master_log_len = strlen(rli->group_master_log_name);
3779
4717
  // on OOM, just do not initialize the structure and print the error
3780
4718
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
3781
4719
                                   MYF(MY_WME))))
3782
4720
  {
3783
 
    master_host.assign(mi->getHostname());
3784
 
    master_log.assign(rli->group_master_log_name);
3785
 
    master_port = mi->getPort();
 
4721
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
 
4722
    memcpy(master_host, mi->host, master_host_len + 1);
 
4723
    master_log = master_host + master_host_len + 1;
 
4724
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
 
4725
    master_port = mi->port;
3786
4726
    master_pos = rli->group_master_log_pos;
3787
4727
  }
3788
4728
  else
3789
 
    sql_print_error(_("Out of memory while recording slave event"));
 
4729
    sql_print_error("Out of memory while recording slave event");
3790
4730
  pthread_mutex_unlock(&rli->data_lock);
3791
4731
  pthread_mutex_unlock(&mi->data_lock);
3792
4732
  return;
3793
4733
}
 
4734
#endif /* !MYSQL_CLIENT */
3794
4735
 
3795
4736
 
3796
4737
Slave_log_event::~Slave_log_event()
3797
4738
{
3798
 
  free(mem_pool);
3799
 
}
 
4739
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 
4740
}
 
4741
 
 
4742
 
 
4743
#ifdef MYSQL_CLIENT
 
4744
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4745
{
 
4746
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
4747
 
 
4748
  char llbuff[22];
 
4749
  if (print_event_info->short_form)
 
4750
    return;
 
4751
  print_header(&cache, print_event_info, false);
 
4752
  my_b_printf(&cache, "\n\
 
4753
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 
4754
          master_host, master_port, master_log, llstr(master_pos, llbuff));
 
4755
}
 
4756
#endif /* MYSQL_CLIENT */
3800
4757
 
3801
4758
 
3802
4759
int Slave_log_event::get_data_size()
3803
4760
{
3804
 
  return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
 
4761
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
3805
4762
}
3806
4763
 
3807
4764
 
 
4765
#ifndef MYSQL_CLIENT
3808
4766
bool Slave_log_event::write(IO_CACHE* file)
3809
4767
{
3810
4768
  ulong event_length= get_data_size();
3813
4771
  // log and host are already there
3814
4772
 
3815
4773
  return (write_header(file, event_length) ||
3816
 
          my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
 
4774
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
3817
4775
}
3818
 
 
3819
 
 
3820
 
void Slave_log_event::init_from_mem_pool()
 
4776
#endif
 
4777
 
 
4778
 
 
4779
void Slave_log_event::init_from_mem_pool(int data_size)
3821
4780
{
3822
4781
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
3823
4782
  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
 
 
 
4783
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
 
4784
  master_host_len = strlen(master_host);
 
4785
  // safety
 
4786
  master_log = master_host + master_host_len + 1;
 
4787
  if (master_log > mem_pool + data_size)
 
4788
  {
 
4789
    master_host = 0;
 
4790
    return;
 
4791
  }
 
4792
  master_log_len = strlen(master_log);
 
4793
}
 
4794
 
 
4795
 
 
4796
/** This code is not used, so has not been updated to be format-tolerant. */
 
4797
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
 
4798
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
 
4799
{
 
4800
  if (event_len < LOG_EVENT_HEADER_LEN)
 
4801
    return;
 
4802
  event_len -= LOG_EVENT_HEADER_LEN;
 
4803
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
 
4804
    return;
 
4805
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
 
4806
  mem_pool[event_len] = 0;
 
4807
  init_from_mem_pool(event_len);
 
4808
}
 
4809
 
 
4810
 
 
4811
#ifndef MYSQL_CLIENT
3832
4812
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
3833
4813
{
3834
4814
  if (mysql_bin_log.is_open())
3835
4815
    mysql_bin_log.write(this);
3836
4816
  return 0;
3837
4817
}
 
4818
#endif /* !MYSQL_CLIENT */
3838
4819
 
3839
4820
 
3840
4821
/**************************************************************************
3842
4823
**************************************************************************/
3843
4824
 
3844
4825
/*
 
4826
  Stop_log_event::print()
 
4827
*/
 
4828
 
 
4829
#ifdef MYSQL_CLIENT
 
4830
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4831
{
 
4832
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4833
                               Write_on_release_cache::FLUSH_F);
 
4834
 
 
4835
  if (print_event_info->short_form)
 
4836
    return;
 
4837
 
 
4838
  print_header(&cache, print_event_info, false);
 
4839
  my_b_printf(&cache, "\tStop\n");
 
4840
}
 
4841
#endif /* MYSQL_CLIENT */
 
4842
 
 
4843
 
 
4844
#ifndef MYSQL_CLIENT
 
4845
/*
3845
4846
  The master stopped.  We used to clean up all temporary tables but
3846
4847
  this is useless as, as the master has shut down properly, it has
3847
 
  written all DROP TEMPORARY Table (prepared statements' deletion is
 
4848
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
3848
4849
  TODO only when we binlog prep stmts).  We used to clean up
3849
4850
  slave_load_tmpdir, but this is useless as it has been cleared at the
3850
4851
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
3871
4872
  return 0;
3872
4873
}
3873
4874
 
 
4875
#endif /* !MYSQL_CLIENT */
 
4876
#endif /* HAVE_REPLICATION */
 
4877
 
3874
4878
 
3875
4879
/**************************************************************************
3876
4880
        Create_file_log_event methods
3880
4884
  Create_file_log_event ctor
3881
4885
*/
3882
4886
 
 
4887
#ifndef MYSQL_CLIENT
3883
4888
Create_file_log_event::
3884
4889
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3885
4890
                      const char* db_arg, const char* table_name_arg,
3886
4891
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
3887
4892
                      bool ignore,
3888
 
                      unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
 
4893
                      uchar* block_arg, uint block_len_arg, bool using_trans)
3889
4894
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3890
4895
                  using_trans),
3891
4896
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3905
4910
  bool res;
3906
4911
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
3907
4912
    return res;
3908
 
  return (my_b_safe_write(file, (unsigned char*) "", 1) ||
3909
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
 
4913
  return (my_b_safe_write(file, (uchar*) "", 1) ||
 
4914
          my_b_safe_write(file, (uchar*) block, block_len));
3910
4915
}
3911
4916
 
3912
4917
 
3917
4922
bool Create_file_log_event::write_data_header(IO_CACHE* file)
3918
4923
{
3919
4924
  bool res;
3920
 
  unsigned char buf[CREATE_FILE_HEADER_LEN];
 
4925
  uchar buf[CREATE_FILE_HEADER_LEN];
3921
4926
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
3922
4927
    return res;
3923
4928
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
3938
4943
  return res;
3939
4944
}
3940
4945
 
 
4946
#endif /* !MYSQL_CLIENT */
 
4947
 
3941
4948
/*
3942
4949
  Create_file_log_event ctor
3943
4950
*/
3944
4951
 
3945
 
Create_file_log_event::Create_file_log_event(const char* buf, uint32_t len,
 
4952
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
3946
4953
                                             const Format_description_log_event* description_event)
3947
4954
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
3948
4955
{
3949
 
  uint32_t block_offset;
3950
 
  uint32_t header_len= description_event->common_header_len;
 
4956
  uint block_offset;
 
4957
  uint header_len= description_event->common_header_len;
3951
4958
  uint8_t load_header_len= description_event->post_header_len[LOAD_EVENT-1];
3952
4959
  uint8_t create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
3953
4960
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
3980
4987
                   create_file_header_len + 1);
3981
4988
    if (len < block_offset)
3982
4989
      return;
3983
 
    block = (unsigned char*)buf + block_offset;
 
4990
    block = (uchar*)buf + block_offset;
3984
4991
    block_len = len - block_offset;
3985
4992
  }
3986
4993
  else
3993
5000
 
3994
5001
 
3995
5002
/*
 
5003
  Create_file_log_event::print()
 
5004
*/
 
5005
 
 
5006
#ifdef MYSQL_CLIENT
 
5007
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
 
5008
                                  bool enable_local)
 
5009
{
 
5010
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5011
 
 
5012
  if (print_event_info->short_form)
 
5013
  {
 
5014
    if (enable_local && check_fname_outside_temp_buf())
 
5015
      Load_log_event::print(file, print_event_info);
 
5016
    return;
 
5017
  }
 
5018
 
 
5019
  if (enable_local)
 
5020
  {
 
5021
    Load_log_event::print(file, print_event_info,
 
5022
                          !check_fname_outside_temp_buf());
 
5023
    /* 
 
5024
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
 
5025
       SHOW BINLOG EVENTS we don't.
 
5026
    */
 
5027
    my_b_printf(&cache, "#"); 
 
5028
  }
 
5029
 
 
5030
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
 
5031
}
 
5032
 
 
5033
 
 
5034
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5035
{
 
5036
  print(file, print_event_info, 0);
 
5037
}
 
5038
#endif /* MYSQL_CLIENT */
 
5039
 
 
5040
 
 
5041
/*
3996
5042
  Create_file_log_event::pack_info()
3997
5043
*/
3998
5044
 
 
5045
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3999
5046
void Create_file_log_event::pack_info(Protocol *protocol)
4000
5047
{
4001
5048
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
4002
 
  pos= my_stpcpy(buf, "db=");
 
5049
  pos= strmov(buf, "db=");
4003
5050
  memcpy(pos, db, db_len);
4004
 
  pos= my_stpcpy(pos + db_len, ";table=");
 
5051
  pos= strmov(pos + db_len, ";table=");
4005
5052
  memcpy(pos, table_name, table_name_len);
4006
 
  pos= my_stpcpy(pos + table_name_len, ";file_id=");
 
5053
  pos= strmov(pos + table_name_len, ";file_id=");
4007
5054
  pos= int10_to_str((long) file_id, pos, 10);
4008
 
  pos= my_stpcpy(pos, ";block_len=");
 
5055
  pos= strmov(pos, ";block_len=");
4009
5056
  pos= int10_to_str((long) block_len, pos, 10);
4010
5057
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4011
5058
}
 
5059
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4012
5060
 
4013
5061
 
4014
5062
/*
4015
5063
  Create_file_log_event::do_apply_event()
4016
5064
*/
4017
5065
 
 
5066
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4018
5067
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
4019
5068
{
4020
5069
  char proc_info[17+FN_REFLEN+10], *fname_buf;
4024
5073
  int error = 1;
4025
5074
 
4026
5075
  memset(&file, 0, sizeof(file));
4027
 
  fname_buf= my_stpcpy(proc_info, "Making temp file ");
 
5076
  fname_buf= strmov(proc_info, "Making temp file ");
4028
5077
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
4029
 
  thd->set_proc_info(proc_info);
 
5078
  thd_proc_info(thd, proc_info);
4030
5079
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4031
5080
  if ((fd= my_create(fname_buf, CREATE_MODE,
4032
 
                     O_WRONLY | O_EXCL,
 
5081
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4033
5082
                     MYF(MY_WME))) < 0 ||
4034
5083
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
4035
5084
                    MYF(MY_WME|MY_NABP)))
4036
5085
  {
4037
5086
    rli->report(ERROR_LEVEL, my_errno,
4038
 
                _("Error in Create_file event: could not open file '%s'"),
 
5087
                "Error in Create_file event: could not open file '%s'",
4039
5088
                fname_buf);
4040
5089
    goto err;
4041
5090
  }
4042
5091
  
4043
5092
  // a trick to avoid allocating another buffer
4044
5093
  fname= fname_buf;
4045
 
  fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
 
5094
  fname_len= (uint) (strmov(ext, ".data") - fname);
4046
5095
  if (write_base(&file))
4047
5096
  {
4048
 
    my_stpcpy(ext, ".info"); // to have it right in the error message
 
5097
    strmov(ext, ".info"); // to have it right in the error message
4049
5098
    rli->report(ERROR_LEVEL, my_errno,
4050
 
                _("Error in Create_file event: could not write to file '%s'"),
 
5099
                "Error in Create_file event: could not write to file '%s'",
4051
5100
                fname_buf);
4052
5101
    goto err;
4053
5102
  }
4054
5103
  end_io_cache(&file);
4055
5104
  my_close(fd, MYF(0));
4056
 
 
 
5105
  
4057
5106
  // fname_buf now already has .data, not .info, because we did our trick
4058
5107
  my_delete(fname_buf, MYF(0)); // old copy may exist already
4059
5108
  if ((fd= my_create(fname_buf, CREATE_MODE,
4060
 
                     O_WRONLY | O_EXCL,
4061
 
                     MYF(MY_WME))) < 0)
 
5109
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5110
                     MYF(MY_WME))) < 0)
4062
5111
  {
4063
5112
    rli->report(ERROR_LEVEL, my_errno,
4064
 
                _("Error in Create_file event: could not open file '%s'"),
 
5113
                "Error in Create_file event: could not open file '%s'",
4065
5114
                fname_buf);
4066
5115
    goto err;
4067
5116
  }
4068
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5117
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4069
5118
  {
4070
5119
    rli->report(ERROR_LEVEL, my_errno,
4071
 
                _("Error in Create_file event: write to '%s' failed"),
 
5120
                "Error in Create_file event: write to '%s' failed",
4072
5121
                fname_buf);
4073
5122
    goto err;
4074
5123
  }
4079
5128
    end_io_cache(&file);
4080
5129
  if (fd >= 0)
4081
5130
    my_close(fd, MYF(0));
4082
 
  thd->set_proc_info(0);
 
5131
  thd_proc_info(thd, 0);
4083
5132
  return error == 0;
4084
5133
}
 
5134
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4085
5135
 
4086
5136
 
4087
5137
/**************************************************************************
4092
5142
  Append_block_log_event ctor
4093
5143
*/
4094
5144
 
 
5145
#ifndef MYSQL_CLIENT  
4095
5146
Append_block_log_event::Append_block_log_event(THD *thd_arg,
4096
5147
                                               const char *db_arg,
4097
 
                                               unsigned char *block_arg,
4098
 
                                               uint32_t block_len_arg,
 
5148
                                               uchar *block_arg,
 
5149
                                               uint block_len_arg,
4099
5150
                                               bool using_trans)
4100
5151
  :Log_event(thd_arg,0, using_trans), block(block_arg),
4101
5152
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
4102
5153
{
4103
5154
}
 
5155
#endif
4104
5156
 
4105
5157
 
4106
5158
/*
4107
5159
  Append_block_log_event ctor
4108
5160
*/
4109
5161
 
4110
 
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
 
5162
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
4111
5163
                                               const Format_description_log_event* description_event)
4112
5164
  :Log_event(buf, description_event),block(0)
4113
5165
{
4114
5166
  uint8_t common_header_len= description_event->common_header_len; 
4115
5167
  uint8_t append_block_header_len=
4116
5168
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
4117
 
  uint32_t total_header_len= common_header_len+append_block_header_len;
 
5169
  uint total_header_len= common_header_len+append_block_header_len;
4118
5170
  if (len < total_header_len)
4119
5171
    return;
4120
5172
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
4121
 
  block= (unsigned char*)buf + total_header_len;
 
5173
  block= (uchar*)buf + total_header_len;
4122
5174
  block_len= len - total_header_len;
4123
5175
  return;
4124
5176
}
4128
5180
  Append_block_log_event::write()
4129
5181
*/
4130
5182
 
 
5183
#ifndef MYSQL_CLIENT
4131
5184
bool Append_block_log_event::write(IO_CACHE* file)
4132
5185
{
4133
 
  unsigned char buf[APPEND_BLOCK_HEADER_LEN];
 
5186
  uchar buf[APPEND_BLOCK_HEADER_LEN];
4134
5187
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
4135
5188
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
4136
5189
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
4137
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
4138
 
}
 
5190
          my_b_safe_write(file, (uchar*) block, block_len));
 
5191
}
 
5192
#endif
 
5193
 
 
5194
 
 
5195
/*
 
5196
  Append_block_log_event::print()
 
5197
*/
 
5198
 
 
5199
#ifdef MYSQL_CLIENT  
 
5200
void Append_block_log_event::print(FILE* file,
 
5201
                                   PRINT_EVENT_INFO* print_event_info)
 
5202
{
 
5203
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5204
 
 
5205
  if (print_event_info->short_form)
 
5206
    return;
 
5207
  print_header(&cache, print_event_info, false);
 
5208
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
 
5209
              get_type_str(), file_id, block_len);
 
5210
}
 
5211
#endif /* MYSQL_CLIENT */
4139
5212
 
4140
5213
 
4141
5214
/*
4142
5215
  Append_block_log_event::pack_info()
4143
5216
*/
4144
5217
 
 
5218
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4145
5219
void Append_block_log_event::pack_info(Protocol *protocol)
4146
5220
{
4147
5221
  char buf[256];
4148
 
  uint32_t length;
 
5222
  uint length;
4149
5223
  length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
4150
5224
                             block_len);
4151
5225
  protocol->store(buf, length, &my_charset_bin);
4171
5245
  int fd;
4172
5246
  int error = 1;
4173
5247
 
4174
 
  fname= my_stpcpy(proc_info, "Making temp file ");
 
5248
  fname= strmov(proc_info, "Making temp file ");
4175
5249
  slave_load_file_stem(fname, file_id, server_id, ".data");
4176
 
  thd->set_proc_info(proc_info);
 
5250
  thd_proc_info(thd, proc_info);
4177
5251
  if (get_create_or_append())
4178
5252
  {
4179
5253
    my_delete(fname, MYF(0)); // old copy may exist already
4180
5254
    if ((fd= my_create(fname, CREATE_MODE,
4181
 
                       O_WRONLY | O_EXCL,
 
5255
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4182
5256
                       MYF(MY_WME))) < 0)
4183
5257
    {
4184
5258
      rli->report(ERROR_LEVEL, my_errno,
4185
 
                  _("Error in %s event: could not create file '%s'"),
 
5259
                  "Error in %s event: could not create file '%s'",
4186
5260
                  get_type_str(), fname);
4187
5261
      goto err;
4188
5262
    }
4189
5263
  }
4190
 
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
 
5264
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
4191
5265
                         MYF(MY_WME))) < 0)
4192
5266
  {
4193
5267
    rli->report(ERROR_LEVEL, my_errno,
4194
 
                _("Error in %s event: could not open file '%s'"),
 
5268
                "Error in %s event: could not open file '%s'",
4195
5269
                get_type_str(), fname);
4196
5270
    goto err;
4197
5271
  }
4198
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5272
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
4199
5273
  {
4200
5274
    rli->report(ERROR_LEVEL, my_errno,
4201
 
                _("Error in %s event: write to '%s' failed"),
 
5275
                "Error in %s event: write to '%s' failed",
4202
5276
                get_type_str(), fname);
4203
5277
    goto err;
4204
5278
  }
4207
5281
err:
4208
5282
  if (fd >= 0)
4209
5283
    my_close(fd, MYF(0));
4210
 
  thd->set_proc_info(0);
 
5284
  thd_proc_info(thd, 0);
4211
5285
  return(error);
4212
5286
}
 
5287
#endif
4213
5288
 
4214
5289
 
4215
5290
/**************************************************************************
4220
5295
  Delete_file_log_event ctor
4221
5296
*/
4222
5297
 
 
5298
#ifndef MYSQL_CLIENT
4223
5299
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
4224
5300
                                             bool using_trans)
4225
5301
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4226
5302
{
4227
5303
}
 
5304
#endif
4228
5305
 
4229
5306
/*
4230
5307
  Delete_file_log_event ctor
4231
5308
*/
4232
5309
 
4233
 
Delete_file_log_event::Delete_file_log_event(const char* buf, uint32_t len,
 
5310
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
4234
5311
                                             const Format_description_log_event* description_event)
4235
5312
  :Log_event(buf, description_event),file_id(0)
4236
5313
{
4246
5323
  Delete_file_log_event::write()
4247
5324
*/
4248
5325
 
 
5326
#ifndef MYSQL_CLIENT
4249
5327
bool Delete_file_log_event::write(IO_CACHE* file)
4250
5328
{
4251
 
 unsigned char buf[DELETE_FILE_HEADER_LEN];
 
5329
 uchar buf[DELETE_FILE_HEADER_LEN];
4252
5330
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
4253
5331
 return (write_header(file, sizeof(buf)) ||
4254
5332
         my_b_safe_write(file, buf, sizeof(buf)));
4255
5333
}
4256
 
 
 
5334
#endif
 
5335
 
 
5336
 
 
5337
/*
 
5338
  Delete_file_log_event::print()
 
5339
*/
 
5340
 
 
5341
#ifdef MYSQL_CLIENT  
 
5342
void Delete_file_log_event::print(FILE* file,
 
5343
                                  PRINT_EVENT_INFO* print_event_info)
 
5344
{
 
5345
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5346
 
 
5347
  if (print_event_info->short_form)
 
5348
    return;
 
5349
  print_header(&cache, print_event_info, false);
 
5350
  my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
 
5351
}
 
5352
#endif /* MYSQL_CLIENT */
4257
5353
 
4258
5354
/*
4259
5355
  Delete_file_log_event::pack_info()
4260
5356
*/
4261
5357
 
 
5358
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4262
5359
void Delete_file_log_event::pack_info(Protocol *protocol)
4263
5360
{
4264
5361
  char buf[64];
4265
 
  uint32_t length;
 
5362
  uint length;
4266
5363
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4267
5364
  protocol->store(buf, (int32_t) length, &my_charset_bin);
4268
5365
}
 
5366
#endif
4269
5367
 
4270
5368
/*
4271
5369
  Delete_file_log_event::do_apply_event()
4272
5370
*/
4273
5371
 
 
5372
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4274
5373
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4275
5374
{
4276
5375
  char fname[FN_REFLEN+10];
4277
5376
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
4278
5377
  (void) my_delete(fname, MYF(MY_WME));
4279
 
  my_stpcpy(ext, ".info");
 
5378
  strmov(ext, ".info");
4280
5379
  (void) my_delete(fname, MYF(MY_WME));
4281
5380
  return 0;
4282
5381
}
 
5382
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4283
5383
 
4284
5384
 
4285
5385
/**************************************************************************
4290
5390
  Execute_load_log_event ctor
4291
5391
*/
4292
5392
 
 
5393
#ifndef MYSQL_CLIENT  
4293
5394
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
4294
5395
                                               const char* db_arg,
4295
5396
                                               bool using_trans)
4296
5397
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4297
5398
{
4298
5399
}
 
5400
#endif
4299
5401
  
4300
5402
 
4301
5403
/*
4302
5404
  Execute_load_log_event ctor
4303
5405
*/
4304
5406
 
4305
 
Execute_load_log_event::Execute_load_log_event(const char* buf, uint32_t len,
 
5407
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
4306
5408
                                               const Format_description_log_event* description_event)
4307
5409
  :Log_event(buf, description_event), file_id(0)
4308
5410
{
4318
5420
  Execute_load_log_event::write()
4319
5421
*/
4320
5422
 
 
5423
#ifndef MYSQL_CLIENT
4321
5424
bool Execute_load_log_event::write(IO_CACHE* file)
4322
5425
{
4323
 
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
 
5426
  uchar buf[EXEC_LOAD_HEADER_LEN];
4324
5427
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
4325
5428
  return (write_header(file, sizeof(buf)) || 
4326
5429
          my_b_safe_write(file, buf, sizeof(buf)));
4327
5430
}
4328
 
 
 
5431
#endif
 
5432
 
 
5433
 
 
5434
/*
 
5435
  Execute_load_log_event::print()
 
5436
*/
 
5437
 
 
5438
#ifdef MYSQL_CLIENT  
 
5439
void Execute_load_log_event::print(FILE* file,
 
5440
                                   PRINT_EVENT_INFO* print_event_info)
 
5441
{
 
5442
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5443
 
 
5444
  if (print_event_info->short_form)
 
5445
    return;
 
5446
  print_header(&cache, print_event_info, false);
 
5447
  my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
 
5448
              file_id);
 
5449
}
 
5450
#endif
4329
5451
 
4330
5452
/*
4331
5453
  Execute_load_log_event::pack_info()
4332
5454
*/
4333
5455
 
 
5456
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4334
5457
void Execute_load_log_event::pack_info(Protocol *protocol)
4335
5458
{
4336
5459
  char buf[64];
4337
 
  uint32_t length;
 
5460
  uint length;
4338
5461
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4339
5462
  protocol->store(buf, (int32_t) length, &my_charset_bin);
4340
5463
}
4354
5477
  Load_log_event *lev= 0;
4355
5478
 
4356
5479
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
4357
 
  if ((fd = my_open(fname, O_RDONLY,
 
5480
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
4358
5481
                    MYF(MY_WME))) < 0 ||
4359
5482
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
4360
5483
                    MYF(MY_WME|MY_NABP)))
4361
5484
  {
4362
5485
    rli->report(ERROR_LEVEL, my_errno,
4363
 
                _("Error in Exec_load event: could not open file '%s'"),
 
5486
                "Error in Exec_load event: could not open file '%s'",
4364
5487
                fname);
4365
5488
    goto err;
4366
5489
  }
4369
5492
                                                         rli->relay_log.description_event_for_exec)) ||
4370
5493
      lev->get_type_code() != NEW_LOAD_EVENT)
4371
5494
  {
4372
 
    rli->report(ERROR_LEVEL, 0,
4373
 
                _("Error in Exec_load event: "
4374
 
                  "file '%s' appears corrupted"),
4375
 
                fname);
 
5495
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
 
5496
                    "file '%s' appears corrupted", fname);
4376
5497
    goto err;
4377
5498
  }
4378
5499
 
4400
5521
    if (tmp)
4401
5522
    {
4402
5523
      rli->report(ERROR_LEVEL, rli->last_error().number,
4403
 
                  _("%s. Failed executing load from '%s'"),
4404
 
                  tmp, fname);
4405
 
      free(tmp);
 
5524
                  "%s. Failed executing load from '%s'", tmp, fname);
 
5525
      my_free(tmp,MYF(0));
4406
5526
    }
4407
5527
    goto err;
4408
5528
  }
4431
5551
  return error;
4432
5552
}
4433
5553
 
 
5554
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5555
 
4434
5556
 
4435
5557
/**************************************************************************
4436
5558
        Begin_load_query_log_event methods
4437
5559
**************************************************************************/
4438
5560
 
 
5561
#ifndef MYSQL_CLIENT
4439
5562
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)
 
5563
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
 
5564
                           uint block_len_arg, bool using_trans)
4442
5565
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4443
5566
                          using_trans)
4444
5567
{
4445
5568
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4446
5569
}
 
5570
#endif
4447
5571
 
4448
5572
 
4449
5573
Begin_load_query_log_event::
4450
 
Begin_load_query_log_event(const char* buf, uint32_t len,
 
5574
Begin_load_query_log_event(const char* buf, uint len,
4451
5575
                           const Format_description_log_event* desc_event)
4452
5576
  :Append_block_log_event(buf, len, desc_event)
4453
5577
{
4454
5578
}
4455
5579
 
4456
5580
 
 
5581
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4457
5582
int Begin_load_query_log_event::get_create_or_append() const
4458
5583
{
4459
5584
  return 1; /* create the file */
4460
5585
}
4461
 
 
4462
 
 
 
5586
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5587
 
 
5588
 
 
5589
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4463
5590
Log_event::enum_skip_reason
4464
5591
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
4465
5592
{
4469
5596
  */
4470
5597
  return continue_group(rli);
4471
5598
}
 
5599
#endif
4472
5600
 
4473
5601
 
4474
5602
/**************************************************************************
4476
5604
**************************************************************************/
4477
5605
 
4478
5606
 
 
5607
#ifndef MYSQL_CLIENT
4479
5608
Execute_load_query_log_event::
4480
5609
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,
 
5610
                             ulong query_length_arg, uint fn_pos_start_arg,
 
5611
                             uint fn_pos_end_arg,
4483
5612
                             enum_load_dup_handling dup_handling_arg,
4484
5613
                             bool using_trans, bool suppress_use,
4485
5614
                             THD::killed_state killed_err_arg):
4489
5618
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
4490
5619
{
4491
5620
}
 
5621
#endif /* !MYSQL_CLIENT */
4492
5622
 
4493
5623
 
4494
5624
Execute_load_query_log_event::
4495
 
Execute_load_query_log_event(const char* buf, uint32_t event_len,
 
5625
Execute_load_query_log_event(const char* buf, uint event_len,
4496
5626
                             const Format_description_log_event* desc_event):
4497
5627
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
4498
5628
  file_id(0), fn_pos_start(0), fn_pos_end(0)
4520
5650
}
4521
5651
 
4522
5652
 
 
5653
#ifndef MYSQL_CLIENT
4523
5654
bool
4524
5655
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
4525
5656
{
4526
 
  unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
5657
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
4527
5658
  int4store(buf, file_id);
4528
5659
  int4store(buf + 4, fn_pos_start);
4529
5660
  int4store(buf + 4 + 4, fn_pos_end);
4530
 
  *(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
 
5661
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
4531
5662
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
4532
5663
}
4533
 
 
4534
 
 
 
5664
#endif
 
5665
 
 
5666
 
 
5667
#ifdef MYSQL_CLIENT
 
5668
void Execute_load_query_log_event::print(FILE* file,
 
5669
                                         PRINT_EVENT_INFO* print_event_info)
 
5670
{
 
5671
  print(file, print_event_info, 0);
 
5672
}
 
5673
 
 
5674
/**
 
5675
  Prints the query as LOAD DATA LOCAL and with rewritten filename.
 
5676
*/
 
5677
void Execute_load_query_log_event::print(FILE* file,
 
5678
                                         PRINT_EVENT_INFO* print_event_info,
 
5679
                                         const char *local_fname)
 
5680
{
 
5681
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5682
 
 
5683
  print_query_header(&cache, print_event_info);
 
5684
 
 
5685
  if (local_fname)
 
5686
  {
 
5687
    my_b_write(&cache, (uchar*) query, fn_pos_start);
 
5688
    my_b_printf(&cache, " LOCAL INFILE \'");
 
5689
    my_b_printf(&cache, local_fname);
 
5690
    my_b_printf(&cache, "\'");
 
5691
    if (dup_handling == LOAD_DUP_REPLACE)
 
5692
      my_b_printf(&cache, " REPLACE");
 
5693
    my_b_printf(&cache, " INTO");
 
5694
    my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
 
5695
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5696
  }
 
5697
  else
 
5698
  {
 
5699
    my_b_write(&cache, (uchar*) query, q_len);
 
5700
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
5701
  }
 
5702
 
 
5703
  if (!print_event_info->short_form)
 
5704
    my_b_printf(&cache, "# file_id: %d \n", file_id);
 
5705
}
 
5706
#endif
 
5707
 
 
5708
 
 
5709
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4535
5710
void Execute_load_query_log_event::pack_info(Protocol *protocol)
4536
5711
{
4537
5712
  char *buf, *pos;
4540
5715
  pos= buf;
4541
5716
  if (db && db_len)
4542
5717
  {
4543
 
    pos= my_stpcpy(buf, "use `");
 
5718
    pos= strmov(buf, "use `");
4544
5719
    memcpy(pos, db, db_len);
4545
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
5720
    pos= strmov(pos+db_len, "`; ");
4546
5721
  }
4547
5722
  if (query && q_len)
4548
5723
  {
4549
5724
    memcpy(pos, query, q_len);
4550
5725
    pos+= q_len;
4551
5726
  }
4552
 
  pos= my_stpcpy(pos, " ;file_id=");
 
5727
  pos= strmov(pos, " ;file_id=");
4553
5728
  pos= int10_to_str((long) file_id, pos, 10);
4554
5729
  protocol->store(buf, pos-buf, &my_charset_bin);
4555
 
  free(buf);
 
5730
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4556
5731
}
4557
5732
 
4558
5733
 
4572
5747
  if (buf == NULL)
4573
5748
  {
4574
5749
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4575
 
                ER(ER_SLAVE_FATAL_ERROR),
4576
 
                _("Not enough memory"));
 
5750
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
4577
5751
    return 1;
4578
5752
  }
4579
5753
 
4582
5756
  p+= fn_pos_start;
4583
5757
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
4584
5758
  p= slave_load_file_stem(p, file_id, server_id, ".data");
4585
 
  fname_end= p= strchr(p, '\0');                      // Safer than p=p+5
 
5759
  fname_end= p= strend(p);                      // Safer than p=p+5
4586
5760
  *(p++)='\'';
4587
5761
  switch (dup_handling) {
4588
5762
  case LOAD_DUP_IGNORE:
4610
5784
  if (!error)
4611
5785
    (void) my_delete(fname, MYF(MY_WME));
4612
5786
 
4613
 
  free(buf);
 
5787
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4614
5788
  return error;
4615
5789
}
 
5790
#endif
4616
5791
 
4617
5792
 
4618
5793
/**************************************************************************
4632
5807
            write_str(file, line_term,  (uint) line_term_len) ||
4633
5808
            write_str(file, line_start, (uint) line_start_len) ||
4634
5809
            write_str(file, escaped,    (uint) escaped_len) ||
4635
 
            my_b_safe_write(file,(unsigned char*) &opt_flags,1));
 
5810
            my_b_safe_write(file,(uchar*) &opt_flags,1));
4636
5811
  }
4637
5812
  else
4638
5813
  {
4648
5823
    old_ex.escaped=    *escaped;
4649
5824
    old_ex.opt_flags=  opt_flags;
4650
5825
    old_ex.empty_flags=empty_flags;
4651
 
    return my_b_safe_write(file, (unsigned char*) &old_ex, sizeof(old_ex)) != 0;
 
5826
    return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
4652
5827
  }
4653
5828
}
4654
5829
 
4708
5883
        Rows_log_event member functions
4709
5884
**************************************************************************/
4710
5885
 
4711
 
Rows_log_event::Rows_log_event(THD *thd_arg, Table *tbl_arg, ulong tid,
 
5886
#ifndef MYSQL_CLIENT
 
5887
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
4712
5888
                               MY_BITMAP const *cols, bool is_transactional)
4713
5889
  : Log_event(thd_arg, 0, is_transactional),
4714
5890
    m_row_count(0),
4716
5892
    m_table_id(tid),
4717
5893
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
4718
5894
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
5895
#ifdef HAVE_REPLICATION
4719
5896
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5897
#endif
4720
5898
{
4721
5899
  /*
4722
5900
    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
 
5901
    are null and the table id is ~0UL.  This is a temporary
4724
5902
    solution, to be able to terminate a started statement in the
4725
5903
    binary log: the extraneous events will be removed in the future.
4726
5904
   */
4727
 
  assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
 
5905
  assert((tbl_arg && tbl_arg->s && tid != ~0UL) || (!tbl_arg && !cols && tid == ~0UL));
4728
5906
 
4729
5907
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
4730
5908
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
4749
5927
    m_cols.bitmap= 0;
4750
5928
  }
4751
5929
}
4752
 
 
4753
 
 
4754
 
Rows_log_event::Rows_log_event(const char *buf, uint32_t event_len,
 
5930
#endif
 
5931
 
 
5932
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
4755
5933
                               Log_event_type event_type,
4756
5934
                               const Format_description_log_event
4757
5935
                               *description_event)
4758
5936
  : Log_event(buf, description_event),
4759
5937
    m_row_count(0),
 
5938
#ifndef MYSQL_CLIENT
4760
5939
    m_table(NULL),
 
5940
#endif
4761
5941
    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
 
5942
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4762
5943
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5944
#endif
4763
5945
{
4764
5946
  uint8_t const common_header_len= description_event->common_header_len;
4765
5947
  uint8_t const post_header_len= description_event->post_header_len[event_type-1];
4780
5962
 
4781
5963
  m_flags= uint2korr(post_start);
4782
5964
 
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;
 
5965
  uchar const *const var_start=
 
5966
    (const uchar *)buf + common_header_len + post_header_len;
 
5967
  uchar const *const ptr_width= var_start;
 
5968
  uchar *ptr_after_width= (uchar*) ptr_width;
4787
5969
  m_width = net_field_length(&ptr_after_width);
4788
5970
  /* if bitmap_init fails, catched in is_valid() */
4789
5971
  if (likely(!bitmap_init(&m_cols,
4824
6006
    }
4825
6007
  }
4826
6008
 
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));
 
6009
  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
 
6010
 
 
6011
  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
 
6012
 
 
6013
  m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
4832
6014
  if (likely((bool)m_rows_buf))
4833
6015
  {
 
6016
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4834
6017
    m_curr_row= m_rows_buf;
 
6018
#endif
4835
6019
    m_rows_end= m_rows_buf + data_size;
4836
6020
    m_rows_cur= m_rows_end;
4837
6021
    memcpy(m_rows_buf, ptr_rows_data, data_size);
4845
6029
Rows_log_event::~Rows_log_event()
4846
6030
{
4847
6031
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
4848
 
    m_cols.bitmap= 0; // so no free in bitmap_free
 
6032
    m_cols.bitmap= 0; // so no my_free in bitmap_free
4849
6033
  bitmap_free(&m_cols); // To pair with bitmap_init().
4850
 
  free((unsigned char*)m_rows_buf);
 
6034
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
4851
6035
}
4852
6036
 
4853
6037
int Rows_log_event::get_data_size()
4854
6038
{
4855
6039
  int const type_code= get_type_code();
4856
6040
 
4857
 
  unsigned char buf[sizeof(m_width)+1];
4858
 
  unsigned char *end= net_store_length(buf, (m_width + 7) / 8);
 
6041
  uchar buf[sizeof(m_width)+1];
 
6042
  uchar *end= net_store_length(buf, (m_width + 7) / 8);
4859
6043
 
4860
6044
  int data_size= ROWS_HEADER_LEN;
4861
6045
  data_size+= no_bytes_in_map(&m_cols);
4869
6053
}
4870
6054
 
4871
6055
 
4872
 
int Rows_log_event::do_add_row_data(unsigned char *row_data, size_t length)
 
6056
#ifndef MYSQL_CLIENT
 
6057
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
4873
6058
{
4874
6059
  /*
4875
6060
    When the table has a primary key, we would probably want, by default, to
4900
6085
    my_ptrdiff_t const new_alloc= 
4901
6086
        block_size * ((cur_size + length + block_size - 1) / block_size);
4902
6087
 
4903
 
    unsigned char* const new_buf= (unsigned char*)my_realloc((unsigned char*)m_rows_buf, (uint) new_alloc,
 
6088
    uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
4904
6089
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
4905
6090
    if (unlikely(!new_buf))
4906
6091
      return(HA_ERR_OUT_OF_MEM);
4925
6110
  m_row_count++;
4926
6111
  return(0);
4927
6112
}
 
6113
#endif
4928
6114
 
 
6115
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4929
6116
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
4930
6117
{
4931
6118
  int error= 0;
4932
6119
  /*
4933
 
    If m_table_id == UINT32_MAX, then we have a dummy event that does not
 
6120
    If m_table_id == ~0UL, then we have a dummy event that does not
4934
6121
    contain any data.  In that case, we just remove all tables in the
4935
6122
    tables_to_lock list, close the thread tables, and return with
4936
6123
    success.
4937
6124
   */
4938
 
  if (m_table_id == UINT32_MAX)
 
6125
  if (m_table_id == ~0UL)
4939
6126
  {
4940
6127
    /*
4941
6128
       This one is supposed to be set: just an extra check so that
5003
6190
            Error reporting borrowed from Query_log_event with many excessive
5004
6191
            simplifications (we don't honour --slave-skip-errors)
5005
6192
          */
5006
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6193
          uint actual_error= thd->main_da.sql_errno();
5007
6194
          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")),
 
6195
                      "Error '%s' in %s event: when locking tables",
 
6196
                      (actual_error ? thd->main_da.message():
 
6197
                       "unexpected success or fatal error"),
5012
6198
                      get_type_str());
5013
6199
          thd->is_fatal_error= 1;
5014
6200
        }
5015
6201
        else
5016
6202
        {
5017
6203
          rli->report(ERROR_LEVEL, error,
5018
 
                      _("Error in %s event: when locking tables"),
 
6204
                      "Error in %s event: when locking tables",
5019
6205
                      get_type_str());
5020
6206
        }
5021
6207
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5036
6222
        need to add code to assert that is the case.
5037
6223
       */
5038
6224
      thd->binlog_flush_pending_rows_event(false);
5039
 
      TableList *tables= rli->tables_to_lock;
 
6225
      TABLE_LIST *tables= rli->tables_to_lock;
5040
6226
      close_tables_for_reopen(thd, &tables);
5041
6227
 
5042
 
      uint32_t tables_count= rli->tables_to_lock_count;
 
6228
      uint tables_count= rli->tables_to_lock_count;
5043
6229
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
5044
6230
      {
5045
6231
        if (thd->is_slave_error || thd->is_fatal_error)
5048
6234
            Error reporting borrowed from Query_log_event with many excessive
5049
6235
            simplifications (we don't honour --slave-skip-errors)
5050
6236
          */
5051
 
          uint32_t actual_error= thd->main_da.sql_errno();
 
6237
          uint actual_error= thd->main_da.sql_errno();
5052
6238
          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")));
 
6239
                      "Error '%s' on reopening tables",
 
6240
                      (actual_error ? thd->main_da.message() :
 
6241
                       "unexpected success or fatal error"));
5057
6242
          thd->is_slave_error= 1;
5058
6243
        }
5059
6244
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5066
6251
      ensure that they still have the correct type.
5067
6252
 
5068
6253
      We can use a down cast here since we know that every table added
5069
 
      to the tables_to_lock is a RPL_TableList.
 
6254
      to the tables_to_lock is a RPL_TABLE_LIST.
5070
6255
    */
5071
6256
 
5072
6257
    {
5073
 
      RPL_TableList *ptr= rli->tables_to_lock;
5074
 
      for ( ; ptr ; ptr= static_cast<RPL_TableList*>(ptr->next_global))
 
6258
      RPL_TABLE_LIST *ptr= rli->tables_to_lock;
 
6259
      for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
5075
6260
      {
5076
6261
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
5077
6262
        {
5098
6283
      Rows_log_event, we can invalidate the query cache for the
5099
6284
      associated table.
5100
6285
     */
5101
 
    for (TableList *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
 
6286
    for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
5102
6287
    {
5103
6288
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
5104
6289
    }
5105
6290
  }
5106
6291
 
5107
 
  Table* 
 
6292
  TABLE* 
5108
6293
    table= 
5109
6294
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
5110
6295
 
5406
6591
    }
5407
6592
    else
5408
6593
      rli->report(ERROR_LEVEL, error,
5409
 
                  _("Error in %s event: commit of row events failed, "
5410
 
                    "table `%s`.`%s`"),
 
6594
                  "Error in %s event: commit of row events failed, "
 
6595
                  "table `%s`.`%s`",
5411
6596
                  get_type_str(), m_table->s->db.str,
5412
6597
                  m_table->s->table_name.str);
5413
6598
  }
5419
6604
  return(error);
5420
6605
}
5421
6606
 
 
6607
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
6608
 
 
6609
#ifndef MYSQL_CLIENT
5422
6610
bool Rows_log_event::write_data_header(IO_CACHE *file)
5423
6611
{
5424
 
  unsigned char buf[ROWS_HEADER_LEN];   // No need to init the buffer
5425
 
  assert(m_table_id != UINT32_MAX);
 
6612
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
6613
  assert(m_table_id != ~0UL);
5426
6614
  int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
5427
6615
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
5428
6616
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
5434
6622
     Note that this should be the number of *bits*, not the number of
5435
6623
     bytes.
5436
6624
  */
5437
 
  unsigned char sbuf[sizeof(m_width)];
 
6625
  uchar sbuf[sizeof(m_width)];
5438
6626
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
5439
6627
  bool res= false;
5440
 
  unsigned char *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
 
6628
  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
5441
6629
  assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
5442
6630
 
5443
6631
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
5444
6632
 
5445
 
  res= res || my_b_safe_write(file, (unsigned char*) m_cols.bitmap,
 
6633
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
5446
6634
                              no_bytes_in_map(&m_cols));
5447
6635
  /*
5448
6636
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
5449
6637
   */
5450
6638
  if (get_type_code() == UPDATE_ROWS_EVENT)
5451
6639
  {
5452
 
    res= res || my_b_safe_write(file, (unsigned char*) m_cols_ai.bitmap,
 
6640
    res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
5453
6641
                                no_bytes_in_map(&m_cols_ai));
5454
6642
  }
5455
6643
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
5457
6645
  return res;
5458
6646
 
5459
6647
}
5460
 
 
5461
 
 
 
6648
#endif
 
6649
 
 
6650
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5462
6651
void Rows_log_event::pack_info(Protocol *protocol)
5463
6652
{
5464
6653
  char buf[256];
5468
6657
                         "table_id: %lu%s", m_table_id, flagstr);
5469
6658
  protocol->store(buf, bytes, &my_charset_bin);
5470
6659
}
5471
 
 
 
6660
#endif
 
6661
 
 
6662
#ifdef MYSQL_CLIENT
 
6663
void Rows_log_event::print_helper(FILE *file,
 
6664
                                  PRINT_EVENT_INFO *print_event_info,
 
6665
                                  char const *const name)
 
6666
{
 
6667
  IO_CACHE *const head= &print_event_info->head_cache;
 
6668
  IO_CACHE *const body= &print_event_info->body_cache;
 
6669
  if (!print_event_info->short_form)
 
6670
  {
 
6671
    bool const last_stmt_event= get_flags(STMT_END_F);
 
6672
    print_header(head, print_event_info, !last_stmt_event);
 
6673
    my_b_printf(head, "\t%s: table id %lu%s\n",
 
6674
                name, m_table_id,
 
6675
                last_stmt_event ? " flags: STMT_END_F" : "");
 
6676
    print_base64(body, print_event_info, !last_stmt_event);
 
6677
  }
 
6678
 
 
6679
  if (get_flags(STMT_END_F))
 
6680
  {
 
6681
    copy_event_cache_to_file_and_reinit(head, file);
 
6682
    copy_event_cache_to_file_and_reinit(body, file);
 
6683
  }
 
6684
}
 
6685
#endif
5472
6686
 
5473
6687
/**************************************************************************
5474
6688
        Table_map_log_event member functions and support functions
5495
6709
  same as the columns for the table on the slave.
5496
6710
 
5497
6711
  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
 
6712
  string of bytes (uchar) in the binlog. A field may require 1 or more bytes
5499
6713
  to store the information. In cases where values require multiple bytes 
5500
6714
  (e.g. values > 255), the endian-safe methods are used to properly encode 
5501
6715
  the values on the master and decode them on the slave. When the field
5506
6720
  type used is uint32_t. 
5507
6721
*/
5508
6722
 
 
6723
#if !defined(MYSQL_CLIENT)
5509
6724
/**
5510
6725
  Save the field metadata based on the real_type of the field.
5511
6726
  The metadata saved depends on the type of the field. Some fields
5537
6752
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
5538
6753
  return(index);
5539
6754
}
 
6755
#endif /* !defined(MYSQL_CLIENT) */
5540
6756
 
5541
6757
/*
5542
6758
  Constructor used to build an event for writing to the binary log.
5543
6759
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
5544
6760
  (tbl->s->db etc) and not pointer content.
5545
6761
 */
5546
 
Table_map_log_event::Table_map_log_event(THD *thd, Table *tbl, ulong tid,
 
6762
#if !defined(MYSQL_CLIENT)
 
6763
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
5547
6764
                                         bool is_transactional __attribute__((unused)),
5548
6765
                                         uint16_t flags)
5549
6766
  : Log_event(thd, 0, true),
5562
6779
    m_null_bits(0),
5563
6780
    m_meta_memory(NULL)
5564
6781
{
5565
 
  assert(m_table_id != UINT32_MAX);
 
6782
  assert(m_table_id != ~0UL);
5566
6783
  /*
5567
6784
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
5568
6785
    table.cc / alloc_table_share():
5580
6797
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
5581
6798
 
5582
6799
  /* If malloc fails, caught in is_valid() */
5583
 
  if ((m_memory= (unsigned char*) my_malloc(m_colcnt, MYF(MY_WME))))
 
6800
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
5584
6801
  {
5585
 
    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
 
6802
    m_coltype= reinterpret_cast<uchar*>(m_memory);
5586
6803
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5587
6804
      m_coltype[i]= m_table->field[i]->type();
5588
6805
  }
5593
6810
    that is not on the slave and is null and thus not in the row data during
5594
6811
    replication.
5595
6812
  */
5596
 
  uint32_t num_null_bytes= (m_table->s->fields + 7) / 8;
 
6813
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
5597
6814
  m_data_size+= num_null_bytes;
5598
 
  m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
 
6815
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5599
6816
                                 &m_null_bits, num_null_bytes,
5600
6817
                                 &m_field_metadata, (m_colcnt * 2),
5601
6818
                                 NULL);
5623
6840
      m_null_bits[(i / 8)]+= 1 << (i % 8);
5624
6841
 
5625
6842
}
5626
 
 
 
6843
#endif /* !defined(MYSQL_CLIENT) */
5627
6844
 
5628
6845
/*
5629
6846
  Constructor used by slave to read the event from the binary log.
5630
6847
 */
5631
 
Table_map_log_event::Table_map_log_event(const char *buf, uint32_t event_len,
 
6848
#if defined(HAVE_REPLICATION)
 
6849
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
5632
6850
                                         const Format_description_log_event
5633
6851
                                         *description_event)
5634
6852
 
5635
6853
  : Log_event(buf, description_event),
 
6854
#ifndef MYSQL_CLIENT
5636
6855
    m_table(NULL),
 
6856
#endif
5637
6857
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
5638
6858
    m_colcnt(0), m_coltype(0),
5639
6859
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
5662
6882
    post_start+= TM_FLAGS_OFFSET;
5663
6883
  }
5664
6884
 
5665
 
  assert(m_table_id != UINT32_MAX);
 
6885
  assert(m_table_id != ~0UL);
5666
6886
 
5667
6887
  m_flags= uint2korr(post_start);
5668
6888
 
5670
6890
  const char *const vpart= buf + common_header_len + post_header_len;
5671
6891
 
5672
6892
  /* 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;
 
6893
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
 
6894
  m_dblen= *(uchar*) ptr_dblen;
5675
6895
 
5676
6896
  /* 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;
 
6897
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
6898
  m_tbllen= *(uchar*) ptr_tbllen;
5679
6899
 
5680
6900
  /* 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;
 
6901
  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
 
6902
  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
5683
6903
  m_colcnt= net_field_length(&ptr_after_colcnt);
5684
6904
 
5685
6905
  /* 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),
 
6906
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
5687
6907
                                     &m_dbnam, (uint) m_dblen + 1,
5688
6908
                                     &m_tblnam, (uint) m_tbllen + 1,
5689
6909
                                     &m_coltype, (uint) m_colcnt,
5690
 
                                     NULL);
 
6910
                                     NullS);
5691
6911
 
5692
6912
  if (m_memory)
5693
6913
  {
5697
6917
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
5698
6918
 
5699
6919
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
5700
 
    bytes_read= ptr_after_colcnt - (unsigned char *)buf;
 
6920
    bytes_read= ptr_after_colcnt - (uchar *)buf;
5701
6921
    if (bytes_read < event_len)
5702
6922
    {
5703
6923
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
5704
6924
      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),
 
6925
      uint num_null_bytes= (m_colcnt + 7) / 8;
 
6926
      m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5707
6927
                                     &m_null_bits, num_null_bytes,
5708
6928
                                     &m_field_metadata, m_field_metadata_size,
5709
6929
                                     NULL);
5710
6930
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
5711
 
      ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
 
6931
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
5712
6932
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
5713
6933
    }
5714
6934
  }
5715
6935
 
5716
6936
  return;
5717
6937
}
 
6938
#endif
5718
6939
 
5719
6940
Table_map_log_event::~Table_map_log_event()
5720
6941
{
5721
 
  free(m_meta_memory);
5722
 
  free(m_memory);
 
6942
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
 
6943
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
5723
6944
}
5724
6945
 
5725
6946
/*
5733
6954
       4     Daisy-chaining RBR with SBR not possible
5734
6955
 */
5735
6956
 
 
6957
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5736
6958
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
5737
6959
{
5738
 
  RPL_TableList *table_list;
 
6960
  RPL_TABLE_LIST *table_list;
5739
6961
  char *db_mem, *tname_mem;
5740
6962
  size_t dummy_len;
5741
6963
  void *memory;
5747
6969
  pthread_mutex_unlock(&LOCK_thread_count);
5748
6970
 
5749
6971
  if (!(memory= my_multi_malloc(MYF(MY_WME),
5750
 
                                &table_list, (uint) sizeof(RPL_TableList),
 
6972
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
5751
6973
                                &db_mem, (uint) NAME_LEN + 1,
5752
6974
                                &tname_mem, (uint) NAME_LEN + 1,
5753
 
                                NULL)))
 
6975
                                NullS)))
5754
6976
    return(HA_ERR_OUT_OF_MEM);
5755
6977
 
5756
6978
  memset(table_list, 0, sizeof(*table_list));
5760
6982
  table_list->next_global= table_list->next_local= 0;
5761
6983
  table_list->table_id= m_table_id;
5762
6984
  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);
 
6985
  strmov(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
 
6986
  strmov(table_list->table_name, m_tblnam);
5765
6987
 
5766
6988
  int error= 0;
5767
6989
 
5768
6990
  if (!rpl_filter->db_ok(table_list->db) ||
5769
6991
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
5770
6992
  {
5771
 
    free(memory);
 
6993
    my_free(memory, MYF(MY_WME));
5772
6994
  }
5773
6995
  else
5774
6996
  {
5795
7017
      table map.  Note that for any table that should not be
5796
7018
      replicated, a filter is needed.
5797
7019
 
5798
 
      The creation of a new TableList is used to up-cast the
5799
 
      table_list consisting of RPL_TableList items. This will work
 
7020
      The creation of a new TABLE_LIST is used to up-cast the
 
7021
      table_list consisting of RPL_TABLE_LIST items. This will work
5800
7022
      since the only case where the argument to open_tables() is
5801
7023
      changed, is when thd->lex->query_tables == table_list, i.e.,
5802
7024
      when the statement requires prelocking. Since this is not
5808
7030
      internally in the open_tables() function, hence we take a copy
5809
7031
      of the pointer to make sure that it's not lost.
5810
7032
    */
5811
 
    uint32_t count;
 
7033
    uint count;
5812
7034
    assert(thd->lex->query_tables != table_list);
5813
 
    TableList *tmp_table_list= table_list;
 
7035
    TABLE_LIST *tmp_table_list= table_list;
5814
7036
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5815
7037
    {
5816
7038
      if (thd->is_slave_error || thd->is_fatal_error)
5819
7041
          Error reporting borrowed from Query_log_event with many excessive
5820
7042
          simplifications (we don't honour --slave-skip-errors)
5821
7043
        */
5822
 
        uint32_t actual_error= thd->main_da.sql_errno();
 
7044
        uint actual_error= thd->main_da.sql_errno();
5823
7045
        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")),
 
7046
                    "Error '%s' on opening table `%s`.`%s`",
 
7047
                    (actual_error ? thd->main_da.message() :
 
7048
                     "unexpected success or fatal error"),
5828
7049
                    table_list->db, table_list->table_name);
5829
7050
        thd->is_slave_error= 1;
5830
7051
      }
5865
7086
  return(error);
5866
7087
 
5867
7088
err:
5868
 
  free(memory);
 
7089
  my_free(memory, MYF(MY_WME));
5869
7090
  return(error);
5870
7091
}
5871
7092
 
5885
7106
  return 0;
5886
7107
}
5887
7108
 
 
7109
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
5888
7110
 
 
7111
#ifndef MYSQL_CLIENT
5889
7112
bool Table_map_log_event::write_data_header(IO_CACHE *file)
5890
7113
{
5891
 
  assert(m_table_id != UINT32_MAX);
5892
 
  unsigned char buf[TABLE_MAP_HEADER_LEN];
 
7114
  assert(m_table_id != ~0UL);
 
7115
  uchar buf[TABLE_MAP_HEADER_LEN];
5893
7116
  int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
5894
7117
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
5895
7118
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
5903
7126
  assert(m_dblen < 128);
5904
7127
  assert(m_tbllen < 128);
5905
7128
 
5906
 
  unsigned char const dbuf[]= { (unsigned char) m_dblen };
5907
 
  unsigned char const tbuf[]= { (unsigned char) m_tbllen };
 
7129
  uchar const dbuf[]= { (uchar) m_dblen };
 
7130
  uchar const tbuf[]= { (uchar) m_tbllen };
5908
7131
 
5909
 
  unsigned char cbuf[sizeof(m_colcnt)];
5910
 
  unsigned char *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
 
7132
  uchar cbuf[sizeof(m_colcnt)];
 
7133
  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
5911
7134
  assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
5912
7135
 
5913
7136
  /*
5914
7137
    Store the size of the field metadata.
5915
7138
  */
5916
 
  unsigned char mbuf[sizeof(m_field_metadata_size)];
5917
 
  unsigned char *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
 
7139
  uchar mbuf[sizeof(m_field_metadata_size)];
 
7140
  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
5918
7141
 
5919
7142
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
5920
 
          my_b_safe_write(file, (const unsigned char*)m_dbnam,   m_dblen+1) ||
 
7143
          my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
5921
7144
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
5922
 
          my_b_safe_write(file, (const unsigned char*)m_tblnam,  m_tbllen+1) ||
 
7145
          my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
5923
7146
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
5924
7147
          my_b_safe_write(file, m_coltype, m_colcnt) ||
5925
7148
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
5926
7149
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
5927
7150
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
5928
7151
 }
 
7152
#endif
5929
7153
 
 
7154
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5930
7155
 
5931
7156
/*
5932
7157
  Print some useful information for the SHOW BINARY LOG information
5933
7158
  field.
5934
7159
 */
5935
7160
 
 
7161
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5936
7162
void Table_map_log_event::pack_info(Protocol *protocol)
5937
7163
{
5938
7164
    char buf[256];
5941
7167
                           m_table_id, m_dbnam, m_tblnam);
5942
7168
    protocol->store(buf, bytes, &my_charset_bin);
5943
7169
}
5944
 
 
 
7170
#endif
 
7171
 
 
7172
 
 
7173
#endif
 
7174
 
 
7175
 
 
7176
#ifdef MYSQL_CLIENT
 
7177
void Table_map_log_event::print(FILE * /* unused */,
 
7178
                                PRINT_EVENT_INFO *print_event_info)
 
7179
{
 
7180
  if (!print_event_info->short_form)
 
7181
  {
 
7182
    print_header(&print_event_info->head_cache, print_event_info, true);
 
7183
    my_b_printf(&print_event_info->head_cache,
 
7184
                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
 
7185
                m_dbnam, m_tblnam, m_table_id);
 
7186
    print_base64(&print_event_info->body_cache, print_event_info, true);
 
7187
  }
 
7188
}
 
7189
#endif
5945
7190
 
5946
7191
/**************************************************************************
5947
7192
        Write_rows_log_event member functions
5950
7195
/*
5951
7196
  Constructor used to build an event for writing to the binary log.
5952
7197
 */
5953
 
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7198
#if !defined(MYSQL_CLIENT)
 
7199
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
5954
7200
                                           ulong tid_arg,
5955
7201
                                           bool is_transactional)
5956
7202
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
5957
7203
{
5958
7204
}
 
7205
#endif
5959
7206
 
5960
7207
/*
5961
7208
  Constructor used by slave to read the event from the binary log.
5962
7209
 */
5963
 
Write_rows_log_event::Write_rows_log_event(const char *buf, uint32_t event_len,
 
7210
#ifdef HAVE_REPLICATION
 
7211
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
5964
7212
                                           const Format_description_log_event
5965
7213
                                           *description_event)
5966
7214
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
5967
7215
{
5968
7216
}
 
7217
#endif
5969
7218
 
 
7219
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5970
7220
int 
5971
7221
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5972
7222
{
6044
7294
  return error? error : local_error;
6045
7295
}
6046
7296
 
 
7297
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6047
7298
 
6048
7299
/*
6049
7300
  Check if there are more UNIQUE keys after the given key.
6050
7301
*/
6051
7302
static int
6052
 
last_uniq_key(Table *table, uint32_t keyno)
 
7303
last_uniq_key(TABLE *table, uint keyno)
6053
7304
{
6054
7305
  while (++keyno < table->s->keys)
6055
7306
    if (table->key_info[keyno].flags & HA_NOSAME)
6123
7374
{
6124
7375
  assert(m_table != NULL && thd != NULL);
6125
7376
 
6126
 
  Table *table= m_table;  // pointer to event's table
 
7377
  TABLE *table= m_table;  // pointer to event's table
6127
7378
  int error;
6128
7379
  int keynum;
6129
7380
  auto_afree_ptr<char> key(NULL);
6215
7466
        }
6216
7467
      }
6217
7468
 
6218
 
      key_copy((unsigned char*)key.get(), table->record[0], table->key_info + keynum,
 
7469
      key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
6219
7470
               0);
6220
7471
      error= table->file->index_read_idx_map(table->record[1], keynum,
6221
 
                                             (const unsigned char*)key.get(),
 
7472
                                             (const uchar*)key.get(),
6222
7473
                                             HA_WHOLE_KEY,
6223
7474
                                             HA_READ_KEY_EXACT);
6224
7475
      if (error)
6292
7543
  return(error);
6293
7544
}
6294
7545
 
 
7546
#endif
6295
7547
 
6296
7548
int 
6297
7549
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6310
7562
  return error; 
6311
7563
}
6312
7564
 
 
7565
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7566
 
 
7567
#ifdef MYSQL_CLIENT
 
7568
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
 
7569
{
 
7570
  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
 
7571
}
 
7572
#endif
6313
7573
 
6314
7574
/**************************************************************************
6315
7575
        Delete_rows_log_event member functions
6316
7576
**************************************************************************/
6317
7577
 
 
7578
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6318
7579
/*
6319
7580
  Compares table->record[0] and table->record[1]
6320
7581
 
6321
7582
  Returns TRUE if different.
6322
7583
*/
6323
 
static bool record_compare(Table *table)
 
7584
static bool record_compare(TABLE *table)
6324
7585
{
6325
7586
  /*
6326
7587
    Need to set the X bit and the filler bits in both records since
6334
7595
    records. Check that the other engines also return correct records.
6335
7596
   */
6336
7597
  bool result= false;
6337
 
  unsigned char saved_x[2], saved_filler[2];
 
7598
  uchar saved_x[2], saved_filler[2];
6338
7599
 
6339
7600
  if (table->s->null_bytes > 0)
6340
7601
  {
6423
7684
{
6424
7685
  assert(m_table && m_table->in_use != NULL);
6425
7686
 
6426
 
  Table *table= m_table;
 
7687
  TABLE *table= m_table;
6427
7688
  int error;
6428
7689
 
6429
7690
  /* unpack row - missing fields get default values */
6611
7872
  return(error);
6612
7873
}
6613
7874
 
 
7875
#endif
6614
7876
 
6615
7877
/*
6616
7878
  Constructor used to build an event for writing to the binary log.
6617
7879
 */
6618
7880
 
6619
 
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7881
#ifndef MYSQL_CLIENT
 
7882
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6620
7883
                                             ulong tid,
6621
7884
                                             bool is_transactional)
6622
7885
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6623
7886
{
6624
7887
}
 
7888
#endif /* #if !defined(MYSQL_CLIENT) */
6625
7889
 
6626
7890
/*
6627
7891
  Constructor used by slave to read the event from the binary log.
6628
7892
 */
6629
 
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint32_t event_len,
 
7893
#ifdef HAVE_REPLICATION
 
7894
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
6630
7895
                                             const Format_description_log_event
6631
7896
                                             *description_event)
6632
7897
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
6633
7898
{
6634
7899
}
 
7900
#endif
6635
7901
 
 
7902
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6636
7903
 
6637
7904
int 
6638
7905
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6649
7916
  if (m_table->s->keys > 0)
6650
7917
  {
6651
7918
    // Allocate buffer for key searches
6652
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
7919
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6653
7920
    if (!m_key)
6654
7921
      return HA_ERR_OUT_OF_MEM;
6655
7922
  }
6663
7930
{
6664
7931
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6665
7932
  m_table->file->ha_index_or_rnd_end();
6666
 
  free(m_key);
 
7933
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
6667
7934
  m_key= NULL;
6668
7935
 
6669
7936
  return error;
6684
7951
  return error;
6685
7952
}
6686
7953
 
 
7954
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
7955
 
 
7956
#ifdef MYSQL_CLIENT
 
7957
void Delete_rows_log_event::print(FILE *file,
 
7958
                                  PRINT_EVENT_INFO* print_event_info)
 
7959
{
 
7960
  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
 
7961
}
 
7962
#endif
 
7963
 
6687
7964
 
6688
7965
/**************************************************************************
6689
7966
        Update_rows_log_event member functions
6692
7969
/*
6693
7970
  Constructor used to build an event for writing to the binary log.
6694
7971
 */
6695
 
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, Table *tbl_arg,
 
7972
#if !defined(MYSQL_CLIENT)
 
7973
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6696
7974
                                             ulong tid,
6697
7975
                                             bool is_transactional)
6698
7976
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6716
7994
    }
6717
7995
  }
6718
7996
}
 
7997
#endif /* !defined(MYSQL_CLIENT) */
6719
7998
 
6720
7999
 
6721
8000
Update_rows_log_event::~Update_rows_log_event()
6722
8001
{
6723
8002
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
6724
 
    m_cols_ai.bitmap= 0; // so no free in bitmap_free
 
8003
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
6725
8004
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
6726
8005
}
6727
8006
 
6729
8008
/*
6730
8009
  Constructor used by slave to read the event from the binary log.
6731
8010
 */
6732
 
Update_rows_log_event::Update_rows_log_event(const char *buf, uint32_t event_len,
 
8011
#ifdef HAVE_REPLICATION
 
8012
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
6733
8013
                                             const
6734
8014
                                             Format_description_log_event
6735
8015
                                             *description_event)
6736
8016
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
6737
8017
{
6738
8018
}
 
8019
#endif
6739
8020
 
 
8021
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6740
8022
 
6741
8023
int 
6742
8024
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6744
8026
  if (m_table->s->keys > 0)
6745
8027
  {
6746
8028
    // Allocate buffer for key searches
6747
 
    m_key= (unsigned char*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
8029
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
6748
8030
    if (!m_key)
6749
8031
      return HA_ERR_OUT_OF_MEM;
6750
8032
  }
6760
8042
{
6761
8043
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6762
8044
  m_table->file->ha_index_or_rnd_end();
6763
 
  free(m_key); // Free for multi_malloc
 
8045
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
6764
8046
  m_key= NULL;
6765
8047
 
6766
8048
  return error;
6815
8097
  return error;
6816
8098
}
6817
8099
 
6818
 
 
6819
 
Incident_log_event::Incident_log_event(const char *buf, uint32_t event_len,
 
8100
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
8101
 
 
8102
#ifdef MYSQL_CLIENT
 
8103
void Update_rows_log_event::print(FILE *file,
 
8104
                                  PRINT_EVENT_INFO* print_event_info)
 
8105
{
 
8106
  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
 
8107
}
 
8108
#endif
 
8109
 
 
8110
 
 
8111
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
6820
8112
                                       const Format_description_log_event *descr_event)
6821
8113
  : Log_event(buf, descr_event)
6822
8114
{
6857
8149
}
6858
8150
 
6859
8151
 
 
8152
#ifndef MYSQL_CLIENT
6860
8153
void Incident_log_event::pack_info(Protocol *protocol)
6861
8154
{
6862
8155
  char buf[256];
6869
8162
                    m_incident, description(), m_message.str);
6870
8163
  protocol->store(buf, bytes, &my_charset_bin);
6871
8164
}
6872
 
 
6873
 
 
 
8165
#endif
 
8166
 
 
8167
 
 
8168
#ifdef MYSQL_CLIENT
 
8169
void
 
8170
Incident_log_event::print(FILE *file,
 
8171
                          PRINT_EVENT_INFO *print_event_info)
 
8172
{
 
8173
  if (print_event_info->short_form)
 
8174
    return;
 
8175
 
 
8176
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
8177
  print_header(&cache, print_event_info, false);
 
8178
  my_b_printf(&cache, "\n# Incident: %s", description());
 
8179
}
 
8180
#endif
 
8181
 
 
8182
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
6874
8183
int
6875
8184
Incident_log_event::do_apply_event(Relay_log_info const *rli)
6876
8185
{
6880
8189
              m_message.length > 0 ? m_message.str : "<none>");
6881
8190
  return(1);
6882
8191
}
6883
 
 
 
8192
#endif
6884
8193
 
6885
8194
bool
6886
8195
Incident_log_event::write_data_header(IO_CACHE *file)
6887
8196
{
6888
 
  unsigned char buf[sizeof(int16_t)];
 
8197
  uchar buf[sizeof(int16_t)];
6889
8198
  int2store(buf, (int16_t) m_incident);
6890
8199
  return(my_b_safe_write(file, buf, sizeof(buf)));
6891
8200
}
6896
8205
  return(write_str(file, m_message.str, m_message.length));
6897
8206
}
6898
8207
 
6899
 
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint32_t event_len,
 
8208
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
8209
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
6900
8210
                    const Format_description_log_event* description_event)
6901
8211
  :Log_event(buf, description_event)
6902
8212
{
6905
8215
  set_if_smaller(ident_len,FN_REFLEN-1);
6906
8216
  log_ident= buf + header_size;
6907
8217
}
 
8218
#endif
 
8219
 
 
8220
 
 
8221
#ifdef MYSQL_CLIENT
 
8222
/**
 
8223
  The default values for these variables should be values that are
 
8224
  *incorrect*, i.e., values that cannot occur in an event.  This way,
 
8225
  they will always be printed for the first event.
 
8226
*/
 
8227
st_print_event_info::st_print_event_info()
 
8228
  :flags2_inited(0), sql_mode_inited(0),
 
8229
   auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
 
8230
   lc_time_names_number(~0),
 
8231
   charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
 
8232
   thread_id(0), thread_id_printed(false),
 
8233
   base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(false)
 
8234
{
 
8235
  /*
 
8236
    Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
 
8237
    program's startup, but these explicit memset() is for the day someone
 
8238
    creates dynamic instances.
 
8239
  */
 
8240
  memset(db, 0, sizeof(db));
 
8241
  memset(charset, 0, sizeof(charset));
 
8242
  memset(time_zone_str, 0, sizeof(time_zone_str));
 
8243
  delimiter[0]= ';';
 
8244
  delimiter[1]= 0;
 
8245
  myf const flags = MYF(MY_WME | MY_NABP);
 
8246
  open_cached_file(&head_cache, NULL, NULL, 0, flags);
 
8247
  open_cached_file(&body_cache, NULL, NULL, 0, flags);
 
8248
}
 
8249
#endif