~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/log_event.cc

  • Committer: Brian Aker
  • Date: 2008-07-13 22:45:08 UTC
  • Revision ID: brian@tangent.org-20080713224508-hb20z4okblotb39a
longlong replacement

Show diffs side-by-side

added added

removed removed

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