~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 Sun Microsystems
5
 
 *
6
 
 *  This program is free software; you can redistribute it and/or modify
7
 
 *  it under the terms of the GNU General Public License as published by
8
 
 *  the Free Software Foundation; version 2 of the License.
9
 
 *
10
 
 *  This program is distributed in the hope that it will be useful,
11
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 
 *  GNU General Public License for more details.
14
 
 *
15
 
 *  You should have received a copy of the GNU General Public License
16
 
 *  along with this program; if not, write to the Free Software
17
 
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18
 
 */
19
 
 
20
 
#include <drizzled/server_includes.h>
21
 
#include <drizzled/log_event.h>
22
 
#include <drizzled/replication/rli.h>
23
 
#include <drizzled/replication/mi.h>
24
 
#include <drizzled/replication/filter.h>
25
 
#include <drizzled/replication/utility.h>
26
 
#include <drizzled/replication/record.h>
 
1
/* Copyright (C) 2000-2004 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
#ifdef MYSQL_CLIENT
 
18
 
 
19
#include "mysql_priv.h"
 
20
 
 
21
#else
 
22
 
 
23
#ifdef USE_PRAGMA_IMPLEMENTATION
 
24
#pragma implementation                          // gcc: Class implementation
 
25
#endif
 
26
 
 
27
#include "mysql_priv.h"
 
28
#include "slave.h"
 
29
#include "rpl_rli.h"
 
30
#include "rpl_mi.h"
 
31
#include "rpl_filter.h"
 
32
#include "rpl_utility.h"
 
33
#include "rpl_record.h"
27
34
#include <mysys/my_dir.h>
28
 
#include <drizzled/error.h>
29
 
#include <libdrizzle/pack.h>
30
 
#include <drizzled/sql_parse.h>
31
 
#include <drizzled/sql_base.h>
32
 
#include <drizzled/sql_load.h>
 
35
#include <drizzled/drizzled_error_messages.h>
33
36
 
34
 
#include <algorithm>
 
37
#endif /* MYSQL_CLIENT */
35
38
 
36
39
#include <mysys/base64.h>
37
40
#include <mysys/my_bitmap.h>
38
41
 
39
 
#include <drizzled/gettext.h>
40
 
#include <libdrizzle/libdrizzle.h>
41
 
#include <drizzled/error.h>
42
 
#include <drizzled/query_id.h>
43
 
#include <drizzled/tztime.h>
44
 
#include <drizzled/slave.h>
45
 
 
46
 
 
 
42
#define log_cs  &my_charset_latin1
 
43
 
 
44
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
 
45
 
 
46
 
 
47
/*
 
48
  Size of buffer for printing a double in format %.<PREC>g
 
49
 
 
50
  optional '-' + optional zero + '.'  + PREC digits + 'e' + sign +
 
51
  exponent digits + '\0'
 
52
*/
 
53
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
 
54
 
 
55
 
 
56
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
47
57
static const char *HA_ERR(int i)
48
58
{
49
59
  switch (i) {
107
117
   @param level     error, warning or info
108
118
   @param ha_error  HA_ERR_ code
109
119
   @param rli       pointer to the active Relay_log_info instance
110
 
   @param session       pointer to the slave thread's session
 
120
   @param thd       pointer to the slave thread's thd
111
121
   @param table     pointer to the event's table object
112
122
   @param type      the type of the event
113
123
   @param log_name  the master binlog file name
115
125
 
116
126
*/
117
127
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
118
 
                                           Relay_log_info const *rli, Session *session,
119
 
                                           Table *table, const char * type,
 
128
                                           Relay_log_info const *rli, THD *thd,
 
129
                                           TABLE *table, const char * type,
120
130
                                           const char *log_name, ulong pos)
121
131
{
122
132
  const char *handler_error= HA_ERR(ha_error);
123
133
  char buff[MAX_SLAVE_ERRMSG], *slider;
124
134
  const char *buff_end= buff + sizeof(buff);
125
 
  uint32_t len;
126
 
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
127
 
  DRIZZLE_ERROR *err;
 
135
  uint len;
 
136
  List_iterator_fast<MYSQL_ERROR> it(thd->warn_list);
 
137
  MYSQL_ERROR *err;
128
138
  buff[0]= 0;
129
139
 
130
140
  for (err= it++, slider= buff; err && slider < buff_end - 1;
131
141
       slider += len, err= it++)
132
142
  {
133
143
    len= snprintf(slider, buff_end - slider,
134
 
                  _(" %s, Error_code: %d;"), err->msg, err->code);
 
144
                  " %s, Error_code: %d;", err->msg, err->code);
135
145
  }
136
146
  
137
 
  rli->report(level, session->is_error()? session->main_da.sql_errno() : 0,
138
 
              _("Could not execute %s event on table %s.%s;"
139
 
                "%s handler error %s; "
140
 
                "the event's master log %s, end_log_pos %lu"),
 
147
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
 
148
              "Could not execute %s event on table %s.%s;"
 
149
              "%s handler error %s; "
 
150
              "the event's master log %s, end_log_pos %lu",
141
151
              type, table->s->db.str,
142
152
              table->s->table_name.str,
143
153
              buff,
144
 
              handler_error == NULL? _("<unknown>") : handler_error,
 
154
              handler_error == NULL? "<unknown>" : handler_error,
145
155
              log_name, pos);
146
156
}
147
 
 
 
157
#endif
148
158
 
149
159
/*
150
160
  Cache that will automatically be written to a dedicated file on
224
234
  flag_set m_flags;
225
235
};
226
236
 
227
 
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
237
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
228
238
 
229
239
/*
230
240
  pretty_print_str()
231
241
*/
232
242
 
233
 
static void clear_all_errors(Session *session, Relay_log_info *rli)
234
 
{
235
 
  session->is_slave_error = 0;
236
 
  session->clear_error();
 
243
#ifdef MYSQL_CLIENT
 
244
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
 
245
{
 
246
  const char* end = str + len;
 
247
  my_b_printf(cache, "\'");
 
248
  while (str < end)
 
249
  {
 
250
    char c;
 
251
    switch ((c=*str++)) {
 
252
    case '\n': my_b_printf(cache, "\\n"); break;
 
253
    case '\r': my_b_printf(cache, "\\r"); break;
 
254
    case '\\': my_b_printf(cache, "\\\\"); break;
 
255
    case '\b': my_b_printf(cache, "\\b"); break;
 
256
    case '\t': my_b_printf(cache, "\\t"); break;
 
257
    case '\'': my_b_printf(cache, "\\'"); break;
 
258
    case 0   : my_b_printf(cache, "\\0"); break;
 
259
    default:
 
260
      my_b_printf(cache, "%c", c);
 
261
      break;
 
262
    }
 
263
  }
 
264
  my_b_printf(cache, "\'");
 
265
}
 
266
#endif /* MYSQL_CLIENT */
 
267
 
 
268
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
269
 
 
270
static void clear_all_errors(THD *thd, Relay_log_info *rli)
 
271
{
 
272
  thd->is_slave_error = 0;
 
273
  thd->clear_error();
237
274
  rli->clear_error();
238
275
}
239
276
 
247
284
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
248
285
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
249
286
}
 
287
#endif
250
288
 
251
289
 
252
290
/*
253
291
  pretty_print_str()
254
292
*/
255
293
 
 
294
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
256
295
static char *pretty_print_str(char *packet, const char *str, int len)
257
296
{
258
297
  const char *end= str + len;
277
316
  *pos++= '\'';
278
317
  return pos;
279
318
}
280
 
 
 
319
#endif /* !MYSQL_CLIENT */
 
320
 
 
321
 
 
322
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
281
323
 
282
324
/**
283
325
  Creates a temporary name for load data infile:.
291
333
    Pointer to start of extension
292
334
*/
293
335
 
294
 
static char *slave_load_file_stem(char *buf, uint32_t file_id,
 
336
static char *slave_load_file_stem(char *buf, uint file_id,
295
337
                                  int event_server_id, const char *ext)
296
338
{
297
339
  char *res;
298
340
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
299
341
  to_unix_path(buf);
300
342
 
301
 
  buf= strchr(buf, '\0');
302
 
  buf= int10_to_str(::server_id, buf, 10);
 
343
  buf = strend(buf);
 
344
  buf = int10_to_str(::server_id, buf, 10);
303
345
  *buf++ = '-';
304
 
  buf= int10_to_str(event_server_id, buf, 10);
 
346
  buf = int10_to_str(event_server_id, buf, 10);
305
347
  *buf++ = '-';
306
348
  res= int10_to_str(file_id, buf, 10);
307
 
  my_stpcpy(res, ext);                             // Add extension last
 
349
  strmov(res, ext);                             // Add extension last
308
350
  return res;                                   // Pointer to extension
309
351
}
310
 
 
 
352
#endif
 
353
 
 
354
 
 
355
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
311
356
 
312
357
/**
313
358
  Delete all temporary files used for SQL_LOAD.
317
362
{
318
363
  MY_DIR *dirp;
319
364
  FILEINFO *file;
320
 
  uint32_t i;
 
365
  uint i;
321
366
  char fname[FN_REFLEN], prefbuf[31], *p;
322
367
 
323
368
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
348
393
 
349
394
  my_dirend(dirp);
350
395
}
 
396
#endif
351
397
 
352
398
 
353
399
/*
354
400
  write_str()
355
401
*/
356
402
 
357
 
static bool write_str(IO_CACHE *file, const char *str, uint32_t length)
 
403
static bool write_str(IO_CACHE *file, const char *str, uint length)
358
404
{
359
 
  unsigned char tmp[1];
360
 
  tmp[0]= (unsigned char) length;
 
405
  uchar tmp[1];
 
406
  tmp[0]= (uchar) length;
361
407
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
362
 
          my_b_safe_write(file, (unsigned char*) str, length));
 
408
          my_b_safe_write(file, (uchar*) str, length));
363
409
}
364
410
 
365
411
 
370
416
static inline int read_str(const char **buf, const char *buf_end,
371
417
                           const char **str, uint8_t *len)
372
418
{
373
 
  if (*buf + ((uint) (unsigned char) **buf) >= buf_end)
 
419
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
374
420
    return 1;
375
421
  *len= (uint8_t) **buf;
376
422
  *str= (*buf)+1;
383
429
  Transforms a string into "" or its expression in 0x... form.
384
430
*/
385
431
 
386
 
char *str_to_hex(char *to, const char *from, uint32_t len)
 
432
char *str_to_hex(char *to, const char *from, uint len)
387
433
{
388
434
  if (len)
389
435
  {
392
438
    to= octet2hex(to, from, len);
393
439
  }
394
440
  else
395
 
    to= my_stpcpy(to, "\"\"");
 
441
    to= strmov(to, "\"\"");
396
442
  return to;                               // pointer to end 0 of 'to'
397
443
}
398
444
 
 
445
#ifndef MYSQL_CLIENT
399
446
 
400
447
/**
401
448
  Append a version of the 'from' string suitable for use in a query to
404
451
*/
405
452
 
406
453
int
407
 
append_query_string(const CHARSET_INFO * const csinfo,
 
454
append_query_string(CHARSET_INFO *csinfo,
408
455
                    String const *from, String *to)
409
456
{
410
457
  char *beg, *ptr;
419
466
  else
420
467
  {
421
468
    *ptr++= '\'';
422
 
    ptr+= drizzle_escape_string(ptr, from->ptr(), from->length());
 
469
    ptr+= escape_string_for_drizzle(csinfo, ptr, 0,
 
470
                                    from->ptr(), from->length());
423
471
    *ptr++='\'';
424
472
  }
425
473
  to->length(orig_len + ptr - beg);
426
474
  return 0;
427
475
}
428
 
 
 
476
#endif
 
477
 
 
478
 
 
479
/**
 
480
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
 
481
  commands just before it prints a query.
 
482
*/
 
483
 
 
484
#ifdef MYSQL_CLIENT
 
485
 
 
486
static void print_set_option(IO_CACHE* file, uint32_t bits_changed,
 
487
                             uint32_t option, uint32_t flags, const char* name,
 
488
                             bool* need_comma)
 
489
{
 
490
  if (bits_changed & option)
 
491
  {
 
492
    if (*need_comma)
 
493
      my_b_printf(file,", ");
 
494
    my_b_printf(file,"%s=%d", name, test(flags & option));
 
495
    *need_comma= 1;
 
496
  }
 
497
}
 
498
#endif
429
499
 
430
500
/**************************************************************************
431
501
        Log_event methods (= the parent class of all events)
479
549
  Log_event::Log_event()
480
550
*/
481
551
 
482
 
Log_event::Log_event(Session* session_arg, uint16_t flags_arg, bool using_trans)
483
 
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), session(session_arg)
 
552
#ifndef MYSQL_CLIENT
 
553
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
 
554
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
484
555
{
485
 
  server_id=    session->server_id;
486
 
  when=         session->start_time;
 
556
  server_id=    thd->server_id;
 
557
  when=         thd->start_time;
487
558
  cache_stmt=   using_trans;
488
559
}
489
560
 
490
561
 
491
562
/**
492
563
  This minimal constructor is for when you are not even sure that there
493
 
  is a valid Session. For example in the server when we are shutting down or
 
564
  is a valid THD. For example in the server when we are shutting down or
494
565
  flushing logs after receiving a SIGHUP (then we must write a Rotate to
495
 
  the binlog but we have no Session, so we need this minimal constructor).
 
566
  the binlog but we have no THD, so we need this minimal constructor).
496
567
*/
497
568
 
498
569
Log_event::Log_event()
499
570
  :temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
500
 
   session(0)
 
571
   thd(0)
501
572
{
502
573
  server_id=    ::server_id;
503
574
  /*
507
578
  when=         0;
508
579
  log_pos=      0;
509
580
}
 
581
#endif /* !MYSQL_CLIENT */
510
582
 
511
583
 
512
584
/*
517
589
                     const Format_description_log_event* description_event)
518
590
  :temp_buf(0), cache_stmt(0)
519
591
{
520
 
  session= 0;
521
 
  when= uint4korr(buf);
522
 
  server_id= uint4korr(buf + SERVER_ID_OFFSET);
 
592
#ifndef MYSQL_CLIENT
 
593
  thd = 0;
 
594
#endif
 
595
  when = uint4korr(buf);
 
596
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
523
597
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
524
598
  if (description_event->binlog_version==1)
525
599
  {
578
652
  /* otherwise, go on with reading the header from buf (nothing now) */
579
653
}
580
654
 
 
655
#ifndef MYSQL_CLIENT
 
656
#ifdef HAVE_REPLICATION
581
657
 
582
658
int Log_event::do_update_pos(Relay_log_info *rli)
583
659
{
636
712
}
637
713
 
638
714
 
639
 
const char* Log_event::get_db()
 
715
/**
 
716
  Only called by SHOW BINLOG EVENTS
 
717
*/
 
718
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
640
719
{
641
 
  return session ? session->db : 0;
 
720
  const char *p= strrchr(log_name, FN_LIBCHAR);
 
721
  const char *event_type;
 
722
  if (p)
 
723
    log_name = p + 1;
 
724
 
 
725
  protocol->prepare_for_resend();
 
726
  protocol->store(log_name, &my_charset_bin);
 
727
  protocol->store((uint64_t) pos);
 
728
  event_type = get_type_str();
 
729
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
 
730
  protocol->store((uint32_t) server_id);
 
731
  protocol->store((uint64_t) log_pos);
 
732
  pack_info(protocol);
 
733
  return protocol->write();
642
734
}
 
735
#endif /* HAVE_REPLICATION */
643
736
 
644
737
 
645
738
/**
652
745
{
653
746
  field_list->push_back(new Item_empty_string("Log_name", 20));
654
747
  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
655
 
                                            DRIZZLE_TYPE_LONGLONG));
 
748
                                            DRIZZLE_TYPE_LONGLONG));
656
749
  field_list->push_back(new Item_empty_string("Event_type", 20));
657
750
  field_list->push_back(new Item_return_int("Server_id", 10,
658
 
                                            DRIZZLE_TYPE_LONG));
 
751
                                            DRIZZLE_TYPE_LONG));
659
752
  field_list->push_back(new Item_return_int("End_log_pos",
660
753
                                            MY_INT32_NUM_DECIMAL_DIGITS,
661
 
                                            DRIZZLE_TYPE_LONGLONG));
 
754
                                            DRIZZLE_TYPE_LONGLONG));
662
755
  field_list->push_back(new Item_empty_string("Info", 20));
663
756
}
664
757
 
668
761
 
669
762
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
670
763
{
671
 
  unsigned char header[LOG_EVENT_HEADER_LEN];
 
764
  uchar header[LOG_EVENT_HEADER_LEN];
672
765
  ulong now;
673
766
 
674
767
  /* Store number of bytes that will be written by this event */
739
832
}
740
833
 
741
834
 
742
 
time_t Log_event::get_time()
743
 
{
744
 
  Session *tmp_session;
745
 
  if (when)
746
 
    return when;
747
 
  if (session)
748
 
    return session->start_time;
749
 
  if ((tmp_session= current_session))
750
 
    return tmp_session->start_time;
751
 
  return my_time(0);
752
 
}
753
 
 
754
 
 
755
835
/**
756
836
  This needn't be format-tolerant, because we only read
757
837
  LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
758
838
*/
759
839
 
760
840
int Log_event::read_log_event(IO_CACHE* file, String* packet,
761
 
                              pthread_mutex_t* log_lock)
 
841
                              pthread_mutex_t* log_lock)
762
842
{
763
843
  ulong data_len;
764
844
  int result=0;
766
846
 
767
847
  if (log_lock)
768
848
    pthread_mutex_lock(log_lock);
769
 
  if (my_b_read(file, (unsigned char*) buf, sizeof(buf)))
 
849
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
770
850
  {
771
851
    /*
772
852
      If the read hits eof, we must report it as eof so the caller
781
861
  }
782
862
  data_len= uint4korr(buf + EVENT_LEN_OFFSET);
783
863
  if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
784
 
      data_len > current_session->variables.max_allowed_packet)
 
864
      data_len > current_thd->variables.max_allowed_packet)
785
865
  {
786
866
    result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
787
867
             LOG_READ_TOO_LARGE);
824
904
    pthread_mutex_unlock(log_lock);
825
905
  return(result);
826
906
}
 
907
#endif /* !MYSQL_CLIENT */
827
908
 
 
909
#ifndef MYSQL_CLIENT
828
910
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
829
911
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
 
912
#else
 
913
#define UNLOCK_MUTEX
 
914
#define LOCK_MUTEX
 
915
#endif
830
916
 
 
917
#ifndef MYSQL_CLIENT
831
918
/**
832
919
  @note
833
920
    Allocates memory;  The caller is responsible for clean-up.
836
923
                                     pthread_mutex_t* log_lock,
837
924
                                     const Format_description_log_event
838
925
                                     *description_event)
 
926
#else
 
927
Log_event* Log_event::read_log_event(IO_CACHE* file,
 
928
                                     const Format_description_log_event
 
929
                                     *description_event)
 
930
#endif
839
931
{
840
932
  assert(description_event != 0);
841
933
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
846
938
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
847
939
    "minimal" over the set {MySQL >=4.0}).
848
940
  */
849
 
  uint32_t header_size= cmin(description_event->common_header_len,
 
941
  uint header_size= min(description_event->common_header_len,
850
942
                        LOG_EVENT_MINIMAL_HEADER_LEN);
851
943
 
852
944
  LOCK_MUTEX;
853
 
  if (my_b_read(file, (unsigned char *) head, header_size))
 
945
  if (my_b_read(file, (uchar *) head, header_size))
854
946
  {
855
947
    UNLOCK_MUTEX;
856
948
    /*
860
952
    */
861
953
    return(0);
862
954
  }
863
 
  uint32_t data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
955
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
864
956
  char *buf= 0;
865
957
  const char *error= 0;
866
958
  Log_event *res=  0;
867
959
#ifndef max_allowed_packet
868
 
  Session *session=current_session;
869
 
  uint32_t max_allowed_packet= session ? session->variables.max_allowed_packet : ~(ulong)0;
 
960
  THD *thd=current_thd;
 
961
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
870
962
#endif
871
963
 
872
964
  if (data_len > max_allowed_packet)
889
981
  }
890
982
  buf[data_len] = 0;
891
983
  memcpy(buf, head, header_size);
892
 
  if (my_b_read(file, (unsigned char*) buf + header_size, data_len - header_size))
 
984
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
893
985
  {
894
986
    error = "read error";
895
987
    goto err;
902
994
  if (!res)
903
995
  {
904
996
    assert(error != 0);
905
 
    sql_print_error(_("Error in Log_event::read_log_event(): "
906
 
                    "'%s', data_len: %d, event_type: %d"),
 
997
    sql_print_error("Error in Log_event::read_log_event(): "
 
998
                    "'%s', data_len: %d, event_type: %d",
907
999
                    error,data_len,head[EVENT_TYPE_OFFSET]);
908
 
    free(buf);
 
1000
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
909
1001
    /*
910
1002
      The SQL slave thread will check if file->error<0 to know
911
1003
      if there was an I/O error. Even if there is no "low-level" I/O errors
925
1017
  constructors.
926
1018
*/
927
1019
 
928
 
Log_event* Log_event::read_log_event(const char* buf, uint32_t event_len,
 
1020
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
929
1021
                                     const char **error,
930
1022
                                     const Format_description_log_event *description_event)
931
1023
{
941
1033
    return(NULL); // general sanity check - will fail on a partial read
942
1034
  }
943
1035
 
944
 
  uint32_t event_type= buf[EVENT_TYPE_OFFSET];
 
1036
  uint event_type= buf[EVENT_TYPE_OFFSET];
945
1037
  if (event_type > description_event->number_of_event_types &&
946
1038
      event_type != FORMAT_DESCRIPTION_EVENT)
947
1039
  {
979
1071
    case ROTATE_EVENT:
980
1072
      ev = new Rotate_log_event(buf, event_len, description_event);
981
1073
      break;
 
1074
    case SLAVE_EVENT: /* can never happen (unused event) */
 
1075
      ev = new Slave_log_event(buf, event_len);
 
1076
      break;
982
1077
    case CREATE_FILE_EVENT:
983
1078
      ev = new Create_file_log_event(buf, event_len, description_event);
984
1079
      break;
1012
1107
    case FORMAT_DESCRIPTION_EVENT:
1013
1108
      ev = new Format_description_log_event(buf, event_len, description_event);
1014
1109
      break;
 
1110
#if defined(HAVE_REPLICATION) 
1015
1111
    case WRITE_ROWS_EVENT:
1016
1112
      ev = new Write_rows_log_event(buf, event_len, description_event);
1017
1113
      break;
1024
1120
    case TABLE_MAP_EVENT:
1025
1121
      ev = new Table_map_log_event(buf, event_len, description_event);
1026
1122
      break;
 
1123
#endif
1027
1124
    case BEGIN_LOAD_QUERY_EVENT:
1028
1125
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
1029
1126
      break;
1051
1148
  if (!ev || !ev->is_valid())
1052
1149
  {
1053
1150
    delete ev;
 
1151
#ifdef MYSQL_CLIENT
 
1152
    if (!force_opt) /* then mysqlbinlog dies */
 
1153
    {
 
1154
      *error= "Found invalid event in binary log";
 
1155
      return(0);
 
1156
    }
 
1157
    ev= new Unknown_log_event(buf, description_event);
 
1158
#else
1054
1159
    *error= "Found invalid event in binary log";
1055
1160
    return(0);
 
1161
#endif
1056
1162
  }
1057
1163
  return(ev);  
1058
1164
}
1059
1165
 
 
1166
#ifdef MYSQL_CLIENT
 
1167
 
 
1168
/*
 
1169
  Log_event::print_header()
 
1170
*/
 
1171
 
 
1172
void Log_event::print_header(IO_CACHE* file,
 
1173
                             PRINT_EVENT_INFO* print_event_info,
 
1174
                             bool is_more __attribute__((unused)))
 
1175
{
 
1176
  char llbuff[22];
 
1177
  my_off_t hexdump_from= print_event_info->hexdump_from;
 
1178
 
 
1179
  my_b_printf(file, "#");
 
1180
  print_timestamp(file);
 
1181
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
 
1182
              llstr(log_pos,llbuff));
 
1183
 
 
1184
  /* mysqlbinlog --hexdump */
 
1185
  if (print_event_info->hexdump_from)
 
1186
  {
 
1187
    my_b_printf(file, "\n");
 
1188
    uchar *ptr= (uchar*)temp_buf;
 
1189
    my_off_t size=
 
1190
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
 
1191
    my_off_t i;
 
1192
 
 
1193
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
 
1194
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
 
1195
    char *c, char_string[16+1]= {0};
 
1196
 
 
1197
    /* Pretty-print event common header if header is exactly 19 bytes */
 
1198
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
 
1199
    {
 
1200
      char emit_buf[256];               // Enough for storing one line
 
1201
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
 
1202
                  "Size      Master Pos    Flags \n");
 
1203
      int const bytes_written=
 
1204
        snprintf(emit_buf, sizeof(emit_buf),
 
1205
                 "# %8.8lx %02x %02x %02x %02x   %02x   "
 
1206
                 "%02x %02x %02x %02x   %02x %02x %02x %02x   "
 
1207
                 "%02x %02x %02x %02x   %02x %02x\n",
 
1208
                 (unsigned long) hexdump_from,
 
1209
                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
 
1210
                 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
 
1211
                 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
 
1212
      assert(bytes_written >= 0);
 
1213
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1214
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1215
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1216
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
 
1217
    }
 
1218
 
 
1219
    /* Rest of event (without common header) */
 
1220
    for (i= 0, c= char_string, h=hex_string;
 
1221
         i < size;
 
1222
         i++, ptr++)
 
1223
    {
 
1224
      snprintf(h, 4, "%02x ", *ptr);
 
1225
      h += 3;
 
1226
 
 
1227
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
 
1228
 
 
1229
      if (i % 16 == 15)
 
1230
      {
 
1231
        /*
 
1232
          my_b_printf() does not support full printf() formats, so we
 
1233
          have to do it this way.
 
1234
 
 
1235
          TODO: Rewrite my_b_printf() to support full printf() syntax.
 
1236
         */
 
1237
        char emit_buf[256];
 
1238
        int const bytes_written=
 
1239
          snprintf(emit_buf, sizeof(emit_buf),
 
1240
                   "# %8.8lx %-48.48s |%16s|\n",
 
1241
                   (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1242
                   hex_string, char_string);
 
1243
        assert(bytes_written >= 0);
 
1244
        assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1245
        my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1246
        hex_string[0]= 0;
 
1247
        char_string[0]= 0;
 
1248
        c= char_string;
 
1249
        h= hex_string;
 
1250
      }
 
1251
      else if (i % 8 == 7) *h++ = ' ';
 
1252
    }
 
1253
    *c= '\0';
 
1254
 
 
1255
    if (hex_string[0])
 
1256
    {
 
1257
      char emit_buf[256];
 
1258
      int const bytes_written=
 
1259
        snprintf(emit_buf, sizeof(emit_buf),
 
1260
                    "# %8.8lx %-48.48s |%s|\n",
 
1261
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
 
1262
                    hex_string, char_string);
 
1263
      assert(bytes_written >= 0);
 
1264
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
 
1265
      my_b_write(file, (uchar*) emit_buf, bytes_written);
 
1266
    }
 
1267
    /*
 
1268
      need a # to prefix the rest of printouts for example those of
 
1269
      Rows_log_event::print_helper().
 
1270
    */
 
1271
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
 
1272
  }
 
1273
  return;
 
1274
}
 
1275
 
 
1276
 
 
1277
void Log_event::print_base64(IO_CACHE* file,
 
1278
                             PRINT_EVENT_INFO* print_event_info,
 
1279
                             bool more)
 
1280
{
 
1281
  const uchar *ptr= (const uchar *)temp_buf;
 
1282
  uint32_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
 
1283
 
 
1284
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
 
1285
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
 
1286
  if (!tmp_str) {
 
1287
    fprintf(stderr, "\nError: Out of memory. "
 
1288
            "Could not print correct binlog event.\n");
 
1289
    return;
 
1290
  }
 
1291
 
 
1292
  if (base64_encode(ptr, (size_t) size, tmp_str))
 
1293
  {
 
1294
    assert(0);
 
1295
  }
 
1296
 
 
1297
  if (my_b_tell(file) == 0)
 
1298
    my_b_printf(file, "\nBINLOG '\n");
 
1299
 
 
1300
  my_b_printf(file, "%s\n", tmp_str);
 
1301
 
 
1302
  if (!more)
 
1303
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
 
1304
 
 
1305
  my_free(tmp_str, MYF(0));
 
1306
  return;
 
1307
}
 
1308
 
 
1309
 
 
1310
/*
 
1311
  Log_event::print_timestamp()
 
1312
*/
 
1313
 
 
1314
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
 
1315
{
 
1316
  struct tm *res;
 
1317
  if (!ts)
 
1318
    ts = &when;
 
1319
#ifdef MYSQL_SERVER                             // This is always false
 
1320
  struct tm tm_tmp;
 
1321
  localtime_r(ts,(res= &tm_tmp));
 
1322
#else
 
1323
  res=localtime(ts);
 
1324
#endif
 
1325
 
 
1326
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
 
1327
              res->tm_year % 100,
 
1328
              res->tm_mon+1,
 
1329
              res->tm_mday,
 
1330
              res->tm_hour,
 
1331
              res->tm_min,
 
1332
              res->tm_sec);
 
1333
  return;
 
1334
}
 
1335
 
 
1336
#endif /* MYSQL_CLIENT */
 
1337
 
 
1338
 
 
1339
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
1060
1340
inline Log_event::enum_skip_reason
1061
1341
Log_event::continue_group(Relay_log_info *rli)
1062
1342
{
1064
1344
    return Log_event::EVENT_SKIP_IGNORE;
1065
1345
  return Log_event::do_shall_skip(rli);
1066
1346
}
 
1347
#endif
1067
1348
 
1068
1349
/**************************************************************************
1069
1350
        Query_log_event methods
1070
1351
**************************************************************************/
1071
1352
 
 
1353
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
1354
 
1072
1355
/**
1073
1356
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
1074
1357
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1088
1371
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1089
1372
      && db && db_len)
1090
1373
  {
1091
 
    pos= my_stpcpy(buf, "use `");
 
1374
    pos= strmov(buf, "use `");
1092
1375
    memcpy(pos, db, db_len);
1093
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
1376
    pos= strmov(pos+db_len, "`; ");
1094
1377
  }
1095
1378
  if (query && q_len)
1096
1379
  {
1098
1381
    pos+= q_len;
1099
1382
  }
1100
1383
  protocol->store(buf, pos-buf, &my_charset_bin);
1101
 
  free(buf);
 
1384
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
1385
}
 
1386
#endif
 
1387
 
 
1388
#ifndef MYSQL_CLIENT
 
1389
 
 
1390
/**
 
1391
  Utility function for the next method (Query_log_event::write()) .
 
1392
*/
 
1393
static void write_str_with_code_and_len(char **dst, const char *src,
 
1394
                                        int len, uint code)
 
1395
{
 
1396
  assert(src);
 
1397
  *((*dst)++)= code;
 
1398
  *((*dst)++)= (uchar) len;
 
1399
  memcpy(*dst, src, len);
 
1400
  (*dst)+= len;
1102
1401
}
1103
1402
 
1104
1403
 
1118
1417
    replicating it correctly, since the length is stored in a byte
1119
1418
    /sven
1120
1419
  */
1121
 
  unsigned char buf[QUERY_HEADER_LEN+
 
1420
  uchar buf[QUERY_HEADER_LEN+
1122
1421
            1+4+           // code of flags2 and flags2
1123
1422
            1+8+           // code of sql_mode and sql_mode
1124
1423
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1187
1486
    int4store(start, flags2);
1188
1487
    start+= 4;
1189
1488
  }
 
1489
  if (sql_mode_inited)
 
1490
  {
 
1491
    *start++= Q_SQL_MODE_CODE;
 
1492
    int8store(start, (uint64_t)sql_mode);
 
1493
    start+= 8;
 
1494
  }
 
1495
  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
 
1496
  {
 
1497
    write_str_with_code_and_len((char **)(&start),
 
1498
                                catalog, catalog_len, Q_CATALOG_NZ_CODE);
 
1499
    /*
 
1500
      In 5.0.x where x<4 masters we used to store the end zero here. This was
 
1501
      a waste of one byte so we don't do it in x>=4 masters. We change code to
 
1502
      Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
 
1503
      of this x>=4 master segfault (expecting a zero when there is
 
1504
      none). Remaining compatibility problems are: the older slave will not
 
1505
      find the catalog; but it is will not crash, and it's not an issue
 
1506
      that it does not find the catalog as catalogs were not used in these
 
1507
      older MySQL versions (we store it in binlog and read it from relay log
 
1508
      but do nothing useful with it). What is an issue is that the older slave
 
1509
      will stop processing the Q_* blocks (and jumps to the db/query) as soon
 
1510
      as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
 
1511
      Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
 
1512
      various ways. Documented that you should not mix alpha/beta versions if
 
1513
      they are not exactly the same version, with example of 5.0.3->5.0.2 and
 
1514
      5.0.4->5.0.3. If replication is from older to new, the new will
 
1515
      recognize Q_CATALOG_CODE and have no problem.
 
1516
    */
 
1517
  }
 
1518
  if (auto_increment_increment != 1 || auto_increment_offset != 1)
 
1519
  {
 
1520
    *start++= Q_AUTO_INCREMENT;
 
1521
    int2store(start, auto_increment_increment);
 
1522
    int2store(start+2, auto_increment_offset);
 
1523
    start+= 4;
 
1524
  }
 
1525
  if (charset_inited)
 
1526
  {
 
1527
    *start++= Q_CHARSET_CODE;
 
1528
    memcpy(start, charset, 6);
 
1529
    start+= 6;
 
1530
  }
 
1531
  if (time_zone_len)
 
1532
  {
 
1533
    /* In the TZ sys table, column Name is of length 64 so this should be ok */
 
1534
    assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
 
1535
    *start++= Q_TIME_ZONE_CODE;
 
1536
    *start++= time_zone_len;
 
1537
    memcpy(start, time_zone_str, time_zone_len);
 
1538
    start+= time_zone_len;
 
1539
  }
1190
1540
  if (lc_time_names_number)
1191
1541
  {
1192
1542
    assert(lc_time_names_number <= 0xFFFF);
1223
1573
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1224
1574
 
1225
1575
  return (write_header(file, event_length) ||
1226
 
          my_b_safe_write(file, (unsigned char*) buf, QUERY_HEADER_LEN) ||
 
1576
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
1227
1577
          write_post_header_for_derived(file) ||
1228
 
          my_b_safe_write(file, (unsigned char*) start_of_status,
 
1578
          my_b_safe_write(file, (uchar*) start_of_status,
1229
1579
                          (uint) (start-start_of_status)) ||
1230
 
          my_b_safe_write(file, (db) ? (unsigned char*) db : (unsigned char*)"", db_len + 1) ||
1231
 
          my_b_safe_write(file, (unsigned char*) query, q_len)) ? 1 : 0;
 
1580
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
 
1581
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
1232
1582
}
1233
1583
 
1234
1584
/**
1245
1595
/*
1246
1596
  SYNOPSIS
1247
1597
    Query_log_event::Query_log_event()
1248
 
      session_arg           - thread handle
 
1598
      thd_arg           - thread handle
1249
1599
      query_arg         - array of char representing the query
1250
1600
      query_length      - size of the  `query_arg' array
1251
1601
      using_trans       - there is a modified transactional table
1252
1602
      suppress_use      - suppress the generation of 'USE' statements
1253
 
      killed_status_arg - an optional with default to Session::KILLED_NO_VALUE
 
1603
      killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
1254
1604
                          if the value is different from the default, the arg
1255
 
                          is set to the current session->killed value.
1256
 
                          A caller might need to masquerade session->killed with
1257
 
                          Session::NOT_KILLED.
 
1605
                          is set to the current thd->killed value.
 
1606
                          A caller might need to masquerade thd->killed with
 
1607
                          THD::NOT_KILLED.
1258
1608
  DESCRIPTION
1259
1609
  Creates an event for binlogging
1260
1610
  The value for local `killed_status' can be supplied by caller.
1261
1611
*/
1262
 
Query_log_event::Query_log_event(Session* session_arg, const char* query_arg,
1263
 
                                 ulong query_length, bool using_trans,
1264
 
                                 bool suppress_use,
1265
 
                                 Session::killed_state killed_status_arg)
1266
 
:Log_event(session_arg,
1267
 
           (session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) |
1268
 
           (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1269
 
           using_trans),
1270
 
  data_buf(0), query(query_arg), catalog(session_arg->catalog),
1271
 
  db(session_arg->db), q_len((uint32_t) query_length),
1272
 
  thread_id(session_arg->thread_id),
1273
 
  /* save the original thread id; we already know the server id */
1274
 
  slave_proxy_id(session_arg->variables.pseudo_thread_id),
1275
 
  flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1276
 
  sql_mode(0),
1277
 
  auto_increment_increment(session_arg->variables.auto_increment_increment),
1278
 
  auto_increment_offset(session_arg->variables.auto_increment_offset),
1279
 
  lc_time_names_number(session_arg->variables.lc_time_names->number),
 
1612
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
 
1613
                                 ulong query_length, bool using_trans,
 
1614
                                 bool suppress_use,
 
1615
                                 THD::killed_state killed_status_arg)
 
1616
  :Log_event(thd_arg,
 
1617
             (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
 
1618
              0) |
 
1619
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
 
1620
             using_trans),
 
1621
   data_buf(0), query(query_arg), catalog(thd_arg->catalog),
 
1622
   db(thd_arg->db), q_len((uint32_t) query_length),
 
1623
   thread_id(thd_arg->thread_id),
 
1624
   /* save the original thread id; we already know the server id */
 
1625
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
 
1626
   flags2_inited(1), sql_mode_inited(1), charset_inited(1),
 
1627
   sql_mode(0),
 
1628
   auto_increment_increment(thd_arg->variables.auto_increment_increment),
 
1629
   auto_increment_offset(thd_arg->variables.auto_increment_offset),
 
1630
   lc_time_names_number(thd_arg->variables.lc_time_names->number),
1280
1631
   charset_database_number(0)
1281
1632
{
1282
1633
  time_t end_time;
1283
1634
 
1284
 
  if (killed_status_arg == Session::KILLED_NO_VALUE)
1285
 
    killed_status_arg= session_arg->killed;
 
1635
  if (killed_status_arg == THD::KILLED_NO_VALUE)
 
1636
    killed_status_arg= thd_arg->killed;
1286
1637
 
1287
1638
  error_code=
1288
 
    (killed_status_arg == Session::NOT_KILLED) ?
1289
 
    (session_arg->is_error() ? session_arg->main_da.sql_errno() : 0) :
1290
 
    (session_arg->killed_errno());
 
1639
    (killed_status_arg == THD::NOT_KILLED) ?
 
1640
    (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
 
1641
    (thd_arg->killed_errno());
1291
1642
  
1292
1643
  time(&end_time);
1293
 
  exec_time = (ulong) (end_time  - session_arg->start_time);
 
1644
  exec_time = (ulong) (end_time  - thd_arg->start_time);
1294
1645
  /**
1295
1646
    @todo this means that if we have no catalog, then it is replicated
1296
1647
    as an existing catalog of length zero. is that safe? /sven
1298
1649
  catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
1299
1650
  /* status_vars_len is set just before writing the event */
1300
1651
  db_len = (db) ? (uint32_t) strlen(db) : 0;
1301
 
  if (session_arg->variables.collation_database != session_arg->db_charset)
1302
 
    charset_database_number= session_arg->variables.collation_database->number;
 
1652
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
 
1653
    charset_database_number= thd_arg->variables.collation_database->number;
1303
1654
  
1304
1655
  /*
1305
1656
    If we don't use flags2 for anything else than options contained in
1306
 
    session_arg->options, it would be more efficient to flags2=session_arg->options
 
1657
    thd_arg->options, it would be more efficient to flags2=thd_arg->options
1307
1658
    (OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1308
1659
    But it's likely that we don't want to use 32 bits for 3 bits; in the future
1309
1660
    we will probably want to reclaim the 29 bits. So we need the &.
1310
1661
  */
1311
 
  flags2= (uint32_t) (session_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1312
 
  assert(session_arg->variables.character_set_client->number < 256*256);
1313
 
  assert(session_arg->variables.collation_connection->number < 256*256);
1314
 
  assert(session_arg->variables.collation_server->number < 256*256);
1315
 
  assert(session_arg->variables.character_set_client->mbminlen == 1);
1316
 
  int2store(charset, session_arg->variables.character_set_client->number);
1317
 
  int2store(charset+2, session_arg->variables.collation_connection->number);
1318
 
  int2store(charset+4, session_arg->variables.collation_server->number);
1319
 
  time_zone_len= 0;
 
1662
  flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
 
1663
  assert(thd_arg->variables.character_set_client->number < 256*256);
 
1664
  assert(thd_arg->variables.collation_connection->number < 256*256);
 
1665
  assert(thd_arg->variables.collation_server->number < 256*256);
 
1666
  assert(thd_arg->variables.character_set_client->mbminlen == 1);
 
1667
  int2store(charset, thd_arg->variables.character_set_client->number);
 
1668
  int2store(charset+2, thd_arg->variables.collation_connection->number);
 
1669
  int2store(charset+4, thd_arg->variables.collation_server->number);
 
1670
  if (thd_arg->time_zone_used)
 
1671
  {
 
1672
    /*
 
1673
      Note that our event becomes dependent on the Time_zone object
 
1674
      representing the time zone. Fortunately such objects are never deleted
 
1675
      or changed during mysqld's lifetime.
 
1676
    */
 
1677
    time_zone_len= thd_arg->variables.time_zone->get_name()->length();
 
1678
    time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
 
1679
  }
 
1680
  else
 
1681
    time_zone_len= 0;
 
1682
}
 
1683
#endif /* MYSQL_CLIENT */
 
1684
 
 
1685
 
 
1686
/* 2 utility functions for the next method */
 
1687
 
 
1688
/**
 
1689
   Read a string with length from memory.
 
1690
 
 
1691
   This function reads the string-with-length stored at
 
1692
   <code>src</code> and extract the length into <code>*len</code> and
 
1693
   a pointer to the start of the string into <code>*dst</code>. The
 
1694
   string can then be copied using <code>memcpy()</code> with the
 
1695
   number of bytes given in <code>*len</code>.
 
1696
 
 
1697
   @param src Pointer to variable holding a pointer to the memory to
 
1698
              read the string from.
 
1699
   @param dst Pointer to variable holding a pointer where the actual
 
1700
              string starts. Starting from this position, the string
 
1701
              can be copied using @c memcpy().
 
1702
   @param len Pointer to variable where the length will be stored.
 
1703
   @param end One-past-the-end of the memory where the string is
 
1704
              stored.
 
1705
 
 
1706
   @return    Zero if the entire string can be copied successfully,
 
1707
              @c UINT_MAX if the length could not be read from memory
 
1708
              (that is, if <code>*src >= end</code>), otherwise the
 
1709
              number of bytes that are missing to read the full
 
1710
              string, which happends <code>*dst + *len >= end</code>.
 
1711
*/
 
1712
static int
 
1713
get_str_len_and_pointer(const Log_event::Byte **src,
 
1714
                        const char **dst,
 
1715
                        uint *len,
 
1716
                        const Log_event::Byte *end)
 
1717
{
 
1718
  if (*src >= end)
 
1719
    return -1;       // Will be UINT_MAX in two-complement arithmetics
 
1720
  uint length= **src;
 
1721
  if (length > 0)
 
1722
  {
 
1723
    if (*src + length >= end)
 
1724
      return *src + length - end + 1;       // Number of bytes missing
 
1725
    *dst= (char *)*src + 1;                    // Will be copied later
 
1726
  }
 
1727
  *len= length;
 
1728
  *src+= length + 1;
 
1729
  return 0;
1320
1730
}
1321
1731
 
1322
1732
static void copy_str_and_move(const char **src, 
1323
1733
                              Log_event::Byte **dst, 
1324
 
                              uint32_t len)
 
1734
                              uint len)
1325
1735
{
1326
1736
  memcpy(*dst, *src, len);
1327
1737
  *src= (const char *)*dst;
1339
1749
 */
1340
1750
#define CHECK_SPACE(PTR,END,CNT)                      \
1341
1751
  do {                                                \
1342
 
    assert((PTR) + (CNT) <= (END));                   \
 
1752
    assert((PTR) + (CNT) <= (END));              \
1343
1753
    if ((PTR) + (CNT) > (END)) {                      \
1344
1754
      query= 0;                                       \
1345
 
      return;                                         \
 
1755
      return;                               \
1346
1756
    }                                                 \
1347
1757
  } while (0)
1348
1758
 
1350
1760
/**
1351
1761
  This is used by the SQL slave thread to prepare the event before execution.
1352
1762
*/
1353
 
Query_log_event::Query_log_event(const char* buf, uint32_t event_len,
 
1763
Query_log_event::Query_log_event(const char* buf, uint event_len,
1354
1764
                                 const Format_description_log_event
1355
1765
                                 *description_event,
1356
1766
                                 Log_event_type event_type)
1357
 
  :Log_event(buf, description_event), data_buf(0), query(NULL),
1358
 
   db(NULL), catalog_len(0), status_vars_len(0),
 
1767
  :Log_event(buf, description_event), data_buf(0), query(NullS),
 
1768
   db(NullS), catalog_len(0), status_vars_len(0),
1359
1769
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1360
1770
   auto_increment_increment(1), auto_increment_offset(1),
1361
1771
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1362
1772
{
1363
 
  uint32_t data_len;
 
1773
  ulong data_len;
1364
1774
  uint32_t tmp;
1365
1775
  uint8_t common_header_len, post_header_len;
1366
1776
  Log_event::Byte *start;
1400
1810
      be even bigger, but this will suffice to catch most corruption
1401
1811
      errors that can lead to a crash.
1402
1812
    */
1403
 
    if (status_vars_len > cmin(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
 
1813
    if (status_vars_len > min(data_len, MAX_SIZE_LOG_EVENT_STATUS))
1404
1814
    {
1405
1815
      query= 0;
1406
1816
      return;
1427
1837
      flags2= uint4korr(pos);
1428
1838
      pos+= 4;
1429
1839
      break;
 
1840
    case Q_SQL_MODE_CODE:
 
1841
    {
 
1842
      CHECK_SPACE(pos, end, 8);
 
1843
      sql_mode_inited= 1;
 
1844
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is uint64_t
 
1845
      pos+= 8;
 
1846
      break;
 
1847
    }
 
1848
    case Q_CATALOG_NZ_CODE:
 
1849
      if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
 
1850
      {
 
1851
        query= 0;
 
1852
        return;
 
1853
      }
 
1854
      break;
 
1855
    case Q_AUTO_INCREMENT:
 
1856
      CHECK_SPACE(pos, end, 4);
 
1857
      auto_increment_increment= uint2korr(pos);
 
1858
      auto_increment_offset=    uint2korr(pos+2);
 
1859
      pos+= 4;
 
1860
      break;
 
1861
    case Q_CHARSET_CODE:
 
1862
    {
 
1863
      CHECK_SPACE(pos, end, 6);
 
1864
      charset_inited= 1;
 
1865
      memcpy(charset, pos, 6);
 
1866
      pos+= 6;
 
1867
      break;
 
1868
    }
 
1869
    case Q_TIME_ZONE_CODE:
 
1870
    {
 
1871
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
 
1872
      {
 
1873
        query= 0;
 
1874
        return;
 
1875
      }
 
1876
      break;
 
1877
    }
 
1878
    case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
 
1879
      CHECK_SPACE(pos, end, 1);
 
1880
      if ((catalog_len= *pos))
 
1881
        catalog= (char*) pos+1;                           // Will be copied later
 
1882
      CHECK_SPACE(pos, end, catalog_len + 2);
 
1883
      pos+= catalog_len+2; // leap over end 0
 
1884
      catalog_nz= 0; // catalog has end 0 in event
 
1885
      break;
1430
1886
    case Q_LC_TIME_NAMES_CODE:
1431
1887
      CHECK_SPACE(pos, end, 2);
1432
1888
      lc_time_names_number= uint2korr(pos);
1439
1895
      break;
1440
1896
    default:
1441
1897
      /* That's why you must write status vars in growing order of code */
1442
 
      pos= (const unsigned char*) end;                         // Break loop
 
1898
      pos= (const uchar*) end;                         // Break loop
1443
1899
    }
1444
1900
  }
1445
1901
  
1475
1931
  */
1476
1932
 
1477
1933
  /* A 2nd variable part; this is common to all versions */ 
1478
 
  memcpy(start, end, data_len);          // Copy db and query
 
1934
  memcpy((char*) start, end, data_len);          // Copy db and query
1479
1935
  start[data_len]= '\0';              // End query with \0 (For safetly)
1480
1936
  db= (char *)start;
1481
1937
  query= (char *)(start + db_len + 1);
1484
1940
}
1485
1941
 
1486
1942
 
 
1943
#ifdef MYSQL_CLIENT
 
1944
/**
 
1945
  Query_log_event::print().
 
1946
 
 
1947
  @todo
 
1948
    print the catalog ??
 
1949
*/
 
1950
void Query_log_event::print_query_header(IO_CACHE* file,
 
1951
                                         PRINT_EVENT_INFO* print_event_info)
 
1952
{
 
1953
  // TODO: print the catalog ??
 
1954
  char buff[40],*end;                           // Enough for SET TIMESTAMP
 
1955
  bool different_db= 1;
 
1956
  uint32_t tmp;
 
1957
 
 
1958
  if (!print_event_info->short_form)
 
1959
  {
 
1960
    print_header(file, print_event_info, false);
 
1961
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
 
1962
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
 
1963
                error_code);
 
1964
  }
 
1965
 
 
1966
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
 
1967
  {
 
1968
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
 
1969
      memcpy(print_event_info->db, db, db_len + 1);
 
1970
    if (db[0] && different_db) 
 
1971
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
 
1972
  }
 
1973
 
 
1974
  end=int10_to_str((long) when, strmov(buff,"SET TIMESTAMP="),10);
 
1975
  end= strmov(end, print_event_info->delimiter);
 
1976
  *end++='\n';
 
1977
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
 
1978
  if ((!print_event_info->thread_id_printed ||
 
1979
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
 
1980
        thread_id != print_event_info->thread_id)))
 
1981
  {
 
1982
    // If --short-form, print deterministic value instead of pseudo_thread_id.
 
1983
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
 
1984
                short_form ? 999999999 : (ulong)thread_id,
 
1985
                print_event_info->delimiter);
 
1986
    print_event_info->thread_id= thread_id;
 
1987
    print_event_info->thread_id_printed= 1;
 
1988
  }
 
1989
 
 
1990
  /*
 
1991
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
 
1992
    print (remember we don't produce mixed relay logs so there cannot be
 
1993
    5.0 events before that one so there is nothing to reset).
 
1994
  */
 
1995
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
 
1996
  {
 
1997
    /* tmp is a bitmask of bits which have changed. */
 
1998
    if (likely(print_event_info->flags2_inited)) 
 
1999
      /* All bits which have changed */
 
2000
      tmp= (print_event_info->flags2) ^ flags2;
 
2001
    else /* that's the first Query event we read */
 
2002
    {
 
2003
      print_event_info->flags2_inited= 1;
 
2004
      tmp= ~((uint32_t)0); /* all bits have changed */
 
2005
    }
 
2006
 
 
2007
    if (unlikely(tmp)) /* some bits have changed */
 
2008
    {
 
2009
      bool need_comma= 0;
 
2010
      my_b_printf(file, "SET ");
 
2011
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
 
2012
                   "@@session.foreign_key_checks", &need_comma);
 
2013
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
 
2014
                   "@@session.sql_auto_is_null", &need_comma);
 
2015
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
 
2016
                   "@@session.unique_checks", &need_comma);
 
2017
      my_b_printf(file,"%s\n", print_event_info->delimiter);
 
2018
      print_event_info->flags2= flags2;
 
2019
    }
 
2020
  }
 
2021
 
 
2022
  /*
 
2023
    Now the session variables;
 
2024
    it's more efficient to pass SQL_MODE as a number instead of a
 
2025
    comma-separated list.
 
2026
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
 
2027
    variables (they have no global version; they're not listed in
 
2028
    sql_class.h), The tests below work for pure binlogs or pure relay
 
2029
    logs. Won't work for mixed relay logs but we don't create mixed
 
2030
    relay logs (that is, there is no relay log with a format change
 
2031
    except within the 3 first events, which mysqlbinlog handles
 
2032
    gracefully). So this code should always be good.
 
2033
  */
 
2034
 
 
2035
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
 
2036
      print_event_info->auto_increment_offset != auto_increment_offset)
 
2037
  {
 
2038
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
 
2039
                auto_increment_increment,auto_increment_offset,
 
2040
                print_event_info->delimiter);
 
2041
    print_event_info->auto_increment_increment= auto_increment_increment;
 
2042
    print_event_info->auto_increment_offset=    auto_increment_offset;
 
2043
  }
 
2044
 
 
2045
  /* TODO: print the catalog when we feature SET CATALOG */
 
2046
 
 
2047
  if (likely(charset_inited) &&
 
2048
      (unlikely(!print_event_info->charset_inited ||
 
2049
                memcmp((uchar*) print_event_info->charset, (uchar*) charset, 6))))
 
2050
  {
 
2051
    CHARSET_INFO *cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
 
2052
    if (cs_info)
 
2053
    {
 
2054
      /* for mysql client */
 
2055
      my_b_printf(file, "/*!\\C %s */%s\n",
 
2056
                  cs_info->csname, print_event_info->delimiter);
 
2057
    }
 
2058
    my_b_printf(file,"SET "
 
2059
                "@@session.character_set_client=%d,"
 
2060
                "@@session.collation_connection=%d,"
 
2061
                "@@session.collation_server=%d"
 
2062
                "%s\n",
 
2063
                uint2korr(charset),
 
2064
                uint2korr(charset+2),
 
2065
                uint2korr(charset+4),
 
2066
                print_event_info->delimiter);
 
2067
    memcpy(print_event_info->charset, charset, 6);
 
2068
    print_event_info->charset_inited= 1;
 
2069
  }
 
2070
  if (time_zone_len)
 
2071
  {
 
2072
    if (memcmp((uchar*) print_event_info->time_zone_str,
 
2073
               (uchar*) time_zone_str, time_zone_len+1))
 
2074
    {
 
2075
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
 
2076
                  time_zone_str, print_event_info->delimiter);
 
2077
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
 
2078
    }
 
2079
  }
 
2080
  if (lc_time_names_number != print_event_info->lc_time_names_number)
 
2081
  {
 
2082
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
 
2083
                lc_time_names_number, print_event_info->delimiter);
 
2084
    print_event_info->lc_time_names_number= lc_time_names_number;
 
2085
  }
 
2086
  if (charset_database_number != print_event_info->charset_database_number)
 
2087
  {
 
2088
    if (charset_database_number)
 
2089
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
 
2090
                  charset_database_number, print_event_info->delimiter);
 
2091
    else
 
2092
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
 
2093
                  print_event_info->delimiter);
 
2094
    print_event_info->charset_database_number= charset_database_number;
 
2095
  }
 
2096
}
 
2097
 
 
2098
 
 
2099
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2100
{
 
2101
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
2102
 
 
2103
  print_query_header(&cache, print_event_info);
 
2104
  my_b_write(&cache, (uchar*) query, q_len);
 
2105
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
 
2106
}
 
2107
#endif /* MYSQL_CLIENT */
 
2108
 
 
2109
 
1487
2110
/*
1488
2111
  Query_log_event::do_apply_event()
1489
2112
*/
 
2113
 
 
2114
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
2115
 
1490
2116
int Query_log_event::do_apply_event(Relay_log_info const *rli)
1491
2117
{
1492
2118
  return do_apply_event(rli, query, q_len);
1503
2129
     sql_print_error("Slave: did not get the expected number of affected \
1504
2130
     rows running query from master - expected %d, got %d (this numbers \
1505
2131
     should have matched modulo 4294967296).", 0, ...);
1506
 
     session->query_error = 1;
 
2132
     thd->query_error = 1;
1507
2133
     }
1508
2134
  @endcode
1509
2135
  We may also want an option to tell the slave to ignore "affected"
1515
2141
{
1516
2142
  LEX_STRING new_db;
1517
2143
  int expected_error,actual_error= 0;
1518
 
  Query_id &query_id= Query_id::get_query_id();
1519
2144
  /*
1520
 
    Colleagues: please never free(session->catalog) in MySQL. This would
1521
 
    lead to bugs as here session->catalog is a part of an alloced block,
 
2145
    Colleagues: please never free(thd->catalog) in MySQL. This would
 
2146
    lead to bugs as here thd->catalog is a part of an alloced block,
1522
2147
    not an entire alloced block (see
1523
 
    Query_log_event::do_apply_event()). Same for session->db.  Thank
 
2148
    Query_log_event::do_apply_event()). Same for thd->db.  Thank
1524
2149
    you.
1525
2150
  */
1526
 
  session->catalog= catalog_len ? (char *) catalog : (char *)"";
 
2151
  thd->catalog= catalog_len ? (char *) catalog : (char *)"";
1527
2152
  new_db.length= db_len;
1528
2153
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
1529
 
  session->set_db(new_db.str, new_db.length);       /* allocates a copy of 'db' */
1530
 
  session->variables.auto_increment_increment= auto_increment_increment;
1531
 
  session->variables.auto_increment_offset=    auto_increment_offset;
 
2154
  thd->set_db(new_db.str, new_db.length);       /* allocates a copy of 'db' */
 
2155
  thd->variables.auto_increment_increment= auto_increment_increment;
 
2156
  thd->variables.auto_increment_offset=    auto_increment_offset;
1532
2157
 
1533
2158
  /*
1534
2159
    InnoDB internally stores the master log position it has executed so far,
1542
2167
  */
1543
2168
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
1544
2169
 
1545
 
  clear_all_errors(session, const_cast<Relay_log_info*>(rli));
 
2170
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
1546
2171
  const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
1547
2172
 
1548
2173
  /*
1555
2180
            ::do_apply_event(), then the companion SET also have so
1556
2181
            we don't need to reset_one_shot_variables().
1557
2182
  */
1558
 
  if (rpl_filter->db_ok(session->db))
 
2183
  if (rpl_filter->db_ok(thd->db))
1559
2184
  {
1560
 
    session->set_time((time_t)when);
1561
 
    session->query_length= q_len_arg;
1562
 
    session->query= (char*)query_arg;
1563
 
    session->query_id= query_id.next();
1564
 
    session->variables.pseudo_thread_id= thread_id;             // for temp tables
 
2185
    thd->set_time((time_t)when);
 
2186
    thd->query_length= q_len_arg;
 
2187
    thd->query= (char*)query_arg;
 
2188
    VOID(pthread_mutex_lock(&LOCK_thread_count));
 
2189
    thd->query_id = next_query_id();
 
2190
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2191
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
1565
2192
 
1566
2193
    if (ignored_error_code((expected_error= error_code)) ||
1567
 
        !check_expected_error(session,rli,expected_error))
 
2194
        !check_expected_error(thd,rli,expected_error))
1568
2195
    {
1569
2196
      if (flags2_inited)
1570
2197
        /*
1571
 
          all bits of session->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
 
2198
          all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
1572
2199
          must take their value from flags2.
1573
2200
        */
1574
 
        session->options= flags2|(session->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2201
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
 
2202
      /*
 
2203
        else, we are in a 3.23/4.0 binlog; we previously received a
 
2204
        Rotate_log_event which reset thd->options and sql_mode etc, so
 
2205
        nothing to do.
 
2206
      */
 
2207
      if (charset_inited)
 
2208
      {
 
2209
        if (rli->cached_charset_compare(charset))
 
2210
        {
 
2211
          /* Verify that we support the charsets found in the event. */
 
2212
          if (!(thd->variables.character_set_client=
 
2213
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
 
2214
              !(thd->variables.collation_connection=
 
2215
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
 
2216
              !(thd->variables.collation_server=
 
2217
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
 
2218
          {
 
2219
            /*
 
2220
              We updated the thd->variables with nonsensical values (0). Let's
 
2221
              set them to something safe (i.e. which avoids crash), and we'll
 
2222
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
 
2223
              ignore this error).
 
2224
            */
 
2225
            set_slave_thread_default_charset(thd, rli);
 
2226
            goto compare_errors;
 
2227
          }
 
2228
          thd->update_charset(); // for the charset change to take effect
 
2229
        }
 
2230
      }
1575
2231
      if (time_zone_len)
1576
2232
      {
1577
2233
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
1578
 
        if (!(session->variables.time_zone= my_tz_find(session, &tmp)))
 
2234
        if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
1579
2235
        {
1580
2236
          my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
1581
 
          session->variables.time_zone= global_system_variables.time_zone;
 
2237
          thd->variables.time_zone= global_system_variables.time_zone;
1582
2238
          goto compare_errors;
1583
2239
        }
1584
2240
      }
1585
2241
      if (lc_time_names_number)
1586
2242
      {
1587
 
        if (!(session->variables.lc_time_names=
 
2243
        if (!(thd->variables.lc_time_names=
1588
2244
              my_locale_by_number(lc_time_names_number)))
1589
2245
        {
1590
2246
          my_printf_error(ER_UNKNOWN_ERROR,
1591
2247
                      "Unknown locale: '%d'", MYF(0), lc_time_names_number);
1592
 
          session->variables.lc_time_names= &my_locale_en_US;
 
2248
          thd->variables.lc_time_names= &my_locale_en_US;
1593
2249
          goto compare_errors;
1594
2250
        }
1595
2251
      }
1596
2252
      else
1597
 
        session->variables.lc_time_names= &my_locale_en_US;
 
2253
        thd->variables.lc_time_names= &my_locale_en_US;
1598
2254
      if (charset_database_number)
1599
2255
      {
1600
 
        const CHARSET_INFO *cs;
 
2256
        CHARSET_INFO *cs;
1601
2257
        if (!(cs= get_charset(charset_database_number, MYF(0))))
1602
2258
        {
1603
2259
          char buf[20];
1605
2261
          my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
1606
2262
          goto compare_errors;
1607
2263
        }
1608
 
        session->variables.collation_database= cs;
 
2264
        thd->variables.collation_database= cs;
1609
2265
      }
1610
2266
      else
1611
 
        session->variables.collation_database= session->db_charset;
 
2267
        thd->variables.collation_database= thd->db_charset;
1612
2268
      
1613
2269
      /* Execute the query (note that we bypass dispatch_command()) */
1614
2270
      const char* found_semicolon= NULL;
1615
 
      mysql_parse(session, session->query, session->query_length, &found_semicolon);
1616
 
      log_slow_statement(session);
 
2271
      mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
 
2272
      log_slow_statement(thd);
1617
2273
    }
1618
2274
    else
1619
2275
    {
1624
2280
        we exit gracefully; otherwise we warn about the bad error and tell DBA
1625
2281
        to check/fix it.
1626
2282
      */
1627
 
      if (mysql_test_parse_for_slave(session, session->query, session->query_length))
1628
 
        clear_all_errors(session, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
 
2283
      if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
 
2284
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
1629
2285
      else
1630
2286
      {
1631
 
        rli->report(ERROR_LEVEL, expected_error,
1632
 
                    _("Query partially completed on the master "
1633
 
                      "(error on master: %d) and was aborted. There is a "
1634
 
                      "chance that your master is inconsistent at this "
1635
 
                      "point. If you are sure that your master is ok, run "
1636
 
                      "this query manually on the slave and then restart the "
1637
 
                      "slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; "
1638
 
                      "START SLAVE; . Query: '%s'"),
1639
 
                    expected_error, session->query);
1640
 
        session->is_slave_error= 1;
 
2287
        rli->report(ERROR_LEVEL, expected_error, 
 
2288
                          "\
 
2289
Query partially completed on the master (error on master: %d) \
 
2290
and was aborted. There is a chance that your master is inconsistent at this \
 
2291
point. If you are sure that your master is ok, run this query manually on the \
 
2292
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
 
2293
START SLAVE; . Query: '%s'", expected_error, thd->query);
 
2294
        thd->is_slave_error= 1;
1641
2295
      }
1642
2296
      goto end;
1643
2297
    }
1644
2298
 
 
2299
    /* If the query was not ignored, it is printed to the general log */
 
2300
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
 
2301
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
 
2302
 
1645
2303
compare_errors:
1646
2304
 
1647
2305
     /*
1648
2306
      If we expected a non-zero error code, and we don't get the same error
1649
2307
      code, and none of them should be ignored.
1650
2308
    */
1651
 
    actual_error= session->is_error() ? session->main_da.sql_errno() : 0;
 
2309
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
1652
2310
    if ((expected_error != actual_error) &&
1653
 
        expected_error &&
1654
 
        !ignored_error_code(actual_error) &&
1655
 
        !ignored_error_code(expected_error))
 
2311
        expected_error &&
 
2312
        !ignored_error_code(actual_error) &&
 
2313
        !ignored_error_code(expected_error))
1656
2314
    {
1657
2315
      rli->report(ERROR_LEVEL, 0,
1658
 
                  _("Query caused differenxt errors on master and slave.\n"
1659
 
                    "Error on master: '%s' (%d), Error on slave: '%s' (%d).\n"
1660
 
                    "Default database: '%s'. Query: '%s'"),
1661
 
                  ER(expected_error),
1662
 
                  expected_error,
1663
 
                  actual_error ? session->main_da.message() : _("no error"),
1664
 
                  actual_error,
1665
 
                  print_slave_db_safe(db), query_arg);
1666
 
      session->is_slave_error= 1;
 
2316
                      "\
 
2317
Query caused different errors on master and slave.     \
 
2318
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
 
2319
Default database: '%s'. Query: '%s'",
 
2320
                      ER_SAFE(expected_error),
 
2321
                      expected_error,
 
2322
                      actual_error ? thd->main_da.message() : "no error",
 
2323
                      actual_error,
 
2324
                      print_slave_db_safe(db), query_arg);
 
2325
      thd->is_slave_error= 1;
1667
2326
    }
1668
2327
    /*
1669
2328
      If we get the same error code as expected, or they should be ignored. 
1671
2330
    else if (expected_error == actual_error ||
1672
2331
             ignored_error_code(actual_error))
1673
2332
    {
1674
 
      clear_all_errors(session, const_cast<Relay_log_info*>(rli));
1675
 
      session->killed= Session::NOT_KILLED;
 
2333
      clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
2334
      thd->killed= THD::NOT_KILLED;
1676
2335
    }
1677
2336
    /*
1678
2337
      Other cases: mostly we expected no error and get one.
1679
2338
    */
1680
 
    else if (session->is_slave_error || session->is_fatal_error)
 
2339
    else if (thd->is_slave_error || thd->is_fatal_error)
1681
2340
    {
1682
2341
      rli->report(ERROR_LEVEL, actual_error,
1683
 
                  _("Error '%s' on query. Default database: '%s'. Query: '%s'"),
1684
 
                  (actual_error ? session->main_da.message() :
1685
 
                   _("unexpected success or fatal error")),
1686
 
                      print_slave_db_safe(session->db), query_arg);
1687
 
      session->is_slave_error= 1;
 
2342
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
 
2343
                      (actual_error ? thd->main_da.message() :
 
2344
                       "unexpected success or fatal error"),
 
2345
                      print_slave_db_safe(thd->db), query_arg);
 
2346
      thd->is_slave_error= 1;
1688
2347
    }
1689
2348
 
1690
2349
    /*
1695
2354
      sql_print_error("Slave: did not get the expected number of affected \
1696
2355
      rows running query from master - expected %d, got %d (this numbers \
1697
2356
      should have matched modulo 4294967296).", 0, ...);
1698
 
      session->is_slave_error = 1;
 
2357
      thd->is_slave_error = 1;
1699
2358
      }
1700
2359
      We may also want an option to tell the slave to ignore "affected"
1701
2360
      mismatch. This mismatch could be implemented with a new ER_ code, and
1711
2370
  } /* End of if (db_ok(... */
1712
2371
 
1713
2372
end:
1714
 
  pthread_mutex_lock(&LOCK_thread_count);
 
2373
  VOID(pthread_mutex_lock(&LOCK_thread_count));
1715
2374
  /*
1716
 
    Probably we have set session->query, session->db, session->catalog to point to places
 
2375
    Probably we have set thd->query, thd->db, thd->catalog to point to places
1717
2376
    in the data_buf of this event. Now the event is going to be deleted
1718
 
    probably, so data_buf will be freed, so the session->... listed above will be
 
2377
    probably, so data_buf will be freed, so the thd->... listed above will be
1719
2378
    pointers to freed memory. 
1720
2379
    So we must set them to 0, so that those bad pointers values are not later
1721
 
    used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
 
2380
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
1722
2381
    don't suffer from these assignments to 0 as DROP TEMPORARY
1723
 
    Table uses the db.table syntax.
1724
 
  */
1725
 
  session->catalog= 0;
1726
 
  session->set_db(NULL, 0);                 /* will free the current database */
1727
 
  session->query= 0;                    // just to be sure
1728
 
  session->query_length= 0;
1729
 
  pthread_mutex_unlock(&LOCK_thread_count);
1730
 
  close_thread_tables(session);      
1731
 
  session->first_successful_insert_id_in_prev_stmt= 0;
1732
 
  session->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
1733
 
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
1734
 
  return session->is_slave_error;
 
2382
    TABLE uses the db.table syntax.
 
2383
  */
 
2384
  thd->catalog= 0;
 
2385
  thd->set_db(NULL, 0);                 /* will free the current database */
 
2386
  thd->query= 0;                        // just to be sure
 
2387
  thd->query_length= 0;
 
2388
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2389
  close_thread_tables(thd);      
 
2390
  /*
 
2391
    As a disk space optimization, future masters will not log an event for
 
2392
    LAST_INSERT_ID() if that function returned 0 (and thus they will be able
 
2393
    to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
 
2394
    variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
 
2395
    resetting below we are ready to support that.
 
2396
  */
 
2397
  thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
 
2398
  thd->first_successful_insert_id_in_prev_stmt= 0;
 
2399
  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
 
2400
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
2401
  return thd->is_slave_error;
1735
2402
}
1736
2403
 
1737
2404
int Query_log_event::do_update_pos(Relay_log_info *rli)
1738
2405
{
1739
 
  return Log_event::do_update_pos(rli);
 
2406
  /*
 
2407
    Note that we will not increment group* positions if we are just
 
2408
    after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
 
2409
    from its following updating query.
 
2410
  */
 
2411
  if (thd->one_shot_set)
 
2412
  {
 
2413
    rli->inc_event_relay_log_pos();
 
2414
    return 0;
 
2415
  }
 
2416
  else
 
2417
    return Log_event::do_update_pos(rli);
1740
2418
}
1741
2419
 
1742
2420
 
1749
2427
  {
1750
2428
    if (strcmp("BEGIN", query) == 0)
1751
2429
    {
1752
 
      session->options|= OPTION_BEGIN;
 
2430
      thd->options|= OPTION_BEGIN;
1753
2431
      return(Log_event::continue_group(rli));
1754
2432
    }
1755
2433
 
1756
2434
    if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
1757
2435
    {
1758
 
      session->options&= ~OPTION_BEGIN;
 
2436
      thd->options&= ~OPTION_BEGIN;
1759
2437
      return(Log_event::EVENT_SKIP_COUNT);
1760
2438
    }
1761
2439
  }
1762
2440
  return(Log_event::do_shall_skip(rli));
1763
2441
}
1764
2442
 
 
2443
#endif
 
2444
 
1765
2445
 
1766
2446
/**************************************************************************
1767
2447
        Start_log_event_v3 methods
1768
2448
**************************************************************************/
1769
2449
 
 
2450
#ifndef MYSQL_CLIENT
1770
2451
Start_log_event_v3::Start_log_event_v3()
1771
2452
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
1772
2453
   artificial_event(0), dont_set_created(0)
1773
2454
{
1774
2455
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
1775
2456
}
 
2457
#endif
1776
2458
 
1777
2459
/*
1778
2460
  Start_log_event_v3::pack_info()
1779
2461
*/
1780
2462
 
 
2463
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1781
2464
void Start_log_event_v3::pack_info(Protocol *protocol)
1782
2465
{
1783
2466
  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
1784
 
  pos= my_stpcpy(buf, "Server ver: ");
1785
 
  pos= my_stpcpy(pos, server_version);
1786
 
  pos= my_stpcpy(pos, ", Binlog ver: ");
 
2467
  pos= strmov(buf, "Server ver: ");
 
2468
  pos= strmov(pos, server_version);
 
2469
  pos= strmov(pos, ", Binlog ver: ");
1787
2470
  pos= int10_to_str(binlog_version, pos, 10);
1788
2471
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
1789
2472
}
1790
 
 
 
2473
#endif
 
2474
 
 
2475
 
 
2476
/*
 
2477
  Start_log_event_v3::print()
 
2478
*/
 
2479
 
 
2480
#ifdef MYSQL_CLIENT
 
2481
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
2482
{
 
2483
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
2484
                               Write_on_release_cache::FLUSH_F);
 
2485
 
 
2486
  if (!print_event_info->short_form)
 
2487
  {
 
2488
    print_header(&cache, print_event_info, false);
 
2489
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
 
2490
                binlog_version, server_version);
 
2491
    print_timestamp(&cache);
 
2492
    if (created)
 
2493
      my_b_printf(&cache," at startup");
 
2494
    my_b_printf(&cache, "\n");
 
2495
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
 
2496
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
 
2497
                  "Most probably mysqld crashed writing it.\n");
 
2498
  }
 
2499
  if (!artificial_event && created)
 
2500
  {
 
2501
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
 
2502
    /*
 
2503
      This is for mysqlbinlog: like in replication, we want to delete the stale
 
2504
      tmp files left by an unclean shutdown of mysqld (temporary tables)
 
2505
      and rollback unfinished transaction.
 
2506
      Probably this can be done with RESET CONNECTION (syntax to be defined).
 
2507
    */
 
2508
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
 
2509
#else
 
2510
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
 
2511
#endif
 
2512
  }
 
2513
  if (temp_buf &&
 
2514
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
 
2515
      !print_event_info->short_form)
 
2516
  {
 
2517
    my_b_printf(&cache, "BINLOG '\n");
 
2518
    print_base64(&cache, print_event_info, false);
 
2519
    print_event_info->printed_fd_event= true;
 
2520
  }
 
2521
  return;
 
2522
}
 
2523
#endif /* MYSQL_CLIENT */
1791
2524
 
1792
2525
/*
1793
2526
  Start_log_event_v3::Start_log_event_v3()
1815
2548
  Start_log_event_v3::write()
1816
2549
*/
1817
2550
 
 
2551
#ifndef MYSQL_CLIENT
1818
2552
bool Start_log_event_v3::write(IO_CACHE* file)
1819
2553
{
1820
2554
  char buff[START_V3_HEADER_LEN];
1824
2558
    created= when= get_time();
1825
2559
  int4store(buff + ST_CREATED_OFFSET,created);
1826
2560
  return (write_header(file, sizeof(buff)) ||
1827
 
          my_b_safe_write(file, (unsigned char*) buff, sizeof(buff)));
 
2561
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
1828
2562
}
1829
 
 
 
2563
#endif
 
2564
 
 
2565
 
 
2566
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
1830
2567
 
1831
2568
/**
1832
2569
  Start_log_event_v3::do_apply_event() .
1834
2571
 
1835
2572
    IMPLEMENTATION
1836
2573
    - To handle the case where the master died without having time to write
1837
 
    DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
 
2574
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
1838
2575
    TODO), we clean up all temporary tables that we got, if we are sure we
1839
2576
    can (see below).
1840
2577
 
1860
2597
    */
1861
2598
    if (created)
1862
2599
    {
1863
 
      close_temporary_tables(session);
 
2600
      close_temporary_tables(thd);
1864
2601
      cleanup_load_tmpdir();
1865
2602
    }
1866
2603
    break;
1877
2614
        Can distinguish, based on the value of 'created': this event was
1878
2615
        generated at master startup.
1879
2616
      */
1880
 
      close_temporary_tables(session);
 
2617
      close_temporary_tables(thd);
1881
2618
    }
1882
2619
    /*
1883
2620
      Otherwise, can't distinguish a Start_log_event generated at
1891
2628
  }
1892
2629
  return(0);
1893
2630
}
 
2631
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
1894
2632
 
1895
2633
/***************************************************************************
1896
2634
       Format_description_log_event methods
1960
2698
      describes what those old master versions send.
1961
2699
    */
1962
2700
    if (binlog_ver==1)
1963
 
      my_stpcpy(server_version, server_ver ? server_ver : "3.23");
 
2701
      strmov(server_version, server_ver ? server_ver : "3.23");
1964
2702
    else
1965
 
      my_stpcpy(server_version, server_ver ? server_ver : "4.0");
 
2703
      strmov(server_version, server_ver ? server_ver : "4.0");
1966
2704
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
1967
2705
      LOG_EVENT_MINIMAL_HEADER_LEN;
1968
2706
    /*
2021
2759
 
2022
2760
Format_description_log_event::
2023
2761
Format_description_log_event(const char* buf,
2024
 
                             uint32_t event_len,
 
2762
                             uint event_len,
2025
2763
                             const
2026
2764
                             Format_description_log_event*
2027
2765
                             description_event)
2033
2771
  number_of_event_types=
2034
2772
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
2035
2773
  /* If alloc fails, we'll detect it in is_valid() */
2036
 
  post_header_len= (uint8_t*) my_memdup((unsigned char*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
 
2774
  post_header_len= (uint8_t*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2037
2775
                                      number_of_event_types*
2038
2776
                                      sizeof(*post_header_len), MYF(0));
2039
2777
  calc_server_version_split();
2108
2846
    if (number_of_event_types != 22)
2109
2847
    {
2110
2848
      /* this makes is_valid() return false. */
2111
 
      free(post_header_len);
 
2849
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
2112
2850
      post_header_len= NULL;
2113
2851
      return;
2114
2852
    }
2142
2880
  return;
2143
2881
}
2144
2882
 
 
2883
#ifndef MYSQL_CLIENT
2145
2884
bool Format_description_log_event::write(IO_CACHE* file)
2146
2885
{
2147
2886
  /*
2148
2887
    We don't call Start_log_event_v3::write() because this would make 2
2149
2888
    my_b_safe_write().
2150
2889
  */
2151
 
  unsigned char buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
2890
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
2152
2891
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2153
 
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
 
2892
  memcpy((char*) buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2154
2893
  if (!dont_set_created)
2155
2894
    created= when= get_time();
2156
2895
  int4store(buff + ST_CREATED_OFFSET,created);
2157
2896
  buff[ST_COMMON_HEADER_LEN_OFFSET]= LOG_EVENT_HEADER_LEN;
2158
 
  memcpy(buff+ST_COMMON_HEADER_LEN_OFFSET+1, post_header_len,
 
2897
  memcpy((char*) buff+ST_COMMON_HEADER_LEN_OFFSET+1, (uchar*) post_header_len,
2159
2898
         LOG_EVENT_TYPES);
2160
2899
  return (write_header(file, sizeof(buff)) ||
2161
2900
          my_b_safe_write(file, buff, sizeof(buff)));
2162
2901
}
2163
 
 
2164
 
 
 
2902
#endif
 
2903
 
 
2904
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2165
2905
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2166
2906
{
2167
2907
  /*
2175
2915
    original place when it comes to us; we'll know this by checking
2176
2916
    log_pos ("artificial" events have log_pos == 0).
2177
2917
  */
2178
 
  if (!artificial_event && created && session->transaction.all.ha_list)
 
2918
  if (!artificial_event && created && thd->transaction.all.ha_list)
2179
2919
  {
2180
2920
    /* This is not an error (XA is safe), just an information */
2181
2921
    rli->report(INFORMATION_LEVEL, 0,
2182
 
                _("Rolling back unfinished transaction (no COMMIT "
2183
 
                  "or ROLLBACK in relay log). A probable cause is that "
2184
 
                  "the master died while writing the transaction to "
2185
 
                  "its binary log, thus rolled back too."));
2186
 
    const_cast<Relay_log_info*>(rli)->cleanup_context(session, 1);
 
2922
                "Rolling back unfinished transaction (no COMMIT "
 
2923
                "or ROLLBACK in relay log). A probable cause is that "
 
2924
                "the master died while writing the transaction to "
 
2925
                "its binary log, thus rolled back too."); 
 
2926
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
2187
2927
  }
2188
2928
  /*
2189
2929
    If this event comes from ourselves, there is no cleaning task to
2190
2930
    perform, we don't call Start_log_event_v3::do_apply_event()
2191
2931
    (this was just to update the log's description event).
2192
2932
  */
2193
 
  if (server_id != ::server_id)
 
2933
  if (server_id != (uint32_t) ::server_id)
2194
2934
  {
2195
2935
    /*
2196
2936
      If the event was not requested by the slave i.e. the master sent
2212
2952
  delete rli->relay_log.description_event_for_exec;
2213
2953
  rli->relay_log.description_event_for_exec= this;
2214
2954
 
2215
 
  if (server_id == ::server_id)
 
2955
  if (server_id == (uint32_t) ::server_id)
2216
2956
  {
2217
2957
    /*
2218
2958
      We only increase the relay log position if we are skipping
2237
2977
}
2238
2978
 
2239
2979
Log_event::enum_skip_reason
2240
 
Format_description_log_event::do_shall_skip(Relay_log_info *)
 
2980
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((unused)))
2241
2981
{
2242
2982
  return Log_event::EVENT_SKIP_NOT;
2243
2983
}
2244
2984
 
 
2985
#endif
 
2986
 
2245
2987
 
2246
2988
/**
2247
2989
   Splits the event's 'server_version' string into three numeric pieces stored
2256
2998
{
2257
2999
  char *p= server_version, *r;
2258
3000
  ulong number;
2259
 
  for (uint32_t i= 0; i<=2; i++)
 
3001
  for (uint i= 0; i<=2; i++)
2260
3002
  {
2261
3003
    number= strtoul(p, &r, 10);
2262
 
    server_version_split[i]= (unsigned char)number;
2263
 
    assert(number < 256); // fit in unsigned char
 
3004
    server_version_split[i]= (uchar)number;
 
3005
    assert(number < 256); // fit in uchar
2264
3006
    p= r;
2265
3007
    assert(!((i == 0) && (*r != '.'))); // should be true in practice
2266
3008
    if (*r == '.')
2290
3032
  Load_log_event::pack_info()
2291
3033
*/
2292
3034
 
2293
 
uint32_t Load_log_event::get_query_buffer_length()
 
3035
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
3036
uint Load_log_event::get_query_buffer_length()
2294
3037
{
2295
3038
  return
2296
3039
    5 + db_len + 3 +                        // "use DB; "
2297
3040
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
2298
3041
    7 +                                     // LOCAL
2299
3042
    9 +                                     // " REPLACE or IGNORE "
2300
 
    13 + table_name_len*2 +                 // "INTO Table `table`"
 
3043
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
2301
3044
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
2302
3045
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
2303
3046
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
2315
3058
 
2316
3059
  if (need_db && db && db_len)
2317
3060
  {
2318
 
    pos= my_stpcpy(pos, "use `");
 
3061
    pos= strmov(pos, "use `");
2319
3062
    memcpy(pos, db, db_len);
2320
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
3063
    pos= strmov(pos+db_len, "`; ");
2321
3064
  }
2322
3065
 
2323
 
  pos= my_stpcpy(pos, "LOAD DATA ");
 
3066
  pos= strmov(pos, "LOAD DATA ");
2324
3067
 
2325
3068
  if (fn_start)
2326
3069
    *fn_start= pos;
2327
3070
 
2328
3071
  if (check_fname_outside_temp_buf())
2329
 
    pos= my_stpcpy(pos, "LOCAL ");
2330
 
  pos= my_stpcpy(pos, "INFILE '");
 
3072
    pos= strmov(pos, "LOCAL ");
 
3073
  pos= strmov(pos, "INFILE '");
2331
3074
  memcpy(pos, fname, fname_len);
2332
 
  pos= my_stpcpy(pos+fname_len, "' ");
 
3075
  pos= strmov(pos+fname_len, "' ");
2333
3076
 
2334
3077
  if (sql_ex.opt_flags & REPLACE_FLAG)
2335
 
    pos= my_stpcpy(pos, " REPLACE ");
 
3078
    pos= strmov(pos, " REPLACE ");
2336
3079
  else if (sql_ex.opt_flags & IGNORE_FLAG)
2337
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3080
    pos= strmov(pos, " IGNORE ");
2338
3081
 
2339
 
  pos= my_stpcpy(pos ,"INTO");
 
3082
  pos= strmov(pos ,"INTO");
2340
3083
 
2341
3084
  if (fn_end)
2342
3085
    *fn_end= pos;
2343
3086
 
2344
 
  pos= my_stpcpy(pos ," Table `");
 
3087
  pos= strmov(pos ," TABLE `");
2345
3088
  memcpy(pos, table_name, table_name_len);
2346
3089
  pos+= table_name_len;
2347
3090
 
2348
3091
  /* We have to create all optinal fields as the default is not empty */
2349
 
  pos= my_stpcpy(pos, "` FIELDS TERMINATED BY ");
 
3092
  pos= strmov(pos, "` FIELDS TERMINATED BY ");
2350
3093
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
2351
3094
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
2352
 
    pos= my_stpcpy(pos, " OPTIONALLY ");
2353
 
  pos= my_stpcpy(pos, " ENCLOSED BY ");
 
3095
    pos= strmov(pos, " OPTIONALLY ");
 
3096
  pos= strmov(pos, " ENCLOSED BY ");
2354
3097
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
2355
3098
 
2356
 
  pos= my_stpcpy(pos, " ESCAPED BY ");
 
3099
  pos= strmov(pos, " ESCAPED BY ");
2357
3100
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
2358
3101
 
2359
 
  pos= my_stpcpy(pos, " LINES TERMINATED BY ");
 
3102
  pos= strmov(pos, " LINES TERMINATED BY ");
2360
3103
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
2361
3104
  if (sql_ex.line_start_len)
2362
3105
  {
2363
 
    pos= my_stpcpy(pos, " STARTING BY ");
 
3106
    pos= strmov(pos, " STARTING BY ");
2364
3107
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
2365
3108
  }
2366
3109
 
2367
3110
  if ((long) skip_lines > 0)
2368
3111
  {
2369
 
    pos= my_stpcpy(pos, " IGNORE ");
 
3112
    pos= strmov(pos, " IGNORE ");
2370
3113
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
2371
 
    pos= my_stpcpy(pos," LINES ");    
 
3114
    pos= strmov(pos," LINES ");    
2372
3115
  }
2373
3116
 
2374
3117
  if (num_fields)
2375
3118
  {
2376
 
    uint32_t i;
 
3119
    uint i;
2377
3120
    const char *field= fields;
2378
 
    pos= my_stpcpy(pos, " (");
 
3121
    pos= strmov(pos, " (");
2379
3122
    for (i = 0; i < num_fields; i++)
2380
3123
    {
2381
3124
      if (i)
2402
3145
    return;
2403
3146
  print_query(true, buf, &end, 0, 0);
2404
3147
  protocol->store(buf, end-buf, &my_charset_bin);
2405
 
  free(buf);
 
3148
  my_free(buf, MYF(0));
2406
3149
}
2407
 
 
 
3150
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
3151
 
 
3152
 
 
3153
#ifndef MYSQL_CLIENT
2408
3154
 
2409
3155
/*
2410
3156
  Load_log_event::write_data_header()
2419
3165
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
2420
3166
  buf[L_DB_LEN_OFFSET] = (char)db_len;
2421
3167
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
2422
 
  return my_b_safe_write(file, (unsigned char*)buf, LOAD_HEADER_LEN) != 0;
 
3168
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
2423
3169
}
2424
3170
 
2425
3171
 
2433
3179
    return 1;
2434
3180
  if (num_fields && fields && field_lens)
2435
3181
  {
2436
 
    if (my_b_safe_write(file, (unsigned char*)field_lens, num_fields) ||
2437
 
        my_b_safe_write(file, (unsigned char*)fields, field_block_len))
 
3182
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
 
3183
        my_b_safe_write(file, (uchar*)fields, field_block_len))
2438
3184
      return 1;
2439
3185
  }
2440
 
  return (my_b_safe_write(file, (unsigned char*)table_name, table_name_len + 1) ||
2441
 
          my_b_safe_write(file, (unsigned char*)db, db_len + 1) ||
2442
 
          my_b_safe_write(file, (unsigned char*)fname, fname_len));
 
3186
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
 
3187
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
 
3188
          my_b_safe_write(file, (uchar*)fname, fname_len));
2443
3189
}
2444
3190
 
2445
3191
 
2447
3193
  Load_log_event::Load_log_event()
2448
3194
*/
2449
3195
 
2450
 
Load_log_event::Load_log_event(Session *session_arg, sql_exchange *ex,
 
3196
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
2451
3197
                               const char *db_arg, const char *table_name_arg,
2452
3198
                               List<Item> &fields_arg,
2453
3199
                               enum enum_duplicates handle_dup,
2454
3200
                               bool ignore, bool using_trans)
2455
 
  :Log_event(session_arg,
2456
 
             session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
 
3201
  :Log_event(thd_arg,
 
3202
             thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
2457
3203
             using_trans),
2458
 
   thread_id(session_arg->thread_id),
2459
 
   slave_proxy_id(session_arg->variables.pseudo_thread_id),
 
3204
   thread_id(thd_arg->thread_id),
 
3205
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
2460
3206
   num_fields(0),fields(0),
2461
3207
   field_lens(0),field_block_len(0),
2462
3208
   table_name(table_name_arg ? table_name_arg : ""),
2464
3210
{
2465
3211
  time_t end_time;
2466
3212
  time(&end_time);
2467
 
  exec_time = (ulong) (end_time  - session_arg->start_time);
 
3213
  exec_time = (ulong) (end_time  - thd_arg->start_time);
2468
3214
  /* db can never be a zero pointer in 4.0 */
2469
3215
  db_len = (uint32_t) strlen(db);
2470
3216
  table_name_len = (uint32_t) strlen(table_name);
2520
3266
  while ((item = li++))
2521
3267
  {
2522
3268
    num_fields++;
2523
 
    unsigned char len = (unsigned char) strlen(item->name);
 
3269
    uchar len = (uchar) strlen(item->name);
2524
3270
    field_block_len += len + 1;
2525
3271
    fields_buf.append(item->name, len + 1);
2526
3272
    field_lens_buf.append((char*)&len, 1);
2527
3273
  }
2528
3274
 
2529
 
  field_lens = (const unsigned char*)field_lens_buf.ptr();
 
3275
  field_lens = (const uchar*)field_lens_buf.ptr();
2530
3276
  fields = fields_buf.ptr();
2531
3277
}
 
3278
#endif /* !MYSQL_CLIENT */
2532
3279
 
2533
3280
 
2534
3281
/**
2536
3283
    The caller must do buf[event_len] = 0 before he starts using the
2537
3284
    constructed event.
2538
3285
*/
2539
 
Load_log_event::Load_log_event(const char *buf, uint32_t event_len,
 
3286
Load_log_event::Load_log_event(const char *buf, uint event_len,
2540
3287
                               const Format_description_log_event *description_event)
2541
3288
  :Log_event(buf, description_event), num_fields(0), fields(0),
2542
3289
   field_lens(0),field_block_len(0),
2566
3313
                                   int body_offset,
2567
3314
                                   const Format_description_log_event *description_event)
2568
3315
{
2569
 
  uint32_t data_len;
 
3316
  uint data_len;
2570
3317
  char* buf_end = (char*)buf + event_len;
2571
3318
  /* this is the beginning of the post-header */
2572
3319
  const char* data_head = buf + description_event->common_header_len;
2583
3330
    Sql_ex.init() on success returns the pointer to the first byte after
2584
3331
    the sql_ex structure, which is the start of field lengths array.
2585
3332
  */
2586
 
  if (!(field_lens= (unsigned char*)sql_ex.init((char*)buf + body_offset,
 
3333
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
2587
3334
                                        buf_end,
2588
3335
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
2589
3336
    return(1);
2591
3338
  data_len = event_len - body_offset;
2592
3339
  if (num_fields > data_len) // simple sanity check against corruption
2593
3340
    return(1);
2594
 
  for (uint32_t i = 0; i < num_fields; i++)
 
3341
  for (uint i = 0; i < num_fields; i++)
2595
3342
    field_block_len += (uint)field_lens[i] + 1;
2596
3343
 
2597
3344
  fields = (char*)field_lens + num_fields;
2605
3352
}
2606
3353
 
2607
3354
 
 
3355
/*
 
3356
  Load_log_event::print()
 
3357
*/
 
3358
 
 
3359
#ifdef MYSQL_CLIENT
 
3360
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3361
{
 
3362
  print(file, print_event_info, 0);
 
3363
}
 
3364
 
 
3365
 
 
3366
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
 
3367
                           bool commented)
 
3368
{
 
3369
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
3370
 
 
3371
  if (!print_event_info->short_form)
 
3372
  {
 
3373
    print_header(&cache, print_event_info, false);
 
3374
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
 
3375
                thread_id, exec_time);
 
3376
  }
 
3377
 
 
3378
  bool different_db= 1;
 
3379
  if (db)
 
3380
  {
 
3381
    /*
 
3382
      If the database is different from the one of the previous statement, we
 
3383
      need to print the "use" command, and we update the last_db.
 
3384
      But if commented, the "use" is going to be commented so we should not
 
3385
      update the last_db.
 
3386
    */
 
3387
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
 
3388
        !commented)
 
3389
      memcpy(print_event_info->db, db, db_len + 1);
 
3390
  }
 
3391
  
 
3392
  if (db && db[0] && different_db)
 
3393
    my_b_printf(&cache, "%suse %s%s\n", 
 
3394
            commented ? "# " : "",
 
3395
            db, print_event_info->delimiter);
 
3396
 
 
3397
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
 
3398
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
 
3399
            commented ? "# " : "", (ulong)thread_id,
 
3400
            print_event_info->delimiter);
 
3401
  my_b_printf(&cache, "%sLOAD DATA ",
 
3402
              commented ? "# " : "");
 
3403
  if (check_fname_outside_temp_buf())
 
3404
    my_b_printf(&cache, "LOCAL ");
 
3405
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
 
3406
 
 
3407
  if (sql_ex.opt_flags & REPLACE_FLAG)
 
3408
    my_b_printf(&cache," REPLACE ");
 
3409
  else if (sql_ex.opt_flags & IGNORE_FLAG)
 
3410
    my_b_printf(&cache," IGNORE ");
 
3411
  
 
3412
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
 
3413
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
 
3414
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
 
3415
 
 
3416
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
 
3417
    my_b_printf(&cache," OPTIONALLY ");
 
3418
  my_b_printf(&cache, " ENCLOSED BY ");
 
3419
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
 
3420
     
 
3421
  my_b_printf(&cache, " ESCAPED BY ");
 
3422
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
 
3423
     
 
3424
  my_b_printf(&cache," LINES TERMINATED BY ");
 
3425
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
 
3426
 
 
3427
 
 
3428
  if (sql_ex.line_start)
 
3429
  {
 
3430
    my_b_printf(&cache," STARTING BY ");
 
3431
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
 
3432
  }
 
3433
  if ((long) skip_lines > 0)
 
3434
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
 
3435
 
 
3436
  if (num_fields)
 
3437
  {
 
3438
    uint i;
 
3439
    const char* field = fields;
 
3440
    my_b_printf(&cache, " (");
 
3441
    for (i = 0; i < num_fields; i++)
 
3442
    {
 
3443
      if (i)
 
3444
        my_b_printf(&cache, ",");
 
3445
      my_b_printf(&cache, field);
 
3446
          
 
3447
      field += field_lens[i]  + 1;
 
3448
    }
 
3449
    my_b_printf(&cache, ")");
 
3450
  }
 
3451
 
 
3452
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
 
3453
  return;
 
3454
}
 
3455
#endif /* MYSQL_CLIENT */
 
3456
 
 
3457
#ifndef MYSQL_CLIENT
 
3458
 
2608
3459
/**
2609
3460
  Load_log_event::set_fields()
2610
3461
 
2619
3470
                                List<Item> &field_list,
2620
3471
                                Name_resolution_context *context)
2621
3472
{
2622
 
  uint32_t i;
 
3473
  uint i;
2623
3474
  const char* field = fields;
2624
3475
  for (i= 0; i < num_fields; i++)
2625
3476
  {
2628
3479
    field+= field_lens[i]  + 1;
2629
3480
  }
2630
3481
}
2631
 
 
2632
 
 
 
3482
#endif /* !MYSQL_CLIENT */
 
3483
 
 
3484
 
 
3485
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2633
3486
/**
2634
3487
  Does the data loading job when executing a LOAD DATA on the slave.
2635
3488
 
2663
3516
                                   bool use_rli_only_for_errors)
2664
3517
{
2665
3518
  LEX_STRING new_db;
2666
 
  Query_id &query_id= Query_id::get_query_id();
2667
3519
  new_db.length= db_len;
2668
3520
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2669
 
  session->set_db(new_db.str, new_db.length);
2670
 
  assert(session->query == 0);
2671
 
  session->query_length= 0;                         // Should not be needed
2672
 
  session->is_slave_error= 0;
2673
 
  clear_all_errors(session, const_cast<Relay_log_info*>(rli));
 
3521
  thd->set_db(new_db.str, new_db.length);
 
3522
  assert(thd->query == 0);
 
3523
  thd->query_length= 0;                         // Should not be needed
 
3524
  thd->is_slave_error= 0;
 
3525
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2674
3526
 
2675
3527
  /* see Query_log_event::do_apply_event() and BUG#13360 */
2676
3528
  assert(!rli->m_table_map.count());
2678
3530
    Usually lex_start() is called by mysql_parse(), but we need it here
2679
3531
    as the present method does not call mysql_parse().
2680
3532
  */
2681
 
  lex_start(session);
2682
 
  mysql_reset_session_for_next_command(session);
 
3533
  lex_start(thd);
 
3534
  mysql_reset_thd_for_next_command(thd);
2683
3535
 
2684
3536
  if (!use_rli_only_for_errors)
2685
3537
  {
2713
3565
            ::do_apply_event(), then the companion SET also have so
2714
3566
            we don't need to reset_one_shot_variables().
2715
3567
  */
2716
 
  if (rpl_filter->db_ok(session->db))
 
3568
  if (rpl_filter->db_ok(thd->db))
2717
3569
  {
2718
 
    session->set_time((time_t)when);
2719
 
    session->query_id = query_id.next();
 
3570
    thd->set_time((time_t)when);
 
3571
    VOID(pthread_mutex_lock(&LOCK_thread_count));
 
3572
    thd->query_id = next_query_id();
 
3573
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
2720
3574
    /*
2721
 
      Initing session->row_count is not necessary in theory as this variable has no
 
3575
      Initing thd->row_count is not necessary in theory as this variable has no
2722
3576
      influence in the case of the slave SQL thread (it is used to generate a
2723
3577
      "data truncated" warning but which is absorbed and never gets to the
2724
3578
      error log); still we init it to avoid a Valgrind message.
2725
3579
    */
2726
 
    drizzle_reset_errors(session, 0);
 
3580
    mysql_reset_errors(thd, 0);
2727
3581
 
2728
 
    TableList tables;
2729
 
    memset(&tables, 0, sizeof(tables));
2730
 
    tables.db= session->strmake(session->db, session->db_length);
 
3582
    TABLE_LIST tables;
 
3583
    memset((char*) &tables, 0, sizeof(tables));
 
3584
    tables.db= thd->strmake(thd->db, thd->db_length);
2731
3585
    tables.alias = tables.table_name = (char*) table_name;
2732
3586
    tables.lock_type = TL_WRITE;
2733
3587
    tables.updating= 1;
2734
3588
 
2735
3589
    // the table will be opened in mysql_load    
2736
 
    if (rpl_filter->is_on() && !rpl_filter->tables_ok(session->db, &tables))
 
3590
    if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
2737
3591
    {
2738
3592
      // TODO: this is a bug - this needs to be moved to the I/O thread
2739
3593
      if (net)
2751
3605
        Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
2752
3606
        and written to slave's binlog if binlogging is on.
2753
3607
      */
2754
 
      if (!(load_data_query= (char *)session->alloc(get_query_buffer_length() + 1)))
 
3608
      if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
2755
3609
      {
2756
3610
        /*
2757
 
          This will set session->fatal_error in case of OOM. So we surely will notice
 
3611
          This will set thd->fatal_error in case of OOM. So we surely will notice
2758
3612
          that something is wrong.
2759
3613
        */
2760
3614
        goto error;
2761
3615
      }
2762
3616
 
2763
 
      print_query(false, load_data_query, &end, (char **)&session->lex->fname_start,
2764
 
                  (char **)&session->lex->fname_end);
 
3617
      print_query(false, load_data_query, &end, (char **)&thd->lex->fname_start,
 
3618
                  (char **)&thd->lex->fname_end);
2765
3619
      *end= 0;
2766
 
      session->query_length= end - load_data_query;
2767
 
      session->query= load_data_query;
 
3620
      thd->query_length= end - load_data_query;
 
3621
      thd->query= load_data_query;
2768
3622
 
2769
3623
      if (sql_ex.opt_flags & REPLACE_FLAG)
2770
3624
      {
2793
3647
        handle_dup= DUP_ERROR;
2794
3648
      }
2795
3649
      /*
2796
 
        We need to set session->lex->sql_command and session->lex->duplicates
 
3650
        We need to set thd->lex->sql_command and thd->lex->duplicates
2797
3651
        since InnoDB tests these variables to decide if this is a LOAD
2798
3652
        DATA ... REPLACE INTO ... statement even though mysql_parse()
2799
3653
        is not called.  This is not needed in 5.0 since there the LOAD
2800
3654
        DATA ... statement is replicated using mysql_parse(), which
2801
 
        sets the session->lex fields correctly.
 
3655
        sets the thd->lex fields correctly.
2802
3656
      */
2803
 
      session->lex->sql_command= SQLCOM_LOAD;
2804
 
      session->lex->duplicates= handle_dup;
 
3657
      thd->lex->sql_command= SQLCOM_LOAD;
 
3658
      thd->lex->duplicates= handle_dup;
2805
3659
 
2806
3660
      sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
2807
 
      String field_term(sql_ex.field_term,sql_ex.field_term_len,&my_charset_utf8_general_ci);
2808
 
      String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,&my_charset_utf8_general_ci);
2809
 
      String line_term(sql_ex.line_term,sql_ex.line_term_len,&my_charset_utf8_general_ci);
2810
 
      String line_start(sql_ex.line_start,sql_ex.line_start_len,&my_charset_utf8_general_ci);
2811
 
      String escaped(sql_ex.escaped,sql_ex.escaped_len, &my_charset_utf8_general_ci);
 
3661
      String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
 
3662
      String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
 
3663
      String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
 
3664
      String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
 
3665
      String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
2812
3666
      ex.field_term= &field_term;
2813
3667
      ex.enclosed= &enclosed;
2814
3668
      ex.line_term= &line_term;
2821
3675
 
2822
3676
      ex.skip_lines = skip_lines;
2823
3677
      List<Item> field_list;
2824
 
      session->lex->select_lex.context.resolve_in_table_list_only(&tables);
2825
 
      set_fields(tables.db, field_list, &session->lex->select_lex.context);
2826
 
      session->variables.pseudo_thread_id= thread_id;
 
3678
      thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
 
3679
      set_fields(tables.db, field_list, &thd->lex->select_lex.context);
 
3680
      thd->variables.pseudo_thread_id= thread_id;
2827
3681
      if (net)
2828
3682
      {
2829
 
        // mysql_load will use session->net to read the file
2830
 
        session->net.vio = net->vio;
 
3683
        // mysql_load will use thd->net to read the file
 
3684
        thd->net.vio = net->vio;
2831
3685
        /*
2832
3686
          Make sure the client does not get confused about the packet sequence
2833
3687
        */
2834
 
        session->net.pkt_nr = net->pkt_nr;
 
3688
        thd->net.pkt_nr = net->pkt_nr;
2835
3689
      }
2836
3690
      /*
2837
3691
        It is safe to use tmp_list twice because we are not going to
2838
3692
        update it inside mysql_load().
2839
3693
      */
2840
3694
      List<Item> tmp_list;
2841
 
      if (mysql_load(session, &ex, &tables, field_list, tmp_list, tmp_list,
 
3695
      if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
2842
3696
                     handle_dup, ignore, net != 0))
2843
 
        session->is_slave_error= 1;
2844
 
      if (session->cuted_fields)
 
3697
        thd->is_slave_error= 1;
 
3698
      if (thd->cuted_fields)
2845
3699
      {
2846
3700
        /* log_pos is the position of the LOAD event in the master log */
2847
 
        sql_print_warning(_("Slave: load data infile on table '%s' at "
 
3701
        sql_print_warning("Slave: load data infile on table '%s' at "
2848
3702
                          "log position %s in log '%s' produced %ld "
2849
 
                          "warning(s). Default database: '%s'"),
 
3703
                          "warning(s). Default database: '%s'",
2850
3704
                          (char*) table_name,
2851
3705
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
2852
 
                          (ulong) session->cuted_fields,
2853
 
                          print_slave_db_safe(session->db));
 
3706
                          (ulong) thd->cuted_fields,
 
3707
                          print_slave_db_safe(thd->db));
2854
3708
      }
2855
3709
      if (net)
2856
 
        net->pkt_nr= session->net.pkt_nr;
 
3710
        net->pkt_nr= thd->net.pkt_nr;
2857
3711
    }
2858
3712
  }
2859
3713
  else
2868
3722
  }
2869
3723
 
2870
3724
error:
2871
 
  session->net.vio = 0; 
2872
 
  const char *remember_db= session->db;
2873
 
  pthread_mutex_lock(&LOCK_thread_count);
2874
 
  session->catalog= 0;
2875
 
  session->set_db(NULL, 0);                   /* will free the current database */
2876
 
  session->query= 0;
2877
 
  session->query_length= 0;
2878
 
  pthread_mutex_unlock(&LOCK_thread_count);
2879
 
  close_thread_tables(session);
 
3725
  thd->net.vio = 0; 
 
3726
  const char *remember_db= thd->db;
 
3727
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
3728
  thd->catalog= 0;
 
3729
  thd->set_db(NULL, 0);                   /* will free the current database */
 
3730
  thd->query= 0;
 
3731
  thd->query_length= 0;
 
3732
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
3733
  close_thread_tables(thd);
2880
3734
 
2881
 
  if (session->is_slave_error)
 
3735
  if (thd->is_slave_error)
2882
3736
  {
2883
3737
    /* this err/sql_errno code is copy-paste from net_send_error() */
2884
3738
    const char *err;
2885
3739
    int sql_errno;
2886
 
    if (session->is_error())
 
3740
    if (thd->is_error())
2887
3741
    {
2888
 
      err= session->main_da.message();
2889
 
      sql_errno= session->main_da.sql_errno();
 
3742
      err= thd->main_da.message();
 
3743
      sql_errno= thd->main_da.sql_errno();
2890
3744
    }
2891
3745
    else
2892
3746
    {
2893
3747
      sql_errno=ER_UNKNOWN_ERROR;
2894
 
      err=ER(sql_errno);
 
3748
      err=ER(sql_errno);       
2895
3749
    }
2896
 
    rli->report(ERROR_LEVEL, sql_errno,
2897
 
                _("Error '%s' running LOAD DATA INFILE on table '%s'. "
2898
 
                  "Default database: '%s'"),
2899
 
                err, (char*)table_name, print_slave_db_safe(remember_db));
2900
 
    free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
3750
    rli->report(ERROR_LEVEL, sql_errno,"\
 
3751
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
 
3752
                    err, (char*)table_name, print_slave_db_safe(remember_db));
 
3753
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2901
3754
    return 1;
2902
3755
  }
2903
 
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
3756
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2904
3757
 
2905
 
  if (session->is_fatal_error)
 
3758
  if (thd->is_fatal_error)
2906
3759
  {
2907
3760
    char buf[256];
2908
3761
    snprintf(buf, sizeof(buf),
2909
 
             _("Running LOAD DATA INFILE on table '%-.64s'."
2910
 
               " Default database: '%-.64s'"),
 
3762
             "Running LOAD DATA INFILE on table '%-.64s'."
 
3763
             " Default database: '%-.64s'",
2911
3764
             (char*)table_name,
2912
3765
             print_slave_db_safe(remember_db));
2913
3766
 
2916
3769
    return 1;
2917
3770
  }
2918
3771
 
2919
 
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
 
3772
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
2920
3773
}
 
3774
#endif
2921
3775
 
2922
3776
 
2923
3777
/**************************************************************************
2928
3782
  Rotate_log_event::pack_info()
2929
3783
*/
2930
3784
 
 
3785
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2931
3786
void Rotate_log_event::pack_info(Protocol *protocol)
2932
3787
{
2933
3788
  char buf1[256], buf[22];
2934
 
  String tmp(buf1, sizeof(buf1), &my_charset_utf8_general_ci);
 
3789
  String tmp(buf1, sizeof(buf1), log_cs);
2935
3790
  tmp.length(0);
2936
3791
  tmp.append(new_log_ident, ident_len);
2937
3792
  tmp.append(STRING_WITH_LEN(";pos="));
2938
3793
  tmp.append(llstr(pos,buf));
2939
3794
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
2940
3795
}
 
3796
#endif
 
3797
 
 
3798
 
 
3799
/*
 
3800
  Rotate_log_event::print()
 
3801
*/
 
3802
 
 
3803
#ifdef MYSQL_CLIENT
 
3804
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
3805
{
 
3806
  char buf[22];
 
3807
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
3808
                               Write_on_release_cache::FLUSH_F);
 
3809
 
 
3810
  if (print_event_info->short_form)
 
3811
    return;
 
3812
  print_header(&cache, print_event_info, false);
 
3813
  my_b_printf(&cache, "\tRotate to ");
 
3814
  if (new_log_ident)
 
3815
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
 
3816
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
 
3817
}
 
3818
#endif /* MYSQL_CLIENT */
 
3819
 
2941
3820
 
2942
3821
 
2943
3822
/*
2945
3824
*/
2946
3825
 
2947
3826
 
 
3827
#ifndef MYSQL_CLIENT
2948
3828
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
2949
 
                                   uint32_t ident_len_arg, uint64_t pos_arg,
2950
 
                                   uint32_t flags_arg)
 
3829
                                   uint ident_len_arg, uint64_t pos_arg,
 
3830
                                   uint flags_arg)
2951
3831
  :Log_event(), new_log_ident(new_log_ident_arg),
2952
3832
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
2953
3833
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
2956
3836
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
2957
3837
  return;
2958
3838
}
2959
 
 
2960
 
 
2961
 
Rotate_log_event::Rotate_log_event(const char* buf, uint32_t event_len,
 
3839
#endif
 
3840
 
 
3841
 
 
3842
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
2962
3843
                                   const Format_description_log_event* description_event)
2963
3844
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
2964
3845
{
2965
3846
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
2966
3847
  uint8_t header_size= description_event->common_header_len;
2967
3848
  uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
2968
 
  uint32_t ident_offset;
 
3849
  uint ident_offset;
2969
3850
  if (event_len < header_size)
2970
3851
    return;
2971
3852
  buf += header_size;
2983
3864
  Rotate_log_event::write()
2984
3865
*/
2985
3866
 
 
3867
#ifndef MYSQL_CLIENT
2986
3868
bool Rotate_log_event::write(IO_CACHE* file)
2987
3869
{
2988
3870
  char buf[ROTATE_HEADER_LEN];
2989
3871
  int8store(buf + R_POS_OFFSET, pos);
2990
3872
  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
2991
 
          my_b_safe_write(file, (unsigned char*)buf, ROTATE_HEADER_LEN) ||
2992
 
          my_b_safe_write(file, (unsigned char*)new_log_ident, (uint) ident_len));
 
3873
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
 
3874
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
2993
3875
}
2994
 
 
 
3876
#endif
 
3877
 
 
3878
 
 
3879
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
2995
3880
 
2996
3881
/*
2997
3882
  Got a rotate log event from the master.
3029
3914
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3030
3915
      !rli->is_in_group())
3031
3916
  {
3032
 
    rli->group_master_log_name.assign(new_log_ident, ident_len+1);
 
3917
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
3033
3918
    rli->notify_group_master_log_name_update();
3034
3919
    rli->group_master_log_pos= pos;
3035
 
    rli->group_relay_log_name.assign(rli->event_relay_log_name);
 
3920
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
 
3921
            sizeof(rli->group_relay_log_name) - 1);
3036
3922
    rli->notify_group_relay_log_name_update();
3037
3923
    rli->group_relay_log_pos= rli->event_relay_log_pos;
3038
3924
    /*
3039
 
      Reset session->options and sql_mode etc, because this could be the signal of
 
3925
      Reset thd->options and sql_mode etc, because this could be the signal of
3040
3926
      a master's downgrade from 5.0 to 4.0.
3041
3927
      However, no need to reset description_event_for_exec: indeed, if the next
3042
3928
      master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
3043
3929
      master is 4.0 then the events are in the slave's format (conversion).
3044
3930
    */
3045
 
    set_slave_thread_options(session);
3046
 
    session->variables.auto_increment_increment=
3047
 
      session->variables.auto_increment_offset= 1;
 
3931
    set_slave_thread_options(thd);
 
3932
    set_slave_thread_default_charset(thd, rli);
 
3933
    thd->variables.auto_increment_increment=
 
3934
      thd->variables.auto_increment_offset= 1;
3048
3935
  }
3049
3936
  pthread_mutex_unlock(&rli->data_lock);
3050
3937
  pthread_cond_broadcast(&rli->data_cond);
3071
3958
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
3072
3959
}
3073
3960
 
 
3961
#endif
 
3962
 
3074
3963
 
3075
3964
/**************************************************************************
3076
3965
        Intvar_log_event methods
3080
3969
  Intvar_log_event::pack_info()
3081
3970
*/
3082
3971
 
 
3972
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3083
3973
void Intvar_log_event::pack_info(Protocol *protocol)
3084
3974
{
3085
3975
  char buf[256], *pos;
3088
3978
  pos= int64_t10_to_str(val, pos, -10);
3089
3979
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3090
3980
}
 
3981
#endif
3091
3982
 
3092
3983
 
3093
3984
/*
3122
4013
  Intvar_log_event::write()
3123
4014
*/
3124
4015
 
 
4016
#ifndef MYSQL_CLIENT
3125
4017
bool Intvar_log_event::write(IO_CACHE* file)
3126
4018
{
3127
 
  unsigned char buf[9];
3128
 
  buf[I_TYPE_OFFSET]= (unsigned char) type;
 
4019
  uchar buf[9];
 
4020
  buf[I_TYPE_OFFSET]= (uchar) type;
3129
4021
  int8store(buf + I_VAL_OFFSET, val);
3130
4022
  return (write_header(file, sizeof(buf)) ||
3131
4023
          my_b_safe_write(file, buf, sizeof(buf)));
3132
4024
}
 
4025
#endif
3133
4026
 
3134
4027
 
3135
4028
/*
3136
4029
  Intvar_log_event::print()
3137
4030
*/
3138
4031
 
 
4032
#ifdef MYSQL_CLIENT
 
4033
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4034
{
 
4035
  char llbuff[22];
 
4036
  const char *msg;
 
4037
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4038
                               Write_on_release_cache::FLUSH_F);
 
4039
 
 
4040
  if (!print_event_info->short_form)
 
4041
  {
 
4042
    print_header(&cache, print_event_info, false);
 
4043
    my_b_printf(&cache, "\tIntvar\n");
 
4044
  }
 
4045
 
 
4046
  my_b_printf(&cache, "SET ");
 
4047
  switch (type) {
 
4048
  case LAST_INSERT_ID_EVENT:
 
4049
    msg="LAST_INSERT_ID";
 
4050
    break;
 
4051
  case INSERT_ID_EVENT:
 
4052
    msg="INSERT_ID";
 
4053
    break;
 
4054
  case INVALID_INT_EVENT:
 
4055
  default: // cannot happen
 
4056
    msg="INVALID_INT";
 
4057
    break;
 
4058
  }
 
4059
  my_b_printf(&cache, "%s=%s%s\n",
 
4060
              msg, llstr(val,llbuff), print_event_info->delimiter);
 
4061
}
 
4062
#endif
 
4063
 
 
4064
 
3139
4065
/*
3140
4066
  Intvar_log_event::do_apply_event()
3141
4067
*/
3142
4068
 
 
4069
#if defined(HAVE_REPLICATION)&& !defined(MYSQL_CLIENT)
3143
4070
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
3144
4071
{
3145
4072
  /*
3150
4077
 
3151
4078
  switch (type) {
3152
4079
  case LAST_INSERT_ID_EVENT:
3153
 
    session->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
3154
 
    session->first_successful_insert_id_in_prev_stmt= val;
 
4080
    thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
 
4081
    thd->first_successful_insert_id_in_prev_stmt= val;
3155
4082
    break;
3156
4083
  case INSERT_ID_EVENT:
3157
 
    session->force_one_auto_inc_interval(val);
 
4084
    thd->force_one_auto_inc_interval(val);
3158
4085
    break;
3159
4086
  }
3160
4087
  return 0;
3181
4108
  return continue_group(rli);
3182
4109
}
3183
4110
 
 
4111
#endif
 
4112
 
3184
4113
 
3185
4114
/**************************************************************************
3186
4115
  Rand_log_event methods
3187
4116
**************************************************************************/
3188
4117
 
 
4118
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3189
4119
void Rand_log_event::pack_info(Protocol *protocol)
3190
4120
{
3191
4121
  char buf1[256], *pos;
3192
 
  pos= my_stpcpy(buf1,"rand_seed1=");
 
4122
  pos= strmov(buf1,"rand_seed1=");
3193
4123
  pos= int10_to_str((long) seed1, pos, 10);
3194
 
  pos= my_stpcpy(pos, ",rand_seed2=");
 
4124
  pos= strmov(pos, ",rand_seed2=");
3195
4125
  pos= int10_to_str((long) seed2, pos, 10);
3196
4126
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
3197
4127
}
 
4128
#endif
3198
4129
 
3199
4130
 
3200
4131
Rand_log_event::Rand_log_event(const char* buf,
3207
4138
}
3208
4139
 
3209
4140
 
 
4141
#ifndef MYSQL_CLIENT
3210
4142
bool Rand_log_event::write(IO_CACHE* file)
3211
4143
{
3212
 
  unsigned char buf[16];
 
4144
  uchar buf[16];
3213
4145
  int8store(buf + RAND_SEED1_OFFSET, seed1);
3214
4146
  int8store(buf + RAND_SEED2_OFFSET, seed2);
3215
4147
  return (write_header(file, sizeof(buf)) ||
3216
4148
          my_b_safe_write(file, buf, sizeof(buf)));
3217
4149
}
3218
 
 
3219
 
 
 
4150
#endif
 
4151
 
 
4152
 
 
4153
#ifdef MYSQL_CLIENT
 
4154
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4155
{
 
4156
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4157
                               Write_on_release_cache::FLUSH_F);
 
4158
 
 
4159
  char llbuff[22],llbuff2[22];
 
4160
  if (!print_event_info->short_form)
 
4161
  {
 
4162
    print_header(&cache, print_event_info, false);
 
4163
    my_b_printf(&cache, "\tRand\n");
 
4164
  }
 
4165
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
 
4166
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
 
4167
              print_event_info->delimiter);
 
4168
}
 
4169
#endif /* MYSQL_CLIENT */
 
4170
 
 
4171
 
 
4172
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3220
4173
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
3221
4174
{
3222
4175
  /*
3225
4178
   */
3226
4179
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
3227
4180
 
3228
 
  session->rand.seed1= (ulong) seed1;
3229
 
  session->rand.seed2= (ulong) seed2;
 
4181
  thd->rand.seed1= (ulong) seed1;
 
4182
  thd->rand.seed2= (ulong) seed2;
3230
4183
  return 0;
3231
4184
}
3232
4185
 
3251
4204
  return continue_group(rli);
3252
4205
}
3253
4206
 
 
4207
#endif /* !MYSQL_CLIENT */
 
4208
 
3254
4209
 
3255
4210
/**************************************************************************
3256
4211
  Xid_log_event methods
3257
4212
**************************************************************************/
3258
4213
 
 
4214
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3259
4215
void Xid_log_event::pack_info(Protocol *protocol)
3260
4216
{
3261
4217
  char buf[128], *pos;
3262
 
  pos= my_stpcpy(buf, "COMMIT /* xid=");
 
4218
  pos= strmov(buf, "COMMIT /* xid=");
3263
4219
  pos= int64_t10_to_str(xid, pos, 10);
3264
 
  pos= my_stpcpy(pos, " */");
 
4220
  pos= strmov(pos, " */");
3265
4221
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3266
4222
}
 
4223
#endif
3267
4224
 
3268
4225
/**
3269
4226
  @note
3270
4227
  It's ok not to use int8store here,
3271
 
  as long as XID::set(uint64_t) and
3272
 
  XID::get_my_xid doesn't do it either.
 
4228
  as long as xid_t::set(uint64_t) and
 
4229
  xid_t::get_my_xid doesn't do it either.
3273
4230
  We don't care about actual values of xids as long as
3274
4231
  identical numbers compare identically
3275
4232
*/
3280
4237
  :Log_event(buf, description_event)
3281
4238
{
3282
4239
  buf+= description_event->common_header_len;
3283
 
  memcpy(&xid, buf, sizeof(xid));
 
4240
  memcpy((char*) &xid, buf, sizeof(xid));
3284
4241
}
3285
4242
 
3286
4243
 
 
4244
#ifndef MYSQL_CLIENT
3287
4245
bool Xid_log_event::write(IO_CACHE* file)
3288
4246
{
3289
4247
  return write_header(file, sizeof(xid)) ||
3290
 
         my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
3291
 
}
3292
 
 
3293
 
 
3294
 
int Xid_log_event::do_apply_event(const Relay_log_info *)
3295
 
{
3296
 
  return end_trans(session, COMMIT);
 
4248
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
 
4249
}
 
4250
#endif
 
4251
 
 
4252
 
 
4253
#ifdef MYSQL_CLIENT
 
4254
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4255
{
 
4256
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4257
                               Write_on_release_cache::FLUSH_F);
 
4258
 
 
4259
  if (!print_event_info->short_form)
 
4260
  {
 
4261
    char buf[64];
 
4262
    int64_t10_to_str(xid, buf, 10);
 
4263
 
 
4264
    print_header(&cache, print_event_info, false);
 
4265
    my_b_printf(&cache, "\tXid = %s\n", buf);
 
4266
  }
 
4267
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
 
4268
}
 
4269
#endif /* MYSQL_CLIENT */
 
4270
 
 
4271
 
 
4272
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
4273
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
4274
{
 
4275
  /* For a slave Xid_log_event is COMMIT */
 
4276
  general_log_print(thd, COM_QUERY,
 
4277
                    "COMMIT /* implicit, from Xid_log_event */");
 
4278
  return end_trans(thd, COMMIT);
3297
4279
}
3298
4280
 
3299
4281
Log_event::enum_skip_reason
3300
4282
Xid_log_event::do_shall_skip(Relay_log_info *rli)
3301
4283
{
3302
4284
  if (rli->slave_skip_counter > 0) {
3303
 
    session->options&= ~OPTION_BEGIN;
 
4285
    thd->options&= ~OPTION_BEGIN;
3304
4286
    return(Log_event::EVENT_SKIP_COUNT);
3305
4287
  }
3306
4288
  return(Log_event::do_shall_skip(rli));
3307
4289
}
 
4290
#endif /* !MYSQL_CLIENT */
3308
4291
 
3309
4292
 
3310
4293
/**************************************************************************
3311
4294
  User_var_log_event methods
3312
4295
**************************************************************************/
3313
4296
 
 
4297
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3314
4298
void User_var_log_event::pack_info(Protocol* protocol)
3315
4299
{
3316
4300
  char *buf= 0;
3317
 
  uint32_t val_offset= 4 + name_len;
3318
 
  uint32_t event_len= val_offset;
 
4301
  uint val_offset= 4 + name_len;
 
4302
  uint event_len= val_offset;
3319
4303
 
3320
4304
  if (is_null)
3321
4305
  {
3322
4306
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
3323
4307
      return;
3324
 
    my_stpcpy(buf + val_offset, "NULL");
 
4308
    strmov(buf + val_offset, "NULL");
3325
4309
    event_len= val_offset + 4;
3326
4310
  }
3327
4311
  else
3348
4332
        return;
3349
4333
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
3350
4334
      my_decimal dec;
3351
 
      binary2my_decimal(E_DEC_FATAL_ERROR, (unsigned char*) (val+2), &dec, val[0],
 
4335
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
3352
4336
                        val[1]);
3353
4337
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
3354
4338
      event_len= str.length() + val_offset;
3358
4342
      /* 15 is for 'COLLATE' and other chars */
3359
4343
      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
3360
4344
                             MYF(MY_WME));
3361
 
      const CHARSET_INFO *cs;
 
4345
      CHARSET_INFO *cs;
3362
4346
      if (!buf)
3363
4347
        return;
3364
4348
      if (!(cs= get_charset(charset_number, MYF(0))))
3365
4349
      {
3366
 
        my_stpcpy(buf+val_offset, "???");
 
4350
        strmov(buf+val_offset, "???");
3367
4351
        event_len+= 3;
3368
4352
      }
3369
4353
      else
3370
4354
      {
3371
 
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NULL);
 
4355
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
3372
4356
        p= str_to_hex(p, val, val_len);
3373
 
        p= strxmov(p, " COLLATE ", cs->name, NULL);
 
4357
        p= strxmov(p, " COLLATE ", cs->name, NullS);
3374
4358
        event_len= p-buf;
3375
4359
      }
3376
4360
      break;
3386
4370
  buf[2+name_len]= '`';
3387
4371
  buf[3+name_len]= '=';
3388
4372
  protocol->store(buf, event_len, &my_charset_bin);
3389
 
  free(buf);
 
4373
  my_free(buf, MYF(0));
3390
4374
}
 
4375
#endif /* !MYSQL_CLIENT */
3391
4376
 
3392
4377
 
3393
4378
User_var_log_event::
3419
4404
}
3420
4405
 
3421
4406
 
 
4407
#ifndef MYSQL_CLIENT
3422
4408
bool User_var_log_event::write(IO_CACHE* file)
3423
4409
{
3424
4410
  char buf[UV_NAME_LEN_SIZE];
3425
4411
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
3426
4412
            UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
3427
 
  unsigned char buf2[(8 > DECIMAL_MAX_FIELD_SIZE + 2) ? 8 : DECIMAL_MAX_FIELD_SIZE +2], *pos= buf2;
3428
 
  uint32_t buf1_length;
 
4413
  uchar buf2[max(8, DECIMAL_MAX_FIELD_SIZE + 2)], *pos= buf2;
 
4414
  uint buf1_length;
3429
4415
  ulong event_length;
3430
4416
 
3431
4417
  int4store(buf, name_len);
3458
4444
      break;
3459
4445
    }
3460
4446
    case STRING_RESULT:
3461
 
      pos= (unsigned char*) val;
 
4447
      pos= (uchar*) val;
3462
4448
      break;
3463
4449
    case ROW_RESULT:
3464
4450
    default:
3473
4459
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
3474
4460
 
3475
4461
  return (write_header(file, event_length) ||
3476
 
          my_b_safe_write(file, (unsigned char*) buf, sizeof(buf))   ||
3477
 
          my_b_safe_write(file, (unsigned char*) name, name_len)     ||
3478
 
          my_b_safe_write(file, (unsigned char*) buf1, buf1_length) ||
 
4462
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
 
4463
          my_b_safe_write(file, (uchar*) name, name_len)     ||
 
4464
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
3479
4465
          my_b_safe_write(file, pos, val_len));
3480
4466
}
3481
 
 
 
4467
#endif
 
4468
 
 
4469
 
 
4470
/*
 
4471
  User_var_log_event::print()
 
4472
*/
 
4473
 
 
4474
#ifdef MYSQL_CLIENT
 
4475
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4476
{
 
4477
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4478
                               Write_on_release_cache::FLUSH_F);
 
4479
 
 
4480
  if (!print_event_info->short_form)
 
4481
  {
 
4482
    print_header(&cache, print_event_info, false);
 
4483
    my_b_printf(&cache, "\tUser_var\n");
 
4484
  }
 
4485
 
 
4486
  my_b_printf(&cache, "SET @`");
 
4487
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
 
4488
  my_b_printf(&cache, "`");
 
4489
 
 
4490
  if (is_null)
 
4491
  {
 
4492
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
 
4493
  }
 
4494
  else
 
4495
  {
 
4496
    switch (type) {
 
4497
    case REAL_RESULT:
 
4498
      double real_val;
 
4499
      char real_buf[FMT_G_BUFSIZE(14)];
 
4500
      float8get(real_val, val);
 
4501
      sprintf(real_buf, "%.14g", real_val);
 
4502
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
 
4503
      break;
 
4504
    case INT_RESULT:
 
4505
      char int_buf[22];
 
4506
      int64_t10_to_str(uint8korr(val), int_buf, -10);
 
4507
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
 
4508
      break;
 
4509
    case DECIMAL_RESULT:
 
4510
    {
 
4511
      char str_buf[200];
 
4512
      int str_len= sizeof(str_buf) - 1;
 
4513
      int precision= (int)val[0];
 
4514
      int scale= (int)val[1];
 
4515
      decimal_digit_t dec_buf[10];
 
4516
      decimal_t dec;
 
4517
      dec.len= 10;
 
4518
      dec.buf= dec_buf;
 
4519
 
 
4520
      bin2decimal((uchar*) val+2, &dec, precision, scale);
 
4521
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
 
4522
      str_buf[str_len]= 0;
 
4523
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
 
4524
      break;
 
4525
    }
 
4526
    case STRING_RESULT:
 
4527
    {
 
4528
      /*
 
4529
        Let's express the string in hex. That's the most robust way. If we
 
4530
        print it in character form instead, we need to escape it with
 
4531
        character_set_client which we don't know (we will know it in 5.0, but
 
4532
        in 4.1 we don't know it easily when we are printing
 
4533
        User_var_log_event). Explanation why we would need to bother with
 
4534
        character_set_client (quoting Bar):
 
4535
        > Note, the parser doesn't switch to another unescaping mode after
 
4536
        > it has met a character set introducer.
 
4537
        > For example, if an SJIS client says something like:
 
4538
        > SET @a= _ucs2 \0a\0b'
 
4539
        > the string constant is still unescaped according to SJIS, not
 
4540
        > according to UCS2.
 
4541
      */
 
4542
      char *hex_str;
 
4543
      CHARSET_INFO *cs;
 
4544
 
 
4545
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
 
4546
        break; // no error, as we are 'void'
 
4547
      str_to_hex(hex_str, val, val_len);
 
4548
      /*
 
4549
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
 
4550
        specify the variable's collation. It will however cause problems when
 
4551
        people want to mysqlbinlog|mysql into another server not supporting the
 
4552
        character set. But there's not much to do about this and it's unlikely.
 
4553
      */
 
4554
      if (!(cs= get_charset(charset_number, MYF(0))))
 
4555
        /*
 
4556
          Generate an unusable command (=> syntax error) is probably the best
 
4557
          thing we can do here.
 
4558
        */
 
4559
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
 
4560
      else
 
4561
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
 
4562
                    cs->csname, hex_str, cs->name,
 
4563
                    print_event_info->delimiter);
 
4564
      my_afree(hex_str);
 
4565
    }
 
4566
      break;
 
4567
    case ROW_RESULT:
 
4568
    default:
 
4569
      assert(1);
 
4570
      return;
 
4571
    }
 
4572
  }
 
4573
}
 
4574
#endif
3482
4575
 
3483
4576
 
3484
4577
/*
3485
4578
  User_var_log_event::do_apply_event()
3486
4579
*/
3487
4580
 
 
4581
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3488
4582
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
3489
4583
{
3490
4584
  Item *it= 0;
3491
 
  const CHARSET_INFO *charset;
 
4585
  CHARSET_INFO *charset;
3492
4586
  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
3493
4587
    return 1;
3494
4588
  LEX_STRING user_var_name;
3524
4618
      break;
3525
4619
    case DECIMAL_RESULT:
3526
4620
    {
3527
 
      Item_decimal *dec= new Item_decimal((unsigned char*) val+2, val[0], val[1]);
 
4621
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
3528
4622
      it= dec;
3529
4623
      val= (char *)dec->val_decimal(NULL);
3530
4624
      val_len= sizeof(my_decimal);
3544
4638
    Item_func_set_user_var can't substitute something else on its place =>
3545
4639
    0 can be passed as last argument (reference on item)
3546
4640
  */
3547
 
  e.fix_fields(session, 0);
 
4641
  e.fix_fields(thd, 0);
3548
4642
  /*
3549
4643
    A variable can just be considered as a table with
3550
4644
    a single record and with a single column. Thus, like
3551
4645
    a column value, it could always have IMPLICIT derivation.
3552
4646
   */
3553
4647
  e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
3554
 
  free_root(session->mem_root,0);
 
4648
  free_root(thd->mem_root,0);
3555
4649
 
3556
4650
  return 0;
3557
4651
}
3575
4669
  */
3576
4670
  return continue_group(rli);
3577
4671
}
 
4672
#endif /* !MYSQL_CLIENT */
3578
4673
 
3579
4674
 
3580
4675
/**************************************************************************
3581
4676
  Slave_log_event methods
3582
4677
**************************************************************************/
3583
4678
 
 
4679
#ifdef HAVE_REPLICATION
 
4680
#ifdef MYSQL_CLIENT
 
4681
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
 
4682
{
 
4683
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
 
4684
 
 
4685
  if (print_event_info->short_form)
 
4686
    return;
 
4687
  print_header(&cache, print_event_info, false);
 
4688
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
 
4689
}
 
4690
#endif  
 
4691
 
 
4692
#ifndef MYSQL_CLIENT
3584
4693
void Slave_log_event::pack_info(Protocol *protocol)
3585
4694
{
3586
4695
  char buf[256+HOSTNAME_LENGTH], *pos;
3587
 
  pos= my_stpcpy(buf, "host=");
3588
 
  pos= my_stpncpy(pos, master_host.c_str(), HOSTNAME_LENGTH);
3589
 
  pos= my_stpcpy(pos, ",port=");
 
4696
  pos= strmov(buf, "host=");
 
4697
  pos= strnmov(pos, master_host, HOSTNAME_LENGTH);
 
4698
  pos= strmov(pos, ",port=");
3590
4699
  pos= int10_to_str((long) master_port, pos, 10);
3591
 
  pos= my_stpcpy(pos, ",log=");
3592
 
  pos= my_stpcpy(pos, master_log.c_str());
3593
 
  pos= my_stpcpy(pos, ",pos=");
 
4700
  pos= strmov(pos, ",log=");
 
4701
  pos= strmov(pos, master_log);
 
4702
  pos= strmov(pos, ",pos=");
3594
4703
  pos= int64_t10_to_str(master_pos, pos, 10);
3595
4704
  protocol->store(buf, pos-buf, &my_charset_bin);
3596
4705
}
3597
 
 
3598
 
 
 
4706
#endif /* !MYSQL_CLIENT */
 
4707
 
 
4708
 
 
4709
#ifndef MYSQL_CLIENT
3599
4710
/**
3600
4711
  @todo
3601
4712
  re-write this better without holding both locks at the same time
3602
4713
*/
3603
 
Slave_log_event::Slave_log_event(Session* session_arg,
 
4714
Slave_log_event::Slave_log_event(THD* thd_arg,
3604
4715
                                 Relay_log_info* rli)
3605
 
  :Log_event(session_arg, 0, 0) , mem_pool(0), master_host(0)
 
4716
  :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
3606
4717
{
3607
4718
  if (!rli->inited)                             // QQ When can this happen ?
3608
4719
    return;
3611
4722
  // TODO: re-write this better without holding both locks at the same time
3612
4723
  pthread_mutex_lock(&mi->data_lock);
3613
4724
  pthread_mutex_lock(&rli->data_lock);
 
4725
  master_host_len = strlen(mi->host);
 
4726
  master_log_len = strlen(rli->group_master_log_name);
3614
4727
  // on OOM, just do not initialize the structure and print the error
3615
4728
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
3616
4729
                                   MYF(MY_WME))))
3617
4730
  {
3618
 
    master_host.assign(mi->getHostname());
3619
 
    master_log.assign(rli->group_master_log_name);
3620
 
    master_port = mi->getPort();
 
4731
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
 
4732
    memcpy(master_host, mi->host, master_host_len + 1);
 
4733
    master_log = master_host + master_host_len + 1;
 
4734
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
 
4735
    master_port = mi->port;
3621
4736
    master_pos = rli->group_master_log_pos;
3622
4737
  }
3623
4738
  else
3624
 
    sql_print_error(_("Out of memory while recording slave event"));
 
4739
    sql_print_error("Out of memory while recording slave event");
3625
4740
  pthread_mutex_unlock(&rli->data_lock);
3626
4741
  pthread_mutex_unlock(&mi->data_lock);
3627
4742
  return;
3628
4743
}
 
4744
#endif /* !MYSQL_CLIENT */
3629
4745
 
3630
4746
 
3631
4747
Slave_log_event::~Slave_log_event()
3632
4748
{
3633
 
  free(mem_pool);
3634
 
}
 
4749
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
 
4750
}
 
4751
 
 
4752
 
 
4753
#ifdef MYSQL_CLIENT
 
4754
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4755
{
 
4756
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
4757
 
 
4758
  char llbuff[22];
 
4759
  if (print_event_info->short_form)
 
4760
    return;
 
4761
  print_header(&cache, print_event_info, false);
 
4762
  my_b_printf(&cache, "\n\
 
4763
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
 
4764
          master_host, master_port, master_log, llstr(master_pos, llbuff));
 
4765
}
 
4766
#endif /* MYSQL_CLIENT */
3635
4767
 
3636
4768
 
3637
4769
int Slave_log_event::get_data_size()
3638
4770
{
3639
 
  return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
 
4771
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
3640
4772
}
3641
4773
 
3642
4774
 
 
4775
#ifndef MYSQL_CLIENT
3643
4776
bool Slave_log_event::write(IO_CACHE* file)
3644
4777
{
3645
4778
  ulong event_length= get_data_size();
3648
4781
  // log and host are already there
3649
4782
 
3650
4783
  return (write_header(file, event_length) ||
3651
 
          my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
 
4784
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
3652
4785
}
3653
 
 
3654
 
 
3655
 
void Slave_log_event::init_from_mem_pool()
 
4786
#endif
 
4787
 
 
4788
 
 
4789
void Slave_log_event::init_from_mem_pool(int data_size)
3656
4790
{
3657
4791
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
3658
4792
  master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
3659
 
#ifdef FIXME
3660
 
  /* Assign these correctly */
3661
 
  master_host.assign(mem_pool + SL_MASTER_HOST_OFFSET);
3662
 
  master_log.assign();
3663
 
#endif
3664
 
}
3665
 
 
3666
 
 
3667
 
int Slave_log_event::do_apply_event(const Relay_log_info *)
3668
 
{
3669
 
  if (drizzle_bin_log.is_open())
3670
 
    drizzle_bin_log.write(this);
 
4793
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
 
4794
  master_host_len = strlen(master_host);
 
4795
  // safety
 
4796
  master_log = master_host + master_host_len + 1;
 
4797
  if (master_log > mem_pool + data_size)
 
4798
  {
 
4799
    master_host = 0;
 
4800
    return;
 
4801
  }
 
4802
  master_log_len = strlen(master_log);
 
4803
}
 
4804
 
 
4805
 
 
4806
/** This code is not used, so has not been updated to be format-tolerant. */
 
4807
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
 
4808
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
 
4809
{
 
4810
  if (event_len < LOG_EVENT_HEADER_LEN)
 
4811
    return;
 
4812
  event_len -= LOG_EVENT_HEADER_LEN;
 
4813
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
 
4814
    return;
 
4815
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
 
4816
  mem_pool[event_len] = 0;
 
4817
  init_from_mem_pool(event_len);
 
4818
}
 
4819
 
 
4820
 
 
4821
#ifndef MYSQL_CLIENT
 
4822
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
4823
{
 
4824
  if (mysql_bin_log.is_open())
 
4825
    mysql_bin_log.write(this);
3671
4826
  return 0;
3672
4827
}
 
4828
#endif /* !MYSQL_CLIENT */
3673
4829
 
3674
4830
 
3675
4831
/**************************************************************************
3677
4833
**************************************************************************/
3678
4834
 
3679
4835
/*
 
4836
  Stop_log_event::print()
 
4837
*/
 
4838
 
 
4839
#ifdef MYSQL_CLIENT
 
4840
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
4841
{
 
4842
  Write_on_release_cache cache(&print_event_info->head_cache, file,
 
4843
                               Write_on_release_cache::FLUSH_F);
 
4844
 
 
4845
  if (print_event_info->short_form)
 
4846
    return;
 
4847
 
 
4848
  print_header(&cache, print_event_info, false);
 
4849
  my_b_printf(&cache, "\tStop\n");
 
4850
}
 
4851
#endif /* MYSQL_CLIENT */
 
4852
 
 
4853
 
 
4854
#ifndef MYSQL_CLIENT
 
4855
/*
3680
4856
  The master stopped.  We used to clean up all temporary tables but
3681
4857
  this is useless as, as the master has shut down properly, it has
3682
 
  written all DROP TEMPORARY Table (prepared statements' deletion is
 
4858
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
3683
4859
  TODO only when we binlog prep stmts).  We used to clean up
3684
4860
  slave_load_tmpdir, but this is useless as it has been cleared at the
3685
4861
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
3696
4872
    could give false triggers in MASTER_POS_WAIT() that we have reached
3697
4873
    the target position when in fact we have not.
3698
4874
  */
3699
 
  if (session->options & OPTION_BEGIN)
 
4875
  if (thd->options & OPTION_BEGIN)
3700
4876
    rli->inc_event_relay_log_pos();
3701
4877
  else
3702
4878
  {
3706
4882
  return 0;
3707
4883
}
3708
4884
 
 
4885
#endif /* !MYSQL_CLIENT */
 
4886
#endif /* HAVE_REPLICATION */
 
4887
 
3709
4888
 
3710
4889
/**************************************************************************
3711
4890
        Create_file_log_event methods
3715
4894
  Create_file_log_event ctor
3716
4895
*/
3717
4896
 
 
4897
#ifndef MYSQL_CLIENT
3718
4898
Create_file_log_event::
3719
 
Create_file_log_event(Session* session_arg, sql_exchange* ex,
 
4899
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
3720
4900
                      const char* db_arg, const char* table_name_arg,
3721
4901
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
3722
4902
                      bool ignore,
3723
 
                      unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
3724
 
  :Load_log_event(session_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
 
4903
                      uchar* block_arg, uint block_len_arg, bool using_trans)
 
4904
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
3725
4905
                  using_trans),
3726
4906
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
3727
 
   file_id(session_arg->file_id = drizzle_bin_log.next_file_id())
 
4907
   file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
3728
4908
{
3729
4909
  sql_ex.force_new_format();
3730
4910
  return;
3740
4920
  bool res;
3741
4921
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
3742
4922
    return res;
3743
 
  return (my_b_safe_write(file, (unsigned char*) "", 1) ||
3744
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
 
4923
  return (my_b_safe_write(file, (uchar*) "", 1) ||
 
4924
          my_b_safe_write(file, (uchar*) block, block_len));
3745
4925
}
3746
4926
 
3747
4927
 
3752
4932
bool Create_file_log_event::write_data_header(IO_CACHE* file)
3753
4933
{
3754
4934
  bool res;
3755
 
  unsigned char buf[CREATE_FILE_HEADER_LEN];
 
4935
  uchar buf[CREATE_FILE_HEADER_LEN];
3756
4936
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
3757
4937
    return res;
3758
4938
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
3773
4953
  return res;
3774
4954
}
3775
4955
 
 
4956
#endif /* !MYSQL_CLIENT */
 
4957
 
3776
4958
/*
3777
4959
  Create_file_log_event ctor
3778
4960
*/
3779
4961
 
3780
 
Create_file_log_event::Create_file_log_event(const char* buf, uint32_t len,
 
4962
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
3781
4963
                                             const Format_description_log_event* description_event)
3782
4964
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
3783
4965
{
3784
 
  uint32_t block_offset;
3785
 
  uint32_t header_len= description_event->common_header_len;
 
4966
  uint block_offset;
 
4967
  uint header_len= description_event->common_header_len;
3786
4968
  uint8_t load_header_len= description_event->post_header_len[LOAD_EVENT-1];
3787
4969
  uint8_t create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
3788
4970
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
3815
4997
                   create_file_header_len + 1);
3816
4998
    if (len < block_offset)
3817
4999
      return;
3818
 
    block = (unsigned char*)buf + block_offset;
 
5000
    block = (uchar*)buf + block_offset;
3819
5001
    block_len = len - block_offset;
3820
5002
  }
3821
5003
  else
3828
5010
 
3829
5011
 
3830
5012
/*
 
5013
  Create_file_log_event::print()
 
5014
*/
 
5015
 
 
5016
#ifdef MYSQL_CLIENT
 
5017
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
 
5018
                                  bool enable_local)
 
5019
{
 
5020
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5021
 
 
5022
  if (print_event_info->short_form)
 
5023
  {
 
5024
    if (enable_local && check_fname_outside_temp_buf())
 
5025
      Load_log_event::print(file, print_event_info);
 
5026
    return;
 
5027
  }
 
5028
 
 
5029
  if (enable_local)
 
5030
  {
 
5031
    Load_log_event::print(file, print_event_info,
 
5032
                          !check_fname_outside_temp_buf());
 
5033
    /* 
 
5034
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
 
5035
       SHOW BINLOG EVENTS we don't.
 
5036
    */
 
5037
    my_b_printf(&cache, "#"); 
 
5038
  }
 
5039
 
 
5040
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
 
5041
}
 
5042
 
 
5043
 
 
5044
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
 
5045
{
 
5046
  print(file, print_event_info, 0);
 
5047
}
 
5048
#endif /* MYSQL_CLIENT */
 
5049
 
 
5050
 
 
5051
/*
3831
5052
  Create_file_log_event::pack_info()
3832
5053
*/
3833
5054
 
 
5055
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3834
5056
void Create_file_log_event::pack_info(Protocol *protocol)
3835
5057
{
3836
5058
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
3837
 
  pos= my_stpcpy(buf, "db=");
 
5059
  pos= strmov(buf, "db=");
3838
5060
  memcpy(pos, db, db_len);
3839
 
  pos= my_stpcpy(pos + db_len, ";table=");
 
5061
  pos= strmov(pos + db_len, ";table=");
3840
5062
  memcpy(pos, table_name, table_name_len);
3841
 
  pos= my_stpcpy(pos + table_name_len, ";file_id=");
 
5063
  pos= strmov(pos + table_name_len, ";file_id=");
3842
5064
  pos= int10_to_str((long) file_id, pos, 10);
3843
 
  pos= my_stpcpy(pos, ";block_len=");
 
5065
  pos= strmov(pos, ";block_len=");
3844
5066
  pos= int10_to_str((long) block_len, pos, 10);
3845
5067
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3846
5068
}
 
5069
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
3847
5070
 
3848
5071
 
3849
5072
/*
3850
5073
  Create_file_log_event::do_apply_event()
3851
5074
*/
3852
5075
 
 
5076
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3853
5077
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
3854
5078
{
3855
5079
  char proc_info[17+FN_REFLEN+10], *fname_buf;
3858
5082
  IO_CACHE file;
3859
5083
  int error = 1;
3860
5084
 
3861
 
  memset(&file, 0, sizeof(file));
3862
 
  fname_buf= my_stpcpy(proc_info, "Making temp file ");
 
5085
  memset((char*)&file, 0, sizeof(file));
 
5086
  fname_buf= strmov(proc_info, "Making temp file ");
3863
5087
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
3864
 
  session->set_proc_info(proc_info);
 
5088
  thd_proc_info(thd, proc_info);
3865
5089
  my_delete(fname_buf, MYF(0)); // old copy may exist already
3866
5090
  if ((fd= my_create(fname_buf, CREATE_MODE,
3867
 
                     O_WRONLY | O_EXCL,
 
5091
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
3868
5092
                     MYF(MY_WME))) < 0 ||
3869
5093
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
3870
5094
                    MYF(MY_WME|MY_NABP)))
3871
5095
  {
3872
5096
    rli->report(ERROR_LEVEL, my_errno,
3873
 
                _("Error in Create_file event: could not open file '%s'"),
 
5097
                "Error in Create_file event: could not open file '%s'",
3874
5098
                fname_buf);
3875
5099
    goto err;
3876
5100
  }
3877
5101
  
3878
5102
  // a trick to avoid allocating another buffer
3879
5103
  fname= fname_buf;
3880
 
  fname_len= (uint) (my_stpcpy(ext, ".data") - fname);
 
5104
  fname_len= (uint) (strmov(ext, ".data") - fname);
3881
5105
  if (write_base(&file))
3882
5106
  {
3883
 
    my_stpcpy(ext, ".info"); // to have it right in the error message
 
5107
    strmov(ext, ".info"); // to have it right in the error message
3884
5108
    rli->report(ERROR_LEVEL, my_errno,
3885
 
                _("Error in Create_file event: could not write to file '%s'"),
 
5109
                "Error in Create_file event: could not write to file '%s'",
3886
5110
                fname_buf);
3887
5111
    goto err;
3888
5112
  }
3889
5113
  end_io_cache(&file);
3890
5114
  my_close(fd, MYF(0));
3891
 
 
 
5115
  
3892
5116
  // fname_buf now already has .data, not .info, because we did our trick
3893
5117
  my_delete(fname_buf, MYF(0)); // old copy may exist already
3894
5118
  if ((fd= my_create(fname_buf, CREATE_MODE,
3895
 
                     O_WRONLY | O_EXCL,
3896
 
                     MYF(MY_WME))) < 0)
 
5119
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
5120
                     MYF(MY_WME))) < 0)
3897
5121
  {
3898
5122
    rli->report(ERROR_LEVEL, my_errno,
3899
 
                _("Error in Create_file event: could not open file '%s'"),
 
5123
                "Error in Create_file event: could not open file '%s'",
3900
5124
                fname_buf);
3901
5125
    goto err;
3902
5126
  }
3903
 
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
 
5127
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
3904
5128
  {
3905
5129
    rli->report(ERROR_LEVEL, my_errno,
3906
 
                _("Error in Create_file event: write to '%s' failed"),
 
5130
                "Error in Create_file event: write to '%s' failed",
3907
5131
                fname_buf);
3908
5132
    goto err;
3909
5133
  }
3914
5138
    end_io_cache(&file);
3915
5139
  if (fd >= 0)
3916
5140
    my_close(fd, MYF(0));
3917
 
  session->set_proc_info(0);
 
5141
  thd_proc_info(thd, 0);
3918
5142
  return error == 0;
3919
5143
}
 
5144
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
3920
5145
 
3921
5146
 
3922
5147
/**************************************************************************
3927
5152
  Append_block_log_event ctor
3928
5153
*/
3929
5154
 
3930
 
Append_block_log_event::Append_block_log_event(Session *session_arg,
 
5155
#ifndef MYSQL_CLIENT  
 
5156
Append_block_log_event::Append_block_log_event(THD *thd_arg,
3931
5157
                                               const char *db_arg,
3932
 
                                               unsigned char *block_arg,
3933
 
                                               uint32_t block_len_arg,
 
5158
                                               uchar *block_arg,
 
5159
                                               uint block_len_arg,
3934
5160
                                               bool using_trans)
3935
 
  :Log_event(session_arg,0, using_trans), block(block_arg),
3936
 
   block_len(block_len_arg), file_id(session_arg->file_id), db(db_arg)
 
5161
  :Log_event(thd_arg,0, using_trans), block(block_arg),
 
5162
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
3937
5163
{
3938
5164
}
 
5165
#endif
3939
5166
 
3940
5167
 
3941
5168
/*
3942
5169
  Append_block_log_event ctor
3943
5170
*/
3944
5171
 
3945
 
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
 
5172
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
3946
5173
                                               const Format_description_log_event* description_event)
3947
5174
  :Log_event(buf, description_event),block(0)
3948
5175
{
3949
5176
  uint8_t common_header_len= description_event->common_header_len; 
3950
5177
  uint8_t append_block_header_len=
3951
5178
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
3952
 
  uint32_t total_header_len= common_header_len+append_block_header_len;
 
5179
  uint total_header_len= common_header_len+append_block_header_len;
3953
5180
  if (len < total_header_len)
3954
5181
    return;
3955
5182
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
3956
 
  block= (unsigned char*)buf + total_header_len;
 
5183
  block= (uchar*)buf + total_header_len;
3957
5184
  block_len= len - total_header_len;
3958
5185
  return;
3959
5186
}
3963
5190
  Append_block_log_event::write()
3964
5191
*/
3965
5192
 
 
5193
#ifndef MYSQL_CLIENT
3966
5194
bool Append_block_log_event::write(IO_CACHE* file)
3967
5195
{
3968
 
  unsigned char buf[APPEND_BLOCK_HEADER_LEN];
 
5196
  uchar buf[APPEND_BLOCK_HEADER_LEN];
3969
5197
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
3970
5198
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
3971
5199
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
3972
 
          my_b_safe_write(file, (unsigned char*) block, block_len));
3973
 
}
 
5200
          my_b_safe_write(file, (uchar*) block, block_len));
 
5201
}
 
5202
#endif
 
5203
 
 
5204
 
 
5205
/*
 
5206
  Append_block_log_event::print()
 
5207
*/
 
5208
 
 
5209
#ifdef MYSQL_CLIENT  
 
5210
void Append_block_log_event::print(FILE* file,
 
5211
                                   PRINT_EVENT_INFO* print_event_info)
 
5212
{
 
5213
  Write_on_release_cache cache(&print_event_info->head_cache, file);
 
5214
 
 
5215
  if (print_event_info->short_form)
 
5216
    return;
 
5217
  print_header(&cache, print_event_info, false);
 
5218
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
 
5219
              get_type_str(), file_id, block_len);
 
5220
}
 
5221
#endif /* MYSQL_CLIENT */
3974
5222
 
3975
5223
 
3976
5224
/*
3977
5225
  Append_block_log_event::pack_info()
3978
5226
*/
3979
5227
 
 
5228
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
3980
5229
void Append_block_log_event::pack_info(Protocol *protocol)
3981
5230
{
3982
5231
  char buf[256];
3983
 
  uint32_t length;
 
5232
  uint length;
3984
5233
  length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
3985
5234
                             block_len);
3986
5235
  protocol->store(buf, length, &my_charset_bin);
4006
5255
  int fd;
4007
5256
  int error = 1;
4008
5257
 
4009
 
  fname= my_stpcpy(proc_info, "Making temp file ");
 
5258
  fname= strmov(proc_info, "Making temp file ");
4010
5259
  slave_load_file_stem(fname, file_id, server_id, ".data");
4011
 
  session->set_proc_info(proc_info);
 
5260
  thd_proc_info(thd, proc_info);
4012
5261
  if (get_create_or_append())
4013
5262
  {
4014
5263
    my_delete(fname, MYF(0)); // old copy may exist already
4015
5264
    if ((fd= my_create(fname, CREATE_MODE,
4016
 
                       O_WRONLY | O_EXCL,
 
5265
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
4017
5266
                       MYF(MY_WME))) < 0)
4018
5267
    {
4019
5268
      rli->report(ERROR_LEVEL, my_errno,
4020
 
                  _("Error in %s event: could not create file '%s'"),
 
5269
                  "Error in %s event: could not create file '%s'",
4021
5270
                  get_type_str(), fname);
4022
5271
      goto err;
4023
5272
    }
4024
5273
  }
4025
 
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
 
5274
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
4026
5275
                         MYF(MY_WME))) < 0)
4027
5276
  {
4028
5277
    rli->report(ERROR_LEVEL, my_errno,
4029
 
                _("Error in %s event: could not open file '%s'"),
 
5278
                "Error in %s event: could not open file '%s'",
4030
5279
                get_type_str(), fname);
4031
5280
    goto err;
4032
5281
  }
4033
 
  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)))
4034
5283
  {
4035
5284
    rli->report(ERROR_LEVEL, my_errno,
4036
 
                _("Error in %s event: write to '%s' failed"),
 
5285
                "Error in %s event: write to '%s' failed",
4037
5286
                get_type_str(), fname);
4038
5287
    goto err;
4039
5288
  }
4042
5291
err:
4043
5292
  if (fd >= 0)
4044
5293
    my_close(fd, MYF(0));
4045
 
  session->set_proc_info(0);
 
5294
  thd_proc_info(thd, 0);
4046
5295
  return(error);
4047
5296
}
 
5297
#endif
4048
5298
 
4049
5299
 
4050
5300
/**************************************************************************
4055
5305
  Delete_file_log_event ctor
4056
5306
*/
4057
5307
 
4058
 
Delete_file_log_event::Delete_file_log_event(Session *session_arg, const char* db_arg,
 
5308
#ifndef MYSQL_CLIENT
 
5309
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
4059
5310
                                             bool using_trans)
4060
 
  :Log_event(session_arg, 0, using_trans), file_id(session_arg->file_id), db(db_arg)
 
5311
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4061
5312
{
4062
5313
}
 
5314
#endif
4063
5315
 
4064
5316
/*
4065
5317
  Delete_file_log_event ctor
4066
5318
*/
4067
5319
 
4068
 
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,
4069
5321
                                             const Format_description_log_event* description_event)
4070
5322
  :Log_event(buf, description_event),file_id(0)
4071
5323
{
4081
5333
  Delete_file_log_event::write()
4082
5334
*/
4083
5335
 
 
5336
#ifndef MYSQL_CLIENT
4084
5337
bool Delete_file_log_event::write(IO_CACHE* file)
4085
5338
{
4086
 
 unsigned char buf[DELETE_FILE_HEADER_LEN];
 
5339
 uchar buf[DELETE_FILE_HEADER_LEN];
4087
5340
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
4088
5341
 return (write_header(file, sizeof(buf)) ||
4089
5342
         my_b_safe_write(file, buf, sizeof(buf)));
4090
5343
}
4091
 
 
 
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 */
4092
5363
 
4093
5364
/*
4094
5365
  Delete_file_log_event::pack_info()
4095
5366
*/
4096
5367
 
 
5368
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4097
5369
void Delete_file_log_event::pack_info(Protocol *protocol)
4098
5370
{
4099
5371
  char buf[64];
4100
 
  uint32_t length;
 
5372
  uint length;
4101
5373
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4102
5374
  protocol->store(buf, (int32_t) length, &my_charset_bin);
4103
5375
}
 
5376
#endif
4104
5377
 
4105
5378
/*
4106
5379
  Delete_file_log_event::do_apply_event()
4107
5380
*/
4108
5381
 
4109
 
int Delete_file_log_event::do_apply_event(const Relay_log_info *)
 
5382
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
 
5383
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4110
5384
{
4111
5385
  char fname[FN_REFLEN+10];
4112
5386
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
4113
5387
  (void) my_delete(fname, MYF(MY_WME));
4114
 
  my_stpcpy(ext, ".info");
 
5388
  strmov(ext, ".info");
4115
5389
  (void) my_delete(fname, MYF(MY_WME));
4116
5390
  return 0;
4117
5391
}
 
5392
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
4118
5393
 
4119
5394
 
4120
5395
/**************************************************************************
4125
5400
  Execute_load_log_event ctor
4126
5401
*/
4127
5402
 
4128
 
Execute_load_log_event::Execute_load_log_event(Session *session_arg,
 
5403
#ifndef MYSQL_CLIENT  
 
5404
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
4129
5405
                                               const char* db_arg,
4130
5406
                                               bool using_trans)
4131
 
  :Log_event(session_arg, 0, using_trans), file_id(session_arg->file_id), db(db_arg)
 
5407
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
4132
5408
{
4133
5409
}
 
5410
#endif
4134
5411
  
4135
5412
 
4136
5413
/*
4137
5414
  Execute_load_log_event ctor
4138
5415
*/
4139
5416
 
4140
 
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,
4141
5418
                                               const Format_description_log_event* description_event)
4142
5419
  :Log_event(buf, description_event), file_id(0)
4143
5420
{
4153
5430
  Execute_load_log_event::write()
4154
5431
*/
4155
5432
 
 
5433
#ifndef MYSQL_CLIENT
4156
5434
bool Execute_load_log_event::write(IO_CACHE* file)
4157
5435
{
4158
 
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
 
5436
  uchar buf[EXEC_LOAD_HEADER_LEN];
4159
5437
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
4160
5438
  return (write_header(file, sizeof(buf)) || 
4161
5439
          my_b_safe_write(file, buf, sizeof(buf)));
4162
5440
}
4163
 
 
 
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
4164
5461
 
4165
5462
/*
4166
5463
  Execute_load_log_event::pack_info()
4167
5464
*/
4168
5465
 
 
5466
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4169
5467
void Execute_load_log_event::pack_info(Protocol *protocol)
4170
5468
{
4171
5469
  char buf[64];
4172
 
  uint32_t length;
 
5470
  uint length;
4173
5471
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
4174
5472
  protocol->store(buf, (int32_t) length, &my_charset_bin);
4175
5473
}
4189
5487
  Load_log_event *lev= 0;
4190
5488
 
4191
5489
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
4192
 
  if ((fd = my_open(fname, O_RDONLY,
 
5490
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
4193
5491
                    MYF(MY_WME))) < 0 ||
4194
5492
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
4195
5493
                    MYF(MY_WME|MY_NABP)))
4196
5494
  {
4197
5495
    rli->report(ERROR_LEVEL, my_errno,
4198
 
                _("Error in Exec_load event: could not open file '%s'"),
 
5496
                "Error in Exec_load event: could not open file '%s'",
4199
5497
                fname);
4200
5498
    goto err;
4201
5499
  }
4204
5502
                                                         rli->relay_log.description_event_for_exec)) ||
4205
5503
      lev->get_type_code() != NEW_LOAD_EVENT)
4206
5504
  {
4207
 
    rli->report(ERROR_LEVEL, 0,
4208
 
                _("Error in Exec_load event: "
4209
 
                  "file '%s' appears corrupted"),
4210
 
                fname);
 
5505
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
 
5506
                    "file '%s' appears corrupted", fname);
4211
5507
    goto err;
4212
5508
  }
4213
5509
 
4214
 
  lev->session = session;
 
5510
  lev->thd = thd;
4215
5511
  /*
4216
5512
    lev->do_apply_event should use rli only for errors i.e. should
4217
5513
    not advance rli's position.
4235
5531
    if (tmp)
4236
5532
    {
4237
5533
      rli->report(ERROR_LEVEL, rli->last_error().number,
4238
 
                  _("%s. Failed executing load from '%s'"),
4239
 
                  tmp, fname);
4240
 
      free(tmp);
 
5534
                  "%s. Failed executing load from '%s'", tmp, fname);
 
5535
      my_free(tmp,MYF(0));
4241
5536
    }
4242
5537
    goto err;
4243
5538
  }
4266
5561
  return error;
4267
5562
}
4268
5563
 
 
5564
#endif /* defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5565
 
4269
5566
 
4270
5567
/**************************************************************************
4271
5568
        Begin_load_query_log_event methods
4272
5569
**************************************************************************/
4273
5570
 
 
5571
#ifndef MYSQL_CLIENT
4274
5572
Begin_load_query_log_event::
4275
 
Begin_load_query_log_event(Session* session_arg, const char* db_arg, unsigned char* block_arg,
4276
 
                           uint32_t block_len_arg, bool using_trans)
4277
 
  :Append_block_log_event(session_arg, db_arg, block_arg, block_len_arg,
 
5573
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
 
5574
                           uint block_len_arg, bool using_trans)
 
5575
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
4278
5576
                          using_trans)
4279
5577
{
4280
 
   file_id= session_arg->file_id= drizzle_bin_log.next_file_id();
 
5578
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
4281
5579
}
 
5580
#endif
4282
5581
 
4283
5582
 
4284
5583
Begin_load_query_log_event::
4285
 
Begin_load_query_log_event(const char* buf, uint32_t len,
 
5584
Begin_load_query_log_event(const char* buf, uint len,
4286
5585
                           const Format_description_log_event* desc_event)
4287
5586
  :Append_block_log_event(buf, len, desc_event)
4288
5587
{
4289
5588
}
4290
5589
 
4291
5590
 
 
5591
#if defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
4292
5592
int Begin_load_query_log_event::get_create_or_append() const
4293
5593
{
4294
5594
  return 1; /* create the file */
4295
5595
}
4296
 
 
4297
 
 
 
5596
#endif /* defined( HAVE_REPLICATION) && !defined(MYSQL_CLIENT) */
 
5597
 
 
5598
 
 
5599
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4298
5600
Log_event::enum_skip_reason
4299
5601
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
4300
5602
{
4304
5606
  */
4305
5607
  return continue_group(rli);
4306
5608
}
 
5609
#endif
4307
5610
 
4308
5611
 
4309
5612
/**************************************************************************
4311
5614
**************************************************************************/
4312
5615
 
4313
5616
 
 
5617
#ifndef MYSQL_CLIENT
4314
5618
Execute_load_query_log_event::
4315
 
Execute_load_query_log_event(Session *session_arg, const char* query_arg,
4316
 
                             ulong query_length_arg, uint32_t fn_pos_start_arg,
4317
 
                             uint32_t fn_pos_end_arg,
 
5619
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
 
5620
                             ulong query_length_arg, uint fn_pos_start_arg,
 
5621
                             uint fn_pos_end_arg,
4318
5622
                             enum_load_dup_handling dup_handling_arg,
4319
5623
                             bool using_trans, bool suppress_use,
4320
 
                             Session::killed_state killed_err_arg):
4321
 
  Query_log_event(session_arg, query_arg, query_length_arg, using_trans,
 
5624
                             THD::killed_state killed_err_arg):
 
5625
  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
4322
5626
                  suppress_use, killed_err_arg),
4323
 
  file_id(session_arg->file_id), fn_pos_start(fn_pos_start_arg),
 
5627
  file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
4324
5628
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
4325
5629
{
4326
5630
}
 
5631
#endif /* !MYSQL_CLIENT */
4327
5632
 
4328
5633
 
4329
5634
Execute_load_query_log_event::
4330
 
Execute_load_query_log_event(const char* buf, uint32_t event_len,
 
5635
Execute_load_query_log_event(const char* buf, uint event_len,
4331
5636
                             const Format_description_log_event* desc_event):
4332
5637
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
4333
5638
  file_id(0), fn_pos_start(0), fn_pos_end(0)
4355
5660
}
4356
5661
 
4357
5662
 
 
5663
#ifndef MYSQL_CLIENT
4358
5664
bool
4359
5665
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
4360
5666
{
4361
 
  unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
5667
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
4362
5668
  int4store(buf, file_id);
4363
5669
  int4store(buf + 4, fn_pos_start);
4364
5670
  int4store(buf + 4 + 4, fn_pos_end);
4365
 
  *(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
 
5671
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
4366
5672
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
4367
5673
}
4368
 
 
4369
 
 
 
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)
4370
5720
void Execute_load_query_log_event::pack_info(Protocol *protocol)
4371
5721
{
4372
5722
  char *buf, *pos;
4375
5725
  pos= buf;
4376
5726
  if (db && db_len)
4377
5727
  {
4378
 
    pos= my_stpcpy(buf, "use `");
 
5728
    pos= strmov(buf, "use `");
4379
5729
    memcpy(pos, db, db_len);
4380
 
    pos= my_stpcpy(pos+db_len, "`; ");
 
5730
    pos= strmov(pos+db_len, "`; ");
4381
5731
  }
4382
5732
  if (query && q_len)
4383
5733
  {
4384
5734
    memcpy(pos, query, q_len);
4385
5735
    pos+= q_len;
4386
5736
  }
4387
 
  pos= my_stpcpy(pos, " ;file_id=");
 
5737
  pos= strmov(pos, " ;file_id=");
4388
5738
  pos= int10_to_str((long) file_id, pos, 10);
4389
5739
  protocol->store(buf, pos-buf, &my_charset_bin);
4390
 
  free(buf);
 
5740
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4391
5741
}
4392
5742
 
4393
5743
 
4407
5757
  if (buf == NULL)
4408
5758
  {
4409
5759
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
4410
 
                ER(ER_SLAVE_FATAL_ERROR),
4411
 
                _("Not enough memory"));
 
5760
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
4412
5761
    return 1;
4413
5762
  }
4414
5763
 
4417
5766
  p+= fn_pos_start;
4418
5767
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
4419
5768
  p= slave_load_file_stem(p, file_id, server_id, ".data");
4420
 
  fname_end= p= strchr(p, '\0');                      // Safer than p=p+5
 
5769
  fname_end= p= strend(p);                      // Safer than p=p+5
4421
5770
  *(p++)='\'';
4422
5771
  switch (dup_handling) {
4423
5772
  case LOAD_DUP_IGNORE:
4445
5794
  if (!error)
4446
5795
    (void) my_delete(fname, MYF(MY_WME));
4447
5796
 
4448
 
  free(buf);
 
5797
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
4449
5798
  return error;
4450
5799
}
 
5800
#endif
4451
5801
 
4452
5802
 
4453
5803
/**************************************************************************
4467
5817
            write_str(file, line_term,  (uint) line_term_len) ||
4468
5818
            write_str(file, line_start, (uint) line_start_len) ||
4469
5819
            write_str(file, escaped,    (uint) escaped_len) ||
4470
 
            my_b_safe_write(file,(unsigned char*) &opt_flags,1));
 
5820
            my_b_safe_write(file,(uchar*) &opt_flags,1));
4471
5821
  }
4472
5822
  else
4473
5823
  {
4483
5833
    old_ex.escaped=    *escaped;
4484
5834
    old_ex.opt_flags=  opt_flags;
4485
5835
    old_ex.empty_flags=empty_flags;
4486
 
    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;
4487
5837
  }
4488
5838
}
4489
5839
 
4543
5893
        Rows_log_event member functions
4544
5894
**************************************************************************/
4545
5895
 
4546
 
Rows_log_event::Rows_log_event(Session *session_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,
4547
5898
                               MY_BITMAP const *cols, bool is_transactional)
4548
 
  : Log_event(session_arg, 0, is_transactional),
 
5899
  : Log_event(thd_arg, 0, is_transactional),
4549
5900
    m_row_count(0),
4550
5901
    m_table(tbl_arg),
4551
5902
    m_table_id(tid),
4552
5903
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
4553
5904
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
 
5905
#ifdef HAVE_REPLICATION
4554
5906
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5907
#endif
4555
5908
{
4556
5909
  /*
4557
5910
    We allow a special form of dummy event when the table, and cols
4558
 
    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
4559
5912
    solution, to be able to terminate a started statement in the
4560
5913
    binary log: the extraneous events will be removed in the future.
4561
5914
   */
4562
 
  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));
4563
5916
 
4564
 
  if (session_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
 
5917
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
4565
5918
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
4566
 
  if (session_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
 
5919
  if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
4567
5920
      set_flags(RELAXED_UNIQUE_CHECKS_F);
4568
5921
  /* if bitmap_init fails, caught in is_valid() */
4569
5922
  if (likely(!bitmap_init(&m_cols,
4584
5937
    m_cols.bitmap= 0;
4585
5938
  }
4586
5939
}
4587
 
 
4588
 
 
4589
 
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,
4590
5943
                               Log_event_type event_type,
4591
5944
                               const Format_description_log_event
4592
5945
                               *description_event)
4593
5946
  : Log_event(buf, description_event),
4594
5947
    m_row_count(0),
 
5948
#ifndef MYSQL_CLIENT
4595
5949
    m_table(NULL),
 
5950
#endif
4596
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)
4597
5953
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
 
5954
#endif
4598
5955
{
4599
5956
  uint8_t const common_header_len= description_event->common_header_len;
4600
5957
  uint8_t const post_header_len= description_event->post_header_len[event_type-1];
4615
5972
 
4616
5973
  m_flags= uint2korr(post_start);
4617
5974
 
4618
 
  unsigned char const *const var_start=
4619
 
    (const unsigned char *)buf + common_header_len + post_header_len;
4620
 
  unsigned char const *const ptr_width= var_start;
4621
 
  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;
4622
5979
  m_width = net_field_length(&ptr_after_width);
4623
5980
  /* if bitmap_init fails, catched in is_valid() */
4624
5981
  if (likely(!bitmap_init(&m_cols,
4659
6016
    }
4660
6017
  }
4661
6018
 
4662
 
  const unsigned char* const ptr_rows_data= (const unsigned char*) ptr_after_width;
4663
 
 
4664
 
  size_t const data_size= event_len - (ptr_rows_data - (const unsigned char *) buf);
4665
 
 
4666
 
  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));
4667
6024
  if (likely((bool)m_rows_buf))
4668
6025
  {
 
6026
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4669
6027
    m_curr_row= m_rows_buf;
 
6028
#endif
4670
6029
    m_rows_end= m_rows_buf + data_size;
4671
6030
    m_rows_cur= m_rows_end;
4672
6031
    memcpy(m_rows_buf, ptr_rows_data, data_size);
4680
6039
Rows_log_event::~Rows_log_event()
4681
6040
{
4682
6041
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
4683
 
    m_cols.bitmap= 0; // so no free in bitmap_free
 
6042
    m_cols.bitmap= 0; // so no my_free in bitmap_free
4684
6043
  bitmap_free(&m_cols); // To pair with bitmap_init().
4685
 
  free((unsigned char*)m_rows_buf);
 
6044
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
4686
6045
}
4687
6046
 
4688
6047
int Rows_log_event::get_data_size()
4689
6048
{
4690
6049
  int const type_code= get_type_code();
4691
6050
 
4692
 
  unsigned char buf[sizeof(m_width)+1];
4693
 
  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);
4694
6053
 
4695
6054
  int data_size= ROWS_HEADER_LEN;
4696
6055
  data_size+= no_bytes_in_map(&m_cols);
4704
6063
}
4705
6064
 
4706
6065
 
4707
 
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)
4708
6068
{
4709
6069
  /*
4710
6070
    When the table has a primary key, we would probably want, by default, to
4735
6095
    my_ptrdiff_t const new_alloc= 
4736
6096
        block_size * ((cur_size + length + block_size - 1) / block_size);
4737
6097
 
4738
 
    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,
4739
6099
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
4740
6100
    if (unlikely(!new_buf))
4741
6101
      return(HA_ERR_OUT_OF_MEM);
4760
6120
  m_row_count++;
4761
6121
  return(0);
4762
6122
}
 
6123
#endif
4763
6124
 
 
6125
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
4764
6126
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
4765
6127
{
4766
6128
  int error= 0;
4767
6129
  /*
4768
 
    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
4769
6131
    contain any data.  In that case, we just remove all tables in the
4770
6132
    tables_to_lock list, close the thread tables, and return with
4771
6133
    success.
4772
6134
   */
4773
 
  if (m_table_id == UINT32_MAX)
 
6135
  if (m_table_id == ~0UL)
4774
6136
  {
4775
6137
    /*
4776
6138
       This one is supposed to be set: just an extra check so that
4779
6141
    assert(get_flags(STMT_END_F));
4780
6142
 
4781
6143
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4782
 
    close_thread_tables(session);
4783
 
    session->clear_error();
 
6144
    close_thread_tables(thd);
 
6145
    thd->clear_error();
4784
6146
    return(0);
4785
6147
  }
4786
6148
 
4787
6149
  /*
4788
 
    'session' has been set by exec_relay_log_event(), just before calling
 
6150
    'thd' has been set by exec_relay_log_event(), just before calling
4789
6151
    do_apply_event(). We still check here to prevent future coding
4790
6152
    errors.
4791
6153
  */
4792
 
  assert(rli->sql_session == session);
 
6154
  assert(rli->sql_thd == thd);
4793
6155
 
4794
6156
  /*
4795
6157
    If there is no locks taken, this is the first binrow event seen
4797
6159
    used in the transaction and proceed with execution of the actual
4798
6160
    event.
4799
6161
  */
4800
 
  if (!session->lock)
 
6162
  if (!thd->lock)
4801
6163
  {
4802
6164
    bool need_reopen= 1; /* To execute the first lap of the loop below */
4803
6165
 
4804
6166
    /*
4805
 
      lock_tables() reads the contents of session->lex, so they must be
 
6167
      lock_tables() reads the contents of thd->lex, so they must be
4806
6168
      initialized. Contrary to in
4807
6169
      Table_map_log_event::do_apply_event() we don't call
4808
6170
      mysql_init_query() as that may reset the binlog format.
4809
6171
    */
4810
 
    lex_start(session);
 
6172
    lex_start(thd);
4811
6173
 
4812
6174
    /*
4813
6175
      There are a few flags that are replicated with each row event.
4815
6177
      the event.
4816
6178
    */
4817
6179
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
4818
 
        session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
6180
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4819
6181
    else
4820
 
        session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
6182
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4821
6183
 
4822
6184
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
4823
 
        session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
6185
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4824
6186
    else
4825
 
        session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
6187
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4826
6188
    /* A small test to verify that objects have consistent types */
4827
 
    assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4828
 
 
4829
 
 
4830
 
    while ((error= lock_tables(session, rli->tables_to_lock,
 
6189
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6190
 
 
6191
 
 
6192
    while ((error= lock_tables(thd, rli->tables_to_lock,
4831
6193
                               rli->tables_to_lock_count, &need_reopen)))
4832
6194
    {
4833
6195
      if (!need_reopen)
4834
6196
      {
4835
 
        if (session->is_slave_error || session->is_fatal_error)
 
6197
        if (thd->is_slave_error || thd->is_fatal_error)
4836
6198
        {
4837
6199
          /*
4838
6200
            Error reporting borrowed from Query_log_event with many excessive
4839
6201
            simplifications (we don't honour --slave-skip-errors)
4840
6202
          */
4841
 
          uint32_t actual_error= session->main_da.sql_errno();
 
6203
          uint actual_error= thd->main_da.sql_errno();
4842
6204
          rli->report(ERROR_LEVEL, actual_error,
4843
 
                      _("Error '%s' in %s event: when locking tables"),
4844
 
                      (actual_error
4845
 
                       ? session->main_da.message()
4846
 
                       : _("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"),
4847
6208
                      get_type_str());
4848
 
          session->is_fatal_error= 1;
 
6209
          thd->is_fatal_error= 1;
4849
6210
        }
4850
6211
        else
4851
6212
        {
4852
6213
          rli->report(ERROR_LEVEL, error,
4853
 
                      _("Error in %s event: when locking tables"),
 
6214
                      "Error in %s event: when locking tables",
4854
6215
                      get_type_str());
4855
6216
        }
4856
6217
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4870
6231
        NOTE: For this new scheme there should be no pending event:
4871
6232
        need to add code to assert that is the case.
4872
6233
       */
4873
 
      session->binlog_flush_pending_rows_event(false);
4874
 
      TableList *tables= rli->tables_to_lock;
4875
 
      close_tables_for_reopen(session, &tables);
 
6234
      thd->binlog_flush_pending_rows_event(false);
 
6235
      TABLE_LIST *tables= rli->tables_to_lock;
 
6236
      close_tables_for_reopen(thd, &tables);
4876
6237
 
4877
 
      uint32_t tables_count= rli->tables_to_lock_count;
4878
 
      if ((error= open_tables(session, &tables, &tables_count, 0)))
 
6238
      uint tables_count= rli->tables_to_lock_count;
 
6239
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
4879
6240
      {
4880
 
        if (session->is_slave_error || session->is_fatal_error)
 
6241
        if (thd->is_slave_error || thd->is_fatal_error)
4881
6242
        {
4882
6243
          /*
4883
6244
            Error reporting borrowed from Query_log_event with many excessive
4884
6245
            simplifications (we don't honour --slave-skip-errors)
4885
6246
          */
4886
 
          uint32_t actual_error= session->main_da.sql_errno();
 
6247
          uint actual_error= thd->main_da.sql_errno();
4887
6248
          rli->report(ERROR_LEVEL, actual_error,
4888
 
                      _("Error '%s' on reopening tables"),
4889
 
                      (actual_error
4890
 
                       ? session->main_da.message()
4891
 
                       : _("unexpected success or fatal error")));
4892
 
          session->is_slave_error= 1;
 
6249
                      "Error '%s' on reopening tables",
 
6250
                      (actual_error ? thd->main_da.message() :
 
6251
                       "unexpected success or fatal error"));
 
6252
          thd->is_slave_error= 1;
4893
6253
        }
4894
6254
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4895
6255
        return(error);
4901
6261
      ensure that they still have the correct type.
4902
6262
 
4903
6263
      We can use a down cast here since we know that every table added
4904
 
      to the tables_to_lock is a RPL_TableList.
 
6264
      to the tables_to_lock is a RPL_TABLE_LIST.
4905
6265
    */
4906
6266
 
4907
6267
    {
4908
 
      RPL_TableList *ptr= rli->tables_to_lock;
4909
 
      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))
4910
6270
      {
4911
6271
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
4912
6272
        {
4913
 
          mysql_unlock_tables(session, session->lock);
4914
 
          session->lock= 0;
4915
 
          session->is_slave_error= 1;
 
6273
          mysql_unlock_tables(thd, thd->lock);
 
6274
          thd->lock= 0;
 
6275
          thd->is_slave_error= 1;
4916
6276
          const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
4917
6277
          return(ERR_BAD_TABLE_DEF);
4918
6278
        }
4933
6293
      Rows_log_event, we can invalidate the query cache for the
4934
6294
      associated table.
4935
6295
     */
4936
 
    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)
4937
6297
    {
4938
6298
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
4939
6299
    }
4940
6300
  }
4941
6301
 
4942
 
  Table* 
 
6302
  TABLE* 
4943
6303
    table= 
4944
6304
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
4945
6305
 
4959
6319
      TIMESTAMP column to a table with one.
4960
6320
      So we call set_time(), like in SBR. Presently it changes nothing.
4961
6321
    */
4962
 
    session->set_time((time_t)when);
 
6322
    thd->set_time((time_t)when);
4963
6323
    /*
4964
6324
      There are a few flags that are replicated with each row event.
4965
6325
      Make sure to set/clear them before executing the main body of
4966
6326
      the event.
4967
6327
    */
4968
6328
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
4969
 
        session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
6329
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
4970
6330
    else
4971
 
        session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
6331
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
4972
6332
 
4973
6333
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
4974
 
        session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
6334
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
4975
6335
    else
4976
 
        session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
6336
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
4977
6337
    
4978
6338
    if (slave_allow_batching)
4979
 
      session->options|= OPTION_ALLOW_BATCH;
 
6339
      thd->options|= OPTION_ALLOW_BATCH;
4980
6340
    else
4981
 
      session->options&= ~OPTION_ALLOW_BATCH;
 
6341
      thd->options&= ~OPTION_ALLOW_BATCH;
4982
6342
    
4983
6343
    /* A small test to verify that objects have consistent types */
4984
 
    assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
6344
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
4985
6345
 
4986
6346
    /*
4987
6347
      Now we are in a statement and will stay in a statement until we
5022
6382
    while (error == 0 && m_curr_row < m_rows_end)
5023
6383
    {
5024
6384
      /* in_use can have been set to NULL in close_tables_for_reopen */
5025
 
      Session* old_session= table->in_use;
 
6385
      THD* old_thd= table->in_use;
5026
6386
      if (!table->in_use)
5027
 
        table->in_use= session;
 
6387
        table->in_use= thd;
5028
6388
 
5029
6389
      error= do_exec_row(rli);
5030
6390
 
5031
 
      table->in_use = old_session;
 
6391
      table->in_use = old_thd;
5032
6392
      switch (error)
5033
6393
      {
5034
6394
      case 0:
5058
6418
        if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
5059
6419
        {
5060
6420
          if (global_system_variables.log_warnings)
5061
 
            slave_rows_error_report(WARNING_LEVEL, error, rli, session, table,
 
6421
            slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
5062
6422
                                    get_type_str(),
5063
6423
                                    RPL_LOG_NAME, (ulong) log_pos);
5064
6424
          error= 0;
5066
6426
        break;
5067
6427
        
5068
6428
      default:
5069
 
        session->is_slave_error= 1;
 
6429
        thd->is_slave_error= 1;
5070
6430
        break;
5071
6431
      }
5072
6432
 
5091
6451
    error= do_after_row_operations(rli, error);
5092
6452
    if (!cache_stmt)
5093
6453
    {
5094
 
      session->options|= OPTION_KEEP_LOG;
 
6454
      thd->options|= OPTION_KEEP_LOG;
5095
6455
    }
5096
6456
  } // if (table)
5097
6457
 
5102
6462
  if (rli->tables_to_lock && get_flags(STMT_END_F))
5103
6463
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
5104
6464
  /* reset OPTION_ALLOW_BATCH as not affect later events */
5105
 
  session->options&= ~OPTION_ALLOW_BATCH;
 
6465
  thd->options&= ~OPTION_ALLOW_BATCH;
5106
6466
  
5107
6467
  if (error)
5108
6468
  {                     /* error has occured during the transaction */
5109
 
    slave_rows_error_report(ERROR_LEVEL, error, rli, session, table,
 
6469
    slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
5110
6470
                            get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
5111
6471
  }
5112
6472
  if (error)
5122
6482
      thread is certainly going to stop.
5123
6483
      rollback at the caller along with sbr.
5124
6484
    */
5125
 
    const_cast<Relay_log_info*>(rli)->cleanup_context(session, error);
5126
 
    session->is_slave_error= 1;
 
6485
    thd->reset_current_stmt_binlog_row_based();
 
6486
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
 
6487
    thd->is_slave_error= 1;
5127
6488
    return(error);
5128
6489
  }
5129
6490
 
5193
6554
      (assume the last master's transaction is ignored by the slave because of
5194
6555
      replicate-ignore rules).
5195
6556
    */
5196
 
    session->binlog_flush_pending_rows_event(true);
 
6557
    thd->binlog_flush_pending_rows_event(true);
5197
6558
 
5198
6559
    /*
5199
6560
      If this event is not in a transaction, the call below will, if some
5204
6565
      are involved, commit the transaction and flush the pending event to the
5205
6566
      binlog.
5206
6567
    */
5207
 
    error= ha_autocommit_or_rollback(session, 0);
 
6568
    error= ha_autocommit_or_rollback(thd, 0);
5208
6569
 
5209
6570
    /*
5210
6571
      Now what if this is not a transactional engine? we still need to
5211
6572
      flush the pending event to the binlog; we did it with
5212
 
      session->binlog_flush_pending_rows_event(). Note that we imitate
 
6573
      thd->binlog_flush_pending_rows_event(). Note that we imitate
5213
6574
      what is done for real queries: a call to
5214
6575
      ha_autocommit_or_rollback() (sometimes only if involves a
5215
6576
      transactional engine), and a call to be sure to have the pending
5216
6577
      event flushed.
5217
6578
    */
5218
6579
 
5219
 
    rli->cleanup_context(session, 0);
 
6580
    thd->reset_current_stmt_binlog_row_based();
 
6581
 
 
6582
    rli->cleanup_context(thd, 0);
5220
6583
    if (error == 0)
5221
6584
    {
5222
6585
      /*
5227
6590
      rli->stmt_done(log_pos, when);
5228
6591
 
5229
6592
      /*
5230
 
        Clear any errors pushed in session->net.last_err* if for example "no key
 
6593
        Clear any errors pushed in thd->net.last_err* if for example "no key
5231
6594
        found" (as this is allowed). This is a safety measure; apparently
5232
6595
        those errors (e.g. when executing a Delete_rows_log_event of a
5233
6596
        non-existing row, like in rpl_row_mystery22.test,
5234
 
        session->net.last_error = "Can't find record in 't1'" and last_errno=1032)
 
6597
        thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
5235
6598
        do not become visible. We still prefer to wipe them out.
5236
6599
      */
5237
 
      session->clear_error();
 
6600
      thd->clear_error();
5238
6601
    }
5239
6602
    else
5240
6603
      rli->report(ERROR_LEVEL, error,
5241
 
                  _("Error in %s event: commit of row events failed, "
5242
 
                    "table `%s`.`%s`"),
 
6604
                  "Error in %s event: commit of row events failed, "
 
6605
                  "table `%s`.`%s`",
5243
6606
                  get_type_str(), m_table->s->db.str,
5244
6607
                  m_table->s->table_name.str);
5245
6608
  }
5251
6614
  return(error);
5252
6615
}
5253
6616
 
 
6617
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
 
6618
 
 
6619
#ifndef MYSQL_CLIENT
5254
6620
bool Rows_log_event::write_data_header(IO_CACHE *file)
5255
6621
{
5256
 
  unsigned char buf[ROWS_HEADER_LEN];   // No need to init the buffer
5257
 
  assert(m_table_id != UINT32_MAX);
 
6622
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
6623
  assert(m_table_id != ~0UL);
5258
6624
  int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
5259
6625
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
5260
6626
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
5266
6632
     Note that this should be the number of *bits*, not the number of
5267
6633
     bytes.
5268
6634
  */
5269
 
  unsigned char sbuf[sizeof(m_width)];
 
6635
  uchar sbuf[sizeof(m_width)];
5270
6636
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
5271
6637
  bool res= false;
5272
 
  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);
5273
6639
  assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
5274
6640
 
5275
6641
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
5276
6642
 
5277
 
  res= res || my_b_safe_write(file, (unsigned char*) m_cols.bitmap,
 
6643
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
5278
6644
                              no_bytes_in_map(&m_cols));
5279
6645
  /*
5280
6646
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
5281
6647
   */
5282
6648
  if (get_type_code() == UPDATE_ROWS_EVENT)
5283
6649
  {
5284
 
    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,
5285
6651
                                no_bytes_in_map(&m_cols_ai));
5286
6652
  }
5287
6653
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
5289
6655
  return res;
5290
6656
 
5291
6657
}
5292
 
 
5293
 
 
 
6658
#endif
 
6659
 
 
6660
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5294
6661
void Rows_log_event::pack_info(Protocol *protocol)
5295
6662
{
5296
6663
  char buf[256];
5300
6667
                         "table_id: %lu%s", m_table_id, flagstr);
5301
6668
  protocol->store(buf, bytes, &my_charset_bin);
5302
6669
}
5303
 
 
 
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
5304
6696
 
5305
6697
/**************************************************************************
5306
6698
        Table_map_log_event member functions and support functions
5327
6719
  same as the columns for the table on the slave.
5328
6720
 
5329
6721
  Additionally, values saved for field metadata on the master are saved as a 
5330
 
  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
5331
6723
  to store the information. In cases where values require multiple bytes 
5332
6724
  (e.g. values > 255), the endian-safe methods are used to properly encode 
5333
6725
  the values on the master and decode them on the slave. When the field
5338
6730
  type used is uint32_t. 
5339
6731
*/
5340
6732
 
 
6733
#if !defined(MYSQL_CLIENT)
5341
6734
/**
5342
6735
  Save the field metadata based on the real_type of the field.
5343
6736
  The metadata saved depends on the type of the field. Some fields
5369
6762
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
5370
6763
  return(index);
5371
6764
}
 
6765
#endif /* !defined(MYSQL_CLIENT) */
5372
6766
 
5373
6767
/*
5374
6768
  Constructor used to build an event for writing to the binary log.
5375
6769
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
5376
6770
  (tbl->s->db etc) and not pointer content.
5377
6771
 */
5378
 
Table_map_log_event::Table_map_log_event(Session *session, Table *tbl,
5379
 
                                         ulong tid, bool, uint16_t flags)
5380
 
  : Log_event(session, 0, true),
 
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_t flags)
 
6776
  : Log_event(thd, 0, true),
5381
6777
    m_table(tbl),
5382
6778
    m_dbnam(tbl->s->db.str),
5383
6779
    m_dblen(m_dbnam ? tbl->s->db.length : 0),
5393
6789
    m_null_bits(0),
5394
6790
    m_meta_memory(NULL)
5395
6791
{
5396
 
  assert(m_table_id != UINT32_MAX);
 
6792
  assert(m_table_id != ~0UL);
5397
6793
  /*
5398
6794
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
5399
6795
    table.cc / alloc_table_share():
5411
6807
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
5412
6808
 
5413
6809
  /* If malloc fails, caught in is_valid() */
5414
 
  if ((m_memory= (unsigned char*) my_malloc(m_colcnt, MYF(MY_WME))))
 
6810
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
5415
6811
  {
5416
 
    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
 
6812
    m_coltype= reinterpret_cast<uchar*>(m_memory);
5417
6813
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
5418
6814
      m_coltype[i]= m_table->field[i]->type();
5419
6815
  }
5424
6820
    that is not on the slave and is null and thus not in the row data during
5425
6821
    replication.
5426
6822
  */
5427
 
  uint32_t num_null_bytes= (m_table->s->fields + 7) / 8;
 
6823
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
5428
6824
  m_data_size+= num_null_bytes;
5429
 
  m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
 
6825
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
5430
6826
                                 &m_null_bits, num_null_bytes,
5431
6827
                                 &m_field_metadata, (m_colcnt * 2),
5432
6828
                                 NULL);
5454
6850
      m_null_bits[(i / 8)]+= 1 << (i % 8);
5455
6851
 
5456
6852
}
5457
 
 
 
6853
#endif /* !defined(MYSQL_CLIENT) */
5458
6854
 
5459
6855
/*
5460
6856
  Constructor used by slave to read the event from the binary log.
5461
6857
 */
5462
 
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,
5463
6860
                                         const Format_description_log_event
5464
6861
                                         *description_event)
5465
6862
 
5466
6863
  : Log_event(buf, description_event),
 
6864
#ifndef MYSQL_CLIENT
5467
6865
    m_table(NULL),
 
6866
#endif
5468
6867
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
5469
6868
    m_colcnt(0), m_coltype(0),
5470
6869
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
5493
6892
    post_start+= TM_FLAGS_OFFSET;
5494
6893
  }
5495
6894
 
5496
 
  assert(m_table_id != UINT32_MAX);
 
6895
  assert(m_table_id != ~0UL);
5497
6896
 
5498
6897
  m_flags= uint2korr(post_start);
5499
6898
 
5501
6900
  const char *const vpart= buf + common_header_len + post_header_len;
5502
6901
 
5503
6902
  /* Extract the length of the various parts from the buffer */
5504
 
  unsigned char const *const ptr_dblen= (unsigned char const*)vpart + 0;
5505
 
  m_dblen= *(unsigned char*) ptr_dblen;
 
6903
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
 
6904
  m_dblen= *(uchar*) ptr_dblen;
5506
6905
 
5507
6906
  /* Length of database name + counter + terminating null */
5508
 
  unsigned char const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
5509
 
  m_tbllen= *(unsigned char*) ptr_tbllen;
 
6907
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
6908
  m_tbllen= *(uchar*) ptr_tbllen;
5510
6909
 
5511
6910
  /* Length of table name + counter + terminating null */
5512
 
  unsigned char const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
5513
 
  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;
5514
6913
  m_colcnt= net_field_length(&ptr_after_colcnt);
5515
6914
 
5516
6915
  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
5517
 
  m_memory= (unsigned char*) my_multi_malloc(MYF(MY_WME),
 
6916
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
5518
6917
                                     &m_dbnam, (uint) m_dblen + 1,
5519
6918
                                     &m_tblnam, (uint) m_tbllen + 1,
5520
6919
                                     &m_coltype, (uint) m_colcnt,
5521
 
                                     NULL);
 
6920
                                     NullS);
5522
6921
 
5523
6922
  if (m_memory)
5524
6923
  {
5528
6927
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
5529
6928
 
5530
6929
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
5531
 
    bytes_read= ptr_after_colcnt - (unsigned char *)buf;
 
6930
    bytes_read= ptr_after_colcnt - (uchar *)buf;
5532
6931
    if (bytes_read < event_len)
5533
6932
    {
5534
6933
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
5535
6934
      assert(m_field_metadata_size <= (m_colcnt * 2));
5536
 
      uint32_t num_null_bytes= (m_colcnt + 7) / 8;
5537
 
      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),
5538
6937
                                     &m_null_bits, num_null_bytes,
5539
6938
                                     &m_field_metadata, m_field_metadata_size,
5540
6939
                                     NULL);
5541
6940
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
5542
 
      ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
 
6941
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
5543
6942
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
5544
6943
    }
5545
6944
  }
5546
6945
 
5547
6946
  return;
5548
6947
}
 
6948
#endif
5549
6949
 
5550
6950
Table_map_log_event::~Table_map_log_event()
5551
6951
{
5552
 
  free(m_meta_memory);
5553
 
  free(m_memory);
 
6952
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
 
6953
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
5554
6954
}
5555
6955
 
5556
6956
/*
5564
6964
       4     Daisy-chaining RBR with SBR not possible
5565
6965
 */
5566
6966
 
 
6967
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5567
6968
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
5568
6969
{
5569
 
  RPL_TableList *table_list;
 
6970
  RPL_TABLE_LIST *table_list;
5570
6971
  char *db_mem, *tname_mem;
5571
 
  Query_id &query_id= Query_id::get_query_id();
5572
6972
  size_t dummy_len;
5573
6973
  void *memory;
5574
 
  assert(rli->sql_session == session);
 
6974
  assert(rli->sql_thd == thd);
5575
6975
 
5576
6976
  /* Step the query id to mark what columns that are actually used. */
5577
 
  session->query_id= query_id.next();
 
6977
  pthread_mutex_lock(&LOCK_thread_count);
 
6978
  thd->query_id= next_query_id();
 
6979
  pthread_mutex_unlock(&LOCK_thread_count);
5578
6980
 
5579
6981
  if (!(memory= my_multi_malloc(MYF(MY_WME),
5580
 
                                &table_list, (uint) sizeof(RPL_TableList),
 
6982
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
5581
6983
                                &db_mem, (uint) NAME_LEN + 1,
5582
6984
                                &tname_mem, (uint) NAME_LEN + 1,
5583
 
                                NULL)))
 
6985
                                NullS)))
5584
6986
    return(HA_ERR_OUT_OF_MEM);
5585
6987
 
5586
6988
  memset(table_list, 0, sizeof(*table_list));
5590
6992
  table_list->next_global= table_list->next_local= 0;
5591
6993
  table_list->table_id= m_table_id;
5592
6994
  table_list->updating= 1;
5593
 
  my_stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
5594
 
  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);
5595
6997
 
5596
6998
  int error= 0;
5597
6999
 
5598
7000
  if (!rpl_filter->db_ok(table_list->db) ||
5599
7001
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
5600
7002
  {
5601
 
    free(memory);
 
7003
    my_free(memory, MYF(MY_WME));
5602
7004
  }
5603
7005
  else
5604
7006
  {
5605
7007
    /*
5606
 
      open_tables() reads the contents of session->lex, so they must be
 
7008
      open_tables() reads the contents of thd->lex, so they must be
5607
7009
      initialized, so we should call lex_start(); to be even safer, we
5608
7010
      call mysql_init_query() which does a more complete set of inits.
5609
7011
    */
5610
 
    lex_start(session);
5611
 
    mysql_reset_session_for_next_command(session);
 
7012
    lex_start(thd);
 
7013
    mysql_reset_thd_for_next_command(thd);
 
7014
    /*
 
7015
      Check if the slave is set to use SBR.  If so, it should switch
 
7016
      to using RBR until the end of the "statement", i.e., next
 
7017
      STMT_END_F or next error.
 
7018
    */
 
7019
    if (!thd->current_stmt_binlog_row_based &&
 
7020
        mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
 
7021
    {
 
7022
      thd->set_current_stmt_binlog_row_based();
 
7023
    }
5612
7024
 
5613
7025
    /*
5614
7026
      Open the table if it is not already open and add the table to
5615
7027
      table map.  Note that for any table that should not be
5616
7028
      replicated, a filter is needed.
5617
7029
 
5618
 
      The creation of a new TableList is used to up-cast the
5619
 
      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
5620
7032
      since the only case where the argument to open_tables() is
5621
 
      changed, is when session->lex->query_tables == table_list, i.e.,
 
7033
      changed, is when thd->lex->query_tables == table_list, i.e.,
5622
7034
      when the statement requires prelocking. Since this is not
5623
7035
      executed when a statement is executed, this case will not occur.
5624
7036
      As a precaution, an assertion is added to ensure that the bad
5628
7040
      internally in the open_tables() function, hence we take a copy
5629
7041
      of the pointer to make sure that it's not lost.
5630
7042
    */
5631
 
    uint32_t count;
5632
 
    assert(session->lex->query_tables != table_list);
5633
 
    TableList *tmp_table_list= table_list;
5634
 
    if ((error= open_tables(session, &tmp_table_list, &count, 0)))
 
7043
    uint count;
 
7044
    assert(thd->lex->query_tables != table_list);
 
7045
    TABLE_LIST *tmp_table_list= table_list;
 
7046
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
5635
7047
    {
5636
 
      if (session->is_slave_error || session->is_fatal_error)
 
7048
      if (thd->is_slave_error || thd->is_fatal_error)
5637
7049
      {
5638
7050
        /*
5639
7051
          Error reporting borrowed from Query_log_event with many excessive
5640
7052
          simplifications (we don't honour --slave-skip-errors)
5641
7053
        */
5642
 
        uint32_t actual_error= session->main_da.sql_errno();
 
7054
        uint actual_error= thd->main_da.sql_errno();
5643
7055
        rli->report(ERROR_LEVEL, actual_error,
5644
 
                    _("Error '%s' on opening table `%s`.`%s`"),
5645
 
                    (actual_error
5646
 
                     ? session->main_da.message()
5647
 
                     : _("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"),
5648
7059
                    table_list->db, table_list->table_name);
5649
 
        session->is_slave_error= 1;
 
7060
        thd->is_slave_error= 1;
5650
7061
      }
5651
7062
      goto err;
5652
7063
    }
5685
7096
  return(error);
5686
7097
 
5687
7098
err:
5688
 
  free(memory);
 
7099
  my_free(memory, MYF(MY_WME));
5689
7100
  return(error);
5690
7101
}
5691
7102
 
5705
7116
  return 0;
5706
7117
}
5707
7118
 
 
7119
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
5708
7120
 
 
7121
#ifndef MYSQL_CLIENT
5709
7122
bool Table_map_log_event::write_data_header(IO_CACHE *file)
5710
7123
{
5711
 
  assert(m_table_id != UINT32_MAX);
5712
 
  unsigned char buf[TABLE_MAP_HEADER_LEN];
 
7124
  assert(m_table_id != ~0UL);
 
7125
  uchar buf[TABLE_MAP_HEADER_LEN];
5713
7126
  int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
5714
7127
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
5715
7128
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
5723
7136
  assert(m_dblen < 128);
5724
7137
  assert(m_tbllen < 128);
5725
7138
 
5726
 
  unsigned char const dbuf[]= { (unsigned char) m_dblen };
5727
 
  unsigned char const tbuf[]= { (unsigned char) m_tbllen };
 
7139
  uchar const dbuf[]= { (uchar) m_dblen };
 
7140
  uchar const tbuf[]= { (uchar) m_tbllen };
5728
7141
 
5729
 
  unsigned char cbuf[sizeof(m_colcnt)];
5730
 
  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);
5731
7144
  assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
5732
7145
 
5733
7146
  /*
5734
7147
    Store the size of the field metadata.
5735
7148
  */
5736
 
  unsigned char mbuf[sizeof(m_field_metadata_size)];
5737
 
  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);
5738
7151
 
5739
7152
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
5740
 
          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) ||
5741
7154
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
5742
 
          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) ||
5743
7156
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
5744
7157
          my_b_safe_write(file, m_coltype, m_colcnt) ||
5745
7158
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
5746
7159
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
5747
7160
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
5748
7161
 }
 
7162
#endif
5749
7163
 
 
7164
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5750
7165
 
5751
7166
/*
5752
7167
  Print some useful information for the SHOW BINARY LOG information
5753
7168
  field.
5754
7169
 */
5755
7170
 
 
7171
#if defined(HAVE_REPLICATION) && !defined(MYSQL_CLIENT)
5756
7172
void Table_map_log_event::pack_info(Protocol *protocol)
5757
7173
{
5758
7174
    char buf[256];
5761
7177
                           m_table_id, m_dbnam, m_tblnam);
5762
7178
    protocol->store(buf, bytes, &my_charset_bin);
5763
7179
}
5764
 
 
 
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
5765
7200
 
5766
7201
/**************************************************************************
5767
7202
        Write_rows_log_event member functions
5770
7205
/*
5771
7206
  Constructor used to build an event for writing to the binary log.
5772
7207
 */
5773
 
Write_rows_log_event::Write_rows_log_event(Session *session_arg, Table *tbl_arg,
 
7208
#if !defined(MYSQL_CLIENT)
 
7209
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
5774
7210
                                           ulong tid_arg,
5775
7211
                                           bool is_transactional)
5776
 
  : Rows_log_event(session_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
 
7212
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
5777
7213
{
5778
7214
}
 
7215
#endif
5779
7216
 
5780
7217
/*
5781
7218
  Constructor used by slave to read the event from the binary log.
5782
7219
 */
5783
 
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,
5784
7222
                                           const Format_description_log_event
5785
7223
                                           *description_event)
5786
7224
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
5787
7225
{
5788
7226
}
 
7227
#endif
5789
7228
 
 
7229
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5790
7230
int 
5791
7231
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
5792
7232
{
5805
7245
    */
5806
7246
    
5807
7247
    /* Tell the storage engine that we are using REPLACE semantics. */
5808
 
    session->lex->duplicates= DUP_REPLACE;
 
7248
    thd->lex->duplicates= DUP_REPLACE;
5809
7249
    
5810
7250
    /*
5811
7251
      Pretend we're executing a REPLACE command: this is needed for
5812
7252
      InnoDB since it is not (properly) checking the
5813
7253
      lex->duplicates flag.
5814
7254
    */
5815
 
    session->lex->sql_command= SQLCOM_REPLACE;
 
7255
    thd->lex->sql_command= SQLCOM_REPLACE;
5816
7256
    /* 
5817
7257
       Do not raise the error flag in case of hitting to an unique attribute
5818
7258
    */
5864
7304
  return error? error : local_error;
5865
7305
}
5866
7306
 
 
7307
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
5867
7308
 
5868
7309
/*
5869
7310
  Check if there are more UNIQUE keys after the given key.
5870
7311
*/
5871
7312
static int
5872
 
last_uniq_key(Table *table, uint32_t keyno)
 
7313
last_uniq_key(TABLE *table, uint keyno)
5873
7314
{
5874
7315
  while (++keyno < table->s->keys)
5875
7316
    if (table->key_info[keyno].flags & HA_NOSAME)
5941
7382
Rows_log_event::write_row(const Relay_log_info *const rli,
5942
7383
                          const bool overwrite)
5943
7384
{
5944
 
  assert(m_table != NULL && session != NULL);
 
7385
  assert(m_table != NULL && thd != NULL);
5945
7386
 
5946
 
  Table *table= m_table;  // pointer to event's table
 
7387
  TABLE *table= m_table;  // pointer to event's table
5947
7388
  int error;
5948
7389
  int keynum;
5949
7390
  auto_afree_ptr<char> key(NULL);
5960
7401
     values filled in and one flag to handle the case that the default
5961
7402
     values should be checked. Maybe these two flags can be combined.
5962
7403
  */
5963
 
  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)))
5964
7406
    return(error);
5965
7407
  
5966
7408
  /* unpack row into table->record[0] */
6035
7477
        }
6036
7478
      }
6037
7479
 
6038
 
      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,
6039
7481
               0);
6040
7482
      error= table->file->index_read_idx_map(table->record[1], keynum,
6041
 
                                             (const unsigned char*)key.get(),
 
7483
                                             (const uchar*)key.get(),
6042
7484
                                             HA_WHOLE_KEY,
6043
7485
                                             HA_READ_KEY_EXACT);
6044
7486
      if (error)
6112
7554
  return(error);
6113
7555
}
6114
7556
 
6115
 
 
6116
 
int Rows_log_event::unpack_current_row(const Relay_log_info *const rli,
6117
 
                                         MY_BITMAP const *cols)
6118
 
{
6119
 
  assert(m_table);
6120
 
  ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
6121
 
  int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
6122
 
                                 &m_curr_row_end, &m_master_reclength);
6123
 
  if (m_curr_row_end > m_rows_end)
6124
 
    my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
6125
 
  ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
6126
 
  return result;
6127
 
}
6128
 
 
 
7557
#endif
6129
7558
 
6130
7559
int 
6131
7560
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
6135
7564
    write_row(rli,        /* if 1 then overwrite */
6136
7565
              bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
6137
7566
    
6138
 
  if (error && !session->is_error())
 
7567
  if (error && !thd->is_error())
6139
7568
  {
6140
7569
    assert(0);
6141
7570
    my_error(ER_UNKNOWN_ERROR, MYF(0));
6144
7573
  return error; 
6145
7574
}
6146
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
6147
7584
 
6148
7585
/**************************************************************************
6149
7586
        Delete_rows_log_event member functions
6150
7587
**************************************************************************/
6151
7588
 
 
7589
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6152
7590
/*
6153
7591
  Compares table->record[0] and table->record[1]
6154
7592
 
6155
7593
  Returns TRUE if different.
6156
7594
*/
6157
 
static bool record_compare(Table *table)
 
7595
static bool record_compare(TABLE *table)
6158
7596
{
6159
7597
  /*
6160
7598
    Need to set the X bit and the filler bits in both records since
6168
7606
    records. Check that the other engines also return correct records.
6169
7607
   */
6170
7608
  bool result= false;
6171
 
  unsigned char saved_x[2], saved_filler[2];
 
7609
  uchar saved_x[2], saved_filler[2];
6172
7610
 
6173
7611
  if (table->s->null_bytes > 0)
6174
7612
  {
6257
7695
{
6258
7696
  assert(m_table && m_table->in_use != NULL);
6259
7697
 
6260
 
  Table *table= m_table;
 
7698
  TABLE *table= m_table;
6261
7699
  int error;
6262
7700
 
6263
7701
  /* unpack row - missing fields get default values */
6445
7883
  return(error);
6446
7884
}
6447
7885
 
 
7886
#endif
6448
7887
 
6449
7888
/*
6450
7889
  Constructor used to build an event for writing to the binary log.
6451
7890
 */
6452
7891
 
6453
 
Delete_rows_log_event::Delete_rows_log_event(Session *session_arg, Table *tbl_arg,
 
7892
#ifndef MYSQL_CLIENT
 
7893
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6454
7894
                                             ulong tid,
6455
7895
                                             bool is_transactional)
6456
 
  : Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
7896
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6457
7897
{
6458
7898
}
 
7899
#endif /* #if !defined(MYSQL_CLIENT) */
6459
7900
 
6460
7901
/*
6461
7902
  Constructor used by slave to read the event from the binary log.
6462
7903
 */
6463
 
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,
6464
7906
                                             const Format_description_log_event
6465
7907
                                             *description_event)
6466
7908
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
6467
7909
{
6468
7910
}
 
7911
#endif
6469
7912
 
 
7913
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6470
7914
 
6471
7915
int 
6472
7916
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6483
7927
  if (m_table->s->keys > 0)
6484
7928
  {
6485
7929
    // Allocate buffer for key searches
6486
 
    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));
6487
7931
    if (!m_key)
6488
7932
      return HA_ERR_OUT_OF_MEM;
6489
7933
  }
6497
7941
{
6498
7942
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6499
7943
  m_table->file->ha_index_or_rnd_end();
6500
 
  free(m_key);
 
7944
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
6501
7945
  m_key= NULL;
6502
7946
 
6503
7947
  return error;
6518
7962
  return error;
6519
7963
}
6520
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
 
6521
7975
 
6522
7976
/**************************************************************************
6523
7977
        Update_rows_log_event member functions
6526
7980
/*
6527
7981
  Constructor used to build an event for writing to the binary log.
6528
7982
 */
6529
 
Update_rows_log_event::Update_rows_log_event(Session *session_arg, Table *tbl_arg,
 
7983
#if !defined(MYSQL_CLIENT)
 
7984
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
6530
7985
                                             ulong tid,
6531
7986
                                             bool is_transactional)
6532
 
: Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
7987
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
6533
7988
{
6534
7989
  init(tbl_arg->write_set);
6535
7990
}
6550
8005
    }
6551
8006
  }
6552
8007
}
 
8008
#endif /* !defined(MYSQL_CLIENT) */
6553
8009
 
6554
8010
 
6555
8011
Update_rows_log_event::~Update_rows_log_event()
6556
8012
{
6557
8013
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
6558
 
    m_cols_ai.bitmap= 0; // so no free in bitmap_free
 
8014
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
6559
8015
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
6560
8016
}
6561
8017
 
6563
8019
/*
6564
8020
  Constructor used by slave to read the event from the binary log.
6565
8021
 */
6566
 
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,
6567
8024
                                             const
6568
8025
                                             Format_description_log_event
6569
8026
                                             *description_event)
6570
8027
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
6571
8028
{
6572
8029
}
 
8030
#endif
6573
8031
 
 
8032
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
6574
8033
 
6575
8034
int 
6576
8035
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
6578
8037
  if (m_table->s->keys > 0)
6579
8038
  {
6580
8039
    // Allocate buffer for key searches
6581
 
    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));
6582
8041
    if (!m_key)
6583
8042
      return HA_ERR_OUT_OF_MEM;
6584
8043
  }
6594
8053
{
6595
8054
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
6596
8055
  m_table->file->ha_index_or_rnd_end();
6597
 
  free(m_key); // Free for multi_malloc
 
8056
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
6598
8057
  m_key= NULL;
6599
8058
 
6600
8059
  return error;
6649
8108
  return error;
6650
8109
}
6651
8110
 
6652
 
 
6653
 
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,
6654
8123
                                       const Format_description_log_event *descr_event)
6655
8124
  : Log_event(buf, descr_event)
6656
8125
{
6691
8160
}
6692
8161
 
6693
8162
 
 
8163
#ifndef MYSQL_CLIENT
6694
8164
void Incident_log_event::pack_info(Protocol *protocol)
6695
8165
{
6696
8166
  char buf[256];
6703
8173
                    m_incident, description(), m_message.str);
6704
8174
  protocol->store(buf, bytes, &my_charset_bin);
6705
8175
}
6706
 
 
6707
 
 
 
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)
6708
8194
int
6709
8195
Incident_log_event::do_apply_event(Relay_log_info const *rli)
6710
8196
{
6714
8200
              m_message.length > 0 ? m_message.str : "<none>");
6715
8201
  return(1);
6716
8202
}
6717
 
 
 
8203
#endif
6718
8204
 
6719
8205
bool
6720
8206
Incident_log_event::write_data_header(IO_CACHE *file)
6721
8207
{
6722
 
  unsigned char buf[sizeof(int16_t)];
 
8208
  uchar buf[sizeof(int16_t)];
6723
8209
  int2store(buf, (int16_t) m_incident);
6724
8210
  return(my_b_safe_write(file, buf, sizeof(buf)));
6725
8211
}
6730
8216
  return(write_str(file, m_message.str, m_message.length));
6731
8217
}
6732
8218
 
6733
 
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,
6734
8221
                    const Format_description_log_event* description_event)
6735
8222
  :Log_event(buf, description_event)
6736
8223
{
6739
8226
  set_if_smaller(ident_len,FN_REFLEN-1);
6740
8227
  log_ident= buf + header_size;
6741
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 memset() is for the day someone
 
8249
    creates dynamic instances.
 
8250
  */
 
8251
  memset(db, 0, sizeof(db));
 
8252
  memset(charset, 0, sizeof(charset));
 
8253
  memset(time_zone_str, 0, 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