~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/log_event.cc

  • Committer: Stewart Smith
  • Date: 2009-01-12 05:43:13 UTC
  • mto: (784.1.4 for-brian)
  • mto: This revision was merged to the branch mainline in revision 785.
  • Revision ID: stewart@flamingspork.com-20090112054313-edk6kpf4l6kpz4j7
fix archive_basic for drizzle

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
 
#ifndef DRIZZLE_CLIENT
 
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
 */
18
19
 
19
20
#include <drizzled/server_includes.h>
20
 
#include "rpl_rli.h"
21
 
#include "rpl_mi.h"
22
 
#include "rpl_filter.h"
23
 
#include "rpl_utility.h"
24
 
#include "rpl_record.h"
 
21
#include <drizzled/log_event.h>
 
22
#include <drizzled/replication/rli.h>
 
23
#include <drizzled/replication/mi.h>
 
24
#include <libdrizzle/libdrizzle.h>
 
25
#include <mysys/hash.h>
 
26
#include <drizzled/replication/utility.h>
 
27
#include <drizzled/replication/record.h>
25
28
#include <mysys/my_dir.h>
26
 
#include <drizzled/drizzled_error_messages.h>
 
29
#include <drizzled/error.h>
 
30
#include <libdrizzle/pack.h>
 
31
#include <drizzled/sql_parse.h>
 
32
#include <drizzled/sql_base.h>
 
33
#include <drizzled/sql_load.h>
 
34
#include <drizzled/item/return_int.h>
 
35
#include <drizzled/item/empty_string.h>
27
36
 
28
 
#endif /* !DRIZZLE_CLIENT */
 
37
#include <algorithm>
 
38
#include <string>
29
39
 
30
40
#include <mysys/base64.h>
31
41
#include <mysys/my_bitmap.h>
32
42
 
33
 
#define log_cs  &my_charset_latin1
34
 
 
35
 
#define FLAGSTR(V,F) ((V)&(F)?#F" ":"")
36
 
 
37
 
 
38
 
/*
39
 
  Size of buffer for printing a double in format %.<PREC>g
40
 
 
41
 
  optional '-' + optional zero + '.'  + PREC digits + 'e' + sign +
42
 
  exponent digits + '\0'
43
 
*/
44
 
#define FMT_G_BUFSIZE(PREC) (3 + (PREC) + 5 + 1)
45
 
 
46
 
 
47
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
 
43
#include <drizzled/gettext.h>
 
44
#include <libdrizzle/libdrizzle.h>
 
45
#include <drizzled/error.h>
 
46
#include <drizzled/query_id.h>
 
47
#include <drizzled/tztime.h>
 
48
#include <drizzled/slave.h>
 
49
#include <drizzled/lock.h>
 
50
 
 
51
using namespace std;
 
52
 
48
53
static const char *HA_ERR(int i)
49
54
{
50
55
  switch (i) {
108
113
   @param level     error, warning or info
109
114
   @param ha_error  HA_ERR_ code
110
115
   @param rli       pointer to the active Relay_log_info instance
111
 
   @param thd       pointer to the slave thread's thd
 
116
   @param session       pointer to the slave thread's session
112
117
   @param table     pointer to the event's table object
113
118
   @param type      the type of the event
114
119
   @param log_name  the master binlog file name
116
121
 
117
122
*/
118
123
static void inline slave_rows_error_report(enum loglevel level, int ha_error,
119
 
                                           Relay_log_info const *rli, THD *thd,
120
 
                                           TABLE *table, const char * type,
 
124
                                           Relay_log_info const *rli, Session *session,
 
125
                                           Table *table, const char * type,
121
126
                                           const char *log_name, ulong pos)
122
127
{
123
128
  const char *handler_error= HA_ERR(ha_error);
124
129
  char buff[MAX_SLAVE_ERRMSG], *slider;
125
130
  const char *buff_end= buff + sizeof(buff);
126
 
  uint len;
127
 
  List_iterator_fast<DRIZZLE_ERROR> it(thd->warn_list);
 
131
  uint32_t len;
 
132
  List_iterator_fast<DRIZZLE_ERROR> it(session->warn_list);
128
133
  DRIZZLE_ERROR *err;
129
134
  buff[0]= 0;
130
135
 
132
137
       slider += len, err= it++)
133
138
  {
134
139
    len= snprintf(slider, buff_end - slider,
135
 
                  " %s, Error_code: %d;", err->msg, err->code);
 
140
                  _(" %s, Error_code: %d;"), err->msg, err->code);
136
141
  }
137
 
  
138
 
  rli->report(level, thd->is_error()? thd->main_da.sql_errno() : 0,
139
 
              "Could not execute %s event on table %s.%s;"
140
 
              "%s handler error %s; "
141
 
              "the event's master log %s, end_log_pos %lu",
 
142
 
 
143
  rli->report(level, session->is_error()? session->main_da.sql_errno() : 0,
 
144
              _("Could not execute %s event on table %s.%s;"
 
145
                "%s handler error %s; "
 
146
                "the event's master log %s, end_log_pos %lu"),
142
147
              type, table->s->db.str,
143
148
              table->s->table_name.str,
144
149
              buff,
145
 
              handler_error == NULL? "<unknown>" : handler_error,
 
150
              handler_error == NULL? _("<unknown>") : handler_error,
146
151
              log_name, pos);
147
152
}
148
 
#endif
 
153
 
149
154
 
150
155
/*
151
156
  Cache that will automatically be written to a dedicated file on
225
230
  flag_set m_flags;
226
231
};
227
232
 
228
 
uint debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
 
233
uint32_t debug_not_change_ts_if_art_event= 1; // bug#29309 simulation
229
234
 
230
235
/*
231
236
  pretty_print_str()
232
237
*/
233
238
 
234
 
#ifdef DRIZZLE_CLIENT
235
 
static void pretty_print_str(IO_CACHE* cache, const char* str, int len)
236
 
{
237
 
  const char* end = str + len;
238
 
  my_b_printf(cache, "\'");
239
 
  while (str < end)
240
 
  {
241
 
    char c;
242
 
    switch ((c=*str++)) {
243
 
    case '\n': my_b_printf(cache, "\\n"); break;
244
 
    case '\r': my_b_printf(cache, "\\r"); break;
245
 
    case '\\': my_b_printf(cache, "\\\\"); break;
246
 
    case '\b': my_b_printf(cache, "\\b"); break;
247
 
    case '\t': my_b_printf(cache, "\\t"); break;
248
 
    case '\'': my_b_printf(cache, "\\'"); break;
249
 
    case 0   : my_b_printf(cache, "\\0"); break;
250
 
    default:
251
 
      my_b_printf(cache, "%c", c);
252
 
      break;
253
 
    }
254
 
  }
255
 
  my_b_printf(cache, "\'");
256
 
}
257
 
#endif /* DRIZZLE_CLIENT */
258
 
 
259
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
260
 
 
261
 
static void clear_all_errors(THD *thd, Relay_log_info *rli)
262
 
{
263
 
  thd->is_slave_error = 0;
264
 
  thd->clear_error();
 
239
static void clear_all_errors(Session *session, Relay_log_info *rli)
 
240
{
 
241
  session->is_slave_error = 0;
 
242
  session->clear_error();
265
243
  rli->clear_error();
266
244
}
267
245
 
275
253
  return ((err_code == ER_SLAVE_IGNORED_TABLE) ||
276
254
          (use_slave_mask && bitmap_is_set(&slave_error_mask, err_code)));
277
255
}
278
 
#endif
279
256
 
280
257
 
281
258
/*
282
259
  pretty_print_str()
283
260
*/
284
261
 
285
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
286
262
static char *pretty_print_str(char *packet, const char *str, int len)
287
263
{
288
264
  const char *end= str + len;
307
283
  *pos++= '\'';
308
284
  return pos;
309
285
}
310
 
#endif /* !DRIZZLE_CLIENT */
311
 
 
312
 
 
313
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
286
 
314
287
 
315
288
/**
316
289
  Creates a temporary name for load data infile:.
324
297
    Pointer to start of extension
325
298
*/
326
299
 
327
 
static char *slave_load_file_stem(char *buf, uint file_id,
 
300
static char *slave_load_file_stem(char *buf, uint32_t file_id,
328
301
                                  int event_server_id, const char *ext)
329
302
{
330
303
  char *res;
331
304
  fn_format(buf,"SQL_LOAD-",slave_load_tmpdir, "", MY_UNPACK_FILENAME);
332
305
  to_unix_path(buf);
333
306
 
334
 
  buf = strend(buf);
335
 
  buf = int10_to_str(::server_id, buf, 10);
 
307
  buf= strchr(buf, '\0');
 
308
  buf= int10_to_str(::server_id, buf, 10);
336
309
  *buf++ = '-';
337
 
  buf = int10_to_str(event_server_id, buf, 10);
 
310
  buf= int10_to_str(event_server_id, buf, 10);
338
311
  *buf++ = '-';
339
312
  res= int10_to_str(file_id, buf, 10);
340
 
  stpcpy(res, ext);                             // Add extension last
 
313
  strcpy(res, ext);                             // Add extension last
341
314
  return res;                                   // Pointer to extension
342
315
}
343
 
#endif
344
 
 
345
 
 
346
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
316
 
347
317
 
348
318
/**
349
319
  Delete all temporary files used for SQL_LOAD.
353
323
{
354
324
  MY_DIR *dirp;
355
325
  FILEINFO *file;
356
 
  uint i;
 
326
  uint32_t i;
357
327
  char fname[FN_REFLEN], prefbuf[31], *p;
358
328
 
359
329
  if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME))))
360
330
    return;
361
331
 
362
 
  /* 
 
332
  /*
363
333
     When we are deleting temporary files, we should only remove
364
334
     the files associated with the server id of our server.
365
335
     We don't use event_server_id here because since we've disabled
366
336
     direct binlogging of Create_file/Append_file/Exec_load events
367
 
     we cannot meet Start_log event in the middle of events from one 
 
337
     we cannot meet Start_log event in the middle of events from one
368
338
     LOAD DATA.
369
339
  */
370
 
  p= strmake(prefbuf, STRING_WITH_LEN("SQL_LOAD-"));
 
340
  p= strncpy(prefbuf, STRING_WITH_LEN("SQL_LOAD-")) + 9;
371
341
  p= int10_to_str(::server_id, p, 10);
372
342
  *(p++)= '-';
373
343
  *p= 0;
384
354
 
385
355
  my_dirend(dirp);
386
356
}
387
 
#endif
388
357
 
389
358
 
390
359
/*
391
360
  write_str()
392
361
*/
393
362
 
394
 
static bool write_str(IO_CACHE *file, const char *str, uint length)
 
363
static bool write_str(IO_CACHE *file, const char *str, uint32_t length)
395
364
{
396
 
  uchar tmp[1];
397
 
  tmp[0]= (uchar) length;
 
365
  unsigned char tmp[1];
 
366
  tmp[0]= (unsigned char) length;
398
367
  return (my_b_safe_write(file, tmp, sizeof(tmp)) ||
399
 
          my_b_safe_write(file, (uchar*) str, length));
 
368
          my_b_safe_write(file, (unsigned char*) str, length));
400
369
}
401
370
 
402
371
 
407
376
static inline int read_str(const char **buf, const char *buf_end,
408
377
                           const char **str, uint8_t *len)
409
378
{
410
 
  if (*buf + ((uint) (uchar) **buf) >= buf_end)
 
379
  if (*buf + ((uint) (unsigned char) **buf) >= buf_end)
411
380
    return 1;
412
381
  *len= (uint8_t) **buf;
413
382
  *str= (*buf)+1;
420
389
  Transforms a string into "" or its expression in 0x... form.
421
390
*/
422
391
 
423
 
char *str_to_hex(char *to, const char *from, uint len)
 
392
char *str_to_hex(char *to, const char *from, uint32_t len)
424
393
{
425
394
  if (len)
426
395
  {
429
398
    to= octet2hex(to, from, len);
430
399
  }
431
400
  else
432
 
    to= stpcpy(to, "\"\"");
 
401
    to= strcpy(to, "\"\"")+2;
433
402
  return to;                               // pointer to end 0 of 'to'
434
403
}
435
404
 
436
 
#ifndef DRIZZLE_CLIENT
437
405
 
438
406
/**
439
407
  Append a version of the 'from' string suitable for use in a query to
457
425
  else
458
426
  {
459
427
    *ptr++= '\'';
460
 
    ptr+= escape_string_for_drizzle(csinfo, ptr, 0,
461
 
                                    from->ptr(), from->length());
 
428
    ptr+= drizzle_escape_string(ptr, from->ptr(), from->length());
462
429
    *ptr++='\'';
463
430
  }
464
431
  to->length(orig_len + ptr - beg);
465
432
  return 0;
466
433
}
467
 
#endif
468
 
 
469
 
 
470
 
/**
471
 
  Prints a "session_var=value" string. Used by mysqlbinlog to print some SET
472
 
  commands just before it prints a query.
473
 
*/
474
 
 
475
 
#ifdef DRIZZLE_CLIENT
476
 
 
477
 
static void print_set_option(IO_CACHE* file, uint32_t bits_changed,
478
 
                             uint32_t option, uint32_t flags, const char* name,
479
 
                             bool* need_comma)
480
 
{
481
 
  if (bits_changed & option)
482
 
  {
483
 
    if (*need_comma)
484
 
      my_b_printf(file,", ");
485
 
    my_b_printf(file,"%s=%d", name, test(flags & option));
486
 
    *need_comma= 1;
487
 
  }
488
 
}
489
 
#endif
 
434
 
490
435
 
491
436
/**************************************************************************
492
437
        Log_event methods (= the parent class of all events)
504
449
  case STOP_EVENT:   return "Stop";
505
450
  case QUERY_EVENT:  return "Query";
506
451
  case ROTATE_EVENT: return "Rotate";
507
 
  case INTVAR_EVENT: return "Intvar";
508
452
  case LOAD_EVENT:   return "Load";
509
453
  case NEW_LOAD_EVENT:   return "New_load";
510
454
  case SLAVE_EVENT:  return "Slave";
512
456
  case APPEND_BLOCK_EVENT: return "Append_block";
513
457
  case DELETE_FILE_EVENT: return "Delete_file";
514
458
  case EXEC_LOAD_EVENT: return "Exec_load";
515
 
  case RAND_EVENT: return "RAND";
516
459
  case XID_EVENT: return "Xid";
517
 
  case USER_VAR_EVENT: return "User var";
518
460
  case FORMAT_DESCRIPTION_EVENT: return "Format_desc";
519
461
  case TABLE_MAP_EVENT: return "Table_map";
520
 
  case PRE_GA_WRITE_ROWS_EVENT: return "Write_rows_event_old";
521
 
  case PRE_GA_UPDATE_ROWS_EVENT: return "Update_rows_event_old";
522
 
  case PRE_GA_DELETE_ROWS_EVENT: return "Delete_rows_event_old";
523
462
  case WRITE_ROWS_EVENT: return "Write_rows";
524
463
  case UPDATE_ROWS_EVENT: return "Update_rows";
525
464
  case DELETE_ROWS_EVENT: return "Delete_rows";
540
479
  Log_event::Log_event()
541
480
*/
542
481
 
543
 
#ifndef DRIZZLE_CLIENT
544
 
Log_event::Log_event(THD* thd_arg, uint16_t flags_arg, bool using_trans)
545
 
  :log_pos(0), temp_buf(0), exec_time(0), flags(flags_arg), thd(thd_arg)
 
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)
546
484
{
547
 
  server_id=    thd->server_id;
548
 
  when=         thd->start_time;
 
485
  server_id=    session->server_id;
 
486
  when=         session->start_time;
549
487
  cache_stmt=   using_trans;
550
488
}
551
489
 
552
490
 
553
491
/**
554
492
  This minimal constructor is for when you are not even sure that there
555
 
  is a valid THD. For example in the server when we are shutting down or
 
493
  is a valid Session. For example in the server when we are shutting down or
556
494
  flushing logs after receiving a SIGHUP (then we must write a Rotate to
557
 
  the binlog but we have no THD, so we need this minimal constructor).
 
495
  the binlog but we have no Session, so we need this minimal constructor).
558
496
*/
559
497
 
560
498
Log_event::Log_event()
561
499
  :temp_buf(0), exec_time(0), flags(0), cache_stmt(0),
562
 
   thd(0)
 
500
   session(0)
563
501
{
564
 
  server_id=    ::server_id;
 
502
  server_id= ::server_id;
565
503
  /*
566
 
    We can't call my_time() here as this would cause a call before
 
504
    We can't call time() here as this would cause a call before
567
505
    my_init() is called
568
506
  */
569
507
  when=         0;
570
508
  log_pos=      0;
571
509
}
572
 
#endif /* !DRIZZLE_CLIENT */
573
510
 
574
511
 
575
512
/*
580
517
                     const Format_description_log_event* description_event)
581
518
  :temp_buf(0), cache_stmt(0)
582
519
{
583
 
#ifndef DRIZZLE_CLIENT
584
 
  thd = 0;
585
 
#endif
586
 
  when = uint4korr(buf);
587
 
  server_id = uint4korr(buf + SERVER_ID_OFFSET);
 
520
  session= 0;
 
521
  when= uint4korr(buf);
 
522
  server_id= uint4korr(buf + SERVER_ID_OFFSET);
588
523
  data_written= uint4korr(buf + EVENT_LEN_OFFSET);
589
524
  if (description_event->binlog_version==1)
590
525
  {
643
578
  /* otherwise, go on with reading the header from buf (nothing now) */
644
579
}
645
580
 
646
 
#ifndef DRIZZLE_CLIENT
647
 
#ifdef HAVE_REPLICATION
648
581
 
649
582
int Log_event::do_update_pos(Relay_log_info *rli)
650
583
{
671
604
    if (debug_not_change_ts_if_art_event == 1
672
605
        && is_artificial_event())
673
606
      debug_not_change_ts_if_art_event= 0;
674
 
    rli->stmt_done(log_pos, 
 
607
    rli->stmt_done(log_pos,
675
608
                   is_artificial_event() &&
676
609
                   debug_not_change_ts_if_art_event > 0 ? 0 : when);
677
610
    if (debug_not_change_ts_if_art_event == 0)
703
636
}
704
637
 
705
638
 
706
 
/**
707
 
  Only called by SHOW BINLOG EVENTS
708
 
*/
709
 
int Log_event::net_send(Protocol *protocol, const char* log_name, my_off_t pos)
 
639
const char* Log_event::get_db()
710
640
{
711
 
  const char *p= strrchr(log_name, FN_LIBCHAR);
712
 
  const char *event_type;
713
 
  if (p)
714
 
    log_name = p + 1;
715
 
 
716
 
  protocol->prepare_for_resend();
717
 
  protocol->store(log_name, &my_charset_bin);
718
 
  protocol->store((uint64_t) pos);
719
 
  event_type = get_type_str();
720
 
  protocol->store(event_type, strlen(event_type), &my_charset_bin);
721
 
  protocol->store((uint32_t) server_id);
722
 
  protocol->store((uint64_t) log_pos);
723
 
  pack_info(protocol);
724
 
  return protocol->write();
 
641
  return session ? session->db : 0;
725
642
}
726
 
#endif /* HAVE_REPLICATION */
727
643
 
728
644
 
729
645
/**
736
652
{
737
653
  field_list->push_back(new Item_empty_string("Log_name", 20));
738
654
  field_list->push_back(new Item_return_int("Pos", MY_INT32_NUM_DECIMAL_DIGITS,
739
 
                                            DRIZZLE_TYPE_LONGLONG));
 
655
                                            DRIZZLE_TYPE_LONGLONG));
740
656
  field_list->push_back(new Item_empty_string("Event_type", 20));
741
657
  field_list->push_back(new Item_return_int("Server_id", 10,
742
 
                                            DRIZZLE_TYPE_LONG));
 
658
                                            DRIZZLE_TYPE_LONG));
743
659
  field_list->push_back(new Item_return_int("End_log_pos",
744
660
                                            MY_INT32_NUM_DECIMAL_DIGITS,
745
 
                                            DRIZZLE_TYPE_LONGLONG));
 
661
                                            DRIZZLE_TYPE_LONGLONG));
746
662
  field_list->push_back(new Item_empty_string("Info", 20));
747
663
}
748
664
 
752
668
 
753
669
bool Log_event::write_header(IO_CACHE* file, ulong event_data_length)
754
670
{
755
 
  uchar header[LOG_EVENT_HEADER_LEN];
 
671
  unsigned char header[LOG_EVENT_HEADER_LEN];
756
672
  ulong now;
757
673
 
758
674
  /* Store number of bytes that will be written by this event */
823
739
}
824
740
 
825
741
 
 
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 time(0);
 
752
}
 
753
 
 
754
 
826
755
/**
827
756
  This needn't be format-tolerant, because we only read
828
757
  LOG_EVENT_MINIMAL_HEADER_LEN (we just want to read the event's length).
829
758
*/
830
759
 
831
760
int Log_event::read_log_event(IO_CACHE* file, String* packet,
832
 
                              pthread_mutex_t* log_lock)
 
761
                              pthread_mutex_t* log_lock)
833
762
{
834
763
  ulong data_len;
835
764
  int result=0;
837
766
 
838
767
  if (log_lock)
839
768
    pthread_mutex_lock(log_lock);
840
 
  if (my_b_read(file, (uchar*) buf, sizeof(buf)))
 
769
  if (my_b_read(file, (unsigned char*) buf, sizeof(buf)))
841
770
  {
842
771
    /*
843
772
      If the read hits eof, we must report it as eof so the caller
852
781
  }
853
782
  data_len= uint4korr(buf + EVENT_LEN_OFFSET);
854
783
  if (data_len < LOG_EVENT_MINIMAL_HEADER_LEN ||
855
 
      data_len > current_thd->variables.max_allowed_packet)
 
784
      data_len > current_session->variables.max_allowed_packet)
856
785
  {
857
786
    result= ((data_len < LOG_EVENT_MINIMAL_HEADER_LEN) ? LOG_READ_BOGUS :
858
787
             LOG_READ_TOO_LARGE);
895
824
    pthread_mutex_unlock(log_lock);
896
825
  return(result);
897
826
}
898
 
#endif /* !DRIZZLE_CLIENT */
899
827
 
900
 
#ifndef DRIZZLE_CLIENT
901
828
#define UNLOCK_MUTEX if (log_lock) pthread_mutex_unlock(log_lock);
902
829
#define LOCK_MUTEX if (log_lock) pthread_mutex_lock(log_lock);
903
 
#else
904
 
#define UNLOCK_MUTEX
905
 
#define LOCK_MUTEX
906
 
#endif
907
830
 
908
 
#ifndef DRIZZLE_CLIENT
909
831
/**
910
832
  @note
911
833
    Allocates memory;  The caller is responsible for clean-up.
914
836
                                     pthread_mutex_t* log_lock,
915
837
                                     const Format_description_log_event
916
838
                                     *description_event)
917
 
#else
918
 
Log_event* Log_event::read_log_event(IO_CACHE* file,
919
 
                                     const Format_description_log_event
920
 
                                     *description_event)
921
 
#endif
922
839
{
923
840
  assert(description_event != 0);
924
841
  char head[LOG_EVENT_MINIMAL_HEADER_LEN];
929
846
    of 13 bytes, whereas LOG_EVENT_MINIMAL_HEADER_LEN is 19 bytes (it's
930
847
    "minimal" over the set {MySQL >=4.0}).
931
848
  */
932
 
  uint header_size= min(description_event->common_header_len,
 
849
  uint32_t header_size= cmin(description_event->common_header_len,
933
850
                        LOG_EVENT_MINIMAL_HEADER_LEN);
934
851
 
935
852
  LOCK_MUTEX;
936
 
  if (my_b_read(file, (uchar *) head, header_size))
 
853
  if (my_b_read(file, (unsigned char *) head, header_size))
937
854
  {
938
855
    UNLOCK_MUTEX;
939
856
    /*
943
860
    */
944
861
    return(0);
945
862
  }
946
 
  uint data_len = uint4korr(head + EVENT_LEN_OFFSET);
 
863
  uint32_t data_len = uint4korr(head + EVENT_LEN_OFFSET);
947
864
  char *buf= 0;
948
865
  const char *error= 0;
949
866
  Log_event *res=  0;
950
867
#ifndef max_allowed_packet
951
 
  THD *thd=current_thd;
952
 
  uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0;
 
868
  Session *session=current_session;
 
869
  uint32_t max_allowed_packet= session ? session->variables.max_allowed_packet : ~(ulong)0;
953
870
#endif
954
871
 
955
872
  if (data_len > max_allowed_packet)
965
882
  }
966
883
 
967
884
  // some events use the extra byte to null-terminate strings
968
 
  if (!(buf = (char*) my_malloc(data_len+1, MYF(MY_WME))))
 
885
  if (!(buf = (char*) malloc(data_len+1)))
969
886
  {
970
887
    error = "Out of memory";
971
888
    goto err;
972
889
  }
973
890
  buf[data_len] = 0;
974
891
  memcpy(buf, head, header_size);
975
 
  if (my_b_read(file, (uchar*) buf + header_size, data_len - header_size))
 
892
  if (my_b_read(file, (unsigned char*) buf + header_size, data_len - header_size))
976
893
  {
977
894
    error = "read error";
978
895
    goto err;
985
902
  if (!res)
986
903
  {
987
904
    assert(error != 0);
988
 
    sql_print_error("Error in Log_event::read_log_event(): "
989
 
                    "'%s', data_len: %d, event_type: %d",
 
905
    errmsg_printf(ERRMSG_LVL_ERROR, _("Error in Log_event::read_log_event(): "
 
906
                    "'%s', data_len: %d, event_type: %d"),
990
907
                    error,data_len,head[EVENT_TYPE_OFFSET]);
991
 
    my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
908
    free(buf);
992
909
    /*
993
910
      The SQL slave thread will check if file->error<0 to know
994
911
      if there was an I/O error. Even if there is no "low-level" I/O errors
1008
925
  constructors.
1009
926
*/
1010
927
 
1011
 
Log_event* Log_event::read_log_event(const char* buf, uint event_len,
 
928
Log_event* Log_event::read_log_event(const char* buf, uint32_t event_len,
1012
929
                                     const char **error,
1013
930
                                     const Format_description_log_event *description_event)
1014
931
{
1024
941
    return(NULL); // general sanity check - will fail on a partial read
1025
942
  }
1026
943
 
1027
 
  uint event_type= buf[EVENT_TYPE_OFFSET];
 
944
  uint32_t event_type= buf[EVENT_TYPE_OFFSET];
1028
945
  if (event_type > description_event->number_of_event_types &&
1029
946
      event_type != FORMAT_DESCRIPTION_EVENT)
1030
947
  {
1062
979
    case ROTATE_EVENT:
1063
980
      ev = new Rotate_log_event(buf, event_len, description_event);
1064
981
      break;
1065
 
    case SLAVE_EVENT: /* can never happen (unused event) */
1066
 
      ev = new Slave_log_event(buf, event_len);
1067
 
      break;
1068
982
    case CREATE_FILE_EVENT:
1069
983
      ev = new Create_file_log_event(buf, event_len, description_event);
1070
984
      break;
1083
997
    case STOP_EVENT:
1084
998
      ev = new Stop_log_event(buf, description_event);
1085
999
      break;
1086
 
    case INTVAR_EVENT:
1087
 
      ev = new Intvar_log_event(buf, description_event);
1088
 
      break;
1089
1000
    case XID_EVENT:
1090
1001
      ev = new Xid_log_event(buf, description_event);
1091
1002
      break;
1092
 
    case RAND_EVENT:
1093
 
      ev = new Rand_log_event(buf, description_event);
1094
 
      break;
1095
 
    case USER_VAR_EVENT:
1096
 
      ev = new User_var_log_event(buf, description_event);
1097
 
      break;
1098
1003
    case FORMAT_DESCRIPTION_EVENT:
1099
1004
      ev = new Format_description_log_event(buf, event_len, description_event);
1100
1005
      break;
1101
 
#if defined(HAVE_REPLICATION) 
1102
1006
    case WRITE_ROWS_EVENT:
1103
1007
      ev = new Write_rows_log_event(buf, event_len, description_event);
1104
1008
      break;
1111
1015
    case TABLE_MAP_EVENT:
1112
1016
      ev = new Table_map_log_event(buf, event_len, description_event);
1113
1017
      break;
1114
 
#endif
1115
1018
    case BEGIN_LOAD_QUERY_EVENT:
1116
1019
      ev = new Begin_load_query_log_event(buf, event_len, description_event);
1117
1020
      break;
1129
1032
 
1130
1033
  /*
1131
1034
    is_valid() are small event-specific sanity tests which are
1132
 
    important; for example there are some my_malloc() in constructors
 
1035
    important; for example there are some malloc() in constructors
1133
1036
    (e.g. Query_log_event::Query_log_event(char*...)); when these
1134
 
    my_malloc() fail we can't return an error out of the constructor
 
1037
    malloc() fail we can't return an error out of the constructor
1135
1038
    (because constructor is "void") ; so instead we leave the pointer we
1136
1039
    wanted to allocate (e.g. 'query') to 0 and we test it in is_valid().
1137
1040
    Same for Format_description_log_event, member 'post_header_len'.
1139
1042
  if (!ev || !ev->is_valid())
1140
1043
  {
1141
1044
    delete ev;
1142
 
#ifdef DRIZZLE_CLIENT
1143
 
    if (!force_opt) /* then mysqlbinlog dies */
1144
 
    {
1145
 
      *error= "Found invalid event in binary log";
1146
 
      return(0);
1147
 
    }
1148
 
    ev= new Unknown_log_event(buf, description_event);
1149
 
#else
1150
1045
    *error= "Found invalid event in binary log";
1151
1046
    return(0);
1152
 
#endif
1153
 
  }
1154
 
  return(ev);  
1155
 
}
1156
 
 
1157
 
#ifdef DRIZZLE_CLIENT
1158
 
 
1159
 
/*
1160
 
  Log_event::print_header()
1161
 
*/
1162
 
 
1163
 
void Log_event::print_header(IO_CACHE* file,
1164
 
                             PRINT_EVENT_INFO* print_event_info,
1165
 
                             bool is_more __attribute__((unused)))
1166
 
{
1167
 
  char llbuff[22];
1168
 
  my_off_t hexdump_from= print_event_info->hexdump_from;
1169
 
 
1170
 
  my_b_printf(file, "#");
1171
 
  print_timestamp(file);
1172
 
  my_b_printf(file, " server id %d  end_log_pos %s ", server_id,
1173
 
              llstr(log_pos,llbuff));
1174
 
 
1175
 
  /* mysqlbinlog --hexdump */
1176
 
  if (print_event_info->hexdump_from)
1177
 
  {
1178
 
    my_b_printf(file, "\n");
1179
 
    uchar *ptr= (uchar*)temp_buf;
1180
 
    my_off_t size=
1181
 
      uint4korr(ptr + EVENT_LEN_OFFSET) - LOG_EVENT_MINIMAL_HEADER_LEN;
1182
 
    my_off_t i;
1183
 
 
1184
 
    /* Header len * 4 >= header len * (2 chars + space + extra space) */
1185
 
    char *h, hex_string[LOG_EVENT_MINIMAL_HEADER_LEN*4]= {0};
1186
 
    char *c, char_string[16+1]= {0};
1187
 
 
1188
 
    /* Pretty-print event common header if header is exactly 19 bytes */
1189
 
    if (print_event_info->common_header_len == LOG_EVENT_MINIMAL_HEADER_LEN)
1190
 
    {
1191
 
      char emit_buf[256];               // Enough for storing one line
1192
 
      my_b_printf(file, "# Position  Timestamp   Type   Master ID        "
1193
 
                  "Size      Master Pos    Flags \n");
1194
 
      int const bytes_written=
1195
 
        snprintf(emit_buf, sizeof(emit_buf),
1196
 
                 "# %8.8lx %02x %02x %02x %02x   %02x   "
1197
 
                 "%02x %02x %02x %02x   %02x %02x %02x %02x   "
1198
 
                 "%02x %02x %02x %02x   %02x %02x\n",
1199
 
                 (unsigned long) hexdump_from,
1200
 
                 ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6],
1201
 
                 ptr[7], ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13],
1202
 
                 ptr[14], ptr[15], ptr[16], ptr[17], ptr[18]);
1203
 
      assert(bytes_written >= 0);
1204
 
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1205
 
      my_b_write(file, (uchar*) emit_buf, bytes_written);
1206
 
      ptr += LOG_EVENT_MINIMAL_HEADER_LEN;
1207
 
      hexdump_from += LOG_EVENT_MINIMAL_HEADER_LEN;
1208
 
    }
1209
 
 
1210
 
    /* Rest of event (without common header) */
1211
 
    for (i= 0, c= char_string, h=hex_string;
1212
 
         i < size;
1213
 
         i++, ptr++)
1214
 
    {
1215
 
      snprintf(h, 4, "%02x ", *ptr);
1216
 
      h += 3;
1217
 
 
1218
 
      *c++= my_isalnum(&my_charset_bin, *ptr) ? *ptr : '.';
1219
 
 
1220
 
      if (i % 16 == 15)
1221
 
      {
1222
 
        /*
1223
 
          my_b_printf() does not support full printf() formats, so we
1224
 
          have to do it this way.
1225
 
 
1226
 
          TODO: Rewrite my_b_printf() to support full printf() syntax.
1227
 
         */
1228
 
        char emit_buf[256];
1229
 
        int const bytes_written=
1230
 
          snprintf(emit_buf, sizeof(emit_buf),
1231
 
                   "# %8.8lx %-48.48s |%16s|\n",
1232
 
                   (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1233
 
                   hex_string, char_string);
1234
 
        assert(bytes_written >= 0);
1235
 
        assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1236
 
        my_b_write(file, (uchar*) emit_buf, bytes_written);
1237
 
        hex_string[0]= 0;
1238
 
        char_string[0]= 0;
1239
 
        c= char_string;
1240
 
        h= hex_string;
1241
 
      }
1242
 
      else if (i % 8 == 7) *h++ = ' ';
1243
 
    }
1244
 
    *c= '\0';
1245
 
 
1246
 
    if (hex_string[0])
1247
 
    {
1248
 
      char emit_buf[256];
1249
 
      int const bytes_written=
1250
 
        snprintf(emit_buf, sizeof(emit_buf),
1251
 
                    "# %8.8lx %-48.48s |%s|\n",
1252
 
                    (unsigned long) (hexdump_from + (i & 0xfffffff0)),
1253
 
                    hex_string, char_string);
1254
 
      assert(bytes_written >= 0);
1255
 
      assert(static_cast<size_t>(bytes_written) < sizeof(emit_buf));
1256
 
      my_b_write(file, (uchar*) emit_buf, bytes_written);
1257
 
    }
1258
 
    /*
1259
 
      need a # to prefix the rest of printouts for example those of
1260
 
      Rows_log_event::print_helper().
1261
 
    */
1262
 
    my_b_write(file, reinterpret_cast<const uchar*>("# "), 2);
1263
 
  }
1264
 
  return;
1265
 
}
1266
 
 
1267
 
 
1268
 
void Log_event::print_base64(IO_CACHE* file,
1269
 
                             PRINT_EVENT_INFO* print_event_info,
1270
 
                             bool more)
1271
 
{
1272
 
  const uchar *ptr= (const uchar *)temp_buf;
1273
 
  uint32_t size= uint4korr(ptr + EVENT_LEN_OFFSET);
1274
 
 
1275
 
  size_t const tmp_str_sz= base64_needed_encoded_length((int) size);
1276
 
  char *const tmp_str= (char *) my_malloc(tmp_str_sz, MYF(MY_WME));
1277
 
  if (!tmp_str) {
1278
 
    fprintf(stderr, "\nError: Out of memory. "
1279
 
            "Could not print correct binlog event.\n");
1280
 
    return;
1281
 
  }
1282
 
 
1283
 
  if (base64_encode(ptr, (size_t) size, tmp_str))
1284
 
  {
1285
 
    assert(0);
1286
 
  }
1287
 
 
1288
 
  if (my_b_tell(file) == 0)
1289
 
    my_b_printf(file, "\nBINLOG '\n");
1290
 
 
1291
 
  my_b_printf(file, "%s\n", tmp_str);
1292
 
 
1293
 
  if (!more)
1294
 
    my_b_printf(file, "'%s\n", print_event_info->delimiter);
1295
 
 
1296
 
  my_free(tmp_str, MYF(0));
1297
 
  return;
1298
 
}
1299
 
 
1300
 
 
1301
 
/*
1302
 
  Log_event::print_timestamp()
1303
 
*/
1304
 
 
1305
 
void Log_event::print_timestamp(IO_CACHE* file, time_t* ts)
1306
 
{
1307
 
  struct tm *res;
1308
 
  if (!ts)
1309
 
    ts = &when;
1310
 
#ifdef DRIZZLE_SERVER                           // This is always false
1311
 
  struct tm tm_tmp;
1312
 
  localtime_r(ts,(res= &tm_tmp));
1313
 
#else
1314
 
  res=localtime(ts);
1315
 
#endif
1316
 
 
1317
 
  my_b_printf(file,"%02d%02d%02d %2d:%02d:%02d",
1318
 
              res->tm_year % 100,
1319
 
              res->tm_mon+1,
1320
 
              res->tm_mday,
1321
 
              res->tm_hour,
1322
 
              res->tm_min,
1323
 
              res->tm_sec);
1324
 
  return;
1325
 
}
1326
 
 
1327
 
#endif /* DRIZZLE_CLIENT */
1328
 
 
1329
 
 
1330
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
 
1047
  }
 
1048
  return(ev);
 
1049
}
 
1050
 
1331
1051
inline Log_event::enum_skip_reason
1332
1052
Log_event::continue_group(Relay_log_info *rli)
1333
1053
{
1335
1055
    return Log_event::EVENT_SKIP_IGNORE;
1336
1056
  return Log_event::do_shall_skip(rli);
1337
1057
}
1338
 
#endif
1339
1058
 
1340
1059
/**************************************************************************
1341
1060
        Query_log_event methods
1342
1061
**************************************************************************/
1343
1062
 
1344
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
1345
 
 
1346
1063
/**
1347
1064
  This (which is used only for SHOW BINLOG EVENTS) could be updated to
1348
1065
  print SET @@session_var=. But this is not urgent, as SHOW BINLOG EVENTS is
1356
1073
{
1357
1074
  // TODO: show the catalog ??
1358
1075
  char *buf, *pos;
1359
 
  if (!(buf= (char*) my_malloc(9 + db_len + q_len, MYF(MY_WME))))
 
1076
  if (!(buf= (char*) malloc(9 + db_len + q_len)))
1360
1077
    return;
1361
1078
  pos= buf;
1362
1079
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F)
1363
1080
      && db && db_len)
1364
1081
  {
1365
 
    pos= stpcpy(buf, "use `");
 
1082
    pos= strcpy(buf, "use `")+5;
1366
1083
    memcpy(pos, db, db_len);
1367
 
    pos= stpcpy(pos+db_len, "`; ");
 
1084
    pos= strcpy(pos+db_len, "`; ")+3;
1368
1085
  }
1369
1086
  if (query && q_len)
1370
1087
  {
1372
1089
    pos+= q_len;
1373
1090
  }
1374
1091
  protocol->store(buf, pos-buf, &my_charset_bin);
1375
 
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
1376
 
}
1377
 
#endif
1378
 
 
1379
 
#ifndef DRIZZLE_CLIENT
1380
 
 
1381
 
/**
1382
 
  Utility function for the next method (Query_log_event::write()) .
1383
 
*/
1384
 
static void write_str_with_code_and_len(char **dst, const char *src,
1385
 
                                        int len, uint code)
1386
 
{
1387
 
  assert(src);
1388
 
  *((*dst)++)= code;
1389
 
  *((*dst)++)= (uchar) len;
1390
 
  memcpy(*dst, src, len);
1391
 
  (*dst)+= len;
 
1092
  free(buf);
1392
1093
}
1393
1094
 
1394
1095
 
1408
1109
    replicating it correctly, since the length is stored in a byte
1409
1110
    /sven
1410
1111
  */
1411
 
  uchar buf[QUERY_HEADER_LEN+
 
1112
  unsigned char buf[QUERY_HEADER_LEN+
1412
1113
            1+4+           // code of flags2 and flags2
1413
1114
            1+8+           // code of sql_mode and sql_mode
1414
1115
            1+1+FN_REFLEN+ // code of catalog and catalog length and catalog
1477
1178
    int4store(start, flags2);
1478
1179
    start+= 4;
1479
1180
  }
1480
 
  if (sql_mode_inited)
1481
 
  {
1482
 
    *start++= Q_SQL_MODE_CODE;
1483
 
    int8store(start, (uint64_t)sql_mode);
1484
 
    start+= 8;
1485
 
  }
1486
 
  if (catalog_len) // i.e. this var is inited (false for 4.0 events)
1487
 
  {
1488
 
    write_str_with_code_and_len((char **)(&start),
1489
 
                                catalog, catalog_len, Q_CATALOG_NZ_CODE);
1490
 
    /*
1491
 
      In 5.0.x where x<4 masters we used to store the end zero here. This was
1492
 
      a waste of one byte so we don't do it in x>=4 masters. We change code to
1493
 
      Q_CATALOG_NZ_CODE, because re-using the old code would make x<4 slaves
1494
 
      of this x>=4 master segfault (expecting a zero when there is
1495
 
      none). Remaining compatibility problems are: the older slave will not
1496
 
      find the catalog; but it is will not crash, and it's not an issue
1497
 
      that it does not find the catalog as catalogs were not used in these
1498
 
      older MySQL versions (we store it in binlog and read it from relay log
1499
 
      but do nothing useful with it). What is an issue is that the older slave
1500
 
      will stop processing the Q_* blocks (and jumps to the db/query) as soon
1501
 
      as it sees unknown Q_CATALOG_NZ_CODE; so it will not be able to read
1502
 
      Q_AUTO_INCREMENT*, Q_CHARSET and so replication will fail silently in
1503
 
      various ways. Documented that you should not mix alpha/beta versions if
1504
 
      they are not exactly the same version, with example of 5.0.3->5.0.2 and
1505
 
      5.0.4->5.0.3. If replication is from older to new, the new will
1506
 
      recognize Q_CATALOG_CODE and have no problem.
1507
 
    */
1508
 
  }
1509
 
  if (auto_increment_increment != 1 || auto_increment_offset != 1)
1510
 
  {
1511
 
    *start++= Q_AUTO_INCREMENT;
1512
 
    int2store(start, auto_increment_increment);
1513
 
    int2store(start+2, auto_increment_offset);
1514
 
    start+= 4;
1515
 
  }
1516
 
  if (charset_inited)
1517
 
  {
1518
 
    *start++= Q_CHARSET_CODE;
1519
 
    memcpy(start, charset, 6);
1520
 
    start+= 6;
1521
 
  }
1522
 
  if (time_zone_len)
1523
 
  {
1524
 
    /* In the TZ sys table, column Name is of length 64 so this should be ok */
1525
 
    assert(time_zone_len <= MAX_TIME_ZONE_NAME_LENGTH);
1526
 
    *start++= Q_TIME_ZONE_CODE;
1527
 
    *start++= time_zone_len;
1528
 
    memcpy(start, time_zone_str, time_zone_len);
1529
 
    start+= time_zone_len;
1530
 
  }
1531
1181
  if (lc_time_names_number)
1532
1182
  {
1533
1183
    assert(lc_time_names_number <= 0xFFFF);
1551
1201
    start+= 4;
1552
1202
    }
1553
1203
  */
1554
 
  
 
1204
 
1555
1205
  /* Store length of status variables */
1556
1206
  status_vars_len= (uint) (start-start_of_status);
1557
1207
  assert(status_vars_len <= MAX_SIZE_LOG_EVENT_STATUS);
1564
1214
  event_length= (uint) (start-buf) + get_post_header_size_for_derived() + db_len + 1 + q_len;
1565
1215
 
1566
1216
  return (write_header(file, event_length) ||
1567
 
          my_b_safe_write(file, (uchar*) buf, QUERY_HEADER_LEN) ||
 
1217
          my_b_safe_write(file, (unsigned char*) buf, QUERY_HEADER_LEN) ||
1568
1218
          write_post_header_for_derived(file) ||
1569
 
          my_b_safe_write(file, (uchar*) start_of_status,
 
1219
          my_b_safe_write(file, (unsigned char*) start_of_status,
1570
1220
                          (uint) (start-start_of_status)) ||
1571
 
          my_b_safe_write(file, (db) ? (uchar*) db : (uchar*)"", db_len + 1) ||
1572
 
          my_b_safe_write(file, (uchar*) query, q_len)) ? 1 : 0;
 
1221
          my_b_safe_write(file, (db) ? (unsigned char*) db : (unsigned char*)"", db_len + 1) ||
 
1222
          my_b_safe_write(file, (unsigned char*) query, q_len)) ? 1 : 0;
1573
1223
}
1574
1224
 
1575
1225
/**
1576
1226
  The simplest constructor that could possibly work.  This is used for
1577
1227
  creating static objects that have a special meaning and are invisible
1578
 
  to the log.  
 
1228
  to the log.
1579
1229
*/
1580
1230
Query_log_event::Query_log_event()
1581
1231
  :Log_event(), data_buf(0)
1586
1236
/*
1587
1237
  SYNOPSIS
1588
1238
    Query_log_event::Query_log_event()
1589
 
      thd_arg           - thread handle
 
1239
      session_arg           - thread handle
1590
1240
      query_arg         - array of char representing the query
1591
1241
      query_length      - size of the  `query_arg' array
1592
1242
      using_trans       - there is a modified transactional table
1593
1243
      suppress_use      - suppress the generation of 'USE' statements
1594
 
      killed_status_arg - an optional with default to THD::KILLED_NO_VALUE
 
1244
      killed_status_arg - an optional with default to Session::KILLED_NO_VALUE
1595
1245
                          if the value is different from the default, the arg
1596
 
                          is set to the current thd->killed value.
1597
 
                          A caller might need to masquerade thd->killed with
1598
 
                          THD::NOT_KILLED.
 
1246
                          is set to the current session->killed value.
 
1247
                          A caller might need to masquerade session->killed with
 
1248
                          Session::NOT_KILLED.
1599
1249
  DESCRIPTION
1600
1250
  Creates an event for binlogging
1601
1251
  The value for local `killed_status' can be supplied by caller.
1602
1252
*/
1603
 
Query_log_event::Query_log_event(THD* thd_arg, const char* query_arg,
1604
 
                                 ulong query_length, bool using_trans,
1605
 
                                 bool suppress_use,
1606
 
                                 THD::killed_state killed_status_arg)
1607
 
  :Log_event(thd_arg,
1608
 
             (thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F :
1609
 
              0) |
1610
 
             (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
1611
 
             using_trans),
1612
 
   data_buf(0), query(query_arg), catalog(thd_arg->catalog),
1613
 
   db(thd_arg->db), q_len((uint32_t) query_length),
1614
 
   thread_id(thd_arg->thread_id),
1615
 
   /* save the original thread id; we already know the server id */
1616
 
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
1617
 
   flags2_inited(1), sql_mode_inited(1), charset_inited(1),
1618
 
   sql_mode(0),
1619
 
   auto_increment_increment(thd_arg->variables.auto_increment_increment),
1620
 
   auto_increment_offset(thd_arg->variables.auto_increment_offset),
1621
 
   lc_time_names_number(thd_arg->variables.lc_time_names->number),
 
1253
Query_log_event::Query_log_event(Session* session_arg, const char* query_arg,
 
1254
                                 ulong query_length, bool using_trans,
 
1255
                                 bool suppress_use,
 
1256
                                 Session::killed_state killed_status_arg)
 
1257
:Log_event(session_arg,
 
1258
           (session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0) |
 
1259
           (suppress_use ? LOG_EVENT_SUPPRESS_USE_F : 0),
 
1260
           using_trans),
 
1261
  data_buf(0), query(query_arg), catalog(session_arg->catalog),
 
1262
  db(session_arg->db), q_len((uint32_t) query_length),
 
1263
  thread_id(session_arg->thread_id),
 
1264
  /* save the original thread id; we already know the server id */
 
1265
  slave_proxy_id(session_arg->variables.pseudo_thread_id),
 
1266
  flags2_inited(1), sql_mode_inited(1), charset_inited(1),
 
1267
  sql_mode(0),
 
1268
  auto_increment_increment(session_arg->variables.auto_increment_increment),
 
1269
  auto_increment_offset(session_arg->variables.auto_increment_offset),
 
1270
  lc_time_names_number(session_arg->variables.lc_time_names->number),
1622
1271
   charset_database_number(0)
1623
1272
{
1624
1273
  time_t end_time;
1625
1274
 
1626
 
  if (killed_status_arg == THD::KILLED_NO_VALUE)
1627
 
    killed_status_arg= thd_arg->killed;
 
1275
  if (killed_status_arg == Session::KILLED_NO_VALUE)
 
1276
    killed_status_arg= session_arg->killed;
1628
1277
 
1629
1278
  error_code=
1630
 
    (killed_status_arg == THD::NOT_KILLED) ?
1631
 
    (thd_arg->is_error() ? thd_arg->main_da.sql_errno() : 0) :
1632
 
    (thd_arg->killed_errno());
1633
 
  
 
1279
    (killed_status_arg == Session::NOT_KILLED) ?
 
1280
    (session_arg->is_error() ? session_arg->main_da.sql_errno() : 0) :
 
1281
    (session_arg->killed_errno());
 
1282
 
1634
1283
  time(&end_time);
1635
 
  exec_time = (ulong) (end_time  - thd_arg->start_time);
 
1284
  exec_time = (ulong) (end_time  - session_arg->start_time);
1636
1285
  /**
1637
1286
    @todo this means that if we have no catalog, then it is replicated
1638
1287
    as an existing catalog of length zero. is that safe? /sven
1640
1289
  catalog_len = (catalog) ? (uint32_t) strlen(catalog) : 0;
1641
1290
  /* status_vars_len is set just before writing the event */
1642
1291
  db_len = (db) ? (uint32_t) strlen(db) : 0;
1643
 
  if (thd_arg->variables.collation_database != thd_arg->db_charset)
1644
 
    charset_database_number= thd_arg->variables.collation_database->number;
1645
 
  
 
1292
  if (session_arg->variables.collation_database != session_arg->db_charset)
 
1293
    charset_database_number= session_arg->variables.collation_database->number;
 
1294
 
1646
1295
  /*
1647
1296
    If we don't use flags2 for anything else than options contained in
1648
 
    thd_arg->options, it would be more efficient to flags2=thd_arg->options
 
1297
    session_arg->options, it would be more efficient to flags2=session_arg->options
1649
1298
    (OPTIONS_WRITTEN_TO_BIN_LOG would be used only at reading time).
1650
1299
    But it's likely that we don't want to use 32 bits for 3 bits; in the future
1651
1300
    we will probably want to reclaim the 29 bits. So we need the &.
1652
1301
  */
1653
 
  flags2= (uint32_t) (thd_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
1654
 
  assert(thd_arg->variables.character_set_client->number < 256*256);
1655
 
  assert(thd_arg->variables.collation_connection->number < 256*256);
1656
 
  assert(thd_arg->variables.collation_server->number < 256*256);
1657
 
  assert(thd_arg->variables.character_set_client->mbminlen == 1);
1658
 
  int2store(charset, thd_arg->variables.character_set_client->number);
1659
 
  int2store(charset+2, thd_arg->variables.collation_connection->number);
1660
 
  int2store(charset+4, thd_arg->variables.collation_server->number);
1661
 
  if (thd_arg->time_zone_used)
1662
 
  {
1663
 
    /*
1664
 
      Note that our event becomes dependent on the Time_zone object
1665
 
      representing the time zone. Fortunately such objects are never deleted
1666
 
      or changed during mysqld's lifetime.
1667
 
    */
1668
 
    time_zone_len= thd_arg->variables.time_zone->get_name()->length();
1669
 
    time_zone_str= thd_arg->variables.time_zone->get_name()->ptr();
1670
 
  }
1671
 
  else
1672
 
    time_zone_len= 0;
1673
 
}
1674
 
#endif /* DRIZZLE_CLIENT */
1675
 
 
1676
 
 
1677
 
/* 2 utility functions for the next method */
1678
 
 
1679
 
/**
1680
 
   Read a string with length from memory.
1681
 
 
1682
 
   This function reads the string-with-length stored at
1683
 
   <code>src</code> and extract the length into <code>*len</code> and
1684
 
   a pointer to the start of the string into <code>*dst</code>. The
1685
 
   string can then be copied using <code>memcpy()</code> with the
1686
 
   number of bytes given in <code>*len</code>.
1687
 
 
1688
 
   @param src Pointer to variable holding a pointer to the memory to
1689
 
              read the string from.
1690
 
   @param dst Pointer to variable holding a pointer where the actual
1691
 
              string starts. Starting from this position, the string
1692
 
              can be copied using @c memcpy().
1693
 
   @param len Pointer to variable where the length will be stored.
1694
 
   @param end One-past-the-end of the memory where the string is
1695
 
              stored.
1696
 
 
1697
 
   @return    Zero if the entire string can be copied successfully,
1698
 
              @c UINT_MAX if the length could not be read from memory
1699
 
              (that is, if <code>*src >= end</code>), otherwise the
1700
 
              number of bytes that are missing to read the full
1701
 
              string, which happends <code>*dst + *len >= end</code>.
1702
 
*/
1703
 
static int
1704
 
get_str_len_and_pointer(const Log_event::Byte **src,
1705
 
                        const char **dst,
1706
 
                        uint *len,
1707
 
                        const Log_event::Byte *end)
1708
 
{
1709
 
  if (*src >= end)
1710
 
    return -1;       // Will be UINT_MAX in two-complement arithmetics
1711
 
  uint length= **src;
1712
 
  if (length > 0)
1713
 
  {
1714
 
    if (*src + length >= end)
1715
 
      return *src + length - end + 1;       // Number of bytes missing
1716
 
    *dst= (char *)*src + 1;                    // Will be copied later
1717
 
  }
1718
 
  *len= length;
1719
 
  *src+= length + 1;
1720
 
  return 0;
1721
 
}
1722
 
 
1723
 
static void copy_str_and_move(const char **src, 
1724
 
                              Log_event::Byte **dst, 
1725
 
                              uint len)
 
1302
  flags2= (uint32_t) (session_arg->options & OPTIONS_WRITTEN_TO_BIN_LOG);
 
1303
  assert(session_arg->variables.collation_server->number < 256*256);
 
1304
  int2store(charset+4, session_arg->variables.collation_server->number);
 
1305
  time_zone_len= 0;
 
1306
}
 
1307
 
 
1308
static void copy_str_and_move(const char **src,
 
1309
                              Log_event::Byte **dst,
 
1310
                              uint32_t len)
1726
1311
{
1727
1312
  memcpy(*dst, *src, len);
1728
1313
  *src= (const char *)*dst;
1740
1325
 */
1741
1326
#define CHECK_SPACE(PTR,END,CNT)                      \
1742
1327
  do {                                                \
1743
 
    assert((PTR) + (CNT) <= (END));              \
 
1328
    assert((PTR) + (CNT) <= (END));                   \
1744
1329
    if ((PTR) + (CNT) > (END)) {                      \
1745
1330
      query= 0;                                       \
1746
 
      return;                               \
 
1331
      return;                                         \
1747
1332
    }                                                 \
1748
1333
  } while (0)
1749
1334
 
1751
1336
/**
1752
1337
  This is used by the SQL slave thread to prepare the event before execution.
1753
1338
*/
1754
 
Query_log_event::Query_log_event(const char* buf, uint event_len,
 
1339
Query_log_event::Query_log_event(const char* buf, uint32_t event_len,
1755
1340
                                 const Format_description_log_event
1756
1341
                                 *description_event,
1757
1342
                                 Log_event_type event_type)
1758
 
  :Log_event(buf, description_event), data_buf(0), query(NullS),
1759
 
   db(NullS), catalog_len(0), status_vars_len(0),
 
1343
  :Log_event(buf, description_event), data_buf(0), query(NULL),
 
1344
   db(NULL), catalog_len(0), status_vars_len(0),
1760
1345
   flags2_inited(0), sql_mode_inited(0), charset_inited(0),
1761
1346
   auto_increment_increment(1), auto_increment_offset(1),
1762
1347
   time_zone_len(0), lc_time_names_number(0), charset_database_number(0)
1770
1355
 
1771
1356
  common_header_len= description_event->common_header_len;
1772
1357
  post_header_len= description_event->post_header_len[event_type-1];
1773
 
  
 
1358
 
1774
1359
  /*
1775
1360
    We test if the event's length is sensible, and if so we compute data_len.
1776
1361
    We cannot rely on QUERY_HEADER_LEN here as it would not be format-tolerant.
1777
1362
    We use QUERY_HEADER_MINIMAL_LEN which is the same for 3.23, 4.0 & 5.0.
1778
1363
  */
1779
1364
  if (event_len < (uint)(common_header_len + post_header_len))
1780
 
    return;                             
 
1365
    return;
1781
1366
  data_len = event_len - (common_header_len + post_header_len);
1782
1367
  buf+= common_header_len;
1783
 
  
 
1368
 
1784
1369
  slave_proxy_id= thread_id = uint4korr(buf + Q_THREAD_ID_OFFSET);
1785
1370
  exec_time = uint4korr(buf + Q_EXEC_TIME_OFFSET);
1786
1371
  db_len = (uint)buf[Q_DB_LEN_OFFSET]; // TODO: add a check of all *_len vars
1791
1376
    Depending on the format, we may or not have affected/warnings etc
1792
1377
    The remnent post-header to be parsed has length:
1793
1378
  */
1794
 
  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN; 
 
1379
  tmp= post_header_len - QUERY_HEADER_MINIMAL_LEN;
1795
1380
  if (tmp)
1796
1381
  {
1797
1382
    status_vars_len= uint2korr(buf + Q_STATUS_VARS_LEN_OFFSET);
1801
1386
      be even bigger, but this will suffice to catch most corruption
1802
1387
      errors that can lead to a crash.
1803
1388
    */
1804
 
    if (status_vars_len > min(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
 
1389
    if (status_vars_len > cmin(data_len, (uint32_t)MAX_SIZE_LOG_EVENT_STATUS))
1805
1390
    {
1806
1391
      query= 0;
1807
1392
      return;
1816
1401
  */
1817
1402
 
1818
1403
  /* variable-part: the status vars; only in MySQL 5.0  */
1819
 
  
 
1404
 
1820
1405
  start= (Log_event::Byte*) (buf+post_header_len);
1821
1406
  end= (const Log_event::Byte*) (start+status_vars_len);
1822
1407
  for (const Log_event::Byte* pos= start; pos < end;)
1828
1413
      flags2= uint4korr(pos);
1829
1414
      pos+= 4;
1830
1415
      break;
1831
 
    case Q_SQL_MODE_CODE:
1832
 
    {
1833
 
      CHECK_SPACE(pos, end, 8);
1834
 
      sql_mode_inited= 1;
1835
 
      sql_mode= (ulong) uint8korr(pos); // QQ: Fix when sql_mode is uint64_t
1836
 
      pos+= 8;
1837
 
      break;
1838
 
    }
1839
 
    case Q_CATALOG_NZ_CODE:
1840
 
      if (get_str_len_and_pointer(&pos, &catalog, &catalog_len, end))
1841
 
      {
1842
 
        query= 0;
1843
 
        return;
1844
 
      }
1845
 
      break;
1846
 
    case Q_AUTO_INCREMENT:
1847
 
      CHECK_SPACE(pos, end, 4);
1848
 
      auto_increment_increment= uint2korr(pos);
1849
 
      auto_increment_offset=    uint2korr(pos+2);
1850
 
      pos+= 4;
1851
 
      break;
1852
 
    case Q_CHARSET_CODE:
1853
 
    {
1854
 
      CHECK_SPACE(pos, end, 6);
1855
 
      charset_inited= 1;
1856
 
      memcpy(charset, pos, 6);
1857
 
      pos+= 6;
1858
 
      break;
1859
 
    }
1860
 
    case Q_TIME_ZONE_CODE:
1861
 
    {
1862
 
      if (get_str_len_and_pointer(&pos, &time_zone_str, &time_zone_len, end))
1863
 
      {
1864
 
        query= 0;
1865
 
        return;
1866
 
      }
1867
 
      break;
1868
 
    }
1869
 
    case Q_CATALOG_CODE: /* for 5.0.x where 0<=x<=3 masters */
1870
 
      CHECK_SPACE(pos, end, 1);
1871
 
      if ((catalog_len= *pos))
1872
 
        catalog= (char*) pos+1;                           // Will be copied later
1873
 
      CHECK_SPACE(pos, end, catalog_len + 2);
1874
 
      pos+= catalog_len+2; // leap over end 0
1875
 
      catalog_nz= 0; // catalog has end 0 in event
1876
 
      break;
1877
1416
    case Q_LC_TIME_NAMES_CODE:
1878
1417
      CHECK_SPACE(pos, end, 2);
1879
1418
      lc_time_names_number= uint2korr(pos);
1886
1425
      break;
1887
1426
    default:
1888
1427
      /* That's why you must write status vars in growing order of code */
1889
 
      pos= (const uchar*) end;                         // Break loop
 
1428
      pos= (const unsigned char*) end;                         // Break loop
1890
1429
    }
1891
1430
  }
1892
 
  
1893
 
  if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 +
 
1431
 
 
1432
  if (!(start= data_buf = (Log_event::Byte*) malloc(catalog_len + 1 +
1894
1433
                                             time_zone_len + 1 +
1895
 
                                             data_len + 1,
1896
 
                                             MYF(MY_WME))))
 
1434
                                             data_len + 1)))
1897
1435
      return;
1898
1436
  if (catalog_len)                                  // If catalog is given
1899
1437
  {
1921
1459
    my_alloc call above? /sven
1922
1460
  */
1923
1461
 
1924
 
  /* A 2nd variable part; this is common to all versions */ 
 
1462
  /* A 2nd variable part; this is common to all versions */
1925
1463
  memcpy(start, end, data_len);          // Copy db and query
1926
1464
  start[data_len]= '\0';              // End query with \0 (For safetly)
1927
1465
  db= (char *)start;
1931
1469
}
1932
1470
 
1933
1471
 
1934
 
#ifdef DRIZZLE_CLIENT
1935
 
/**
1936
 
  Query_log_event::print().
1937
 
 
1938
 
  @todo
1939
 
    print the catalog ??
1940
 
*/
1941
 
void Query_log_event::print_query_header(IO_CACHE* file,
1942
 
                                         PRINT_EVENT_INFO* print_event_info)
1943
 
{
1944
 
  // TODO: print the catalog ??
1945
 
  char buff[40],*end;                           // Enough for SET TIMESTAMP
1946
 
  bool different_db= 1;
1947
 
  uint32_t tmp;
1948
 
 
1949
 
  if (!print_event_info->short_form)
1950
 
  {
1951
 
    print_header(file, print_event_info, false);
1952
 
    my_b_printf(file, "\t%s\tthread_id=%lu\texec_time=%lu\terror_code=%d\n",
1953
 
                get_type_str(), (ulong) thread_id, (ulong) exec_time,
1954
 
                error_code);
1955
 
  }
1956
 
 
1957
 
  if (!(flags & LOG_EVENT_SUPPRESS_USE_F) && db)
1958
 
  {
1959
 
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)))
1960
 
      memcpy(print_event_info->db, db, db_len + 1);
1961
 
    if (db[0] && different_db) 
1962
 
      my_b_printf(file, "use %s%s\n", db, print_event_info->delimiter);
1963
 
  }
1964
 
 
1965
 
  end=int10_to_str((long) when, stpcpy(buff,"SET TIMESTAMP="),10);
1966
 
  end= stpcpy(end, print_event_info->delimiter);
1967
 
  *end++='\n';
1968
 
  my_b_write(file, (uchar*) buff, (uint) (end-buff));
1969
 
  if ((!print_event_info->thread_id_printed ||
1970
 
       ((flags & LOG_EVENT_THREAD_SPECIFIC_F) &&
1971
 
        thread_id != print_event_info->thread_id)))
1972
 
  {
1973
 
    // If --short-form, print deterministic value instead of pseudo_thread_id.
1974
 
    my_b_printf(file,"SET @@session.pseudo_thread_id=%lu%s\n",
1975
 
                short_form ? 999999999 : (ulong)thread_id,
1976
 
                print_event_info->delimiter);
1977
 
    print_event_info->thread_id= thread_id;
1978
 
    print_event_info->thread_id_printed= 1;
1979
 
  }
1980
 
 
1981
 
  /*
1982
 
    If flags2_inited==0, this is an event from 3.23 or 4.0; nothing to
1983
 
    print (remember we don't produce mixed relay logs so there cannot be
1984
 
    5.0 events before that one so there is nothing to reset).
1985
 
  */
1986
 
  if (likely(flags2_inited)) /* likely as this will mainly read 5.0 logs */
1987
 
  {
1988
 
    /* tmp is a bitmask of bits which have changed. */
1989
 
    if (likely(print_event_info->flags2_inited)) 
1990
 
      /* All bits which have changed */
1991
 
      tmp= (print_event_info->flags2) ^ flags2;
1992
 
    else /* that's the first Query event we read */
1993
 
    {
1994
 
      print_event_info->flags2_inited= 1;
1995
 
      tmp= ~((uint32_t)0); /* all bits have changed */
1996
 
    }
1997
 
 
1998
 
    if (unlikely(tmp)) /* some bits have changed */
1999
 
    {
2000
 
      bool need_comma= 0;
2001
 
      my_b_printf(file, "SET ");
2002
 
      print_set_option(file, tmp, OPTION_NO_FOREIGN_KEY_CHECKS, ~flags2,
2003
 
                   "@@session.foreign_key_checks", &need_comma);
2004
 
      print_set_option(file, tmp, OPTION_AUTO_IS_NULL, flags2,
2005
 
                   "@@session.sql_auto_is_null", &need_comma);
2006
 
      print_set_option(file, tmp, OPTION_RELAXED_UNIQUE_CHECKS, ~flags2,
2007
 
                   "@@session.unique_checks", &need_comma);
2008
 
      my_b_printf(file,"%s\n", print_event_info->delimiter);
2009
 
      print_event_info->flags2= flags2;
2010
 
    }
2011
 
  }
2012
 
 
2013
 
  /*
2014
 
    Now the session variables;
2015
 
    it's more efficient to pass SQL_MODE as a number instead of a
2016
 
    comma-separated list.
2017
 
    FOREIGN_KEY_CHECKS, SQL_AUTO_IS_NULL, UNIQUE_CHECKS are session-only
2018
 
    variables (they have no global version; they're not listed in
2019
 
    sql_class.h), The tests below work for pure binlogs or pure relay
2020
 
    logs. Won't work for mixed relay logs but we don't create mixed
2021
 
    relay logs (that is, there is no relay log with a format change
2022
 
    except within the 3 first events, which mysqlbinlog handles
2023
 
    gracefully). So this code should always be good.
2024
 
  */
2025
 
 
2026
 
  if (print_event_info->auto_increment_increment != auto_increment_increment ||
2027
 
      print_event_info->auto_increment_offset != auto_increment_offset)
2028
 
  {
2029
 
    my_b_printf(file,"SET @@session.auto_increment_increment=%lu, @@session.auto_increment_offset=%lu%s\n",
2030
 
                auto_increment_increment,auto_increment_offset,
2031
 
                print_event_info->delimiter);
2032
 
    print_event_info->auto_increment_increment= auto_increment_increment;
2033
 
    print_event_info->auto_increment_offset=    auto_increment_offset;
2034
 
  }
2035
 
 
2036
 
  /* TODO: print the catalog when we feature SET CATALOG */
2037
 
 
2038
 
  if (likely(charset_inited) &&
2039
 
      (unlikely(!print_event_info->charset_inited ||
2040
 
                memcmp(print_event_info->charset, charset, 6))))
2041
 
  {
2042
 
    const CHARSET_INFO * const cs_info= get_charset(uint2korr(charset), MYF(MY_WME));
2043
 
    if (cs_info)
2044
 
    {
2045
 
      /* for mysql client */
2046
 
      my_b_printf(file, "/*!\\C %s */%s\n",
2047
 
                  cs_info->csname, print_event_info->delimiter);
2048
 
    }
2049
 
    my_b_printf(file,"SET "
2050
 
                "@@session.character_set_client=%d,"
2051
 
                "@@session.collation_connection=%d,"
2052
 
                "@@session.collation_server=%d"
2053
 
                "%s\n",
2054
 
                uint2korr(charset),
2055
 
                uint2korr(charset+2),
2056
 
                uint2korr(charset+4),
2057
 
                print_event_info->delimiter);
2058
 
    memcpy(print_event_info->charset, charset, 6);
2059
 
    print_event_info->charset_inited= 1;
2060
 
  }
2061
 
  if (time_zone_len)
2062
 
  {
2063
 
    if (memcmp(print_event_info->time_zone_str, time_zone_str, time_zone_len+1))
2064
 
    {
2065
 
      my_b_printf(file,"SET @@session.time_zone='%s'%s\n",
2066
 
                  time_zone_str, print_event_info->delimiter);
2067
 
      memcpy(print_event_info->time_zone_str, time_zone_str, time_zone_len+1);
2068
 
    }
2069
 
  }
2070
 
  if (lc_time_names_number != print_event_info->lc_time_names_number)
2071
 
  {
2072
 
    my_b_printf(file, "SET @@session.lc_time_names=%d%s\n",
2073
 
                lc_time_names_number, print_event_info->delimiter);
2074
 
    print_event_info->lc_time_names_number= lc_time_names_number;
2075
 
  }
2076
 
  if (charset_database_number != print_event_info->charset_database_number)
2077
 
  {
2078
 
    if (charset_database_number)
2079
 
      my_b_printf(file, "SET @@session.collation_database=%d%s\n",
2080
 
                  charset_database_number, print_event_info->delimiter);
2081
 
    else
2082
 
      my_b_printf(file, "SET @@session.collation_database=DEFAULT%s\n",
2083
 
                  print_event_info->delimiter);
2084
 
    print_event_info->charset_database_number= charset_database_number;
2085
 
  }
2086
 
}
2087
 
 
2088
 
 
2089
 
void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2090
 
{
2091
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
2092
 
 
2093
 
  print_query_header(&cache, print_event_info);
2094
 
  my_b_write(&cache, (uchar*) query, q_len);
2095
 
  my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
2096
 
}
2097
 
#endif /* DRIZZLE_CLIENT */
2098
 
 
2099
 
 
2100
1472
/*
2101
1473
  Query_log_event::do_apply_event()
2102
1474
*/
2103
 
 
2104
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2105
 
 
2106
1475
int Query_log_event::do_apply_event(Relay_log_info const *rli)
2107
1476
{
2108
1477
  return do_apply_event(rli, query, q_len);
2116
1485
  @code
2117
1486
     if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
2118
1487
     {
2119
 
     sql_print_error("Slave: did not get the expected number of affected \
 
1488
     errmsg_printf(ERRMSG_LVL_ERROR, "Slave: did not get the expected number of affected \
2120
1489
     rows running query from master - expected %d, got %d (this numbers \
2121
1490
     should have matched modulo 4294967296).", 0, ...);
2122
 
     thd->query_error = 1;
 
1491
     session->query_error = 1;
2123
1492
     }
2124
1493
  @endcode
2125
1494
  We may also want an option to tell the slave to ignore "affected"
2129
1498
int Query_log_event::do_apply_event(Relay_log_info const *rli,
2130
1499
                                      const char *query_arg, uint32_t q_len_arg)
2131
1500
{
2132
 
  LEX_STRING new_db;
2133
1501
  int expected_error,actual_error= 0;
 
1502
  Query_id &query_id= Query_id::get_query_id();
2134
1503
  /*
2135
 
    Colleagues: please never free(thd->catalog) in MySQL. This would
2136
 
    lead to bugs as here thd->catalog is a part of an alloced block,
 
1504
    Colleagues: please never free(session->catalog) in MySQL. This would
 
1505
    lead to bugs as here session->catalog is a part of an alloced block,
2137
1506
    not an entire alloced block (see
2138
 
    Query_log_event::do_apply_event()). Same for thd->db.  Thank
 
1507
    Query_log_event::do_apply_event()). Same for session->db.  Thank
2139
1508
    you.
2140
1509
  */
2141
 
  thd->catalog= catalog_len ? (char *) catalog : (char *)"";
2142
 
  new_db.length= db_len;
2143
 
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
2144
 
  thd->set_db(new_db.str, new_db.length);       /* allocates a copy of 'db' */
2145
 
  thd->variables.auto_increment_increment= auto_increment_increment;
2146
 
  thd->variables.auto_increment_offset=    auto_increment_offset;
 
1510
  session->catalog= catalog_len ? (char *) catalog : (char *)"";
 
1511
  session->set_db(db, strlen(db));       /* allocates a copy of 'db' */
 
1512
  session->variables.auto_increment_increment= auto_increment_increment;
 
1513
  session->variables.auto_increment_offset=    auto_increment_offset;
2147
1514
 
2148
1515
  /*
2149
1516
    InnoDB internally stores the master log position it has executed so far,
2157
1524
  */
2158
1525
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
2159
1526
 
2160
 
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
1527
  clear_all_errors(session, const_cast<Relay_log_info*>(rli));
2161
1528
  const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
2162
1529
 
2163
1530
  /*
2170
1537
            ::do_apply_event(), then the companion SET also have so
2171
1538
            we don't need to reset_one_shot_variables().
2172
1539
  */
2173
 
  if (rpl_filter->db_ok(thd->db))
 
1540
  if (1)
2174
1541
  {
2175
 
    thd->set_time((time_t)when);
2176
 
    thd->query_length= q_len_arg;
2177
 
    thd->query= (char*)query_arg;
2178
 
    VOID(pthread_mutex_lock(&LOCK_thread_count));
2179
 
    thd->query_id = next_query_id();
2180
 
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
2181
 
    thd->variables.pseudo_thread_id= thread_id;         // for temp tables
 
1542
    session->set_time((time_t)when);
 
1543
    session->query_length= q_len_arg;
 
1544
    session->query= (char*)query_arg;
 
1545
    session->query_id= query_id.next();
 
1546
    session->variables.pseudo_thread_id= thread_id;             // for temp tables
2182
1547
 
2183
1548
    if (ignored_error_code((expected_error= error_code)) ||
2184
 
        !check_expected_error(thd,rli,expected_error))
 
1549
        !check_expected_error(session,rli,expected_error))
2185
1550
    {
2186
1551
      if (flags2_inited)
2187
1552
        /*
2188
 
          all bits of thd->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
 
1553
          all bits of session->options which are 1 in OPTIONS_WRITTEN_TO_BIN_LOG
2189
1554
          must take their value from flags2.
2190
1555
        */
2191
 
        thd->options= flags2|(thd->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2192
 
      /*
2193
 
        else, we are in a 3.23/4.0 binlog; we previously received a
2194
 
        Rotate_log_event which reset thd->options and sql_mode etc, so
2195
 
        nothing to do.
2196
 
      */
2197
 
      if (charset_inited)
2198
 
      {
2199
 
        if (rli->cached_charset_compare(charset))
2200
 
        {
2201
 
          /* Verify that we support the charsets found in the event. */
2202
 
          if (!(thd->variables.character_set_client=
2203
 
                get_charset(uint2korr(charset), MYF(MY_WME))) ||
2204
 
              !(thd->variables.collation_connection=
2205
 
                get_charset(uint2korr(charset+2), MYF(MY_WME))) ||
2206
 
              !(thd->variables.collation_server=
2207
 
                get_charset(uint2korr(charset+4), MYF(MY_WME))))
2208
 
          {
2209
 
            /*
2210
 
              We updated the thd->variables with nonsensical values (0). Let's
2211
 
              set them to something safe (i.e. which avoids crash), and we'll
2212
 
              stop with EE_UNKNOWN_CHARSET in compare_errors (unless set to
2213
 
              ignore this error).
2214
 
            */
2215
 
            set_slave_thread_default_charset(thd, rli);
2216
 
            goto compare_errors;
2217
 
          }
2218
 
          thd->update_charset(); // for the charset change to take effect
2219
 
        }
2220
 
      }
 
1556
        session->options= flags2|(session->options & ~OPTIONS_WRITTEN_TO_BIN_LOG);
2221
1557
      if (time_zone_len)
2222
1558
      {
2223
1559
        String tmp(time_zone_str, time_zone_len, &my_charset_bin);
2224
 
        if (!(thd->variables.time_zone= my_tz_find(thd, &tmp)))
 
1560
        if (!(session->variables.time_zone= my_tz_find(session, &tmp)))
2225
1561
        {
2226
1562
          my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), tmp.c_ptr());
2227
 
          thd->variables.time_zone= global_system_variables.time_zone;
 
1563
          session->variables.time_zone= global_system_variables.time_zone;
2228
1564
          goto compare_errors;
2229
1565
        }
2230
1566
      }
2231
1567
      if (lc_time_names_number)
2232
1568
      {
2233
 
        if (!(thd->variables.lc_time_names=
 
1569
        if (!(session->variables.lc_time_names=
2234
1570
              my_locale_by_number(lc_time_names_number)))
2235
1571
        {
2236
1572
          my_printf_error(ER_UNKNOWN_ERROR,
2237
1573
                      "Unknown locale: '%d'", MYF(0), lc_time_names_number);
2238
 
          thd->variables.lc_time_names= &my_locale_en_US;
 
1574
          session->variables.lc_time_names= &my_locale_en_US;
2239
1575
          goto compare_errors;
2240
1576
        }
2241
1577
      }
2242
1578
      else
2243
 
        thd->variables.lc_time_names= &my_locale_en_US;
 
1579
        session->variables.lc_time_names= &my_locale_en_US;
2244
1580
      if (charset_database_number)
2245
1581
      {
2246
1582
        const CHARSET_INFO *cs;
2251
1587
          my_error(ER_UNKNOWN_COLLATION, MYF(0), buf);
2252
1588
          goto compare_errors;
2253
1589
        }
2254
 
        thd->variables.collation_database= cs;
 
1590
        session->variables.collation_database= cs;
2255
1591
      }
2256
1592
      else
2257
 
        thd->variables.collation_database= thd->db_charset;
2258
 
      
 
1593
        session->variables.collation_database= session->db_charset;
 
1594
 
2259
1595
      /* Execute the query (note that we bypass dispatch_command()) */
2260
1596
      const char* found_semicolon= NULL;
2261
 
      mysql_parse(thd, thd->query, thd->query_length, &found_semicolon);
2262
 
      log_slow_statement(thd);
 
1597
      mysql_parse(session, session->query, session->query_length, &found_semicolon);
 
1598
      log_slow_statement(session);
2263
1599
    }
2264
1600
    else
2265
1601
    {
2270
1606
        we exit gracefully; otherwise we warn about the bad error and tell DBA
2271
1607
        to check/fix it.
2272
1608
      */
2273
 
      if (mysql_test_parse_for_slave(thd, thd->query, thd->query_length))
2274
 
        clear_all_errors(thd, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
 
1609
      if (mysql_test_parse_for_slave(session, session->query, session->query_length))
 
1610
        clear_all_errors(session, const_cast<Relay_log_info*>(rli)); /* Can ignore query */
2275
1611
      else
2276
1612
      {
2277
 
        rli->report(ERROR_LEVEL, expected_error, 
2278
 
                          "\
2279
 
Query partially completed on the master (error on master: %d) \
2280
 
and was aborted. There is a chance that your master is inconsistent at this \
2281
 
point. If you are sure that your master is ok, run this query manually on the \
2282
 
slave and then restart the slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; \
2283
 
START SLAVE; . Query: '%s'", expected_error, thd->query);
2284
 
        thd->is_slave_error= 1;
 
1613
        rli->report(ERROR_LEVEL, expected_error,
 
1614
                    _("Query partially completed on the master "
 
1615
                      "(error on master: %d) and was aborted. There is a "
 
1616
                      "chance that your master is inconsistent at this "
 
1617
                      "point. If you are sure that your master is ok, run "
 
1618
                      "this query manually on the slave and then restart the "
 
1619
                      "slave with SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; "
 
1620
                      "START SLAVE; . Query: '%s'"),
 
1621
                    expected_error, session->query);
 
1622
        session->is_slave_error= 1;
2285
1623
      }
2286
1624
      goto end;
2287
1625
    }
2288
1626
 
2289
 
    /* If the query was not ignored, it is printed to the general log */
2290
 
    if (!thd->is_error() || thd->main_da.sql_errno() != ER_SLAVE_IGNORED_TABLE)
2291
 
      general_log_write(thd, COM_QUERY, thd->query, thd->query_length);
2292
 
 
2293
1627
compare_errors:
2294
1628
 
2295
1629
     /*
2296
1630
      If we expected a non-zero error code, and we don't get the same error
2297
1631
      code, and none of them should be ignored.
2298
1632
    */
2299
 
    actual_error= thd->is_error() ? thd->main_da.sql_errno() : 0;
 
1633
    actual_error= session->is_error() ? session->main_da.sql_errno() : 0;
2300
1634
    if ((expected_error != actual_error) &&
2301
 
        expected_error &&
2302
 
        !ignored_error_code(actual_error) &&
2303
 
        !ignored_error_code(expected_error))
 
1635
        expected_error &&
 
1636
        !ignored_error_code(actual_error) &&
 
1637
        !ignored_error_code(expected_error))
2304
1638
    {
2305
1639
      rli->report(ERROR_LEVEL, 0,
2306
 
                      "\
2307
 
Query caused different errors on master and slave.     \
2308
 
Error on master: '%s' (%d), Error on slave: '%s' (%d). \
2309
 
Default database: '%s'. Query: '%s'",
2310
 
                      ER_SAFE(expected_error),
2311
 
                      expected_error,
2312
 
                      actual_error ? thd->main_da.message() : "no error",
2313
 
                      actual_error,
2314
 
                      print_slave_db_safe(db), query_arg);
2315
 
      thd->is_slave_error= 1;
 
1640
                  _("Query caused differenxt errors on master and slave.\n"
 
1641
                    "Error on master: '%s' (%d), Error on slave: '%s' (%d).\n"
 
1642
                    "Default database: '%s'. Query: '%s'"),
 
1643
                  ER(expected_error),
 
1644
                  expected_error,
 
1645
                  actual_error ? session->main_da.message() : _("no error"),
 
1646
                  actual_error,
 
1647
                  print_slave_db_safe(db), query_arg);
 
1648
      session->is_slave_error= 1;
2316
1649
    }
2317
1650
    /*
2318
 
      If we get the same error code as expected, or they should be ignored. 
 
1651
      If we get the same error code as expected, or they should be ignored.
2319
1652
    */
2320
1653
    else if (expected_error == actual_error ||
2321
1654
             ignored_error_code(actual_error))
2322
1655
    {
2323
 
      clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
2324
 
      thd->killed= THD::NOT_KILLED;
 
1656
      clear_all_errors(session, const_cast<Relay_log_info*>(rli));
 
1657
      session->killed= Session::NOT_KILLED;
2325
1658
    }
2326
1659
    /*
2327
1660
      Other cases: mostly we expected no error and get one.
2328
1661
    */
2329
 
    else if (thd->is_slave_error || thd->is_fatal_error)
 
1662
    else if (session->is_slave_error || session->is_fatal_error)
2330
1663
    {
2331
1664
      rli->report(ERROR_LEVEL, actual_error,
2332
 
                      "Error '%s' on query. Default database: '%s'. Query: '%s'",
2333
 
                      (actual_error ? thd->main_da.message() :
2334
 
                       "unexpected success or fatal error"),
2335
 
                      print_slave_db_safe(thd->db), query_arg);
2336
 
      thd->is_slave_error= 1;
 
1665
                  _("Error '%s' on query. Default database: '%s'. Query: '%s'"),
 
1666
                  (actual_error ? session->main_da.message() :
 
1667
                   _("unexpected success or fatal error")),
 
1668
                      print_slave_db_safe(session->db), query_arg);
 
1669
      session->is_slave_error= 1;
2337
1670
    }
2338
1671
 
2339
1672
    /*
2341
1674
      like:
2342
1675
      if ((uint32_t) affected_in_event != (uint32_t) affected_on_slave)
2343
1676
      {
2344
 
      sql_print_error("Slave: did not get the expected number of affected \
 
1677
      errmsg_printf(ERRMSG_LVL_ERROR, "Slave: did not get the expected number of affected \
2345
1678
      rows running query from master - expected %d, got %d (this numbers \
2346
1679
      should have matched modulo 4294967296).", 0, ...);
2347
 
      thd->is_slave_error = 1;
 
1680
      session->is_slave_error = 1;
2348
1681
      }
2349
1682
      We may also want an option to tell the slave to ignore "affected"
2350
1683
      mismatch. This mismatch could be implemented with a new ER_ code, and
2360
1693
  } /* End of if (db_ok(... */
2361
1694
 
2362
1695
end:
2363
 
  VOID(pthread_mutex_lock(&LOCK_thread_count));
 
1696
  pthread_mutex_lock(&LOCK_thread_count);
2364
1697
  /*
2365
 
    Probably we have set thd->query, thd->db, thd->catalog to point to places
 
1698
    Probably we have set session->query, session->db, session->catalog to point to places
2366
1699
    in the data_buf of this event. Now the event is going to be deleted
2367
 
    probably, so data_buf will be freed, so the thd->... listed above will be
2368
 
    pointers to freed memory. 
 
1700
    probably, so data_buf will be freed, so the session->... listed above will be
 
1701
    pointers to freed memory.
2369
1702
    So we must set them to 0, so that those bad pointers values are not later
2370
 
    used. Note that "cleanup" queries like automatic DROP TEMPORARY TABLE
 
1703
    used. Note that "cleanup" queries like automatic DROP TEMPORARY Table
2371
1704
    don't suffer from these assignments to 0 as DROP TEMPORARY
2372
 
    TABLE uses the db.table syntax.
2373
 
  */
2374
 
  thd->catalog= 0;
2375
 
  thd->set_db(NULL, 0);                 /* will free the current database */
2376
 
  thd->query= 0;                        // just to be sure
2377
 
  thd->query_length= 0;
2378
 
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
2379
 
  close_thread_tables(thd);      
2380
 
  /*
2381
 
    As a disk space optimization, future masters will not log an event for
2382
 
    LAST_INSERT_ID() if that function returned 0 (and thus they will be able
2383
 
    to replace the THD::stmt_depends_on_first_successful_insert_id_in_prev_stmt
2384
 
    variable by (THD->first_successful_insert_id_in_prev_stmt > 0) ; with the
2385
 
    resetting below we are ready to support that.
2386
 
  */
2387
 
  thd->first_successful_insert_id_in_prev_stmt_for_binlog= 0;
2388
 
  thd->first_successful_insert_id_in_prev_stmt= 0;
2389
 
  thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 0;
2390
 
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
2391
 
  return thd->is_slave_error;
 
1705
    Table uses the db.table syntax.
 
1706
  */
 
1707
  session->catalog= 0;
 
1708
  session->set_db(NULL, 0);                 /* will free the current database */
 
1709
  session->query= 0;                    // just to be sure
 
1710
  session->query_length= 0;
 
1711
  pthread_mutex_unlock(&LOCK_thread_count);
 
1712
  close_thread_tables(session);
 
1713
  session->first_successful_insert_id_in_prev_stmt= 0;
 
1714
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
 
1715
  return session->is_slave_error;
2392
1716
}
2393
1717
 
2394
1718
int Query_log_event::do_update_pos(Relay_log_info *rli)
2395
1719
{
2396
 
  /*
2397
 
    Note that we will not increment group* positions if we are just
2398
 
    after a SET ONE_SHOT, because SET ONE_SHOT should not be separated
2399
 
    from its following updating query.
2400
 
  */
2401
 
  if (thd->one_shot_set)
2402
 
  {
2403
 
    rli->inc_event_relay_log_pos();
2404
 
    return 0;
2405
 
  }
2406
 
  else
2407
 
    return Log_event::do_update_pos(rli);
 
1720
  return Log_event::do_update_pos(rli);
2408
1721
}
2409
1722
 
2410
1723
 
2417
1730
  {
2418
1731
    if (strcmp("BEGIN", query) == 0)
2419
1732
    {
2420
 
      thd->options|= OPTION_BEGIN;
 
1733
      session->options|= OPTION_BEGIN;
2421
1734
      return(Log_event::continue_group(rli));
2422
1735
    }
2423
1736
 
2424
1737
    if (strcmp("COMMIT", query) == 0 || strcmp("ROLLBACK", query) == 0)
2425
1738
    {
2426
 
      thd->options&= ~OPTION_BEGIN;
 
1739
      session->options&= ~OPTION_BEGIN;
2427
1740
      return(Log_event::EVENT_SKIP_COUNT);
2428
1741
    }
2429
1742
  }
2430
1743
  return(Log_event::do_shall_skip(rli));
2431
1744
}
2432
1745
 
2433
 
#endif
2434
 
 
2435
1746
 
2436
1747
/**************************************************************************
2437
1748
        Start_log_event_v3 methods
2438
1749
**************************************************************************/
2439
1750
 
2440
 
#ifndef DRIZZLE_CLIENT
2441
1751
Start_log_event_v3::Start_log_event_v3()
2442
1752
  :Log_event(), created(0), binlog_version(BINLOG_VERSION),
2443
1753
   artificial_event(0), dont_set_created(0)
2444
1754
{
2445
1755
  memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2446
1756
}
2447
 
#endif
2448
1757
 
2449
1758
/*
2450
1759
  Start_log_event_v3::pack_info()
2451
1760
*/
2452
1761
 
2453
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
2454
1762
void Start_log_event_v3::pack_info(Protocol *protocol)
2455
1763
{
2456
1764
  char buf[12 + ST_SERVER_VER_LEN + 14 + 22], *pos;
2457
 
  pos= stpcpy(buf, "Server ver: ");
2458
 
  pos= stpcpy(pos, server_version);
2459
 
  pos= stpcpy(pos, ", Binlog ver: ");
 
1765
  pos= strcpy(buf, "Server ver: ")+12;
 
1766
  pos= strcpy(pos, server_version)+strlen(server_version);
 
1767
  pos= strcpy(pos, ", Binlog ver: ")+14;
2460
1768
  pos= int10_to_str(binlog_version, pos, 10);
2461
1769
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
2462
1770
}
2463
 
#endif
2464
 
 
2465
 
 
2466
 
/*
2467
 
  Start_log_event_v3::print()
2468
 
*/
2469
 
 
2470
 
#ifdef DRIZZLE_CLIENT
2471
 
void Start_log_event_v3::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
2472
 
{
2473
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
2474
 
                               Write_on_release_cache::FLUSH_F);
2475
 
 
2476
 
  if (!print_event_info->short_form)
2477
 
  {
2478
 
    print_header(&cache, print_event_info, false);
2479
 
    my_b_printf(&cache, "\tStart: binlog v %d, server v %s created ",
2480
 
                binlog_version, server_version);
2481
 
    print_timestamp(&cache);
2482
 
    if (created)
2483
 
      my_b_printf(&cache," at startup");
2484
 
    my_b_printf(&cache, "\n");
2485
 
    if (flags & LOG_EVENT_BINLOG_IN_USE_F)
2486
 
      my_b_printf(&cache, "# Warning: this binlog was not closed properly. "
2487
 
                  "Most probably mysqld crashed writing it.\n");
2488
 
  }
2489
 
  if (!artificial_event && created)
2490
 
  {
2491
 
#ifdef WHEN_WE_HAVE_THE_RESET_CONNECTION_SQL_COMMAND
2492
 
    /*
2493
 
      This is for mysqlbinlog: like in replication, we want to delete the stale
2494
 
      tmp files left by an unclean shutdown of mysqld (temporary tables)
2495
 
      and rollback unfinished transaction.
2496
 
      Probably this can be done with RESET CONNECTION (syntax to be defined).
2497
 
    */
2498
 
    my_b_printf(&cache,"RESET CONNECTION%s\n", print_event_info->delimiter);
2499
 
#else
2500
 
    my_b_printf(&cache,"ROLLBACK%s\n", print_event_info->delimiter);
2501
 
#endif
2502
 
  }
2503
 
  if (temp_buf &&
2504
 
      print_event_info->base64_output_mode != BASE64_OUTPUT_NEVER &&
2505
 
      !print_event_info->short_form)
2506
 
  {
2507
 
    my_b_printf(&cache, "BINLOG '\n");
2508
 
    print_base64(&cache, print_event_info, false);
2509
 
    print_event_info->printed_fd_event= true;
2510
 
  }
2511
 
  return;
2512
 
}
2513
 
#endif /* DRIZZLE_CLIENT */
 
1771
 
2514
1772
 
2515
1773
/*
2516
1774
  Start_log_event_v3::Start_log_event_v3()
2538
1796
  Start_log_event_v3::write()
2539
1797
*/
2540
1798
 
2541
 
#ifndef DRIZZLE_CLIENT
2542
1799
bool Start_log_event_v3::write(IO_CACHE* file)
2543
1800
{
2544
1801
  char buff[START_V3_HEADER_LEN];
2548
1805
    created= when= get_time();
2549
1806
  int4store(buff + ST_CREATED_OFFSET,created);
2550
1807
  return (write_header(file, sizeof(buff)) ||
2551
 
          my_b_safe_write(file, (uchar*) buff, sizeof(buff)));
 
1808
          my_b_safe_write(file, (unsigned char*) buff, sizeof(buff)));
2552
1809
}
2553
 
#endif
2554
 
 
2555
 
 
2556
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
1810
 
2557
1811
 
2558
1812
/**
2559
1813
  Start_log_event_v3::do_apply_event() .
2561
1815
 
2562
1816
    IMPLEMENTATION
2563
1817
    - To handle the case where the master died without having time to write
2564
 
    DROP TEMPORARY TABLE, DO RELEASE_LOCK (prepared statements' deletion is
 
1818
    DROP TEMPORARY Table, DO RELEASE_LOCK (prepared statements' deletion is
2565
1819
    TODO), we clean up all temporary tables that we got, if we are sure we
2566
1820
    can (see below).
2567
1821
 
2587
1841
    */
2588
1842
    if (created)
2589
1843
    {
2590
 
      close_temporary_tables(thd);
 
1844
      close_temporary_tables(session);
2591
1845
      cleanup_load_tmpdir();
2592
1846
    }
2593
1847
    break;
2604
1858
        Can distinguish, based on the value of 'created': this event was
2605
1859
        generated at master startup.
2606
1860
      */
2607
 
      close_temporary_tables(thd);
 
1861
      close_temporary_tables(session);
2608
1862
    }
2609
1863
    /*
2610
1864
      Otherwise, can't distinguish a Start_log_event generated at
2618
1872
  }
2619
1873
  return(0);
2620
1874
}
2621
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
2622
1875
 
2623
1876
/***************************************************************************
2624
1877
       Format_description_log_event methods
2641
1894
*/
2642
1895
 
2643
1896
Format_description_log_event::
2644
 
Format_description_log_event(uint8_t binlog_ver, const char* server_ver)
 
1897
Format_description_log_event(uint8_t binlog_ver, const char*)
2645
1898
  :Start_log_event_v3(), event_type_permutation(0)
2646
1899
{
2647
1900
  binlog_version= binlog_ver;
2650
1903
    memcpy(server_version, ::server_version, ST_SERVER_VER_LEN);
2651
1904
    common_header_len= LOG_EVENT_HEADER_LEN;
2652
1905
    number_of_event_types= LOG_EVENT_TYPES;
2653
 
    /* we'll catch my_malloc() error in is_valid() */
2654
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
2655
 
                                       MYF(MY_ZEROFILL));
 
1906
    /* we'll catch malloc() error in is_valid() */
 
1907
    post_header_len=(uint8_t*) malloc(number_of_event_types*sizeof(uint8_t));
 
1908
    memset(post_header_len, 0, number_of_event_types*sizeof(uint8_t));
2656
1909
    /*
2657
1910
      This long list of assignments is not beautiful, but I see no way to
2658
1911
      make it nicer, as the right members are #defines, not array members, so
2681
1934
    }
2682
1935
    break;
2683
1936
 
2684
 
  case 1: /* 3.23 */
2685
 
  case 3: /* 4.0.x x>=2 */
2686
 
    /*
2687
 
      We build an artificial (i.e. not sent by the master) event, which
2688
 
      describes what those old master versions send.
2689
 
    */
2690
 
    if (binlog_ver==1)
2691
 
      stpcpy(server_version, server_ver ? server_ver : "3.23");
2692
 
    else
2693
 
      stpcpy(server_version, server_ver ? server_ver : "4.0");
2694
 
    common_header_len= binlog_ver==1 ? OLD_HEADER_LEN :
2695
 
      LOG_EVENT_MINIMAL_HEADER_LEN;
2696
 
    /*
2697
 
      The first new event in binlog version 4 is Format_desc. So any event type
2698
 
      after that does not exist in older versions. We use the events known by
2699
 
      version 3, even if version 1 had only a subset of them (this is not a
2700
 
      problem: it uses a few bytes for nothing but unifies code; it does not
2701
 
      make the slave detect less corruptions).
2702
 
    */
2703
 
    number_of_event_types= FORMAT_DESCRIPTION_EVENT - 1;
2704
 
    post_header_len=(uint8_t*) my_malloc(number_of_event_types*sizeof(uint8_t),
2705
 
                                       MYF(0));
2706
 
    if (post_header_len)
2707
 
    {
2708
 
      post_header_len[START_EVENT_V3-1]= START_V3_HEADER_LEN;
2709
 
      post_header_len[QUERY_EVENT-1]= QUERY_HEADER_MINIMAL_LEN;
2710
 
      post_header_len[STOP_EVENT-1]= 0;
2711
 
      post_header_len[ROTATE_EVENT-1]= (binlog_ver==1) ? 0 : ROTATE_HEADER_LEN;
2712
 
      post_header_len[INTVAR_EVENT-1]= 0;
2713
 
      post_header_len[LOAD_EVENT-1]= LOAD_HEADER_LEN;
2714
 
      post_header_len[SLAVE_EVENT-1]= 0;
2715
 
      post_header_len[CREATE_FILE_EVENT-1]= CREATE_FILE_HEADER_LEN;
2716
 
      post_header_len[APPEND_BLOCK_EVENT-1]= APPEND_BLOCK_HEADER_LEN;
2717
 
      post_header_len[EXEC_LOAD_EVENT-1]= EXEC_LOAD_HEADER_LEN;
2718
 
      post_header_len[DELETE_FILE_EVENT-1]= DELETE_FILE_HEADER_LEN;
2719
 
      post_header_len[NEW_LOAD_EVENT-1]= post_header_len[LOAD_EVENT-1];
2720
 
      post_header_len[RAND_EVENT-1]= 0;
2721
 
      post_header_len[USER_VAR_EVENT-1]= 0;
2722
 
    }
2723
 
    break;
2724
1937
  default: /* Includes binlog version 2 i.e. 4.0.x x<=1 */
2725
 
    post_header_len= 0; /* will make is_valid() fail */
2726
 
    break;
 
1938
    assert(0);
2727
1939
  }
2728
1940
  calc_server_version_split();
2729
1941
}
2749
1961
 
2750
1962
Format_description_log_event::
2751
1963
Format_description_log_event(const char* buf,
2752
 
                             uint event_len,
 
1964
                             uint32_t event_len,
2753
1965
                             const
2754
1966
                             Format_description_log_event*
2755
1967
                             description_event)
2760
1972
    return; /* sanity check */
2761
1973
  number_of_event_types=
2762
1974
    event_len-(LOG_EVENT_MINIMAL_HEADER_LEN+ST_COMMON_HEADER_LEN_OFFSET+1);
 
1975
  post_header_len= (uint8_t*) malloc(number_of_event_types*
 
1976
                                     sizeof(*post_header_len));
2763
1977
  /* If alloc fails, we'll detect it in is_valid() */
2764
 
  post_header_len= (uint8_t*) my_memdup((uchar*)buf+ST_COMMON_HEADER_LEN_OFFSET+1,
2765
 
                                      number_of_event_types*
2766
 
                                      sizeof(*post_header_len), MYF(0));
 
1978
  if (post_header_len != NULL)
 
1979
    memcpy(post_header_len, buf+ST_COMMON_HEADER_LEN_OFFSET+1,
 
1980
           number_of_event_types* sizeof(*post_header_len));
2767
1981
  calc_server_version_split();
2768
1982
 
2769
1983
  /*
2836
2050
    if (number_of_event_types != 22)
2837
2051
    {
2838
2052
      /* this makes is_valid() return false. */
2839
 
      my_free(post_header_len, MYF(MY_ALLOW_ZERO_PTR));
 
2053
      free(post_header_len);
2840
2054
      post_header_len= NULL;
2841
2055
      return;
2842
2056
    }
2843
2057
    static const uint8_t perm[23]=
2844
2058
      {
2845
2059
        UNKNOWN_EVENT, START_EVENT_V3, QUERY_EVENT, STOP_EVENT, ROTATE_EVENT,
2846
 
        INTVAR_EVENT, LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
 
2060
        LOAD_EVENT, SLAVE_EVENT, CREATE_FILE_EVENT,
2847
2061
        APPEND_BLOCK_EVENT, EXEC_LOAD_EVENT, DELETE_FILE_EVENT,
2848
2062
        NEW_LOAD_EVENT,
2849
 
        RAND_EVENT, USER_VAR_EVENT,
2850
2063
        FORMAT_DESCRIPTION_EVENT,
2851
2064
        TABLE_MAP_EVENT,
2852
 
        PRE_GA_WRITE_ROWS_EVENT,
2853
 
        PRE_GA_UPDATE_ROWS_EVENT,
2854
 
        PRE_GA_DELETE_ROWS_EVENT,
2855
2065
        XID_EVENT,
2856
2066
        BEGIN_LOAD_QUERY_EVENT,
2857
2067
        EXECUTE_LOAD_QUERY_EVENT,
2870
2080
  return;
2871
2081
}
2872
2082
 
2873
 
#ifndef DRIZZLE_CLIENT
2874
2083
bool Format_description_log_event::write(IO_CACHE* file)
2875
2084
{
2876
2085
  /*
2877
2086
    We don't call Start_log_event_v3::write() because this would make 2
2878
2087
    my_b_safe_write().
2879
2088
  */
2880
 
  uchar buff[FORMAT_DESCRIPTION_HEADER_LEN];
 
2089
  unsigned char buff[FORMAT_DESCRIPTION_HEADER_LEN];
2881
2090
  int2store(buff + ST_BINLOG_VER_OFFSET,binlog_version);
2882
2091
  memcpy(buff + ST_SERVER_VER_OFFSET,server_version,ST_SERVER_VER_LEN);
2883
2092
  if (!dont_set_created)
2889
2098
  return (write_header(file, sizeof(buff)) ||
2890
2099
          my_b_safe_write(file, buff, sizeof(buff)));
2891
2100
}
2892
 
#endif
2893
 
 
2894
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
2101
 
 
2102
 
2895
2103
int Format_description_log_event::do_apply_event(Relay_log_info const *rli)
2896
2104
{
2897
2105
  /*
2905
2113
    original place when it comes to us; we'll know this by checking
2906
2114
    log_pos ("artificial" events have log_pos == 0).
2907
2115
  */
2908
 
  if (!artificial_event && created && thd->transaction.all.ha_list)
 
2116
  if (!artificial_event && created && session->transaction.all.ha_list)
2909
2117
  {
2910
2118
    /* This is not an error (XA is safe), just an information */
2911
2119
    rli->report(INFORMATION_LEVEL, 0,
2912
 
                "Rolling back unfinished transaction (no COMMIT "
2913
 
                "or ROLLBACK in relay log). A probable cause is that "
2914
 
                "the master died while writing the transaction to "
2915
 
                "its binary log, thus rolled back too."); 
2916
 
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, 1);
 
2120
                _("Rolling back unfinished transaction (no COMMIT "
 
2121
                  "or ROLLBACK in relay log). A probable cause is that "
 
2122
                  "the master died while writing the transaction to "
 
2123
                  "its binary log, thus rolled back too."));
 
2124
    const_cast<Relay_log_info*>(rli)->cleanup_context(session, 1);
2917
2125
  }
2918
2126
  /*
2919
2127
    If this event comes from ourselves, there is no cleaning task to
2920
2128
    perform, we don't call Start_log_event_v3::do_apply_event()
2921
2129
    (this was just to update the log's description event).
2922
2130
  */
2923
 
  if (server_id != (uint32_t) ::server_id)
 
2131
  if (server_id != ::server_id)
2924
2132
  {
2925
2133
    /*
2926
2134
      If the event was not requested by the slave i.e. the master sent
2942
2150
  delete rli->relay_log.description_event_for_exec;
2943
2151
  rli->relay_log.description_event_for_exec= this;
2944
2152
 
2945
 
  if (server_id == (uint32_t) ::server_id)
 
2153
  if (server_id == ::server_id)
2946
2154
  {
2947
2155
    /*
2948
2156
      We only increase the relay log position if we are skipping
2967
2175
}
2968
2176
 
2969
2177
Log_event::enum_skip_reason
2970
 
Format_description_log_event::do_shall_skip(Relay_log_info *rli __attribute__((unused)))
 
2178
Format_description_log_event::do_shall_skip(Relay_log_info *)
2971
2179
{
2972
2180
  return Log_event::EVENT_SKIP_NOT;
2973
2181
}
2974
2182
 
2975
 
#endif
2976
 
 
2977
2183
 
2978
2184
/**
2979
2185
   Splits the event's 'server_version' string into three numeric pieces stored
2988
2194
{
2989
2195
  char *p= server_version, *r;
2990
2196
  ulong number;
2991
 
  for (uint i= 0; i<=2; i++)
 
2197
  for (uint32_t i= 0; i<=2; i++)
2992
2198
  {
2993
2199
    number= strtoul(p, &r, 10);
2994
 
    server_version_split[i]= (uchar)number;
2995
 
    assert(number < 256); // fit in uchar
 
2200
    server_version_split[i]= (unsigned char)number;
 
2201
    assert(number < 256); // fit in unsigned char
2996
2202
    p= r;
2997
2203
    assert(!((i == 0) && (*r != '.'))); // should be true in practice
2998
2204
    if (*r == '.')
3022
2228
  Load_log_event::pack_info()
3023
2229
*/
3024
2230
 
3025
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3026
 
uint Load_log_event::get_query_buffer_length()
 
2231
uint32_t Load_log_event::get_query_buffer_length()
3027
2232
{
3028
2233
  return
3029
2234
    5 + db_len + 3 +                        // "use DB; "
3030
2235
    18 + fname_len + 2 +                    // "LOAD DATA INFILE 'file''"
3031
2236
    7 +                                     // LOCAL
3032
2237
    9 +                                     // " REPLACE or IGNORE "
3033
 
    13 + table_name_len*2 +                 // "INTO TABLE `table`"
 
2238
    13 + table_name_len*2 +                 // "INTO Table `table`"
3034
2239
    21 + sql_ex.field_term_len*4 + 2 +      // " FIELDS TERMINATED BY 'str'"
3035
2240
    23 + sql_ex.enclosed_len*4 + 2 +        // " OPTIONALLY ENCLOSED BY 'str'"
3036
2241
    12 + sql_ex.escaped_len*4 + 2 +         // " ESCAPED BY 'str'"
3048
2253
 
3049
2254
  if (need_db && db && db_len)
3050
2255
  {
3051
 
    pos= stpcpy(pos, "use `");
 
2256
    pos= strcpy(pos, "use `")+5;
3052
2257
    memcpy(pos, db, db_len);
3053
 
    pos= stpcpy(pos+db_len, "`; ");
 
2258
    pos= strcpy(pos+db_len, "`; ")+3;
3054
2259
  }
3055
2260
 
3056
 
  pos= stpcpy(pos, "LOAD DATA ");
 
2261
  pos= strcpy(pos, "LOAD DATA ")+10;
3057
2262
 
3058
2263
  if (fn_start)
3059
2264
    *fn_start= pos;
3060
2265
 
3061
2266
  if (check_fname_outside_temp_buf())
3062
 
    pos= stpcpy(pos, "LOCAL ");
3063
 
  pos= stpcpy(pos, "INFILE '");
 
2267
    pos= strcpy(pos, "LOCAL ")+6;
 
2268
  pos= strcpy(pos, "INFILE '")+8;
3064
2269
  memcpy(pos, fname, fname_len);
3065
 
  pos= stpcpy(pos+fname_len, "' ");
 
2270
  pos= strcpy(pos+fname_len, "' ")+2;
3066
2271
 
3067
2272
  if (sql_ex.opt_flags & REPLACE_FLAG)
3068
 
    pos= stpcpy(pos, " REPLACE ");
 
2273
    pos= strcpy(pos, " REPLACE ")+9;
3069
2274
  else if (sql_ex.opt_flags & IGNORE_FLAG)
3070
 
    pos= stpcpy(pos, " IGNORE ");
 
2275
    pos= strcpy(pos, " IGNORE ")+8;
3071
2276
 
3072
 
  pos= stpcpy(pos ,"INTO");
 
2277
  pos= strcpy(pos ,"INTO")+4;
3073
2278
 
3074
2279
  if (fn_end)
3075
2280
    *fn_end= pos;
3076
2281
 
3077
 
  pos= stpcpy(pos ," TABLE `");
 
2282
  pos= strcpy(pos ," Table `")+8;
3078
2283
  memcpy(pos, table_name, table_name_len);
3079
2284
  pos+= table_name_len;
3080
2285
 
3081
2286
  /* We have to create all optinal fields as the default is not empty */
3082
 
  pos= stpcpy(pos, "` FIELDS TERMINATED BY ");
 
2287
  pos= strcpy(pos, "` FIELDS TERMINATED BY ")+23;
3083
2288
  pos= pretty_print_str(pos, sql_ex.field_term, sql_ex.field_term_len);
3084
2289
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3085
 
    pos= stpcpy(pos, " OPTIONALLY ");
3086
 
  pos= stpcpy(pos, " ENCLOSED BY ");
 
2290
    pos= strcpy(pos, " OPTIONALLY ")+12;
 
2291
  pos= strcpy(pos, " ENCLOSED BY ")+13;
3087
2292
  pos= pretty_print_str(pos, sql_ex.enclosed, sql_ex.enclosed_len);
3088
2293
 
3089
 
  pos= stpcpy(pos, " ESCAPED BY ");
 
2294
  pos= strcpy(pos, " ESCAPED BY ")+12;
3090
2295
  pos= pretty_print_str(pos, sql_ex.escaped, sql_ex.escaped_len);
3091
2296
 
3092
 
  pos= stpcpy(pos, " LINES TERMINATED BY ");
 
2297
  pos= strcpy(pos, " LINES TERMINATED BY ")+21;
3093
2298
  pos= pretty_print_str(pos, sql_ex.line_term, sql_ex.line_term_len);
3094
2299
  if (sql_ex.line_start_len)
3095
2300
  {
3096
 
    pos= stpcpy(pos, " STARTING BY ");
 
2301
    pos= strcpy(pos, " STARTING BY ")+13;
3097
2302
    pos= pretty_print_str(pos, sql_ex.line_start, sql_ex.line_start_len);
3098
2303
  }
3099
2304
 
3100
2305
  if ((long) skip_lines > 0)
3101
2306
  {
3102
 
    pos= stpcpy(pos, " IGNORE ");
 
2307
    pos= strcpy(pos, " IGNORE ")+8;
3103
2308
    pos= int64_t10_to_str((int64_t) skip_lines, pos, 10);
3104
 
    pos= stpcpy(pos," LINES ");    
 
2309
    pos= strcpy(pos," LINES ")+7;
3105
2310
  }
3106
2311
 
3107
2312
  if (num_fields)
3108
2313
  {
3109
 
    uint i;
 
2314
    uint32_t i;
3110
2315
    const char *field= fields;
3111
 
    pos= stpcpy(pos, " (");
 
2316
    pos= strcpy(pos, " (")+2;
3112
2317
    for (i = 0; i < num_fields; i++)
3113
2318
    {
3114
2319
      if (i)
3131
2336
{
3132
2337
  char *buf, *end;
3133
2338
 
3134
 
  if (!(buf= (char*) my_malloc(get_query_buffer_length(), MYF(MY_WME))))
 
2339
  if (!(buf= (char*) malloc(get_query_buffer_length())))
3135
2340
    return;
3136
2341
  print_query(true, buf, &end, 0, 0);
3137
2342
  protocol->store(buf, end-buf, &my_charset_bin);
3138
 
  my_free(buf, MYF(0));
 
2343
  free(buf);
3139
2344
}
3140
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
3141
 
 
3142
 
 
3143
 
#ifndef DRIZZLE_CLIENT
 
2345
 
3144
2346
 
3145
2347
/*
3146
2348
  Load_log_event::write_data_header()
3155
2357
  buf[L_TBL_LEN_OFFSET] = (char)table_name_len;
3156
2358
  buf[L_DB_LEN_OFFSET] = (char)db_len;
3157
2359
  int4store(buf + L_NUM_FIELDS_OFFSET, num_fields);
3158
 
  return my_b_safe_write(file, (uchar*)buf, LOAD_HEADER_LEN) != 0;
 
2360
  return my_b_safe_write(file, (unsigned char*)buf, LOAD_HEADER_LEN) != 0;
3159
2361
}
3160
2362
 
3161
2363
 
3169
2371
    return 1;
3170
2372
  if (num_fields && fields && field_lens)
3171
2373
  {
3172
 
    if (my_b_safe_write(file, (uchar*)field_lens, num_fields) ||
3173
 
        my_b_safe_write(file, (uchar*)fields, field_block_len))
 
2374
    if (my_b_safe_write(file, (unsigned char*)field_lens, num_fields) ||
 
2375
        my_b_safe_write(file, (unsigned char*)fields, field_block_len))
3174
2376
      return 1;
3175
2377
  }
3176
 
  return (my_b_safe_write(file, (uchar*)table_name, table_name_len + 1) ||
3177
 
          my_b_safe_write(file, (uchar*)db, db_len + 1) ||
3178
 
          my_b_safe_write(file, (uchar*)fname, fname_len));
 
2378
  return (my_b_safe_write(file, (unsigned char*)table_name, table_name_len + 1) ||
 
2379
          my_b_safe_write(file, (unsigned char*)db, db_len + 1) ||
 
2380
          my_b_safe_write(file, (unsigned char*)fname, fname_len));
3179
2381
}
3180
2382
 
3181
2383
 
3183
2385
  Load_log_event::Load_log_event()
3184
2386
*/
3185
2387
 
3186
 
Load_log_event::Load_log_event(THD *thd_arg, sql_exchange *ex,
 
2388
Load_log_event::Load_log_event(Session *session_arg, sql_exchange *ex,
3187
2389
                               const char *db_arg, const char *table_name_arg,
3188
2390
                               List<Item> &fields_arg,
3189
2391
                               enum enum_duplicates handle_dup,
3190
2392
                               bool ignore, bool using_trans)
3191
 
  :Log_event(thd_arg,
3192
 
             thd_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
 
2393
  :Log_event(session_arg,
 
2394
             session_arg->thread_specific_used ? LOG_EVENT_THREAD_SPECIFIC_F : 0,
3193
2395
             using_trans),
3194
 
   thread_id(thd_arg->thread_id),
3195
 
   slave_proxy_id(thd_arg->variables.pseudo_thread_id),
 
2396
   thread_id(session_arg->thread_id),
 
2397
   slave_proxy_id(session_arg->variables.pseudo_thread_id),
3196
2398
   num_fields(0),fields(0),
3197
2399
   field_lens(0),field_block_len(0),
3198
2400
   table_name(table_name_arg ? table_name_arg : ""),
3200
2402
{
3201
2403
  time_t end_time;
3202
2404
  time(&end_time);
3203
 
  exec_time = (ulong) (end_time  - thd_arg->start_time);
 
2405
  exec_time = (ulong) (end_time  - session_arg->start_time);
3204
2406
  /* db can never be a zero pointer in 4.0 */
3205
2407
  db_len = (uint32_t) strlen(db);
3206
2408
  table_name_len = (uint32_t) strlen(table_name);
3217
2419
  sql_ex.escaped_len = (uint8_t) ex->escaped->length();
3218
2420
  sql_ex.opt_flags = 0;
3219
2421
  sql_ex.cached_new_format = -1;
3220
 
    
 
2422
 
3221
2423
  if (ex->dumpfile)
3222
2424
    sql_ex.opt_flags|= DUMPFILE_FLAG;
3223
2425
  if (ex->opt_enclosed)
3231
2433
    break;
3232
2434
  case DUP_UPDATE:                              // Impossible here
3233
2435
  case DUP_ERROR:
3234
 
    break;      
 
2436
    break;
3235
2437
  }
3236
2438
  if (ignore)
3237
2439
    sql_ex.opt_flags|= IGNORE_FLAG;
3246
2448
    sql_ex.empty_flags |= LINE_START_EMPTY;
3247
2449
  if (!ex->escaped->length())
3248
2450
    sql_ex.empty_flags |= ESCAPED_EMPTY;
3249
 
    
 
2451
 
3250
2452
  skip_lines = ex->skip_lines;
3251
2453
 
3252
2454
  List_iterator<Item> li(fields_arg);
3256
2458
  while ((item = li++))
3257
2459
  {
3258
2460
    num_fields++;
3259
 
    uchar len = (uchar) strlen(item->name);
 
2461
    unsigned char len = (unsigned char) strlen(item->name);
3260
2462
    field_block_len += len + 1;
3261
2463
    fields_buf.append(item->name, len + 1);
3262
2464
    field_lens_buf.append((char*)&len, 1);
3263
2465
  }
3264
2466
 
3265
 
  field_lens = (const uchar*)field_lens_buf.ptr();
 
2467
  field_lens = (const unsigned char*)field_lens_buf.ptr();
3266
2468
  fields = fields_buf.ptr();
3267
2469
}
3268
 
#endif /* !DRIZZLE_CLIENT */
3269
2470
 
3270
2471
 
3271
2472
/**
3273
2474
    The caller must do buf[event_len] = 0 before he starts using the
3274
2475
    constructed event.
3275
2476
*/
3276
 
Load_log_event::Load_log_event(const char *buf, uint event_len,
 
2477
Load_log_event::Load_log_event(const char *buf, uint32_t event_len,
3277
2478
                               const Format_description_log_event *description_event)
3278
2479
  :Log_event(buf, description_event), num_fields(0), fields(0),
3279
2480
   field_lens(0),field_block_len(0),
3286
2487
  if (event_len)
3287
2488
    copy_log_event(buf, event_len,
3288
2489
                   ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
3289
 
                    LOAD_HEADER_LEN + 
 
2490
                    LOAD_HEADER_LEN +
3290
2491
                    description_event->common_header_len :
3291
2492
                    LOAD_HEADER_LEN + LOG_EVENT_HEADER_LEN),
3292
2493
                   description_event);
3303
2504
                                   int body_offset,
3304
2505
                                   const Format_description_log_event *description_event)
3305
2506
{
3306
 
  uint data_len;
 
2507
  uint32_t data_len;
3307
2508
  char* buf_end = (char*)buf + event_len;
3308
2509
  /* this is the beginning of the post-header */
3309
2510
  const char* data_head = buf + description_event->common_header_len;
3313
2514
  table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
3314
2515
  db_len = (uint)data_head[L_DB_LEN_OFFSET];
3315
2516
  num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
3316
 
          
 
2517
 
3317
2518
  if ((int) event_len < body_offset)
3318
2519
    return(1);
3319
2520
  /*
3320
2521
    Sql_ex.init() on success returns the pointer to the first byte after
3321
2522
    the sql_ex structure, which is the start of field lengths array.
3322
2523
  */
3323
 
  if (!(field_lens= (uchar*)sql_ex.init((char*)buf + body_offset,
 
2524
  if (!(field_lens= (unsigned char*)sql_ex.init((char*)buf + body_offset,
3324
2525
                                        buf_end,
3325
2526
                                        buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
3326
2527
    return(1);
3327
 
  
 
2528
 
3328
2529
  data_len = event_len - body_offset;
3329
2530
  if (num_fields > data_len) // simple sanity check against corruption
3330
2531
    return(1);
3331
 
  for (uint i = 0; i < num_fields; i++)
 
2532
  for (uint32_t i = 0; i < num_fields; i++)
3332
2533
    field_block_len += (uint)field_lens[i] + 1;
3333
2534
 
3334
2535
  fields = (char*)field_lens + num_fields;
3342
2543
}
3343
2544
 
3344
2545
 
3345
 
/*
3346
 
  Load_log_event::print()
3347
 
*/
3348
 
 
3349
 
#ifdef DRIZZLE_CLIENT
3350
 
void Load_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3351
 
{
3352
 
  print(file, print_event_info, 0);
3353
 
}
3354
 
 
3355
 
 
3356
 
void Load_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info,
3357
 
                           bool commented)
3358
 
{
3359
 
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
3360
 
 
3361
 
  if (!print_event_info->short_form)
3362
 
  {
3363
 
    print_header(&cache, print_event_info, false);
3364
 
    my_b_printf(&cache, "\tQuery\tthread_id=%ld\texec_time=%ld\n",
3365
 
                thread_id, exec_time);
3366
 
  }
3367
 
 
3368
 
  bool different_db= 1;
3369
 
  if (db)
3370
 
  {
3371
 
    /*
3372
 
      If the database is different from the one of the previous statement, we
3373
 
      need to print the "use" command, and we update the last_db.
3374
 
      But if commented, the "use" is going to be commented so we should not
3375
 
      update the last_db.
3376
 
    */
3377
 
    if ((different_db= memcmp(print_event_info->db, db, db_len + 1)) &&
3378
 
        !commented)
3379
 
      memcpy(print_event_info->db, db, db_len + 1);
3380
 
  }
3381
 
  
3382
 
  if (db && db[0] && different_db)
3383
 
    my_b_printf(&cache, "%suse %s%s\n", 
3384
 
            commented ? "# " : "",
3385
 
            db, print_event_info->delimiter);
3386
 
 
3387
 
  if (flags & LOG_EVENT_THREAD_SPECIFIC_F)
3388
 
    my_b_printf(&cache,"%sSET @@session.pseudo_thread_id=%lu%s\n",
3389
 
            commented ? "# " : "", (ulong)thread_id,
3390
 
            print_event_info->delimiter);
3391
 
  my_b_printf(&cache, "%sLOAD DATA ",
3392
 
              commented ? "# " : "");
3393
 
  if (check_fname_outside_temp_buf())
3394
 
    my_b_printf(&cache, "LOCAL ");
3395
 
  my_b_printf(&cache, "INFILE '%-*s' ", fname_len, fname);
3396
 
 
3397
 
  if (sql_ex.opt_flags & REPLACE_FLAG)
3398
 
    my_b_printf(&cache," REPLACE ");
3399
 
  else if (sql_ex.opt_flags & IGNORE_FLAG)
3400
 
    my_b_printf(&cache," IGNORE ");
3401
 
  
3402
 
  my_b_printf(&cache, "INTO TABLE `%s`", table_name);
3403
 
  my_b_printf(&cache, " FIELDS TERMINATED BY ");
3404
 
  pretty_print_str(&cache, sql_ex.field_term, sql_ex.field_term_len);
3405
 
 
3406
 
  if (sql_ex.opt_flags & OPT_ENCLOSED_FLAG)
3407
 
    my_b_printf(&cache," OPTIONALLY ");
3408
 
  my_b_printf(&cache, " ENCLOSED BY ");
3409
 
  pretty_print_str(&cache, sql_ex.enclosed, sql_ex.enclosed_len);
3410
 
     
3411
 
  my_b_printf(&cache, " ESCAPED BY ");
3412
 
  pretty_print_str(&cache, sql_ex.escaped, sql_ex.escaped_len);
3413
 
     
3414
 
  my_b_printf(&cache," LINES TERMINATED BY ");
3415
 
  pretty_print_str(&cache, sql_ex.line_term, sql_ex.line_term_len);
3416
 
 
3417
 
 
3418
 
  if (sql_ex.line_start)
3419
 
  {
3420
 
    my_b_printf(&cache," STARTING BY ");
3421
 
    pretty_print_str(&cache, sql_ex.line_start, sql_ex.line_start_len);
3422
 
  }
3423
 
  if ((long) skip_lines > 0)
3424
 
    my_b_printf(&cache, " IGNORE %ld LINES", (long) skip_lines);
3425
 
 
3426
 
  if (num_fields)
3427
 
  {
3428
 
    uint i;
3429
 
    const char* field = fields;
3430
 
    my_b_printf(&cache, " (");
3431
 
    for (i = 0; i < num_fields; i++)
3432
 
    {
3433
 
      if (i)
3434
 
        my_b_printf(&cache, ",");
3435
 
      my_b_printf(&cache, field);
3436
 
          
3437
 
      field += field_lens[i]  + 1;
3438
 
    }
3439
 
    my_b_printf(&cache, ")");
3440
 
  }
3441
 
 
3442
 
  my_b_printf(&cache, "%s\n", print_event_info->delimiter);
3443
 
  return;
3444
 
}
3445
 
#endif /* DRIZZLE_CLIENT */
3446
 
 
3447
 
#ifndef DRIZZLE_CLIENT
3448
 
 
3449
2546
/**
3450
2547
  Load_log_event::set_fields()
3451
2548
 
3452
2549
  @note
3453
 
    This function can not use the member variable 
 
2550
    This function can not use the member variable
3454
2551
    for the database, since LOAD DATA INFILE on the slave
3455
2552
    can be for a different database than the current one.
3456
2553
    This is the reason for the affected_db argument to this method.
3457
2554
*/
3458
2555
 
3459
 
void Load_log_event::set_fields(const char* affected_db, 
 
2556
void Load_log_event::set_fields(const char* affected_db,
3460
2557
                                List<Item> &field_list,
3461
2558
                                Name_resolution_context *context)
3462
2559
{
3463
 
  uint i;
 
2560
  uint32_t i;
3464
2561
  const char* field = fields;
3465
2562
  for (i= 0; i < num_fields; i++)
3466
2563
  {
3469
2566
    field+= field_lens[i]  + 1;
3470
2567
  }
3471
2568
}
3472
 
#endif /* !DRIZZLE_CLIENT */
3473
 
 
3474
 
 
3475
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
2569
 
 
2570
 
3476
2571
/**
3477
2572
  Does the data loading job when executing a LOAD DATA on the slave.
3478
2573
 
3505
2600
int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli,
3506
2601
                                   bool use_rli_only_for_errors)
3507
2602
{
3508
 
  LEX_STRING new_db;
3509
 
  new_db.length= db_len;
3510
 
  new_db.str= (char *) rpl_filter->get_rewrite_db(db, &new_db.length);
3511
 
  thd->set_db(new_db.str, new_db.length);
3512
 
  assert(thd->query == 0);
3513
 
  thd->query_length= 0;                         // Should not be needed
3514
 
  thd->is_slave_error= 0;
3515
 
  clear_all_errors(thd, const_cast<Relay_log_info*>(rli));
 
2603
  Query_id &query_id= Query_id::get_query_id();
 
2604
  session->set_db(db, strlen(db));
 
2605
  assert(session->query == 0);
 
2606
  session->query_length= 0;                         // Should not be needed
 
2607
  session->is_slave_error= 0;
 
2608
  clear_all_errors(session, const_cast<Relay_log_info*>(rli));
3516
2609
 
3517
2610
  /* see Query_log_event::do_apply_event() and BUG#13360 */
3518
2611
  assert(!rli->m_table_map.count());
3520
2613
    Usually lex_start() is called by mysql_parse(), but we need it here
3521
2614
    as the present method does not call mysql_parse().
3522
2615
  */
3523
 
  lex_start(thd);
3524
 
  mysql_reset_thd_for_next_command(thd);
 
2616
  lex_start(session);
 
2617
  session->reset_for_next_command();
3525
2618
 
3526
2619
  if (!use_rli_only_for_errors)
3527
2620
  {
3531
2624
    */
3532
2625
    const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
3533
2626
  }
3534
 
 
 
2627
 
3535
2628
   /*
3536
2629
    We test replicate_*_db rules. Note that we have already prepared
3537
2630
    the file to load, even if we are going to ignore and delete it
3555
2648
            ::do_apply_event(), then the companion SET also have so
3556
2649
            we don't need to reset_one_shot_variables().
3557
2650
  */
3558
 
  if (rpl_filter->db_ok(thd->db))
 
2651
  if (1)
3559
2652
  {
3560
 
    thd->set_time((time_t)when);
3561
 
    VOID(pthread_mutex_lock(&LOCK_thread_count));
3562
 
    thd->query_id = next_query_id();
3563
 
    VOID(pthread_mutex_unlock(&LOCK_thread_count));
 
2653
    session->set_time((time_t)when);
 
2654
    session->query_id = query_id.next();
3564
2655
    /*
3565
 
      Initing thd->row_count is not necessary in theory as this variable has no
 
2656
      Initing session->row_count is not necessary in theory as this variable has no
3566
2657
      influence in the case of the slave SQL thread (it is used to generate a
3567
2658
      "data truncated" warning but which is absorbed and never gets to the
3568
2659
      error log); still we init it to avoid a Valgrind message.
3569
2660
    */
3570
 
    drizzle_reset_errors(thd, 0);
 
2661
    drizzle_reset_errors(session, 0);
3571
2662
 
3572
 
    TABLE_LIST tables;
 
2663
    TableList tables;
3573
2664
    memset(&tables, 0, sizeof(tables));
3574
 
    tables.db= thd->strmake(thd->db, thd->db_length);
 
2665
    tables.db= session->strmake(session->db, session->db_length);
3575
2666
    tables.alias = tables.table_name = (char*) table_name;
3576
2667
    tables.lock_type = TL_WRITE;
3577
2668
    tables.updating= 1;
3578
2669
 
3579
 
    // the table will be opened in mysql_load    
3580
 
    if (rpl_filter->is_on() && !rpl_filter->tables_ok(thd->db, &tables))
3581
 
    {
3582
 
      // TODO: this is a bug - this needs to be moved to the I/O thread
3583
 
      if (net)
3584
 
        skip_load_data_infile(net);
3585
 
    }
3586
 
    else
 
2670
    // the table will be opened in mysql_load
3587
2671
    {
3588
2672
      char llbuff[22];
3589
2673
      char *end;
3595
2679
        Forge LOAD DATA INFILE query which will be used in SHOW PROCESS LIST
3596
2680
        and written to slave's binlog if binlogging is on.
3597
2681
      */
3598
 
      if (!(load_data_query= (char *)thd->alloc(get_query_buffer_length() + 1)))
 
2682
      if (!(load_data_query= (char *)session->alloc(get_query_buffer_length() + 1)))
3599
2683
      {
3600
2684
        /*
3601
 
          This will set thd->fatal_error in case of OOM. So we surely will notice
 
2685
          This will set session->fatal_error in case of OOM. So we surely will notice
3602
2686
          that something is wrong.
3603
2687
        */
3604
2688
        goto error;
3605
2689
      }
3606
2690
 
3607
 
      print_query(false, load_data_query, &end, (char **)&thd->lex->fname_start,
3608
 
                  (char **)&thd->lex->fname_end);
 
2691
      print_query(false, load_data_query, &end, (char **)&session->lex->fname_start,
 
2692
                  (char **)&session->lex->fname_end);
3609
2693
      *end= 0;
3610
 
      thd->query_length= end - load_data_query;
3611
 
      thd->query= load_data_query;
 
2694
      session->query_length= end - load_data_query;
 
2695
      session->query= load_data_query;
3612
2696
 
3613
2697
      if (sql_ex.opt_flags & REPLACE_FLAG)
3614
2698
      {
3615
 
        handle_dup= DUP_REPLACE;
 
2699
        handle_dup= DUP_REPLACE;
3616
2700
      }
3617
2701
      else if (sql_ex.opt_flags & IGNORE_FLAG)
3618
2702
      {
3622
2706
      else
3623
2707
      {
3624
2708
        /*
3625
 
          When replication is running fine, if it was DUP_ERROR on the
 
2709
          When replication is running fine, if it was DUP_ERROR on the
3626
2710
          master then we could choose IGNORE here, because if DUP_ERROR
3627
2711
          suceeded on master, and data is identical on the master and slave,
3628
2712
          then there should be no uniqueness errors on slave, so IGNORE is
3629
2713
          the same as DUP_ERROR. But in the unlikely case of uniqueness errors
3630
2714
          (because the data on the master and slave happen to be different
3631
 
          (user error or bug), we want LOAD DATA to print an error message on
3632
 
          the slave to discover the problem.
 
2715
          (user error or bug), we want LOAD DATA to print an error message on
 
2716
          the slave to discover the problem.
3633
2717
 
3634
2718
          If reading from net (a 3.23 master), mysql_load() will change this
3635
2719
          to IGNORE.
3637
2721
        handle_dup= DUP_ERROR;
3638
2722
      }
3639
2723
      /*
3640
 
        We need to set thd->lex->sql_command and thd->lex->duplicates
 
2724
        We need to set session->lex->sql_command and session->lex->duplicates
3641
2725
        since InnoDB tests these variables to decide if this is a LOAD
3642
2726
        DATA ... REPLACE INTO ... statement even though mysql_parse()
3643
2727
        is not called.  This is not needed in 5.0 since there the LOAD
3644
2728
        DATA ... statement is replicated using mysql_parse(), which
3645
 
        sets the thd->lex fields correctly.
 
2729
        sets the session->lex fields correctly.
3646
2730
      */
3647
 
      thd->lex->sql_command= SQLCOM_LOAD;
3648
 
      thd->lex->duplicates= handle_dup;
 
2731
      session->lex->sql_command= SQLCOM_LOAD;
 
2732
      session->lex->duplicates= handle_dup;
3649
2733
 
3650
2734
      sql_exchange ex((char*)fname, sql_ex.opt_flags & DUMPFILE_FLAG);
3651
 
      String field_term(sql_ex.field_term,sql_ex.field_term_len,log_cs);
3652
 
      String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,log_cs);
3653
 
      String line_term(sql_ex.line_term,sql_ex.line_term_len,log_cs);
3654
 
      String line_start(sql_ex.line_start,sql_ex.line_start_len,log_cs);
3655
 
      String escaped(sql_ex.escaped,sql_ex.escaped_len, log_cs);
 
2735
      String field_term(sql_ex.field_term,sql_ex.field_term_len,&my_charset_utf8_general_ci);
 
2736
      String enclosed(sql_ex.enclosed,sql_ex.enclosed_len,&my_charset_utf8_general_ci);
 
2737
      String line_term(sql_ex.line_term,sql_ex.line_term_len,&my_charset_utf8_general_ci);
 
2738
      String line_start(sql_ex.line_start,sql_ex.line_start_len,&my_charset_utf8_general_ci);
 
2739
      String escaped(sql_ex.escaped,sql_ex.escaped_len, &my_charset_utf8_general_ci);
3656
2740
      ex.field_term= &field_term;
3657
2741
      ex.enclosed= &enclosed;
3658
2742
      ex.line_term= &line_term;
3661
2745
 
3662
2746
      ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG);
3663
2747
      if (sql_ex.empty_flags & FIELD_TERM_EMPTY)
3664
 
        ex.field_term->length(0);
 
2748
        ex.field_term->length(0);
3665
2749
 
3666
2750
      ex.skip_lines = skip_lines;
3667
2751
      List<Item> field_list;
3668
 
      thd->lex->select_lex.context.resolve_in_table_list_only(&tables);
3669
 
      set_fields(tables.db, field_list, &thd->lex->select_lex.context);
3670
 
      thd->variables.pseudo_thread_id= thread_id;
 
2752
      session->lex->select_lex.context.resolve_in_table_list_only(&tables);
 
2753
      set_fields(tables.db, field_list, &session->lex->select_lex.context);
 
2754
      session->variables.pseudo_thread_id= thread_id;
3671
2755
      if (net)
3672
2756
      {
3673
 
        // mysql_load will use thd->net to read the file
3674
 
        thd->net.vio = net->vio;
3675
 
        /*
3676
 
          Make sure the client does not get confused about the packet sequence
3677
 
        */
3678
 
        thd->net.pkt_nr = net->pkt_nr;
 
2757
        // mysql_load will use session->net to read the file
 
2758
        session->net.vio = net->vio;
 
2759
        /*
 
2760
          Make sure the client does not get confused about the packet sequence
 
2761
        */
 
2762
        session->net.pkt_nr = net->pkt_nr;
3679
2763
      }
3680
2764
      /*
3681
2765
        It is safe to use tmp_list twice because we are not going to
3682
2766
        update it inside mysql_load().
3683
2767
      */
3684
2768
      List<Item> tmp_list;
3685
 
      if (mysql_load(thd, &ex, &tables, field_list, tmp_list, tmp_list,
 
2769
      if (mysql_load(session, &ex, &tables, field_list, tmp_list, tmp_list,
3686
2770
                     handle_dup, ignore, net != 0))
3687
 
        thd->is_slave_error= 1;
3688
 
      if (thd->cuted_fields)
 
2771
        session->is_slave_error= 1;
 
2772
      if (session->cuted_fields)
3689
2773
      {
3690
 
        /* log_pos is the position of the LOAD event in the master log */
3691
 
        sql_print_warning("Slave: load data infile on table '%s' at "
3692
 
                          "log position %s in log '%s' produced %ld "
3693
 
                          "warning(s). Default database: '%s'",
 
2774
        /* log_pos is the position of the LOAD event in the master log */
 
2775
        errmsg_printf(ERRMSG_LVL_WARN, _("Slave: load data infile on table '%s' at "
 
2776
                            "log position %s in log '%s' produced %ld "
 
2777
                            "warning(s). Default database: '%s'"),
3694
2778
                          (char*) table_name,
3695
 
                          llstr(log_pos,llbuff), RPL_LOG_NAME, 
3696
 
                          (ulong) thd->cuted_fields,
3697
 
                          print_slave_db_safe(thd->db));
 
2779
                          llstr(log_pos,llbuff), RPL_LOG_NAME,
 
2780
                          (ulong) session->cuted_fields,
 
2781
                          print_slave_db_safe(session->db));
3698
2782
      }
3699
2783
      if (net)
3700
 
        net->pkt_nr= thd->net.pkt_nr;
 
2784
        net->pkt_nr= session->net.pkt_nr;
3701
2785
    }
3702
2786
  }
3703
2787
  else
3712
2796
  }
3713
2797
 
3714
2798
error:
3715
 
  thd->net.vio = 0; 
3716
 
  const char *remember_db= thd->db;
3717
 
  VOID(pthread_mutex_lock(&LOCK_thread_count));
3718
 
  thd->catalog= 0;
3719
 
  thd->set_db(NULL, 0);                   /* will free the current database */
3720
 
  thd->query= 0;
3721
 
  thd->query_length= 0;
3722
 
  VOID(pthread_mutex_unlock(&LOCK_thread_count));
3723
 
  close_thread_tables(thd);
 
2799
  session->net.vio = 0;
 
2800
  const char *remember_db= session->db;
 
2801
  pthread_mutex_lock(&LOCK_thread_count);
 
2802
  session->catalog= 0;
 
2803
  session->set_db(NULL, 0);                   /* will free the current database */
 
2804
  session->query= 0;
 
2805
  session->query_length= 0;
 
2806
  pthread_mutex_unlock(&LOCK_thread_count);
 
2807
  close_thread_tables(session);
3724
2808
 
3725
 
  if (thd->is_slave_error)
 
2809
  if (session->is_slave_error)
3726
2810
  {
3727
2811
    /* this err/sql_errno code is copy-paste from net_send_error() */
3728
2812
    const char *err;
3729
2813
    int sql_errno;
3730
 
    if (thd->is_error())
 
2814
    if (session->is_error())
3731
2815
    {
3732
 
      err= thd->main_da.message();
3733
 
      sql_errno= thd->main_da.sql_errno();
 
2816
      err= session->main_da.message();
 
2817
      sql_errno= session->main_da.sql_errno();
3734
2818
    }
3735
2819
    else
3736
2820
    {
3737
2821
      sql_errno=ER_UNKNOWN_ERROR;
3738
 
      err=ER(sql_errno);       
 
2822
      err=ER(sql_errno);
3739
2823
    }
3740
 
    rli->report(ERROR_LEVEL, sql_errno,"\
3741
 
Error '%s' running LOAD DATA INFILE on table '%s'. Default database: '%s'",
3742
 
                    err, (char*)table_name, print_slave_db_safe(remember_db));
3743
 
    free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
2824
    rli->report(ERROR_LEVEL, sql_errno,
 
2825
                _("Error '%s' running LOAD DATA INFILE on table '%s'. "
 
2826
                  "Default database: '%s'"),
 
2827
                err, (char*)table_name, print_slave_db_safe(remember_db));
 
2828
    free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3744
2829
    return 1;
3745
2830
  }
3746
 
  free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC));
 
2831
  free_root(session->mem_root,MYF(MY_KEEP_PREALLOC));
3747
2832
 
3748
 
  if (thd->is_fatal_error)
 
2833
  if (session->is_fatal_error)
3749
2834
  {
3750
2835
    char buf[256];
3751
2836
    snprintf(buf, sizeof(buf),
3752
 
             "Running LOAD DATA INFILE on table '%-.64s'."
3753
 
             " Default database: '%-.64s'",
 
2837
             _("Running LOAD DATA INFILE on table '%-.64s'."
 
2838
               " Default database: '%-.64s'"),
3754
2839
             (char*)table_name,
3755
2840
             print_slave_db_safe(remember_db));
3756
2841
 
3759
2844
    return 1;
3760
2845
  }
3761
2846
 
3762
 
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) ); 
 
2847
  return ( use_rli_only_for_errors ? 0 : Log_event::do_apply_event(rli) );
3763
2848
}
3764
 
#endif
3765
2849
 
3766
2850
 
3767
2851
/**************************************************************************
3772
2856
  Rotate_log_event::pack_info()
3773
2857
*/
3774
2858
 
3775
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3776
2859
void Rotate_log_event::pack_info(Protocol *protocol)
3777
2860
{
3778
2861
  char buf1[256], buf[22];
3779
 
  String tmp(buf1, sizeof(buf1), log_cs);
 
2862
  String tmp(buf1, sizeof(buf1), &my_charset_utf8_general_ci);
3780
2863
  tmp.length(0);
3781
 
  tmp.append(new_log_ident, ident_len);
 
2864
  tmp.append(new_log_ident.c_str(), ident_len);
3782
2865
  tmp.append(STRING_WITH_LEN(";pos="));
3783
2866
  tmp.append(llstr(pos,buf));
3784
2867
  protocol->store(tmp.ptr(), tmp.length(), &my_charset_bin);
3785
2868
}
3786
 
#endif
3787
 
 
3788
 
 
3789
 
/*
3790
 
  Rotate_log_event::print()
3791
 
*/
3792
 
 
3793
 
#ifdef DRIZZLE_CLIENT
3794
 
void Rotate_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
3795
 
{
3796
 
  char buf[22];
3797
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
3798
 
                               Write_on_release_cache::FLUSH_F);
3799
 
 
3800
 
  if (print_event_info->short_form)
3801
 
    return;
3802
 
  print_header(&cache, print_event_info, false);
3803
 
  my_b_printf(&cache, "\tRotate to ");
3804
 
  if (new_log_ident)
3805
 
    my_b_write(&cache, (uchar*) new_log_ident, (uint)ident_len);
3806
 
  my_b_printf(&cache, "  pos: %s\n", llstr(pos, buf));
3807
 
}
3808
 
#endif /* DRIZZLE_CLIENT */
3809
 
 
3810
2869
 
3811
2870
 
3812
2871
/*
3814
2873
*/
3815
2874
 
3816
2875
 
3817
 
#ifndef DRIZZLE_CLIENT
3818
2876
Rotate_log_event::Rotate_log_event(const char* new_log_ident_arg,
3819
 
                                   uint ident_len_arg, uint64_t pos_arg,
3820
 
                                   uint flags_arg)
3821
 
  :Log_event(), new_log_ident(new_log_ident_arg),
3822
 
   pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
3823
 
                          (uint) strlen(new_log_ident_arg)), flags(flags_arg)
 
2877
                                   uint32_t ident_len_arg, uint64_t pos_arg,
 
2878
                                   uint32_t flags_arg)
 
2879
  :Log_event(), pos(pos_arg),
 
2880
   ident_len(ident_len_arg
 
2881
               ? ident_len_arg
 
2882
               : strlen(new_log_ident_arg)),
 
2883
   flags(flags_arg)
3824
2884
{
3825
 
  if (flags & DUP_NAME)
3826
 
    new_log_ident= my_strndup(new_log_ident_arg, ident_len, MYF(MY_WME));
 
2885
  new_log_ident.assign(new_log_ident_arg, ident_len);
3827
2886
  return;
3828
2887
}
3829
 
#endif
3830
 
 
3831
 
 
3832
 
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
 
2888
 
 
2889
 
 
2890
Rotate_log_event::Rotate_log_event(const char* buf, uint32_t event_len,
3833
2891
                                   const Format_description_log_event* description_event)
3834
 
  :Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
 
2892
  :Log_event(buf, description_event), flags(DUP_NAME)
3835
2893
{
3836
2894
  // The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
3837
2895
  uint8_t header_size= description_event->common_header_len;
3838
2896
  uint8_t post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
3839
 
  uint ident_offset;
 
2897
  uint32_t ident_offset;
3840
2898
  if (event_len < header_size)
3841
2899
    return;
3842
2900
  buf += header_size;
3843
2901
  pos = post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
3844
2902
  ident_len = (uint)(event_len -
3845
 
                     (header_size+post_header_len)); 
3846
 
  ident_offset = post_header_len; 
 
2903
                     (header_size+post_header_len));
 
2904
  ident_offset = post_header_len;
3847
2905
  set_if_smaller(ident_len,FN_REFLEN-1);
3848
 
  new_log_ident= my_strndup(buf + ident_offset, (uint) ident_len, MYF(MY_WME));
 
2906
  new_log_ident.assign(buf + ident_offset, ident_len);
3849
2907
  return;
3850
2908
}
3851
2909
 
3854
2912
  Rotate_log_event::write()
3855
2913
*/
3856
2914
 
3857
 
#ifndef DRIZZLE_CLIENT
3858
2915
bool Rotate_log_event::write(IO_CACHE* file)
3859
2916
{
3860
2917
  char buf[ROTATE_HEADER_LEN];
3861
2918
  int8store(buf + R_POS_OFFSET, pos);
3862
2919
  return (write_header(file, ROTATE_HEADER_LEN + ident_len) ||
3863
 
          my_b_safe_write(file, (uchar*)buf, ROTATE_HEADER_LEN) ||
3864
 
          my_b_safe_write(file, (uchar*)new_log_ident, (uint) ident_len));
 
2920
          my_b_safe_write(file, (unsigned char*)buf, ROTATE_HEADER_LEN) ||
 
2921
          my_b_safe_write(file, (const unsigned char*)new_log_ident.c_str(),
 
2922
                          (uint) ident_len));
3865
2923
}
3866
 
#endif
3867
 
 
3868
 
 
3869
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
2924
 
3870
2925
 
3871
2926
/*
3872
2927
  Got a rotate log event from the master.
3904
2959
  if ((server_id != ::server_id || rli->replicate_same_server_id) &&
3905
2960
      !rli->is_in_group())
3906
2961
  {
3907
 
    memcpy(rli->group_master_log_name, new_log_ident, ident_len+1);
 
2962
    rli->group_master_log_name.assign(new_log_ident);
3908
2963
    rli->notify_group_master_log_name_update();
3909
2964
    rli->group_master_log_pos= pos;
3910
 
    strmake(rli->group_relay_log_name, rli->event_relay_log_name,
3911
 
            sizeof(rli->group_relay_log_name) - 1);
 
2965
    rli->group_relay_log_name.assign(rli->event_relay_log_name);
3912
2966
    rli->notify_group_relay_log_name_update();
3913
2967
    rli->group_relay_log_pos= rli->event_relay_log_pos;
3914
2968
    /*
3915
 
      Reset thd->options and sql_mode etc, because this could be the signal of
 
2969
      Reset session->options and sql_mode etc, because this could be the signal of
3916
2970
      a master's downgrade from 5.0 to 4.0.
3917
2971
      However, no need to reset description_event_for_exec: indeed, if the next
3918
2972
      master is 5.0 (even 5.0.1) we will soon get a Format_desc; if the next
3919
2973
      master is 4.0 then the events are in the slave's format (conversion).
3920
2974
    */
3921
 
    set_slave_thread_options(thd);
3922
 
    set_slave_thread_default_charset(thd, rli);
3923
 
    thd->variables.auto_increment_increment=
3924
 
      thd->variables.auto_increment_offset= 1;
 
2975
    set_slave_thread_options(session);
 
2976
    session->variables.auto_increment_increment=
 
2977
      session->variables.auto_increment_offset= 1;
3925
2978
  }
3926
2979
  pthread_mutex_unlock(&rli->data_lock);
3927
2980
  pthread_cond_broadcast(&rli->data_cond);
3948
3001
  return Log_event::EVENT_SKIP_NOT;             // To keep compiler happy
3949
3002
}
3950
3003
 
3951
 
#endif
3952
 
 
3953
 
 
3954
 
/**************************************************************************
3955
 
        Intvar_log_event methods
3956
 
**************************************************************************/
3957
 
 
3958
 
/*
3959
 
  Intvar_log_event::pack_info()
3960
 
*/
3961
 
 
3962
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
3963
 
void Intvar_log_event::pack_info(Protocol *protocol)
3964
 
{
3965
 
  char buf[256], *pos;
3966
 
  pos= strmake(buf, get_var_type_name(), sizeof(buf)-23);
3967
 
  *pos++= '=';
3968
 
  pos= int64_t10_to_str(val, pos, -10);
3969
 
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
3970
 
}
3971
 
#endif
3972
 
 
3973
 
 
3974
 
/*
3975
 
  Intvar_log_event::Intvar_log_event()
3976
 
*/
3977
 
 
3978
 
Intvar_log_event::Intvar_log_event(const char* buf,
3979
 
                                   const Format_description_log_event* description_event)
3980
 
  :Log_event(buf, description_event)
3981
 
{
3982
 
  buf+= description_event->common_header_len;
3983
 
  type= buf[I_TYPE_OFFSET];
3984
 
  val= uint8korr(buf+I_VAL_OFFSET);
3985
 
}
3986
 
 
3987
 
 
3988
 
/*
3989
 
  Intvar_log_event::get_var_type_name()
3990
 
*/
3991
 
 
3992
 
const char* Intvar_log_event::get_var_type_name()
3993
 
{
3994
 
  switch(type) {
3995
 
  case LAST_INSERT_ID_EVENT: return "LAST_INSERT_ID";
3996
 
  case INSERT_ID_EVENT: return "INSERT_ID";
3997
 
  default: /* impossible */ return "UNKNOWN";
3998
 
  }
3999
 
}
4000
 
 
4001
 
 
4002
 
/*
4003
 
  Intvar_log_event::write()
4004
 
*/
4005
 
 
4006
 
#ifndef DRIZZLE_CLIENT
4007
 
bool Intvar_log_event::write(IO_CACHE* file)
4008
 
{
4009
 
  uchar buf[9];
4010
 
  buf[I_TYPE_OFFSET]= (uchar) type;
4011
 
  int8store(buf + I_VAL_OFFSET, val);
4012
 
  return (write_header(file, sizeof(buf)) ||
4013
 
          my_b_safe_write(file, buf, sizeof(buf)));
4014
 
}
4015
 
#endif
4016
 
 
4017
 
 
4018
 
/*
4019
 
  Intvar_log_event::print()
4020
 
*/
4021
 
 
4022
 
#ifdef DRIZZLE_CLIENT
4023
 
void Intvar_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4024
 
{
4025
 
  char llbuff[22];
4026
 
  const char *msg;
4027
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
4028
 
                               Write_on_release_cache::FLUSH_F);
4029
 
 
4030
 
  if (!print_event_info->short_form)
4031
 
  {
4032
 
    print_header(&cache, print_event_info, false);
4033
 
    my_b_printf(&cache, "\tIntvar\n");
4034
 
  }
4035
 
 
4036
 
  my_b_printf(&cache, "SET ");
4037
 
  switch (type) {
4038
 
  case LAST_INSERT_ID_EVENT:
4039
 
    msg="LAST_INSERT_ID";
4040
 
    break;
4041
 
  case INSERT_ID_EVENT:
4042
 
    msg="INSERT_ID";
4043
 
    break;
4044
 
  case INVALID_INT_EVENT:
4045
 
  default: // cannot happen
4046
 
    msg="INVALID_INT";
4047
 
    break;
4048
 
  }
4049
 
  my_b_printf(&cache, "%s=%s%s\n",
4050
 
              msg, llstr(val,llbuff), print_event_info->delimiter);
4051
 
}
4052
 
#endif
4053
 
 
4054
 
 
4055
 
/*
4056
 
  Intvar_log_event::do_apply_event()
4057
 
*/
4058
 
 
4059
 
#if defined(HAVE_REPLICATION)&& !defined(DRIZZLE_CLIENT)
4060
 
int Intvar_log_event::do_apply_event(Relay_log_info const *rli)
4061
 
{
4062
 
  /*
4063
 
    We are now in a statement until the associated query log event has
4064
 
    been processed.
4065
 
   */
4066
 
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4067
 
 
4068
 
  switch (type) {
4069
 
  case LAST_INSERT_ID_EVENT:
4070
 
    thd->stmt_depends_on_first_successful_insert_id_in_prev_stmt= 1;
4071
 
    thd->first_successful_insert_id_in_prev_stmt= val;
4072
 
    break;
4073
 
  case INSERT_ID_EVENT:
4074
 
    thd->force_one_auto_inc_interval(val);
4075
 
    break;
4076
 
  }
4077
 
  return 0;
4078
 
}
4079
 
 
4080
 
int Intvar_log_event::do_update_pos(Relay_log_info *rli)
4081
 
{
4082
 
  rli->inc_event_relay_log_pos();
4083
 
  return 0;
4084
 
}
4085
 
 
4086
 
 
4087
 
Log_event::enum_skip_reason
4088
 
Intvar_log_event::do_shall_skip(Relay_log_info *rli)
4089
 
{
4090
 
  /*
4091
 
    It is a common error to set the slave skip counter to 1 instead of
4092
 
    2 when recovering from an insert which used a auto increment,
4093
 
    rand, or user var.  Therefore, if the slave skip counter is 1, we
4094
 
    just say that this event should be skipped by ignoring it, meaning
4095
 
    that we do not change the value of the slave skip counter since it
4096
 
    will be decreased by the following insert event.
4097
 
  */
4098
 
  return continue_group(rli);
4099
 
}
4100
 
 
4101
 
#endif
4102
 
 
4103
 
 
4104
 
/**************************************************************************
4105
 
  Rand_log_event methods
4106
 
**************************************************************************/
4107
 
 
4108
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4109
 
void Rand_log_event::pack_info(Protocol *protocol)
4110
 
{
4111
 
  char buf1[256], *pos;
4112
 
  pos= stpcpy(buf1,"rand_seed1=");
4113
 
  pos= int10_to_str((long) seed1, pos, 10);
4114
 
  pos= stpcpy(pos, ",rand_seed2=");
4115
 
  pos= int10_to_str((long) seed2, pos, 10);
4116
 
  protocol->store(buf1, (uint) (pos-buf1), &my_charset_bin);
4117
 
}
4118
 
#endif
4119
 
 
4120
 
 
4121
 
Rand_log_event::Rand_log_event(const char* buf,
4122
 
                               const Format_description_log_event* description_event)
4123
 
  :Log_event(buf, description_event)
4124
 
{
4125
 
  buf+= description_event->common_header_len;
4126
 
  seed1= uint8korr(buf+RAND_SEED1_OFFSET);
4127
 
  seed2= uint8korr(buf+RAND_SEED2_OFFSET);
4128
 
}
4129
 
 
4130
 
 
4131
 
#ifndef DRIZZLE_CLIENT
4132
 
bool Rand_log_event::write(IO_CACHE* file)
4133
 
{
4134
 
  uchar buf[16];
4135
 
  int8store(buf + RAND_SEED1_OFFSET, seed1);
4136
 
  int8store(buf + RAND_SEED2_OFFSET, seed2);
4137
 
  return (write_header(file, sizeof(buf)) ||
4138
 
          my_b_safe_write(file, buf, sizeof(buf)));
4139
 
}
4140
 
#endif
4141
 
 
4142
 
 
4143
 
#ifdef DRIZZLE_CLIENT
4144
 
void Rand_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4145
 
{
4146
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
4147
 
                               Write_on_release_cache::FLUSH_F);
4148
 
 
4149
 
  char llbuff[22],llbuff2[22];
4150
 
  if (!print_event_info->short_form)
4151
 
  {
4152
 
    print_header(&cache, print_event_info, false);
4153
 
    my_b_printf(&cache, "\tRand\n");
4154
 
  }
4155
 
  my_b_printf(&cache, "SET @@RAND_SEED1=%s, @@RAND_SEED2=%s%s\n",
4156
 
              llstr(seed1, llbuff),llstr(seed2, llbuff2),
4157
 
              print_event_info->delimiter);
4158
 
}
4159
 
#endif /* DRIZZLE_CLIENT */
4160
 
 
4161
 
 
4162
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4163
 
int Rand_log_event::do_apply_event(Relay_log_info const *rli)
4164
 
{
4165
 
  /*
4166
 
    We are now in a statement until the associated query log event has
4167
 
    been processed.
4168
 
   */
4169
 
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4170
 
 
4171
 
  thd->rand.seed1= (ulong) seed1;
4172
 
  thd->rand.seed2= (ulong) seed2;
4173
 
  return 0;
4174
 
}
4175
 
 
4176
 
int Rand_log_event::do_update_pos(Relay_log_info *rli)
4177
 
{
4178
 
  rli->inc_event_relay_log_pos();
4179
 
  return 0;
4180
 
}
4181
 
 
4182
 
 
4183
 
Log_event::enum_skip_reason
4184
 
Rand_log_event::do_shall_skip(Relay_log_info *rli)
4185
 
{
4186
 
  /*
4187
 
    It is a common error to set the slave skip counter to 1 instead of
4188
 
    2 when recovering from an insert which used a auto increment,
4189
 
    rand, or user var.  Therefore, if the slave skip counter is 1, we
4190
 
    just say that this event should be skipped by ignoring it, meaning
4191
 
    that we do not change the value of the slave skip counter since it
4192
 
    will be decreased by the following insert event.
4193
 
  */
4194
 
  return continue_group(rli);
4195
 
}
4196
 
 
4197
 
#endif /* !DRIZZLE_CLIENT */
4198
 
 
4199
3004
 
4200
3005
/**************************************************************************
4201
3006
  Xid_log_event methods
4202
3007
**************************************************************************/
4203
3008
 
4204
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4205
3009
void Xid_log_event::pack_info(Protocol *protocol)
4206
3010
{
4207
3011
  char buf[128], *pos;
4208
 
  pos= stpcpy(buf, "COMMIT /* xid=");
 
3012
  pos= strcpy(buf, "COMMIT /* xid=")+14;
4209
3013
  pos= int64_t10_to_str(xid, pos, 10);
4210
 
  pos= stpcpy(pos, " */");
 
3014
  pos= strcpy(pos, " */")+3;
4211
3015
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
4212
3016
}
4213
 
#endif
4214
3017
 
4215
3018
/**
4216
3019
  @note
4217
3020
  It's ok not to use int8store here,
4218
 
  as long as xid_t::set(uint64_t) and
4219
 
  xid_t::get_my_xid doesn't do it either.
 
3021
  as long as XID::set(uint64_t) and
 
3022
  XID::get_my_xid doesn't do it either.
4220
3023
  We don't care about actual values of xids as long as
4221
3024
  identical numbers compare identically
4222
3025
*/
4231
3034
}
4232
3035
 
4233
3036
 
4234
 
#ifndef DRIZZLE_CLIENT
4235
3037
bool Xid_log_event::write(IO_CACHE* file)
4236
3038
{
4237
3039
  return write_header(file, sizeof(xid)) ||
4238
 
         my_b_safe_write(file, (uchar*) &xid, sizeof(xid));
4239
 
}
4240
 
#endif
4241
 
 
4242
 
 
4243
 
#ifdef DRIZZLE_CLIENT
4244
 
void Xid_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4245
 
{
4246
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
4247
 
                               Write_on_release_cache::FLUSH_F);
4248
 
 
4249
 
  if (!print_event_info->short_form)
4250
 
  {
4251
 
    char buf[64];
4252
 
    int64_t10_to_str(xid, buf, 10);
4253
 
 
4254
 
    print_header(&cache, print_event_info, false);
4255
 
    my_b_printf(&cache, "\tXid = %s\n", buf);
4256
 
  }
4257
 
  my_b_printf(&cache, "COMMIT%s\n", print_event_info->delimiter);
4258
 
}
4259
 
#endif /* DRIZZLE_CLIENT */
4260
 
 
4261
 
 
4262
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4263
 
int Xid_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4264
 
{
4265
 
  /* For a slave Xid_log_event is COMMIT */
4266
 
  general_log_print(thd, COM_QUERY,
4267
 
                    "COMMIT /* implicit, from Xid_log_event */");
4268
 
  return end_trans(thd, COMMIT);
 
3040
         my_b_safe_write(file, (unsigned char*) &xid, sizeof(xid));
 
3041
}
 
3042
 
 
3043
 
 
3044
int Xid_log_event::do_apply_event(const Relay_log_info *)
 
3045
{
 
3046
  return end_trans(session, COMMIT);
4269
3047
}
4270
3048
 
4271
3049
Log_event::enum_skip_reason
4272
3050
Xid_log_event::do_shall_skip(Relay_log_info *rli)
4273
3051
{
4274
3052
  if (rli->slave_skip_counter > 0) {
4275
 
    thd->options&= ~OPTION_BEGIN;
 
3053
    session->options&= ~OPTION_BEGIN;
4276
3054
    return(Log_event::EVENT_SKIP_COUNT);
4277
3055
  }
4278
3056
  return(Log_event::do_shall_skip(rli));
4279
3057
}
4280
 
#endif /* !DRIZZLE_CLIENT */
4281
 
 
4282
 
 
4283
 
/**************************************************************************
4284
 
  User_var_log_event methods
4285
 
**************************************************************************/
4286
 
 
4287
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4288
 
void User_var_log_event::pack_info(Protocol* protocol)
4289
 
{
4290
 
  char *buf= 0;
4291
 
  uint val_offset= 4 + name_len;
4292
 
  uint event_len= val_offset;
4293
 
 
4294
 
  if (is_null)
4295
 
  {
4296
 
    if (!(buf= (char*) my_malloc(val_offset + 5, MYF(MY_WME))))
4297
 
      return;
4298
 
    stpcpy(buf + val_offset, "NULL");
4299
 
    event_len= val_offset + 4;
4300
 
  }
4301
 
  else
4302
 
  {
4303
 
    switch (type) {
4304
 
    case REAL_RESULT:
4305
 
      double real_val;
4306
 
      float8get(real_val, val);
4307
 
      if (!(buf= (char*) my_malloc(val_offset + MY_GCVT_MAX_FIELD_WIDTH + 1,
4308
 
                                   MYF(MY_WME))))
4309
 
        return;
4310
 
      event_len+= my_gcvt(real_val, MY_GCVT_ARG_DOUBLE, MY_GCVT_MAX_FIELD_WIDTH,
4311
 
                          buf + val_offset, NULL);
4312
 
      break;
4313
 
    case INT_RESULT:
4314
 
      if (!(buf= (char*) my_malloc(val_offset + 22, MYF(MY_WME))))
4315
 
        return;
4316
 
      event_len= int64_t10_to_str(uint8korr(val), buf + val_offset,-10)-buf;
4317
 
      break;
4318
 
    case DECIMAL_RESULT:
4319
 
    {
4320
 
      if (!(buf= (char*) my_malloc(val_offset + DECIMAL_MAX_STR_LENGTH,
4321
 
                                   MYF(MY_WME))))
4322
 
        return;
4323
 
      String str(buf+val_offset, DECIMAL_MAX_STR_LENGTH, &my_charset_bin);
4324
 
      my_decimal dec;
4325
 
      binary2my_decimal(E_DEC_FATAL_ERROR, (uchar*) (val+2), &dec, val[0],
4326
 
                        val[1]);
4327
 
      my_decimal2string(E_DEC_FATAL_ERROR, &dec, 0, 0, 0, &str);
4328
 
      event_len= str.length() + val_offset;
4329
 
      break;
4330
 
    } 
4331
 
    case STRING_RESULT:
4332
 
      /* 15 is for 'COLLATE' and other chars */
4333
 
      buf= (char*) my_malloc(event_len+val_len*2+1+2*MY_CS_NAME_SIZE+15,
4334
 
                             MYF(MY_WME));
4335
 
      const CHARSET_INFO *cs;
4336
 
      if (!buf)
4337
 
        return;
4338
 
      if (!(cs= get_charset(charset_number, MYF(0))))
4339
 
      {
4340
 
        stpcpy(buf+val_offset, "???");
4341
 
        event_len+= 3;
4342
 
      }
4343
 
      else
4344
 
      {
4345
 
        char *p= strxmov(buf + val_offset, "_", cs->csname, " ", NullS);
4346
 
        p= str_to_hex(p, val, val_len);
4347
 
        p= strxmov(p, " COLLATE ", cs->name, NullS);
4348
 
        event_len= p-buf;
4349
 
      }
4350
 
      break;
4351
 
    case ROW_RESULT:
4352
 
    default:
4353
 
      assert(1);
4354
 
      return;
4355
 
    }
4356
 
  }
4357
 
  buf[0]= '@';
4358
 
  buf[1]= '`';
4359
 
  memcpy(buf+2, name, name_len);
4360
 
  buf[2+name_len]= '`';
4361
 
  buf[3+name_len]= '=';
4362
 
  protocol->store(buf, event_len, &my_charset_bin);
4363
 
  my_free(buf, MYF(0));
4364
 
}
4365
 
#endif /* !DRIZZLE_CLIENT */
4366
 
 
4367
 
 
4368
 
User_var_log_event::
4369
 
User_var_log_event(const char* buf,
4370
 
                   const Format_description_log_event* description_event)
4371
 
  :Log_event(buf, description_event)
4372
 
{
4373
 
  buf+= description_event->common_header_len;
4374
 
  name_len= uint4korr(buf);
4375
 
  name= (char *) buf + UV_NAME_LEN_SIZE;
4376
 
  buf+= UV_NAME_LEN_SIZE + name_len;
4377
 
  is_null= (bool) *buf;
4378
 
  if (is_null)
4379
 
  {
4380
 
    type= STRING_RESULT;
4381
 
    charset_number= my_charset_bin.number;
4382
 
    val_len= 0;
4383
 
    val= 0;  
4384
 
  }
4385
 
  else
4386
 
  {
4387
 
    type= (Item_result) buf[UV_VAL_IS_NULL];
4388
 
    charset_number= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE);
4389
 
    val_len= uint4korr(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
4390
 
                       UV_CHARSET_NUMBER_SIZE);
4391
 
    val= (char *) (buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
4392
 
                   UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE);
4393
 
  }
4394
 
}
4395
 
 
4396
 
 
4397
 
#ifndef DRIZZLE_CLIENT
4398
 
bool User_var_log_event::write(IO_CACHE* file)
4399
 
{
4400
 
  char buf[UV_NAME_LEN_SIZE];
4401
 
  char buf1[UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE + 
4402
 
            UV_CHARSET_NUMBER_SIZE + UV_VAL_LEN_SIZE];
4403
 
  uchar buf2[(8 > DECIMAL_MAX_FIELD_SIZE + 2) ? 8 : DECIMAL_MAX_FIELD_SIZE +2], *pos= buf2;
4404
 
  uint buf1_length;
4405
 
  ulong event_length;
4406
 
 
4407
 
  int4store(buf, name_len);
4408
 
  
4409
 
  if ((buf1[0]= is_null))
4410
 
  {
4411
 
    buf1_length= 1;
4412
 
    val_len= 0;                                 // Length of 'pos'
4413
 
  }    
4414
 
  else
4415
 
  {
4416
 
    buf1[1]= type;
4417
 
    int4store(buf1 + 2, charset_number);
4418
 
 
4419
 
    switch (type) {
4420
 
    case REAL_RESULT:
4421
 
      float8store(buf2, *(double*) val);
4422
 
      break;
4423
 
    case INT_RESULT:
4424
 
      int8store(buf2, *(int64_t*) val);
4425
 
      break;
4426
 
    case DECIMAL_RESULT:
4427
 
    {
4428
 
      my_decimal *dec= (my_decimal *)val;
4429
 
      dec->fix_buffer_pointer();
4430
 
      buf2[0]= (char)(dec->intg + dec->frac);
4431
 
      buf2[1]= (char)dec->frac;
4432
 
      decimal2bin((decimal_t*)val, buf2+2, buf2[0], buf2[1]);
4433
 
      val_len= decimal_bin_size(buf2[0], buf2[1]) + 2;
4434
 
      break;
4435
 
    }
4436
 
    case STRING_RESULT:
4437
 
      pos= (uchar*) val;
4438
 
      break;
4439
 
    case ROW_RESULT:
4440
 
    default:
4441
 
      assert(1);
4442
 
      return 0;
4443
 
    }
4444
 
    int4store(buf1 + 2 + UV_CHARSET_NUMBER_SIZE, val_len);
4445
 
    buf1_length= 10;
4446
 
  }
4447
 
 
4448
 
  /* Length of the whole event */
4449
 
  event_length= sizeof(buf)+ name_len + buf1_length + val_len;
4450
 
 
4451
 
  return (write_header(file, event_length) ||
4452
 
          my_b_safe_write(file, (uchar*) buf, sizeof(buf))   ||
4453
 
          my_b_safe_write(file, (uchar*) name, name_len)     ||
4454
 
          my_b_safe_write(file, (uchar*) buf1, buf1_length) ||
4455
 
          my_b_safe_write(file, pos, val_len));
4456
 
}
4457
 
#endif
4458
 
 
4459
 
 
4460
 
/*
4461
 
  User_var_log_event::print()
4462
 
*/
4463
 
 
4464
 
#ifdef DRIZZLE_CLIENT
4465
 
void User_var_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4466
 
{
4467
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
4468
 
                               Write_on_release_cache::FLUSH_F);
4469
 
 
4470
 
  if (!print_event_info->short_form)
4471
 
  {
4472
 
    print_header(&cache, print_event_info, false);
4473
 
    my_b_printf(&cache, "\tUser_var\n");
4474
 
  }
4475
 
 
4476
 
  my_b_printf(&cache, "SET @`");
4477
 
  my_b_write(&cache, (uchar*) name, (uint) (name_len));
4478
 
  my_b_printf(&cache, "`");
4479
 
 
4480
 
  if (is_null)
4481
 
  {
4482
 
    my_b_printf(&cache, ":=NULL%s\n", print_event_info->delimiter);
4483
 
  }
4484
 
  else
4485
 
  {
4486
 
    switch (type) {
4487
 
    case REAL_RESULT:
4488
 
      double real_val;
4489
 
      char real_buf[FMT_G_BUFSIZE(14)];
4490
 
      float8get(real_val, val);
4491
 
      sprintf(real_buf, "%.14g", real_val);
4492
 
      my_b_printf(&cache, ":=%s%s\n", real_buf, print_event_info->delimiter);
4493
 
      break;
4494
 
    case INT_RESULT:
4495
 
      char int_buf[22];
4496
 
      int64_t10_to_str(uint8korr(val), int_buf, -10);
4497
 
      my_b_printf(&cache, ":=%s%s\n", int_buf, print_event_info->delimiter);
4498
 
      break;
4499
 
    case DECIMAL_RESULT:
4500
 
    {
4501
 
      char str_buf[200];
4502
 
      int str_len= sizeof(str_buf) - 1;
4503
 
      int precision= (int)val[0];
4504
 
      int scale= (int)val[1];
4505
 
      decimal_digit_t dec_buf[10];
4506
 
      decimal_t dec;
4507
 
      dec.len= 10;
4508
 
      dec.buf= dec_buf;
4509
 
 
4510
 
      bin2decimal((uchar*) val+2, &dec, precision, scale);
4511
 
      decimal2string(&dec, str_buf, &str_len, 0, 0, 0);
4512
 
      str_buf[str_len]= 0;
4513
 
      my_b_printf(&cache, ":=%s%s\n", str_buf, print_event_info->delimiter);
4514
 
      break;
4515
 
    }
4516
 
    case STRING_RESULT:
4517
 
    {
4518
 
      /*
4519
 
        Let's express the string in hex. That's the most robust way. If we
4520
 
        print it in character form instead, we need to escape it with
4521
 
        character_set_client which we don't know (we will know it in 5.0, but
4522
 
        in 4.1 we don't know it easily when we are printing
4523
 
        User_var_log_event). Explanation why we would need to bother with
4524
 
        character_set_client (quoting Bar):
4525
 
        > Note, the parser doesn't switch to another unescaping mode after
4526
 
        > it has met a character set introducer.
4527
 
        > For example, if an SJIS client says something like:
4528
 
        > SET @a= _ucs2 \0a\0b'
4529
 
        > the string constant is still unescaped according to SJIS, not
4530
 
        > according to UCS2.
4531
 
      */
4532
 
      char *hex_str;
4533
 
      const CHARSET_INFO *cs;
4534
 
 
4535
 
      if (!(hex_str= (char *)my_alloca(2*val_len+1+2))) // 2 hex digits / byte
4536
 
        break; // no error, as we are 'void'
4537
 
      str_to_hex(hex_str, val, val_len);
4538
 
      /*
4539
 
        For proper behaviour when mysqlbinlog|mysql, we need to explicitely
4540
 
        specify the variable's collation. It will however cause problems when
4541
 
        people want to mysqlbinlog|mysql into another server not supporting the
4542
 
        character set. But there's not much to do about this and it's unlikely.
4543
 
      */
4544
 
      if (!(cs= get_charset(charset_number, MYF(0))))
4545
 
        /*
4546
 
          Generate an unusable command (=> syntax error) is probably the best
4547
 
          thing we can do here.
4548
 
        */
4549
 
        my_b_printf(&cache, ":=???%s\n", print_event_info->delimiter);
4550
 
      else
4551
 
        my_b_printf(&cache, ":=_%s %s COLLATE `%s`%s\n",
4552
 
                    cs->csname, hex_str, cs->name,
4553
 
                    print_event_info->delimiter);
4554
 
      my_afree(hex_str);
4555
 
    }
4556
 
      break;
4557
 
    case ROW_RESULT:
4558
 
    default:
4559
 
      assert(1);
4560
 
      return;
4561
 
    }
4562
 
  }
4563
 
}
4564
 
#endif
4565
 
 
4566
 
 
4567
 
/*
4568
 
  User_var_log_event::do_apply_event()
4569
 
*/
4570
 
 
4571
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
4572
 
int User_var_log_event::do_apply_event(Relay_log_info const *rli)
4573
 
{
4574
 
  Item *it= 0;
4575
 
  const CHARSET_INFO *charset;
4576
 
  if (!(charset= get_charset(charset_number, MYF(MY_WME))))
4577
 
    return 1;
4578
 
  LEX_STRING user_var_name;
4579
 
  user_var_name.str= name;
4580
 
  user_var_name.length= name_len;
4581
 
  double real_val;
4582
 
  int64_t int_val;
4583
 
 
4584
 
  /*
4585
 
    We are now in a statement until the associated query log event has
4586
 
    been processed.
4587
 
   */
4588
 
  const_cast<Relay_log_info*>(rli)->set_flag(Relay_log_info::IN_STMT);
4589
 
 
4590
 
  if (is_null)
4591
 
  {
4592
 
    it= new Item_null();
4593
 
  }
4594
 
  else
4595
 
  {
4596
 
    switch (type) {
4597
 
    case REAL_RESULT:
4598
 
      float8get(real_val, val);
4599
 
      it= new Item_float(real_val, 0);
4600
 
      val= (char*) &real_val;           // Pointer to value in native format
4601
 
      val_len= 8;
4602
 
      break;
4603
 
    case INT_RESULT:
4604
 
      int_val= (int64_t) uint8korr(val);
4605
 
      it= new Item_int(int_val);
4606
 
      val= (char*) &int_val;            // Pointer to value in native format
4607
 
      val_len= 8;
4608
 
      break;
4609
 
    case DECIMAL_RESULT:
4610
 
    {
4611
 
      Item_decimal *dec= new Item_decimal((uchar*) val+2, val[0], val[1]);
4612
 
      it= dec;
4613
 
      val= (char *)dec->val_decimal(NULL);
4614
 
      val_len= sizeof(my_decimal);
4615
 
      break;
4616
 
    }
4617
 
    case STRING_RESULT:
4618
 
      it= new Item_string(val, val_len, charset);
4619
 
      break;
4620
 
    case ROW_RESULT:
4621
 
    default:
4622
 
      assert(1);
4623
 
      return 0;
4624
 
    }
4625
 
  }
4626
 
  Item_func_set_user_var e(user_var_name, it);
4627
 
  /*
4628
 
    Item_func_set_user_var can't substitute something else on its place =>
4629
 
    0 can be passed as last argument (reference on item)
4630
 
  */
4631
 
  e.fix_fields(thd, 0);
4632
 
  /*
4633
 
    A variable can just be considered as a table with
4634
 
    a single record and with a single column. Thus, like
4635
 
    a column value, it could always have IMPLICIT derivation.
4636
 
   */
4637
 
  e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
4638
 
  free_root(thd->mem_root,0);
4639
 
 
4640
 
  return 0;
4641
 
}
4642
 
 
4643
 
int User_var_log_event::do_update_pos(Relay_log_info *rli)
4644
 
{
4645
 
  rli->inc_event_relay_log_pos();
4646
 
  return 0;
4647
 
}
4648
 
 
4649
 
Log_event::enum_skip_reason
4650
 
User_var_log_event::do_shall_skip(Relay_log_info *rli)
4651
 
{
4652
 
  /*
4653
 
    It is a common error to set the slave skip counter to 1 instead
4654
 
    of 2 when recovering from an insert which used a auto increment,
4655
 
    rand, or user var.  Therefore, if the slave skip counter is 1, we
4656
 
    just say that this event should be skipped by ignoring it, meaning
4657
 
    that we do not change the value of the slave skip counter since it
4658
 
    will be decreased by the following insert event.
4659
 
  */
4660
 
  return continue_group(rli);
4661
 
}
4662
 
#endif /* !DRIZZLE_CLIENT */
4663
3058
 
4664
3059
 
4665
3060
/**************************************************************************
4666
3061
  Slave_log_event methods
4667
3062
**************************************************************************/
4668
3063
 
4669
 
#ifdef HAVE_REPLICATION
4670
 
#ifdef DRIZZLE_CLIENT
4671
 
void Unknown_log_event::print(FILE* file_arg, PRINT_EVENT_INFO* print_event_info)
4672
 
{
4673
 
  Write_on_release_cache cache(&print_event_info->head_cache, file_arg);
4674
 
 
4675
 
  if (print_event_info->short_form)
4676
 
    return;
4677
 
  print_header(&cache, print_event_info, false);
4678
 
  my_b_printf(&cache, "\n# %s", "Unknown event\n");
4679
 
}
4680
 
#endif  
4681
 
 
4682
 
#ifndef DRIZZLE_CLIENT
4683
3064
void Slave_log_event::pack_info(Protocol *protocol)
4684
3065
{
4685
 
  char buf[256+HOSTNAME_LENGTH], *pos;
4686
 
  pos= stpcpy(buf, "host=");
4687
 
  pos= stpncpy(pos, master_host, HOSTNAME_LENGTH);
4688
 
  pos= stpcpy(pos, ",port=");
4689
 
  pos= int10_to_str((long) master_port, pos, 10);
4690
 
  pos= stpcpy(pos, ",log=");
4691
 
  pos= stpcpy(pos, master_log);
4692
 
  pos= stpcpy(pos, ",pos=");
4693
 
  pos= int64_t10_to_str(master_pos, pos, 10);
4694
 
  protocol->store(buf, pos-buf, &my_charset_bin);
 
3066
  ostringstream stream;
 
3067
  stream << "host=" << master_host << ",port=" << master_port;
 
3068
  stream << ",log=" << master_log << ",pos=" << master_pos;
 
3069
 
 
3070
  protocol->store(stream.str().c_str(), stream.str().length(),
 
3071
                  &my_charset_bin);
4695
3072
}
4696
 
#endif /* !DRIZZLE_CLIENT */
4697
 
 
4698
 
 
4699
 
#ifndef DRIZZLE_CLIENT
 
3073
 
 
3074
 
4700
3075
/**
4701
3076
  @todo
4702
3077
  re-write this better without holding both locks at the same time
4703
3078
*/
4704
 
Slave_log_event::Slave_log_event(THD* thd_arg,
 
3079
Slave_log_event::Slave_log_event(Session* session_arg,
4705
3080
                                 Relay_log_info* rli)
4706
 
  :Log_event(thd_arg, 0, 0) , mem_pool(0), master_host(0)
 
3081
  :Log_event(session_arg, 0, 0) , mem_pool(0), master_host(0)
4707
3082
{
4708
3083
  if (!rli->inited)                             // QQ When can this happen ?
4709
3084
    return;
4712
3087
  // TODO: re-write this better without holding both locks at the same time
4713
3088
  pthread_mutex_lock(&mi->data_lock);
4714
3089
  pthread_mutex_lock(&rli->data_lock);
4715
 
  master_host_len = strlen(mi->host);
4716
 
  master_log_len = strlen(rli->group_master_log_name);
4717
3090
  // on OOM, just do not initialize the structure and print the error
4718
 
  if ((mem_pool = (char*)my_malloc(get_data_size() + 1,
4719
 
                                   MYF(MY_WME))))
 
3091
  if ((mem_pool = (char*)malloc(get_data_size() + 1)))
4720
3092
  {
4721
 
    master_host = mem_pool + SL_MASTER_HOST_OFFSET ;
4722
 
    memcpy(master_host, mi->host, master_host_len + 1);
4723
 
    master_log = master_host + master_host_len + 1;
4724
 
    memcpy(master_log, rli->group_master_log_name, master_log_len + 1);
4725
 
    master_port = mi->port;
 
3093
    master_host.assign(mi->getHostname());
 
3094
    master_log.assign(rli->group_master_log_name);
 
3095
    master_port = mi->getPort();
4726
3096
    master_pos = rli->group_master_log_pos;
4727
3097
  }
4728
3098
  else
4729
 
    sql_print_error("Out of memory while recording slave event");
 
3099
    errmsg_printf(ERRMSG_LVL_ERROR, _("Out of memory while recording slave event"));
4730
3100
  pthread_mutex_unlock(&rli->data_lock);
4731
3101
  pthread_mutex_unlock(&mi->data_lock);
4732
3102
  return;
4733
3103
}
4734
 
#endif /* !DRIZZLE_CLIENT */
4735
3104
 
4736
3105
 
4737
3106
Slave_log_event::~Slave_log_event()
4738
3107
{
4739
 
  my_free(mem_pool, MYF(MY_ALLOW_ZERO_PTR));
4740
 
}
4741
 
 
4742
 
 
4743
 
#ifdef DRIZZLE_CLIENT
4744
 
void Slave_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4745
 
{
4746
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
4747
 
 
4748
 
  char llbuff[22];
4749
 
  if (print_event_info->short_form)
4750
 
    return;
4751
 
  print_header(&cache, print_event_info, false);
4752
 
  my_b_printf(&cache, "\n\
4753
 
Slave: master_host: '%s'  master_port: %d  master_log: '%s'  master_pos: %s\n",
4754
 
          master_host, master_port, master_log, llstr(master_pos, llbuff));
4755
 
}
4756
 
#endif /* DRIZZLE_CLIENT */
 
3108
  free(mem_pool);
 
3109
}
4757
3110
 
4758
3111
 
4759
3112
int Slave_log_event::get_data_size()
4760
3113
{
4761
 
  return master_host_len + master_log_len + 1 + SL_MASTER_HOST_OFFSET;
 
3114
  return master_host.length() + master_log.length() + 1 + SL_MASTER_HOST_OFFSET;
4762
3115
}
4763
3116
 
4764
3117
 
4765
 
#ifndef DRIZZLE_CLIENT
4766
3118
bool Slave_log_event::write(IO_CACHE* file)
4767
3119
{
4768
3120
  ulong event_length= get_data_size();
4771
3123
  // log and host are already there
4772
3124
 
4773
3125
  return (write_header(file, event_length) ||
4774
 
          my_b_safe_write(file, (uchar*) mem_pool, event_length));
 
3126
          my_b_safe_write(file, (unsigned char*) mem_pool, event_length));
4775
3127
}
4776
 
#endif
4777
 
 
4778
 
 
4779
 
void Slave_log_event::init_from_mem_pool(int data_size)
 
3128
 
 
3129
 
 
3130
void Slave_log_event::init_from_mem_pool()
4780
3131
{
4781
3132
  master_pos = uint8korr(mem_pool + SL_MASTER_POS_OFFSET);
4782
3133
  master_port = uint2korr(mem_pool + SL_MASTER_PORT_OFFSET);
4783
 
  master_host = mem_pool + SL_MASTER_HOST_OFFSET;
4784
 
  master_host_len = strlen(master_host);
4785
 
  // safety
4786
 
  master_log = master_host + master_host_len + 1;
4787
 
  if (master_log > mem_pool + data_size)
4788
 
  {
4789
 
    master_host = 0;
4790
 
    return;
4791
 
  }
4792
 
  master_log_len = strlen(master_log);
4793
 
}
4794
 
 
4795
 
 
4796
 
/** This code is not used, so has not been updated to be format-tolerant. */
4797
 
Slave_log_event::Slave_log_event(const char* buf, uint event_len)
4798
 
  :Log_event(buf,0) /*unused event*/ ,mem_pool(0),master_host(0)
4799
 
{
4800
 
  if (event_len < LOG_EVENT_HEADER_LEN)
4801
 
    return;
4802
 
  event_len -= LOG_EVENT_HEADER_LEN;
4803
 
  if (!(mem_pool = (char*) my_malloc(event_len + 1, MYF(MY_WME))))
4804
 
    return;
4805
 
  memcpy(mem_pool, buf + LOG_EVENT_HEADER_LEN, event_len);
4806
 
  mem_pool[event_len] = 0;
4807
 
  init_from_mem_pool(event_len);
4808
 
}
4809
 
 
4810
 
 
4811
 
#ifndef DRIZZLE_CLIENT
4812
 
int Slave_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
4813
 
{
4814
 
  if (mysql_bin_log.is_open())
4815
 
    mysql_bin_log.write(this);
 
3134
#ifdef FIXME
 
3135
  /* Assign these correctly */
 
3136
  master_host.assign(mem_pool + SL_MASTER_HOST_OFFSET);
 
3137
  master_log.assign();
 
3138
#endif
 
3139
}
 
3140
 
 
3141
 
 
3142
int Slave_log_event::do_apply_event(const Relay_log_info *)
 
3143
{
 
3144
  if (drizzle_bin_log.is_open())
 
3145
    drizzle_bin_log.write(this);
4816
3146
  return 0;
4817
3147
}
4818
 
#endif /* !DRIZZLE_CLIENT */
4819
3148
 
4820
3149
 
4821
3150
/**************************************************************************
4823
3152
**************************************************************************/
4824
3153
 
4825
3154
/*
4826
 
  Stop_log_event::print()
4827
 
*/
4828
 
 
4829
 
#ifdef DRIZZLE_CLIENT
4830
 
void Stop_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
4831
 
{
4832
 
  Write_on_release_cache cache(&print_event_info->head_cache, file,
4833
 
                               Write_on_release_cache::FLUSH_F);
4834
 
 
4835
 
  if (print_event_info->short_form)
4836
 
    return;
4837
 
 
4838
 
  print_header(&cache, print_event_info, false);
4839
 
  my_b_printf(&cache, "\tStop\n");
4840
 
}
4841
 
#endif /* DRIZZLE_CLIENT */
4842
 
 
4843
 
 
4844
 
#ifndef DRIZZLE_CLIENT
4845
 
/*
4846
3155
  The master stopped.  We used to clean up all temporary tables but
4847
3156
  this is useless as, as the master has shut down properly, it has
4848
 
  written all DROP TEMPORARY TABLE (prepared statements' deletion is
 
3157
  written all DROP TEMPORARY Table (prepared statements' deletion is
4849
3158
  TODO only when we binlog prep stmts).  We used to clean up
4850
3159
  slave_load_tmpdir, but this is useless as it has been cleared at the
4851
3160
  end of LOAD DATA INFILE.  So we have nothing to do here.  The place
4862
3171
    could give false triggers in MASTER_POS_WAIT() that we have reached
4863
3172
    the target position when in fact we have not.
4864
3173
  */
4865
 
  if (thd->options & OPTION_BEGIN)
 
3174
  if (session->options & OPTION_BEGIN)
4866
3175
    rli->inc_event_relay_log_pos();
4867
3176
  else
4868
3177
  {
4872
3181
  return 0;
4873
3182
}
4874
3183
 
4875
 
#endif /* !DRIZZLE_CLIENT */
4876
 
#endif /* HAVE_REPLICATION */
4877
 
 
4878
3184
 
4879
3185
/**************************************************************************
4880
3186
        Create_file_log_event methods
4884
3190
  Create_file_log_event ctor
4885
3191
*/
4886
3192
 
4887
 
#ifndef DRIZZLE_CLIENT
4888
3193
Create_file_log_event::
4889
 
Create_file_log_event(THD* thd_arg, sql_exchange* ex,
 
3194
Create_file_log_event(Session* session_arg, sql_exchange* ex,
4890
3195
                      const char* db_arg, const char* table_name_arg,
4891
3196
                      List<Item>& fields_arg, enum enum_duplicates handle_dup,
4892
3197
                      bool ignore,
4893
 
                      uchar* block_arg, uint block_len_arg, bool using_trans)
4894
 
  :Load_log_event(thd_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
 
3198
                      unsigned char* block_arg, uint32_t block_len_arg, bool using_trans)
 
3199
  :Load_log_event(session_arg,ex,db_arg,table_name_arg,fields_arg,handle_dup, ignore,
4895
3200
                  using_trans),
4896
3201
   fake_base(0), block(block_arg), event_buf(0), block_len(block_len_arg),
4897
 
   file_id(thd_arg->file_id = mysql_bin_log.next_file_id())
 
3202
   file_id(session_arg->file_id = drizzle_bin_log.next_file_id())
4898
3203
{
4899
3204
  sql_ex.force_new_format();
4900
3205
  return;
4910
3215
  bool res;
4911
3216
  if ((res= Load_log_event::write_data_body(file)) || fake_base)
4912
3217
    return res;
4913
 
  return (my_b_safe_write(file, (uchar*) "", 1) ||
4914
 
          my_b_safe_write(file, (uchar*) block, block_len));
 
3218
  return (my_b_safe_write(file, (unsigned char*) "", 1) ||
 
3219
          my_b_safe_write(file, (unsigned char*) block, block_len));
4915
3220
}
4916
3221
 
4917
3222
 
4922
3227
bool Create_file_log_event::write_data_header(IO_CACHE* file)
4923
3228
{
4924
3229
  bool res;
4925
 
  uchar buf[CREATE_FILE_HEADER_LEN];
 
3230
  unsigned char buf[CREATE_FILE_HEADER_LEN];
4926
3231
  if ((res= Load_log_event::write_data_header(file)) || fake_base)
4927
3232
    return res;
4928
3233
  int4store(buf + CF_FILE_ID_OFFSET, file_id);
4943
3248
  return res;
4944
3249
}
4945
3250
 
4946
 
#endif /* !DRIZZLE_CLIENT */
4947
 
 
4948
3251
/*
4949
3252
  Create_file_log_event ctor
4950
3253
*/
4951
3254
 
4952
 
Create_file_log_event::Create_file_log_event(const char* buf, uint len,
 
3255
Create_file_log_event::Create_file_log_event(const char* buf, uint32_t len,
4953
3256
                                             const Format_description_log_event* description_event)
4954
3257
  :Load_log_event(buf,0,description_event),fake_base(0),block(0),inited_from_old(0)
4955
3258
{
4956
 
  uint block_offset;
4957
 
  uint header_len= description_event->common_header_len;
 
3259
  uint32_t block_offset;
 
3260
  uint32_t header_len= description_event->common_header_len;
4958
3261
  uint8_t load_header_len= description_event->post_header_len[LOAD_EVENT-1];
4959
3262
  uint8_t create_file_header_len= description_event->post_header_len[CREATE_FILE_EVENT-1];
4960
 
  if (!(event_buf= (char*) my_memdup(buf, len, MYF(MY_WME))) ||
 
3263
  if (!(event_buf= (const char*)malloc(len)) ||
 
3264
      memcpy((char *)event_buf, buf, len) ||
4961
3265
      copy_log_event(event_buf,len,
4962
3266
                     ((buf[EVENT_TYPE_OFFSET] == LOAD_EVENT) ?
4963
3267
                      load_header_len + header_len :
4968
3272
    return;
4969
3273
  if (description_event->binlog_version!=1)
4970
3274
  {
4971
 
    file_id= uint4korr(buf + 
 
3275
    file_id= uint4korr(buf +
4972
3276
                       header_len +
4973
3277
                       load_header_len + CF_FILE_ID_OFFSET);
4974
3278
    /*
4980
3284
      as these Load events are not changed between 4.0 and 5.0 (as logging of
4981
3285
      LOAD DATA INFILE does not use Load_log_event in 5.0).
4982
3286
 
4983
 
      The + 1 is for \0 terminating fname  
 
3287
      The + 1 is for \0 terminating fname
4984
3288
    */
4985
3289
    block_offset= (description_event->common_header_len +
4986
3290
                   Load_log_event::get_data_size() +
4987
3291
                   create_file_header_len + 1);
4988
3292
    if (len < block_offset)
4989
3293
      return;
4990
 
    block = (uchar*)buf + block_offset;
 
3294
    block = (unsigned char*)buf + block_offset;
4991
3295
    block_len = len - block_offset;
4992
3296
  }
4993
3297
  else
5000
3304
 
5001
3305
 
5002
3306
/*
5003
 
  Create_file_log_event::print()
5004
 
*/
5005
 
 
5006
 
#ifdef DRIZZLE_CLIENT
5007
 
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info,
5008
 
                                  bool enable_local)
5009
 
{
5010
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
5011
 
 
5012
 
  if (print_event_info->short_form)
5013
 
  {
5014
 
    if (enable_local && check_fname_outside_temp_buf())
5015
 
      Load_log_event::print(file, print_event_info);
5016
 
    return;
5017
 
  }
5018
 
 
5019
 
  if (enable_local)
5020
 
  {
5021
 
    Load_log_event::print(file, print_event_info,
5022
 
                          !check_fname_outside_temp_buf());
5023
 
    /* 
5024
 
       That one is for "file_id: etc" below: in mysqlbinlog we want the #, in
5025
 
       SHOW BINLOG EVENTS we don't.
5026
 
    */
5027
 
    my_b_printf(&cache, "#"); 
5028
 
  }
5029
 
 
5030
 
  my_b_printf(&cache, " file_id: %d  block_len: %d\n", file_id, block_len);
5031
 
}
5032
 
 
5033
 
 
5034
 
void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info)
5035
 
{
5036
 
  print(file, print_event_info, 0);
5037
 
}
5038
 
#endif /* DRIZZLE_CLIENT */
5039
 
 
5040
 
 
5041
 
/*
5042
3307
  Create_file_log_event::pack_info()
5043
3308
*/
5044
3309
 
5045
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5046
3310
void Create_file_log_event::pack_info(Protocol *protocol)
5047
3311
{
5048
3312
  char buf[NAME_LEN*2 + 30 + 21*2], *pos;
5049
 
  pos= stpcpy(buf, "db=");
 
3313
  pos= strcpy(buf, "db=")+3;
5050
3314
  memcpy(pos, db, db_len);
5051
 
  pos= stpcpy(pos + db_len, ";table=");
 
3315
  pos= strcpy(pos + db_len, ";table=")+7;
5052
3316
  memcpy(pos, table_name, table_name_len);
5053
 
  pos= stpcpy(pos + table_name_len, ";file_id=");
 
3317
  pos= strcpy(pos + table_name_len, ";file_id=")+9;
5054
3318
  pos= int10_to_str((long) file_id, pos, 10);
5055
 
  pos= stpcpy(pos, ";block_len=");
 
3319
  pos= strcpy(pos, ";block_len=")+11;
5056
3320
  pos= int10_to_str((long) block_len, pos, 10);
5057
3321
  protocol->store(buf, (uint) (pos-buf), &my_charset_bin);
5058
3322
}
5059
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5060
3323
 
5061
3324
 
5062
3325
/*
5063
3326
  Create_file_log_event::do_apply_event()
5064
3327
*/
5065
3328
 
5066
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5067
3329
int Create_file_log_event::do_apply_event(Relay_log_info const *rli)
5068
3330
{
5069
3331
  char proc_info[17+FN_REFLEN+10], *fname_buf;
5073
3335
  int error = 1;
5074
3336
 
5075
3337
  memset(&file, 0, sizeof(file));
5076
 
  fname_buf= stpcpy(proc_info, "Making temp file ");
 
3338
  fname_buf= strcpy(proc_info, "Making temp file ")+17;
5077
3339
  ext= slave_load_file_stem(fname_buf, file_id, server_id, ".info");
5078
 
  thd_proc_info(thd, proc_info);
 
3340
  session->set_proc_info(proc_info);
5079
3341
  my_delete(fname_buf, MYF(0)); // old copy may exist already
5080
3342
  if ((fd= my_create(fname_buf, CREATE_MODE,
5081
 
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
3343
                     O_WRONLY | O_EXCL,
5082
3344
                     MYF(MY_WME))) < 0 ||
5083
3345
      init_io_cache(&file, fd, IO_SIZE, WRITE_CACHE, (my_off_t)0, 0,
5084
3346
                    MYF(MY_WME|MY_NABP)))
5085
3347
  {
5086
3348
    rli->report(ERROR_LEVEL, my_errno,
5087
 
                "Error in Create_file event: could not open file '%s'",
 
3349
                _("Error in Create_file event: could not open file '%s'"),
5088
3350
                fname_buf);
5089
3351
    goto err;
5090
3352
  }
5091
 
  
 
3353
 
5092
3354
  // a trick to avoid allocating another buffer
5093
3355
  fname= fname_buf;
5094
 
  fname_len= (uint) (stpcpy(ext, ".data") - fname);
 
3356
  fname_len= (uint) ((strcpy(ext, ".data") + 5) - fname);
5095
3357
  if (write_base(&file))
5096
3358
  {
5097
 
    stpcpy(ext, ".info"); // to have it right in the error message
 
3359
    strcpy(ext, ".info"); // to have it right in the error message
5098
3360
    rli->report(ERROR_LEVEL, my_errno,
5099
 
                "Error in Create_file event: could not write to file '%s'",
 
3361
                _("Error in Create_file event: could not write to file '%s'"),
5100
3362
                fname_buf);
5101
3363
    goto err;
5102
3364
  }
5103
3365
  end_io_cache(&file);
5104
3366
  my_close(fd, MYF(0));
5105
 
  
 
3367
 
5106
3368
  // fname_buf now already has .data, not .info, because we did our trick
5107
3369
  my_delete(fname_buf, MYF(0)); // old copy may exist already
5108
3370
  if ((fd= my_create(fname_buf, CREATE_MODE,
5109
 
                     O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
5110
 
                     MYF(MY_WME))) < 0)
 
3371
                     O_WRONLY | O_EXCL,
 
3372
                     MYF(MY_WME))) < 0)
5111
3373
  {
5112
3374
    rli->report(ERROR_LEVEL, my_errno,
5113
 
                "Error in Create_file event: could not open file '%s'",
 
3375
                _("Error in Create_file event: could not open file '%s'"),
5114
3376
                fname_buf);
5115
3377
    goto err;
5116
3378
  }
5117
 
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
 
3379
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
5118
3380
  {
5119
3381
    rli->report(ERROR_LEVEL, my_errno,
5120
 
                "Error in Create_file event: write to '%s' failed",
 
3382
                _("Error in Create_file event: write to '%s' failed"),
5121
3383
                fname_buf);
5122
3384
    goto err;
5123
3385
  }
5128
3390
    end_io_cache(&file);
5129
3391
  if (fd >= 0)
5130
3392
    my_close(fd, MYF(0));
5131
 
  thd_proc_info(thd, 0);
 
3393
  session->set_proc_info(0);
5132
3394
  return error == 0;
5133
3395
}
5134
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5135
3396
 
5136
3397
 
5137
3398
/**************************************************************************
5142
3403
  Append_block_log_event ctor
5143
3404
*/
5144
3405
 
5145
 
#ifndef DRIZZLE_CLIENT  
5146
 
Append_block_log_event::Append_block_log_event(THD *thd_arg,
 
3406
Append_block_log_event::Append_block_log_event(Session *session_arg,
5147
3407
                                               const char *db_arg,
5148
 
                                               uchar *block_arg,
5149
 
                                               uint block_len_arg,
 
3408
                                               unsigned char *block_arg,
 
3409
                                               uint32_t block_len_arg,
5150
3410
                                               bool using_trans)
5151
 
  :Log_event(thd_arg,0, using_trans), block(block_arg),
5152
 
   block_len(block_len_arg), file_id(thd_arg->file_id), db(db_arg)
 
3411
  :Log_event(session_arg,0, using_trans), block(block_arg),
 
3412
   block_len(block_len_arg), file_id(session_arg->file_id), db(db_arg)
5153
3413
{
5154
3414
}
5155
 
#endif
5156
3415
 
5157
3416
 
5158
3417
/*
5159
3418
  Append_block_log_event ctor
5160
3419
*/
5161
3420
 
5162
 
Append_block_log_event::Append_block_log_event(const char* buf, uint len,
 
3421
Append_block_log_event::Append_block_log_event(const char* buf, uint32_t len,
5163
3422
                                               const Format_description_log_event* description_event)
5164
3423
  :Log_event(buf, description_event),block(0)
5165
3424
{
5166
 
  uint8_t common_header_len= description_event->common_header_len; 
 
3425
  uint8_t common_header_len= description_event->common_header_len;
5167
3426
  uint8_t append_block_header_len=
5168
3427
    description_event->post_header_len[APPEND_BLOCK_EVENT-1];
5169
 
  uint total_header_len= common_header_len+append_block_header_len;
 
3428
  uint32_t total_header_len= common_header_len+append_block_header_len;
5170
3429
  if (len < total_header_len)
5171
3430
    return;
5172
3431
  file_id= uint4korr(buf + common_header_len + AB_FILE_ID_OFFSET);
5173
 
  block= (uchar*)buf + total_header_len;
 
3432
  block= (unsigned char*)buf + total_header_len;
5174
3433
  block_len= len - total_header_len;
5175
3434
  return;
5176
3435
}
5180
3439
  Append_block_log_event::write()
5181
3440
*/
5182
3441
 
5183
 
#ifndef DRIZZLE_CLIENT
5184
3442
bool Append_block_log_event::write(IO_CACHE* file)
5185
3443
{
5186
 
  uchar buf[APPEND_BLOCK_HEADER_LEN];
 
3444
  unsigned char buf[APPEND_BLOCK_HEADER_LEN];
5187
3445
  int4store(buf + AB_FILE_ID_OFFSET, file_id);
5188
3446
  return (write_header(file, APPEND_BLOCK_HEADER_LEN + block_len) ||
5189
3447
          my_b_safe_write(file, buf, APPEND_BLOCK_HEADER_LEN) ||
5190
 
          my_b_safe_write(file, (uchar*) block, block_len));
5191
 
}
5192
 
#endif
5193
 
 
5194
 
 
5195
 
/*
5196
 
  Append_block_log_event::print()
5197
 
*/
5198
 
 
5199
 
#ifdef DRIZZLE_CLIENT  
5200
 
void Append_block_log_event::print(FILE* file,
5201
 
                                   PRINT_EVENT_INFO* print_event_info)
5202
 
{
5203
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
5204
 
 
5205
 
  if (print_event_info->short_form)
5206
 
    return;
5207
 
  print_header(&cache, print_event_info, false);
5208
 
  my_b_printf(&cache, "\n#%s: file_id: %d  block_len: %d\n",
5209
 
              get_type_str(), file_id, block_len);
5210
 
}
5211
 
#endif /* DRIZZLE_CLIENT */
 
3448
          my_b_safe_write(file, (unsigned char*) block, block_len));
 
3449
}
5212
3450
 
5213
3451
 
5214
3452
/*
5215
3453
  Append_block_log_event::pack_info()
5216
3454
*/
5217
3455
 
5218
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5219
3456
void Append_block_log_event::pack_info(Protocol *protocol)
5220
3457
{
5221
3458
  char buf[256];
5222
 
  uint length;
 
3459
  uint32_t length;
5223
3460
  length= (uint) sprintf(buf, ";file_id=%u;block_len=%u", file_id,
5224
3461
                             block_len);
5225
3462
  protocol->store(buf, length, &my_charset_bin);
5245
3482
  int fd;
5246
3483
  int error = 1;
5247
3484
 
5248
 
  fname= stpcpy(proc_info, "Making temp file ");
 
3485
  fname= strcpy(proc_info, "Making temp file ")+17;
5249
3486
  slave_load_file_stem(fname, file_id, server_id, ".data");
5250
 
  thd_proc_info(thd, proc_info);
 
3487
  session->set_proc_info(proc_info);
5251
3488
  if (get_create_or_append())
5252
3489
  {
5253
3490
    my_delete(fname, MYF(0)); // old copy may exist already
5254
3491
    if ((fd= my_create(fname, CREATE_MODE,
5255
 
                       O_WRONLY | O_BINARY | O_EXCL | O_NOFOLLOW,
 
3492
                       O_WRONLY | O_EXCL,
5256
3493
                       MYF(MY_WME))) < 0)
5257
3494
    {
5258
3495
      rli->report(ERROR_LEVEL, my_errno,
5259
 
                  "Error in %s event: could not create file '%s'",
 
3496
                  _("Error in %s event: could not create file '%s'"),
5260
3497
                  get_type_str(), fname);
5261
3498
      goto err;
5262
3499
    }
5263
3500
  }
5264
 
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND | O_BINARY | O_NOFOLLOW,
 
3501
  else if ((fd = my_open(fname, O_WRONLY | O_APPEND,
5265
3502
                         MYF(MY_WME))) < 0)
5266
3503
  {
5267
3504
    rli->report(ERROR_LEVEL, my_errno,
5268
 
                "Error in %s event: could not open file '%s'",
 
3505
                _("Error in %s event: could not open file '%s'"),
5269
3506
                get_type_str(), fname);
5270
3507
    goto err;
5271
3508
  }
5272
 
  if (my_write(fd, (uchar*) block, block_len, MYF(MY_WME+MY_NABP)))
 
3509
  if (my_write(fd, (unsigned char*) block, block_len, MYF(MY_WME+MY_NABP)))
5273
3510
  {
5274
3511
    rli->report(ERROR_LEVEL, my_errno,
5275
 
                "Error in %s event: write to '%s' failed",
 
3512
                _("Error in %s event: write to '%s' failed"),
5276
3513
                get_type_str(), fname);
5277
3514
    goto err;
5278
3515
  }
5281
3518
err:
5282
3519
  if (fd >= 0)
5283
3520
    my_close(fd, MYF(0));
5284
 
  thd_proc_info(thd, 0);
 
3521
  session->set_proc_info(0);
5285
3522
  return(error);
5286
3523
}
5287
 
#endif
5288
3524
 
5289
3525
 
5290
3526
/**************************************************************************
5295
3531
  Delete_file_log_event ctor
5296
3532
*/
5297
3533
 
5298
 
#ifndef DRIZZLE_CLIENT
5299
 
Delete_file_log_event::Delete_file_log_event(THD *thd_arg, const char* db_arg,
 
3534
Delete_file_log_event::Delete_file_log_event(Session *session_arg, const char* db_arg,
5300
3535
                                             bool using_trans)
5301
 
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
 
3536
  :Log_event(session_arg, 0, using_trans), file_id(session_arg->file_id), db(db_arg)
5302
3537
{
5303
3538
}
5304
 
#endif
5305
3539
 
5306
3540
/*
5307
3541
  Delete_file_log_event ctor
5308
3542
*/
5309
3543
 
5310
 
Delete_file_log_event::Delete_file_log_event(const char* buf, uint len,
 
3544
Delete_file_log_event::Delete_file_log_event(const char* buf, uint32_t len,
5311
3545
                                             const Format_description_log_event* description_event)
5312
3546
  :Log_event(buf, description_event),file_id(0)
5313
3547
{
5323
3557
  Delete_file_log_event::write()
5324
3558
*/
5325
3559
 
5326
 
#ifndef DRIZZLE_CLIENT
5327
3560
bool Delete_file_log_event::write(IO_CACHE* file)
5328
3561
{
5329
 
 uchar buf[DELETE_FILE_HEADER_LEN];
 
3562
 unsigned char buf[DELETE_FILE_HEADER_LEN];
5330
3563
 int4store(buf + DF_FILE_ID_OFFSET, file_id);
5331
3564
 return (write_header(file, sizeof(buf)) ||
5332
3565
         my_b_safe_write(file, buf, sizeof(buf)));
5333
3566
}
5334
 
#endif
5335
 
 
5336
 
 
5337
 
/*
5338
 
  Delete_file_log_event::print()
5339
 
*/
5340
 
 
5341
 
#ifdef DRIZZLE_CLIENT  
5342
 
void Delete_file_log_event::print(FILE* file,
5343
 
                                  PRINT_EVENT_INFO* print_event_info)
5344
 
{
5345
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
5346
 
 
5347
 
  if (print_event_info->short_form)
5348
 
    return;
5349
 
  print_header(&cache, print_event_info, false);
5350
 
  my_b_printf(&cache, "\n#Delete_file: file_id=%u\n", file_id);
5351
 
}
5352
 
#endif /* DRIZZLE_CLIENT */
 
3567
 
5353
3568
 
5354
3569
/*
5355
3570
  Delete_file_log_event::pack_info()
5356
3571
*/
5357
3572
 
5358
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5359
3573
void Delete_file_log_event::pack_info(Protocol *protocol)
5360
3574
{
5361
3575
  char buf[64];
5362
 
  uint length;
 
3576
  uint32_t length;
5363
3577
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
5364
3578
  protocol->store(buf, (int32_t) length, &my_charset_bin);
5365
3579
}
5366
 
#endif
5367
3580
 
5368
3581
/*
5369
3582
  Delete_file_log_event::do_apply_event()
5370
3583
*/
5371
3584
 
5372
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5373
 
int Delete_file_log_event::do_apply_event(Relay_log_info const *rli __attribute__((unused)))
 
3585
int Delete_file_log_event::do_apply_event(const Relay_log_info *)
5374
3586
{
5375
3587
  char fname[FN_REFLEN+10];
5376
3588
  char *ext= slave_load_file_stem(fname, file_id, server_id, ".data");
5377
3589
  (void) my_delete(fname, MYF(MY_WME));
5378
 
  stpcpy(ext, ".info");
 
3590
  strcpy(ext, ".info");
5379
3591
  (void) my_delete(fname, MYF(MY_WME));
5380
3592
  return 0;
5381
3593
}
5382
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5383
3594
 
5384
3595
 
5385
3596
/**************************************************************************
5390
3601
  Execute_load_log_event ctor
5391
3602
*/
5392
3603
 
5393
 
#ifndef DRIZZLE_CLIENT  
5394
 
Execute_load_log_event::Execute_load_log_event(THD *thd_arg,
 
3604
Execute_load_log_event::Execute_load_log_event(Session *session_arg,
5395
3605
                                               const char* db_arg,
5396
3606
                                               bool using_trans)
5397
 
  :Log_event(thd_arg, 0, using_trans), file_id(thd_arg->file_id), db(db_arg)
 
3607
  :Log_event(session_arg, 0, using_trans), file_id(session_arg->file_id), db(db_arg)
5398
3608
{
5399
3609
}
5400
 
#endif
5401
 
  
 
3610
 
5402
3611
 
5403
3612
/*
5404
3613
  Execute_load_log_event ctor
5405
3614
*/
5406
3615
 
5407
 
Execute_load_log_event::Execute_load_log_event(const char* buf, uint len,
 
3616
Execute_load_log_event::Execute_load_log_event(const char* buf, uint32_t len,
5408
3617
                                               const Format_description_log_event* description_event)
5409
3618
  :Log_event(buf, description_event), file_id(0)
5410
3619
{
5420
3629
  Execute_load_log_event::write()
5421
3630
*/
5422
3631
 
5423
 
#ifndef DRIZZLE_CLIENT
5424
3632
bool Execute_load_log_event::write(IO_CACHE* file)
5425
3633
{
5426
 
  uchar buf[EXEC_LOAD_HEADER_LEN];
 
3634
  unsigned char buf[EXEC_LOAD_HEADER_LEN];
5427
3635
  int4store(buf + EL_FILE_ID_OFFSET, file_id);
5428
 
  return (write_header(file, sizeof(buf)) || 
 
3636
  return (write_header(file, sizeof(buf)) ||
5429
3637
          my_b_safe_write(file, buf, sizeof(buf)));
5430
3638
}
5431
 
#endif
5432
 
 
5433
 
 
5434
 
/*
5435
 
  Execute_load_log_event::print()
5436
 
*/
5437
 
 
5438
 
#ifdef DRIZZLE_CLIENT  
5439
 
void Execute_load_log_event::print(FILE* file,
5440
 
                                   PRINT_EVENT_INFO* print_event_info)
5441
 
{
5442
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
5443
 
 
5444
 
  if (print_event_info->short_form)
5445
 
    return;
5446
 
  print_header(&cache, print_event_info, false);
5447
 
  my_b_printf(&cache, "\n#Exec_load: file_id=%d\n",
5448
 
              file_id);
5449
 
}
5450
 
#endif
 
3639
 
5451
3640
 
5452
3641
/*
5453
3642
  Execute_load_log_event::pack_info()
5454
3643
*/
5455
3644
 
5456
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5457
3645
void Execute_load_log_event::pack_info(Protocol *protocol)
5458
3646
{
5459
3647
  char buf[64];
5460
 
  uint length;
 
3648
  uint32_t length;
5461
3649
  length= (uint) sprintf(buf, ";file_id=%u", (uint) file_id);
5462
3650
  protocol->store(buf, (int32_t) length, &my_charset_bin);
5463
3651
}
5477
3665
  Load_log_event *lev= 0;
5478
3666
 
5479
3667
  ext= slave_load_file_stem(fname, file_id, server_id, ".info");
5480
 
  if ((fd = my_open(fname, O_RDONLY | O_BINARY | O_NOFOLLOW,
 
3668
  if ((fd = my_open(fname, O_RDONLY,
5481
3669
                    MYF(MY_WME))) < 0 ||
5482
3670
      init_io_cache(&file, fd, IO_SIZE, READ_CACHE, (my_off_t)0, 0,
5483
3671
                    MYF(MY_WME|MY_NABP)))
5484
3672
  {
5485
3673
    rli->report(ERROR_LEVEL, my_errno,
5486
 
                "Error in Exec_load event: could not open file '%s'",
 
3674
                _("Error in Exec_load event: could not open file '%s'"),
5487
3675
                fname);
5488
3676
    goto err;
5489
3677
  }
5492
3680
                                                         rli->relay_log.description_event_for_exec)) ||
5493
3681
      lev->get_type_code() != NEW_LOAD_EVENT)
5494
3682
  {
5495
 
    rli->report(ERROR_LEVEL, 0, "Error in Exec_load event: "
5496
 
                    "file '%s' appears corrupted", fname);
 
3683
    rli->report(ERROR_LEVEL, 0,
 
3684
                _("Error in Exec_load event: "
 
3685
                  "file '%s' appears corrupted"),
 
3686
                fname);
5497
3687
    goto err;
5498
3688
  }
5499
3689
 
5500
 
  lev->thd = thd;
 
3690
  lev->session = session;
5501
3691
  /*
5502
3692
    lev->do_apply_event should use rli only for errors i.e. should
5503
3693
    not advance rli's position.
5507
3697
  */
5508
3698
 
5509
3699
  const_cast<Relay_log_info*>(rli)->future_group_master_log_pos= log_pos;
5510
 
  if (lev->do_apply_event(0,rli,1)) 
 
3700
  if (lev->do_apply_event(0,rli,1))
5511
3701
  {
5512
3702
    /*
5513
3703
      We want to indicate the name of the file that could not be loaded
5517
3707
      don't want to overwrite it with the filename.
5518
3708
      What we want instead is add the filename to the current error message.
5519
3709
    */
5520
 
    char *tmp= my_strdup(rli->last_error().message, MYF(MY_WME));
 
3710
    char *tmp= strdup(rli->last_error().message);
5521
3711
    if (tmp)
5522
3712
    {
5523
3713
      rli->report(ERROR_LEVEL, rli->last_error().number,
5524
 
                  "%s. Failed executing load from '%s'", tmp, fname);
5525
 
      my_free(tmp,MYF(0));
 
3714
                  _("%s. Failed executing load from '%s'"),
 
3715
                  tmp, fname);
 
3716
      free(tmp);
5526
3717
    }
5527
3718
    goto err;
5528
3719
  }
5551
3742
  return error;
5552
3743
}
5553
3744
 
5554
 
#endif /* defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5555
 
 
5556
3745
 
5557
3746
/**************************************************************************
5558
3747
        Begin_load_query_log_event methods
5559
3748
**************************************************************************/
5560
3749
 
5561
 
#ifndef DRIZZLE_CLIENT
5562
3750
Begin_load_query_log_event::
5563
 
Begin_load_query_log_event(THD* thd_arg, const char* db_arg, uchar* block_arg,
5564
 
                           uint block_len_arg, bool using_trans)
5565
 
  :Append_block_log_event(thd_arg, db_arg, block_arg, block_len_arg,
 
3751
Begin_load_query_log_event(Session* session_arg, const char* db_arg, unsigned char* block_arg,
 
3752
                           uint32_t block_len_arg, bool using_trans)
 
3753
  :Append_block_log_event(session_arg, db_arg, block_arg, block_len_arg,
5566
3754
                          using_trans)
5567
3755
{
5568
 
   file_id= thd_arg->file_id= mysql_bin_log.next_file_id();
 
3756
   file_id= session_arg->file_id= drizzle_bin_log.next_file_id();
5569
3757
}
5570
 
#endif
5571
3758
 
5572
3759
 
5573
3760
Begin_load_query_log_event::
5574
 
Begin_load_query_log_event(const char* buf, uint len,
 
3761
Begin_load_query_log_event(const char* buf, uint32_t len,
5575
3762
                           const Format_description_log_event* desc_event)
5576
3763
  :Append_block_log_event(buf, len, desc_event)
5577
3764
{
5578
3765
}
5579
3766
 
5580
3767
 
5581
 
#if defined( HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
5582
3768
int Begin_load_query_log_event::get_create_or_append() const
5583
3769
{
5584
3770
  return 1; /* create the file */
5585
3771
}
5586
 
#endif /* defined( HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT) */
5587
 
 
5588
 
 
5589
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
 
3772
 
 
3773
 
5590
3774
Log_event::enum_skip_reason
5591
3775
Begin_load_query_log_event::do_shall_skip(Relay_log_info *rli)
5592
3776
{
5596
3780
  */
5597
3781
  return continue_group(rli);
5598
3782
}
5599
 
#endif
5600
3783
 
5601
3784
 
5602
3785
/**************************************************************************
5604
3787
**************************************************************************/
5605
3788
 
5606
3789
 
5607
 
#ifndef DRIZZLE_CLIENT
5608
3790
Execute_load_query_log_event::
5609
 
Execute_load_query_log_event(THD *thd_arg, const char* query_arg,
5610
 
                             ulong query_length_arg, uint fn_pos_start_arg,
5611
 
                             uint fn_pos_end_arg,
 
3791
Execute_load_query_log_event(Session *session_arg, const char* query_arg,
 
3792
                             ulong query_length_arg, uint32_t fn_pos_start_arg,
 
3793
                             uint32_t fn_pos_end_arg,
5612
3794
                             enum_load_dup_handling dup_handling_arg,
5613
3795
                             bool using_trans, bool suppress_use,
5614
 
                             THD::killed_state killed_err_arg):
5615
 
  Query_log_event(thd_arg, query_arg, query_length_arg, using_trans,
 
3796
                             Session::killed_state killed_err_arg):
 
3797
  Query_log_event(session_arg, query_arg, query_length_arg, using_trans,
5616
3798
                  suppress_use, killed_err_arg),
5617
 
  file_id(thd_arg->file_id), fn_pos_start(fn_pos_start_arg),
 
3799
  file_id(session_arg->file_id), fn_pos_start(fn_pos_start_arg),
5618
3800
  fn_pos_end(fn_pos_end_arg), dup_handling(dup_handling_arg)
5619
3801
{
5620
3802
}
5621
 
#endif /* !DRIZZLE_CLIENT */
5622
3803
 
5623
3804
 
5624
3805
Execute_load_query_log_event::
5625
 
Execute_load_query_log_event(const char* buf, uint event_len,
 
3806
Execute_load_query_log_event(const char* buf, uint32_t event_len,
5626
3807
                             const Format_description_log_event* desc_event):
5627
3808
  Query_log_event(buf, event_len, desc_event, EXECUTE_LOAD_QUERY_EVENT),
5628
3809
  file_id(0), fn_pos_start(0), fn_pos_end(0)
5650
3831
}
5651
3832
 
5652
3833
 
5653
 
#ifndef DRIZZLE_CLIENT
5654
3834
bool
5655
3835
Execute_load_query_log_event::write_post_header_for_derived(IO_CACHE* file)
5656
3836
{
5657
 
  uchar buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
 
3837
  unsigned char buf[EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN];
5658
3838
  int4store(buf, file_id);
5659
3839
  int4store(buf + 4, fn_pos_start);
5660
3840
  int4store(buf + 4 + 4, fn_pos_end);
5661
 
  *(buf + 4 + 4 + 4)= (uchar) dup_handling;
 
3841
  *(buf + 4 + 4 + 4)= (unsigned char) dup_handling;
5662
3842
  return my_b_safe_write(file, buf, EXECUTE_LOAD_QUERY_EXTRA_HEADER_LEN);
5663
3843
}
5664
 
#endif
5665
 
 
5666
 
 
5667
 
#ifdef DRIZZLE_CLIENT
5668
 
void Execute_load_query_log_event::print(FILE* file,
5669
 
                                         PRINT_EVENT_INFO* print_event_info)
5670
 
{
5671
 
  print(file, print_event_info, 0);
5672
 
}
5673
 
 
5674
 
/**
5675
 
  Prints the query as LOAD DATA LOCAL and with rewritten filename.
5676
 
*/
5677
 
void Execute_load_query_log_event::print(FILE* file,
5678
 
                                         PRINT_EVENT_INFO* print_event_info,
5679
 
                                         const char *local_fname)
5680
 
{
5681
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
5682
 
 
5683
 
  print_query_header(&cache, print_event_info);
5684
 
 
5685
 
  if (local_fname)
5686
 
  {
5687
 
    my_b_write(&cache, (uchar*) query, fn_pos_start);
5688
 
    my_b_printf(&cache, " LOCAL INFILE \'");
5689
 
    my_b_printf(&cache, local_fname);
5690
 
    my_b_printf(&cache, "\'");
5691
 
    if (dup_handling == LOAD_DUP_REPLACE)
5692
 
      my_b_printf(&cache, " REPLACE");
5693
 
    my_b_printf(&cache, " INTO");
5694
 
    my_b_write(&cache, (uchar*) query + fn_pos_end, q_len-fn_pos_end);
5695
 
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5696
 
  }
5697
 
  else
5698
 
  {
5699
 
    my_b_write(&cache, (uchar*) query, q_len);
5700
 
    my_b_printf(&cache, "\n%s\n", print_event_info->delimiter);
5701
 
  }
5702
 
 
5703
 
  if (!print_event_info->short_form)
5704
 
    my_b_printf(&cache, "# file_id: %d \n", file_id);
5705
 
}
5706
 
#endif
5707
 
 
5708
 
 
5709
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
3844
 
 
3845
 
5710
3846
void Execute_load_query_log_event::pack_info(Protocol *protocol)
5711
3847
{
5712
3848
  char *buf, *pos;
5713
 
  if (!(buf= (char*) my_malloc(9 + db_len + q_len + 10 + 21, MYF(MY_WME))))
 
3849
  if (!(buf= (char*) malloc(9 + db_len + q_len + 10 + 21)))
5714
3850
    return;
5715
3851
  pos= buf;
5716
3852
  if (db && db_len)
5717
3853
  {
5718
 
    pos= stpcpy(buf, "use `");
 
3854
    pos= strcpy(buf, "use `")+5;
5719
3855
    memcpy(pos, db, db_len);
5720
 
    pos= stpcpy(pos+db_len, "`; ");
 
3856
    pos= strcpy(pos+db_len, "`; ")+3;
5721
3857
  }
5722
3858
  if (query && q_len)
5723
3859
  {
5724
3860
    memcpy(pos, query, q_len);
5725
3861
    pos+= q_len;
5726
3862
  }
5727
 
  pos= stpcpy(pos, " ;file_id=");
 
3863
  pos= strcpy(pos, " ;file_id=")+10;
5728
3864
  pos= int10_to_str((long) file_id, pos, 10);
5729
3865
  protocol->store(buf, pos-buf, &my_charset_bin);
5730
 
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
3866
  free(buf);
5731
3867
}
5732
3868
 
5733
3869
 
5740
3876
  char *fname_end;
5741
3877
  int error;
5742
3878
 
5743
 
  buf= (char*) my_malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
5744
 
                         (FN_REFLEN + 10) + 10 + 8 + 5, MYF(MY_WME));
 
3879
  buf= (char*) malloc(q_len + 1 - (fn_pos_end - fn_pos_start) +
 
3880
                      (FN_REFLEN + 10) + 10 + 8 + 5);
5745
3881
 
5746
3882
  /* Replace filename and LOCAL keyword in query before executing it */
5747
3883
  if (buf == NULL)
5748
3884
  {
5749
3885
    rli->report(ERROR_LEVEL, ER_SLAVE_FATAL_ERROR,
5750
 
                ER(ER_SLAVE_FATAL_ERROR), "Not enough memory");
 
3886
                ER(ER_SLAVE_FATAL_ERROR),
 
3887
                _("Not enough memory"));
5751
3888
    return 1;
5752
3889
  }
5753
3890
 
5754
3891
  p= buf;
5755
3892
  memcpy(p, query, fn_pos_start);
5756
3893
  p+= fn_pos_start;
5757
 
  fname= (p= strmake(p, STRING_WITH_LEN(" INFILE \'")));
 
3894
  fname= (p= strncpy(p, STRING_WITH_LEN(" INFILE \'")) + 9);
5758
3895
  p= slave_load_file_stem(p, file_id, server_id, ".data");
5759
 
  fname_end= p= strend(p);                      // Safer than p=p+5
 
3896
  fname_end= p= strchr(p, '\0');                      // Safer than p=p+5
5760
3897
  *(p++)='\'';
5761
3898
  switch (dup_handling) {
5762
3899
  case LOAD_DUP_IGNORE:
5763
 
    p= strmake(p, STRING_WITH_LEN(" IGNORE"));
 
3900
    p= strncpy(p, STRING_WITH_LEN(" IGNORE")) + 7;
5764
3901
    break;
5765
3902
  case LOAD_DUP_REPLACE:
5766
 
    p= strmake(p, STRING_WITH_LEN(" REPLACE"));
 
3903
    p= strncpy(p, STRING_WITH_LEN(" REPLACE")) + 8;
5767
3904
    break;
5768
3905
  default:
5769
3906
    /* Ordinary load data */
5770
3907
    break;
5771
3908
  }
5772
 
  p= strmake(p, STRING_WITH_LEN(" INTO"));
5773
 
  p= strmake(p, query+fn_pos_end, q_len-fn_pos_end);
 
3909
  size_t end_len = q_len-fn_pos_end;
 
3910
  p= strncpy(p, STRING_WITH_LEN(" INTO")) + 5;
 
3911
  p= strncpy(p, query+fn_pos_end, end_len);
 
3912
  p+= end_len;
5774
3913
 
5775
3914
  error= Query_log_event::do_apply_event(rli, buf, p-buf);
5776
3915
 
5784
3923
  if (!error)
5785
3924
    (void) my_delete(fname, MYF(MY_WME));
5786
3925
 
5787
 
  my_free(buf, MYF(MY_ALLOW_ZERO_PTR));
 
3926
  free(buf);
5788
3927
  return error;
5789
3928
}
5790
 
#endif
5791
3929
 
5792
3930
 
5793
3931
/**************************************************************************
5807
3945
            write_str(file, line_term,  (uint) line_term_len) ||
5808
3946
            write_str(file, line_start, (uint) line_start_len) ||
5809
3947
            write_str(file, escaped,    (uint) escaped_len) ||
5810
 
            my_b_safe_write(file,(uchar*) &opt_flags,1));
 
3948
            my_b_safe_write(file,(unsigned char*) &opt_flags,1));
5811
3949
  }
5812
3950
  else
5813
 
  {
5814
 
    /**
5815
 
      @todo This is sensitive to field padding. We should write a
5816
 
      char[7], not an old_sql_ex. /sven
5817
 
    */
5818
 
    old_sql_ex old_ex;
5819
 
    old_ex.field_term= *field_term;
5820
 
    old_ex.enclosed=   *enclosed;
5821
 
    old_ex.line_term=  *line_term;
5822
 
    old_ex.line_start= *line_start;
5823
 
    old_ex.escaped=    *escaped;
5824
 
    old_ex.opt_flags=  opt_flags;
5825
 
    old_ex.empty_flags=empty_flags;
5826
 
    return my_b_safe_write(file, (uchar*) &old_ex, sizeof(old_ex)) != 0;
5827
 
  }
 
3951
    assert(0);
 
3952
  return true;
5828
3953
}
5829
3954
 
5830
3955
 
5883
4008
        Rows_log_event member functions
5884
4009
**************************************************************************/
5885
4010
 
5886
 
#ifndef DRIZZLE_CLIENT
5887
 
Rows_log_event::Rows_log_event(THD *thd_arg, TABLE *tbl_arg, ulong tid,
 
4011
Rows_log_event::Rows_log_event(Session *session_arg, Table *tbl_arg, ulong tid,
5888
4012
                               MY_BITMAP const *cols, bool is_transactional)
5889
 
  : Log_event(thd_arg, 0, is_transactional),
 
4013
  : Log_event(session_arg, 0, is_transactional),
5890
4014
    m_row_count(0),
5891
4015
    m_table(tbl_arg),
5892
4016
    m_table_id(tid),
5893
4017
    m_width(tbl_arg ? tbl_arg->s->fields : 1),
5894
 
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0) 
5895
 
#ifdef HAVE_REPLICATION
 
4018
    m_rows_buf(0), m_rows_cur(0), m_rows_end(0), m_flags(0)
5896
4019
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
5897
 
#endif
5898
4020
{
5899
4021
  /*
5900
4022
    We allow a special form of dummy event when the table, and cols
5901
 
    are null and the table id is ~0UL.  This is a temporary
 
4023
    are null and the table id is UINT32_MAX.  This is a temporary
5902
4024
    solution, to be able to terminate a started statement in the
5903
4025
    binary log: the extraneous events will be removed in the future.
5904
4026
   */
5905
 
  assert((tbl_arg && tbl_arg->s && tid != ~0UL) || (!tbl_arg && !cols && tid == ~0UL));
 
4027
  assert((tbl_arg && tbl_arg->s && tid != UINT32_MAX) || (!tbl_arg && !cols && tid == UINT32_MAX));
5906
4028
 
5907
 
  if (thd_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
 
4029
  if (session_arg->options & OPTION_NO_FOREIGN_KEY_CHECKS)
5908
4030
      set_flags(NO_FOREIGN_KEY_CHECKS_F);
5909
 
  if (thd_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
 
4031
  if (session_arg->options & OPTION_RELAXED_UNIQUE_CHECKS)
5910
4032
      set_flags(RELAXED_UNIQUE_CHECKS_F);
5911
4033
  /* if bitmap_init fails, caught in is_valid() */
5912
4034
  if (likely(!bitmap_init(&m_cols,
5927
4049
    m_cols.bitmap= 0;
5928
4050
  }
5929
4051
}
5930
 
#endif
5931
 
 
5932
 
Rows_log_event::Rows_log_event(const char *buf, uint event_len,
 
4052
 
 
4053
 
 
4054
Rows_log_event::Rows_log_event(const char *buf, uint32_t event_len,
5933
4055
                               Log_event_type event_type,
5934
4056
                               const Format_description_log_event
5935
4057
                               *description_event)
5936
4058
  : Log_event(buf, description_event),
5937
4059
    m_row_count(0),
5938
 
#ifndef DRIZZLE_CLIENT
5939
4060
    m_table(NULL),
5940
 
#endif
5941
4061
    m_table_id(0), m_rows_buf(0), m_rows_cur(0), m_rows_end(0)
5942
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
5943
4062
    , m_curr_row(NULL), m_curr_row_end(NULL), m_key(NULL)
5944
 
#endif
5945
4063
{
5946
4064
  uint8_t const common_header_len= description_event->common_header_len;
5947
4065
  uint8_t const post_header_len= description_event->post_header_len[event_type-1];
5962
4080
 
5963
4081
  m_flags= uint2korr(post_start);
5964
4082
 
5965
 
  uchar const *const var_start=
5966
 
    (const uchar *)buf + common_header_len + post_header_len;
5967
 
  uchar const *const ptr_width= var_start;
5968
 
  uchar *ptr_after_width= (uchar*) ptr_width;
 
4083
  unsigned char const *const var_start=
 
4084
    (const unsigned char *)buf + common_header_len + post_header_len;
 
4085
  unsigned char const *const ptr_width= var_start;
 
4086
  unsigned char *ptr_after_width= (unsigned char*) ptr_width;
5969
4087
  m_width = net_field_length(&ptr_after_width);
5970
4088
  /* if bitmap_init fails, catched in is_valid() */
5971
4089
  if (likely(!bitmap_init(&m_cols,
6006
4124
    }
6007
4125
  }
6008
4126
 
6009
 
  const uchar* const ptr_rows_data= (const uchar*) ptr_after_width;
6010
 
 
6011
 
  size_t const data_size= event_len - (ptr_rows_data - (const uchar *) buf);
6012
 
 
6013
 
  m_rows_buf= (uchar*) my_malloc(data_size, MYF(MY_WME));
 
4127
  const unsigned char* const ptr_rows_data= (const unsigned char*) ptr_after_width;
 
4128
 
 
4129
  size_t const data_size= event_len - (ptr_rows_data - (const unsigned char *) buf);
 
4130
 
 
4131
  m_rows_buf= (unsigned char*) malloc(data_size);
6014
4132
  if (likely((bool)m_rows_buf))
6015
4133
  {
6016
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6017
4134
    m_curr_row= m_rows_buf;
6018
 
#endif
6019
4135
    m_rows_end= m_rows_buf + data_size;
6020
4136
    m_rows_cur= m_rows_end;
6021
4137
    memcpy(m_rows_buf, ptr_rows_data, data_size);
6028
4144
 
6029
4145
Rows_log_event::~Rows_log_event()
6030
4146
{
6031
 
  if (m_cols.bitmap == m_bitbuf) // no my_malloc happened
6032
 
    m_cols.bitmap= 0; // so no my_free in bitmap_free
 
4147
  if (m_cols.bitmap == m_bitbuf) // no malloc happened
 
4148
    m_cols.bitmap= 0; // so no free in bitmap_free
6033
4149
  bitmap_free(&m_cols); // To pair with bitmap_init().
6034
 
  my_free((uchar*)m_rows_buf, MYF(MY_ALLOW_ZERO_PTR));
 
4150
  free((unsigned char*)m_rows_buf);
6035
4151
}
6036
4152
 
6037
4153
int Rows_log_event::get_data_size()
6038
4154
{
6039
4155
  int const type_code= get_type_code();
6040
4156
 
6041
 
  uchar buf[sizeof(m_width)+1];
6042
 
  uchar *end= net_store_length(buf, (m_width + 7) / 8);
 
4157
  unsigned char buf[sizeof(m_width)+1];
 
4158
  unsigned char *end= net_store_length(buf, (m_width + 7) / 8);
6043
4159
 
6044
4160
  int data_size= ROWS_HEADER_LEN;
6045
4161
  data_size+= no_bytes_in_map(&m_cols);
6049
4165
    data_size+= no_bytes_in_map(&m_cols_ai);
6050
4166
 
6051
4167
  data_size+= (m_rows_cur - m_rows_buf);
6052
 
  return data_size; 
 
4168
  return data_size;
6053
4169
}
6054
4170
 
6055
4171
 
6056
 
#ifndef DRIZZLE_CLIENT
6057
 
int Rows_log_event::do_add_row_data(uchar *row_data, size_t length)
 
4172
int Rows_log_event::do_add_row_data(unsigned char *row_data, size_t length)
6058
4173
{
6059
4174
  /*
6060
4175
    When the table has a primary key, we would probably want, by default, to
6081
4196
  if (static_cast<size_t>(m_rows_end - m_rows_cur) <= length)
6082
4197
  {
6083
4198
    size_t const block_size= 1024;
6084
 
    my_ptrdiff_t const cur_size= m_rows_cur - m_rows_buf;
6085
 
    my_ptrdiff_t const new_alloc= 
 
4199
    const size_t cur_size= m_rows_cur - m_rows_buf;
 
4200
    const size_t new_alloc=
6086
4201
        block_size * ((cur_size + length + block_size - 1) / block_size);
6087
4202
 
6088
 
    uchar* const new_buf= (uchar*)my_realloc((uchar*)m_rows_buf, (uint) new_alloc,
6089
 
                                           MYF(MY_ALLOW_ZERO_PTR|MY_WME));
 
4203
    unsigned char* new_buf= (unsigned char*)realloc(m_rows_buf, new_alloc);
6090
4204
    if (unlikely(!new_buf))
6091
4205
      return(HA_ERR_OUT_OF_MEM);
6092
4206
 
6110
4224
  m_row_count++;
6111
4225
  return(0);
6112
4226
}
6113
 
#endif
6114
4227
 
6115
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6116
4228
int Rows_log_event::do_apply_event(Relay_log_info const *rli)
6117
4229
{
6118
4230
  int error= 0;
6119
4231
  /*
6120
 
    If m_table_id == ~0UL, then we have a dummy event that does not
 
4232
    If m_table_id == UINT32_MAX, then we have a dummy event that does not
6121
4233
    contain any data.  In that case, we just remove all tables in the
6122
4234
    tables_to_lock list, close the thread tables, and return with
6123
4235
    success.
6124
4236
   */
6125
 
  if (m_table_id == ~0UL)
 
4237
  if (m_table_id == UINT32_MAX)
6126
4238
  {
6127
4239
    /*
6128
4240
       This one is supposed to be set: just an extra check so that
6131
4243
    assert(get_flags(STMT_END_F));
6132
4244
 
6133
4245
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6134
 
    close_thread_tables(thd);
6135
 
    thd->clear_error();
 
4246
    close_thread_tables(session);
 
4247
    session->clear_error();
6136
4248
    return(0);
6137
4249
  }
6138
4250
 
6139
4251
  /*
6140
 
    'thd' has been set by exec_relay_log_event(), just before calling
 
4252
    'session' has been set by exec_relay_log_event(), just before calling
6141
4253
    do_apply_event(). We still check here to prevent future coding
6142
4254
    errors.
6143
4255
  */
6144
 
  assert(rli->sql_thd == thd);
 
4256
  assert(rli->sql_session == session);
6145
4257
 
6146
4258
  /*
6147
4259
    If there is no locks taken, this is the first binrow event seen
6149
4261
    used in the transaction and proceed with execution of the actual
6150
4262
    event.
6151
4263
  */
6152
 
  if (!thd->lock)
 
4264
  if (!session->lock)
6153
4265
  {
6154
4266
    bool need_reopen= 1; /* To execute the first lap of the loop below */
6155
4267
 
6156
4268
    /*
6157
 
      lock_tables() reads the contents of thd->lex, so they must be
 
4269
      lock_tables() reads the contents of session->lex, so they must be
6158
4270
      initialized. Contrary to in
6159
4271
      Table_map_log_event::do_apply_event() we don't call
6160
4272
      mysql_init_query() as that may reset the binlog format.
6161
4273
    */
6162
 
    lex_start(thd);
 
4274
    lex_start(session);
6163
4275
 
6164
4276
    /*
6165
4277
      There are a few flags that are replicated with each row event.
6167
4279
      the event.
6168
4280
    */
6169
4281
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6170
 
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
4282
        session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6171
4283
    else
6172
 
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
4284
        session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6173
4285
 
6174
4286
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6175
 
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
4287
        session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6176
4288
    else
6177
 
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
4289
        session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6178
4290
    /* A small test to verify that objects have consistent types */
6179
 
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6180
 
 
6181
 
 
6182
 
    while ((error= lock_tables(thd, rli->tables_to_lock,
 
4291
    assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
4292
 
 
4293
 
 
4294
    while ((error= lock_tables(session, rli->tables_to_lock,
6183
4295
                               rli->tables_to_lock_count, &need_reopen)))
6184
4296
    {
6185
4297
      if (!need_reopen)
6186
4298
      {
6187
 
        if (thd->is_slave_error || thd->is_fatal_error)
 
4299
        if (session->is_slave_error || session->is_fatal_error)
6188
4300
        {
6189
4301
          /*
6190
4302
            Error reporting borrowed from Query_log_event with many excessive
6191
4303
            simplifications (we don't honour --slave-skip-errors)
6192
4304
          */
6193
 
          uint actual_error= thd->main_da.sql_errno();
 
4305
          uint32_t actual_error= session->main_da.sql_errno();
6194
4306
          rli->report(ERROR_LEVEL, actual_error,
6195
 
                      "Error '%s' in %s event: when locking tables",
6196
 
                      (actual_error ? thd->main_da.message():
6197
 
                       "unexpected success or fatal error"),
 
4307
                      _("Error '%s' in %s event: when locking tables"),
 
4308
                      (actual_error
 
4309
                       ? session->main_da.message()
 
4310
                       : _("unexpected success or fatal error")),
6198
4311
                      get_type_str());
6199
 
          thd->is_fatal_error= 1;
 
4312
          session->is_fatal_error= 1;
6200
4313
        }
6201
4314
        else
6202
4315
        {
6203
4316
          rli->report(ERROR_LEVEL, error,
6204
 
                      "Error in %s event: when locking tables",
 
4317
                      _("Error in %s event: when locking tables"),
6205
4318
                      get_type_str());
6206
4319
        }
6207
4320
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6208
4321
        return(error);
6209
4322
      }
6210
4323
 
6211
 
      /*
6212
 
        So we need to reopen the tables.
6213
 
 
6214
 
        We need to flush the pending RBR event, since it keeps a
6215
 
        pointer to an open table.
6216
 
 
6217
 
        ALTERNATIVE SOLUTION (not implemented): Extract a pointer to
6218
 
        the pending RBR event and reset the table pointer after the
6219
 
        tables has been reopened.
6220
 
 
6221
 
        NOTE: For this new scheme there should be no pending event:
6222
 
        need to add code to assert that is the case.
6223
 
       */
6224
 
      thd->binlog_flush_pending_rows_event(false);
6225
 
      TABLE_LIST *tables= rli->tables_to_lock;
6226
 
      close_tables_for_reopen(thd, &tables);
6227
 
 
6228
 
      uint tables_count= rli->tables_to_lock_count;
6229
 
      if ((error= open_tables(thd, &tables, &tables_count, 0)))
 
4324
      TableList *tables= rli->tables_to_lock;
 
4325
      close_tables_for_reopen(session, &tables);
 
4326
 
 
4327
      uint32_t tables_count= rli->tables_to_lock_count;
 
4328
      if ((error= open_tables(session, &tables, &tables_count, 0)))
6230
4329
      {
6231
 
        if (thd->is_slave_error || thd->is_fatal_error)
 
4330
        if (session->is_slave_error || session->is_fatal_error)
6232
4331
        {
6233
4332
          /*
6234
4333
            Error reporting borrowed from Query_log_event with many excessive
6235
4334
            simplifications (we don't honour --slave-skip-errors)
6236
4335
          */
6237
 
          uint actual_error= thd->main_da.sql_errno();
 
4336
          uint32_t actual_error= session->main_da.sql_errno();
6238
4337
          rli->report(ERROR_LEVEL, actual_error,
6239
 
                      "Error '%s' on reopening tables",
6240
 
                      (actual_error ? thd->main_da.message() :
6241
 
                       "unexpected success or fatal error"));
6242
 
          thd->is_slave_error= 1;
 
4338
                      _("Error '%s' on reopening tables"),
 
4339
                      (actual_error
 
4340
                       ? session->main_da.message()
 
4341
                       : _("unexpected success or fatal error")));
 
4342
          session->is_slave_error= 1;
6243
4343
        }
6244
4344
        const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6245
4345
        return(error);
6251
4351
      ensure that they still have the correct type.
6252
4352
 
6253
4353
      We can use a down cast here since we know that every table added
6254
 
      to the tables_to_lock is a RPL_TABLE_LIST.
 
4354
      to the tables_to_lock is a RPL_TableList.
6255
4355
    */
6256
4356
 
6257
4357
    {
6258
 
      RPL_TABLE_LIST *ptr= rli->tables_to_lock;
6259
 
      for ( ; ptr ; ptr= static_cast<RPL_TABLE_LIST*>(ptr->next_global))
 
4358
      RPL_TableList *ptr= rli->tables_to_lock;
 
4359
      for ( ; ptr ; ptr= static_cast<RPL_TableList*>(ptr->next_global))
6260
4360
      {
6261
4361
        if (ptr->m_tabledef.compatible_with(rli, ptr->table))
6262
4362
        {
6263
 
          mysql_unlock_tables(thd, thd->lock);
6264
 
          thd->lock= 0;
6265
 
          thd->is_slave_error= 1;
 
4363
          mysql_unlock_tables(session, session->lock);
 
4364
          session->lock= 0;
 
4365
          session->is_slave_error= 1;
6266
4366
          const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6267
4367
          return(ERR_BAD_TABLE_DEF);
6268
4368
        }
6283
4383
      Rows_log_event, we can invalidate the query cache for the
6284
4384
      associated table.
6285
4385
     */
6286
 
    for (TABLE_LIST *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
 
4386
    for (TableList *ptr= rli->tables_to_lock ; ptr ; ptr= ptr->next_global)
6287
4387
    {
6288
4388
      const_cast<Relay_log_info*>(rli)->m_table_map.set_table(ptr->table_id, ptr->table);
6289
4389
    }
6290
4390
  }
6291
4391
 
6292
 
  TABLE* 
6293
 
    table= 
 
4392
  Table*
 
4393
    table=
6294
4394
    m_table= const_cast<Relay_log_info*>(rli)->m_table_map.get_table(m_table_id);
6295
4395
 
6296
4396
  if (table)
6309
4409
      TIMESTAMP column to a table with one.
6310
4410
      So we call set_time(), like in SBR. Presently it changes nothing.
6311
4411
    */
6312
 
    thd->set_time((time_t)when);
 
4412
    session->set_time((time_t)when);
6313
4413
    /*
6314
4414
      There are a few flags that are replicated with each row event.
6315
4415
      Make sure to set/clear them before executing the main body of
6316
4416
      the event.
6317
4417
    */
6318
4418
    if (get_flags(NO_FOREIGN_KEY_CHECKS_F))
6319
 
        thd->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
 
4419
        session->options|= OPTION_NO_FOREIGN_KEY_CHECKS;
6320
4420
    else
6321
 
        thd->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
 
4421
        session->options&= ~OPTION_NO_FOREIGN_KEY_CHECKS;
6322
4422
 
6323
4423
    if (get_flags(RELAXED_UNIQUE_CHECKS_F))
6324
 
        thd->options|= OPTION_RELAXED_UNIQUE_CHECKS;
 
4424
        session->options|= OPTION_RELAXED_UNIQUE_CHECKS;
6325
4425
    else
6326
 
        thd->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
6327
 
    
 
4426
        session->options&= ~OPTION_RELAXED_UNIQUE_CHECKS;
 
4427
 
6328
4428
    if (slave_allow_batching)
6329
 
      thd->options|= OPTION_ALLOW_BATCH;
 
4429
      session->options|= OPTION_ALLOW_BATCH;
6330
4430
    else
6331
 
      thd->options&= ~OPTION_ALLOW_BATCH;
6332
 
    
 
4431
      session->options&= ~OPTION_ALLOW_BATCH;
 
4432
 
6333
4433
    /* A small test to verify that objects have consistent types */
6334
 
    assert(sizeof(thd->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
 
4434
    assert(sizeof(session->options) == sizeof(OPTION_RELAXED_UNIQUE_CHECKS));
6335
4435
 
6336
4436
    /*
6337
4437
      Now we are in a statement and will stay in a statement until we
6347
4447
     if ( m_width == table->s->fields && bitmap_is_set_all(&m_cols))
6348
4448
      set_flags(COMPLETE_ROWS_F);
6349
4449
 
6350
 
    /* 
 
4450
    /*
6351
4451
      Set tables write and read sets.
6352
 
      
 
4452
 
6353
4453
      Read_set contains all slave columns (in case we are going to fetch
6354
4454
      a complete record from slave)
6355
 
      
6356
 
      Write_set equals the m_cols bitmap sent from master but it can be 
6357
 
      longer if slave has extra columns. 
6358
 
     */ 
 
4455
 
 
4456
      Write_set equals the m_cols bitmap sent from master but it can be
 
4457
      longer if slave has extra columns.
 
4458
     */
6359
4459
 
6360
4460
    bitmap_set_all(table->read_set);
6361
4461
    bitmap_set_all(table->write_set);
6364
4464
 
6365
4465
    this->slave_exec_mode= slave_exec_mode_options; // fix the mode
6366
4466
 
6367
 
    // Do event specific preparations 
 
4467
    // Do event specific preparations
6368
4468
    error= do_before_row_operations(rli);
6369
4469
 
6370
4470
    // row processing loop
6372
4472
    while (error == 0 && m_curr_row < m_rows_end)
6373
4473
    {
6374
4474
      /* in_use can have been set to NULL in close_tables_for_reopen */
6375
 
      THD* old_thd= table->in_use;
 
4475
      Session* old_session= table->in_use;
6376
4476
      if (!table->in_use)
6377
 
        table->in_use= thd;
 
4477
        table->in_use= session;
6378
4478
 
6379
4479
      error= do_exec_row(rli);
6380
4480
 
6381
 
      table->in_use = old_thd;
 
4481
      table->in_use = old_session;
6382
4482
      switch (error)
6383
4483
      {
6384
4484
      case 0:
6386
4486
      /*
6387
4487
        The following list of "idempotent" errors
6388
4488
        means that an error from the list might happen
6389
 
        because of idempotent (more than once) 
 
4489
        because of idempotent (more than once)
6390
4490
        applying of a binlog file.
6391
4491
        Notice, that binlog has a  ddl operation its
6392
4492
        second applying may cause
6393
4493
 
6394
4494
        case HA_ERR_TABLE_DEF_CHANGED:
6395
4495
        case HA_ERR_CANNOT_ADD_FOREIGN:
6396
 
        
 
4496
 
6397
4497
        which are not included into to the list.
6398
4498
      */
6399
4499
      case HA_ERR_RECORD_CHANGED:
6408
4508
        if (bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1)
6409
4509
        {
6410
4510
          if (global_system_variables.log_warnings)
6411
 
            slave_rows_error_report(WARNING_LEVEL, error, rli, thd, table,
 
4511
            slave_rows_error_report(WARNING_LEVEL, error, rli, session, table,
6412
4512
                                    get_type_str(),
6413
4513
                                    RPL_LOG_NAME, (ulong) log_pos);
6414
4514
          error= 0;
6415
4515
        }
6416
4516
        break;
6417
 
        
 
4517
 
6418
4518
      default:
6419
 
        thd->is_slave_error= 1;
 
4519
        session->is_slave_error= 1;
6420
4520
        break;
6421
4521
      }
6422
4522
 
6423
4523
      /*
6424
4524
       If m_curr_row_end  was not set during event execution (e.g., because
6425
4525
       of errors) we can't proceed to the next row. If the error is transient
6426
 
       (i.e., error==0 at this point) we must call unpack_current_row() to set 
 
4526
       (i.e., error==0 at this point) we must call unpack_current_row() to set
6427
4527
       m_curr_row_end.
6428
 
      */ 
 
4528
      */
6429
4529
      if (!m_curr_row_end && !error)
6430
4530
        unpack_current_row(rli, &m_cols);
6431
 
  
 
4531
 
6432
4532
      // at this moment m_curr_row_end should be set
6433
 
      assert(error || m_curr_row_end != NULL); 
 
4533
      assert(error || m_curr_row_end != NULL);
6434
4534
      assert(error || m_curr_row < m_curr_row_end);
6435
4535
      assert(error || m_curr_row_end <= m_rows_end);
6436
 
  
 
4536
 
6437
4537
      m_curr_row= m_curr_row_end;
6438
 
 
 
4538
 
6439
4539
    } // row processing loop
6440
4540
 
6441
4541
    error= do_after_row_operations(rli, error);
6442
4542
    if (!cache_stmt)
6443
4543
    {
6444
 
      thd->options|= OPTION_KEEP_LOG;
 
4544
      session->options|= OPTION_KEEP_LOG;
6445
4545
    }
6446
4546
  } // if (table)
6447
4547
 
6452
4552
  if (rli->tables_to_lock && get_flags(STMT_END_F))
6453
4553
    const_cast<Relay_log_info*>(rli)->clear_tables_to_lock();
6454
4554
  /* reset OPTION_ALLOW_BATCH as not affect later events */
6455
 
  thd->options&= ~OPTION_ALLOW_BATCH;
6456
 
  
 
4555
  session->options&= ~OPTION_ALLOW_BATCH;
 
4556
 
6457
4557
  if (error)
6458
4558
  {                     /* error has occured during the transaction */
6459
 
    slave_rows_error_report(ERROR_LEVEL, error, rli, thd, table,
 
4559
    slave_rows_error_report(ERROR_LEVEL, error, rli, session, table,
6460
4560
                            get_type_str(), RPL_LOG_NAME, (ulong) log_pos);
6461
4561
  }
6462
4562
  if (error)
6472
4572
      thread is certainly going to stop.
6473
4573
      rollback at the caller along with sbr.
6474
4574
    */
6475
 
    thd->reset_current_stmt_binlog_row_based();
6476
 
    const_cast<Relay_log_info*>(rli)->cleanup_context(thd, error);
6477
 
    thd->is_slave_error= 1;
 
4575
    const_cast<Relay_log_info*>(rli)->cleanup_context(session, error);
 
4576
    session->is_slave_error= 1;
6478
4577
    return(error);
6479
4578
  }
6480
4579
 
6502
4601
      problem.  When WL#2975 is implemented, just remove the member
6503
4602
      Relay_log_info::last_event_start_time and all its occurrences.
6504
4603
    */
6505
 
    const_cast<Relay_log_info*>(rli)->last_event_start_time= my_time(0);
 
4604
    time_t t= time(0);
 
4605
 
 
4606
    /* don't trust time() all the time */
 
4607
    if (t == (time_t)-1)
 
4608
      return (-1);
 
4609
    const_cast<Relay_log_info*>(rli)->last_event_start_time= time(0);
6506
4610
  }
6507
4611
 
6508
4612
  return(0);
6530
4634
  if (get_flags(STMT_END_F))
6531
4635
  {
6532
4636
    /*
6533
 
      This is the end of a statement or transaction, so close (and
6534
 
      unlock) the tables we opened when processing the
6535
 
      Table_map_log_event starting the statement.
6536
 
 
6537
 
      OBSERVER.  This will clear *all* mappings, not only those that
6538
 
      are open for the table. There is not good handle for on-close
6539
 
      actions for tables.
6540
 
 
6541
 
      NOTE. Even if we have no table ('table' == 0) we still need to be
6542
 
      here, so that we increase the group relay log position. If we didn't, we
6543
 
      could have a group relay log position which lags behind "forever"
6544
 
      (assume the last master's transaction is ignored by the slave because of
6545
 
      replicate-ignore rules).
6546
 
    */
6547
 
    thd->binlog_flush_pending_rows_event(true);
6548
 
 
6549
 
    /*
6550
4637
      If this event is not in a transaction, the call below will, if some
6551
4638
      transactional storage engines are involved, commit the statement into
6552
4639
      them and flush the pending event to binlog.
6555
4642
      are involved, commit the transaction and flush the pending event to the
6556
4643
      binlog.
6557
4644
    */
6558
 
    error= ha_autocommit_or_rollback(thd, 0);
 
4645
    error= ha_autocommit_or_rollback(session, 0);
6559
4646
 
6560
4647
    /*
6561
4648
      Now what if this is not a transactional engine? we still need to
6562
4649
      flush the pending event to the binlog; we did it with
6563
 
      thd->binlog_flush_pending_rows_event(). Note that we imitate
 
4650
      session->binlog_flush_pending_rows_event(). Note that we imitate
6564
4651
      what is done for real queries: a call to
6565
4652
      ha_autocommit_or_rollback() (sometimes only if involves a
6566
4653
      transactional engine), and a call to be sure to have the pending
6567
4654
      event flushed.
6568
4655
    */
6569
4656
 
6570
 
    thd->reset_current_stmt_binlog_row_based();
6571
 
 
6572
 
    rli->cleanup_context(thd, 0);
 
4657
    rli->cleanup_context(session, 0);
6573
4658
    if (error == 0)
6574
4659
    {
6575
4660
      /*
6580
4665
      rli->stmt_done(log_pos, when);
6581
4666
 
6582
4667
      /*
6583
 
        Clear any errors pushed in thd->net.last_err* if for example "no key
 
4668
        Clear any errors pushed in session->net.last_err* if for example "no key
6584
4669
        found" (as this is allowed). This is a safety measure; apparently
6585
4670
        those errors (e.g. when executing a Delete_rows_log_event of a
6586
4671
        non-existing row, like in rpl_row_mystery22.test,
6587
 
        thd->net.last_error = "Can't find record in 't1'" and last_errno=1032)
 
4672
        session->net.last_error = "Can't find record in 't1'" and last_errno=1032)
6588
4673
        do not become visible. We still prefer to wipe them out.
6589
4674
      */
6590
 
      thd->clear_error();
 
4675
      session->clear_error();
6591
4676
    }
6592
4677
    else
6593
4678
      rli->report(ERROR_LEVEL, error,
6594
 
                  "Error in %s event: commit of row events failed, "
6595
 
                  "table `%s`.`%s`",
 
4679
                  _("Error in %s event: commit of row events failed, "
 
4680
                    "table `%s`.`%s`"),
6596
4681
                  get_type_str(), m_table->s->db.str,
6597
4682
                  m_table->s->table_name.str);
6598
4683
  }
6604
4689
  return(error);
6605
4690
}
6606
4691
 
6607
 
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
6608
 
 
6609
 
#ifndef DRIZZLE_CLIENT
6610
4692
bool Rows_log_event::write_data_header(IO_CACHE *file)
6611
4693
{
6612
 
  uchar buf[ROWS_HEADER_LEN];   // No need to init the buffer
6613
 
  assert(m_table_id != ~0UL);
 
4694
  unsigned char buf[ROWS_HEADER_LEN];   // No need to init the buffer
 
4695
  assert(m_table_id != UINT32_MAX);
6614
4696
  int6store(buf + RW_MAPID_OFFSET, (uint64_t)m_table_id);
6615
4697
  int2store(buf + RW_FLAGS_OFFSET, m_flags);
6616
4698
  return (my_b_safe_write(file, buf, ROWS_HEADER_LEN));
6622
4704
     Note that this should be the number of *bits*, not the number of
6623
4705
     bytes.
6624
4706
  */
6625
 
  uchar sbuf[sizeof(m_width)];
 
4707
  unsigned char sbuf[sizeof(m_width)];
6626
4708
  my_ptrdiff_t const data_size= m_rows_cur - m_rows_buf;
6627
4709
  bool res= false;
6628
 
  uchar *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
 
4710
  unsigned char *const sbuf_end= net_store_length(sbuf, (size_t) m_width);
6629
4711
  assert(static_cast<size_t>(sbuf_end - sbuf) <= sizeof(sbuf));
6630
4712
 
6631
4713
  res= res || my_b_safe_write(file, sbuf, (size_t) (sbuf_end - sbuf));
6632
4714
 
6633
 
  res= res || my_b_safe_write(file, (uchar*) m_cols.bitmap,
 
4715
  res= res || my_b_safe_write(file, (unsigned char*) m_cols.bitmap,
6634
4716
                              no_bytes_in_map(&m_cols));
6635
4717
  /*
6636
4718
    TODO[refactor write]: Remove the "down cast" here (and elsewhere).
6637
4719
   */
6638
4720
  if (get_type_code() == UPDATE_ROWS_EVENT)
6639
4721
  {
6640
 
    res= res || my_b_safe_write(file, (uchar*) m_cols_ai.bitmap,
 
4722
    res= res || my_b_safe_write(file, (unsigned char*) m_cols_ai.bitmap,
6641
4723
                                no_bytes_in_map(&m_cols_ai));
6642
4724
  }
6643
4725
  res= res || my_b_safe_write(file, m_rows_buf, (size_t) data_size);
6645
4727
  return res;
6646
4728
 
6647
4729
}
6648
 
#endif
6649
 
 
6650
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
4730
 
 
4731
 
6651
4732
void Rows_log_event::pack_info(Protocol *protocol)
6652
4733
{
6653
4734
  char buf[256];
6657
4738
                         "table_id: %lu%s", m_table_id, flagstr);
6658
4739
  protocol->store(buf, bytes, &my_charset_bin);
6659
4740
}
6660
 
#endif
6661
 
 
6662
 
#ifdef DRIZZLE_CLIENT
6663
 
void Rows_log_event::print_helper(FILE *file,
6664
 
                                  PRINT_EVENT_INFO *print_event_info,
6665
 
                                  char const *const name)
6666
 
{
6667
 
  IO_CACHE *const head= &print_event_info->head_cache;
6668
 
  IO_CACHE *const body= &print_event_info->body_cache;
6669
 
  if (!print_event_info->short_form)
6670
 
  {
6671
 
    bool const last_stmt_event= get_flags(STMT_END_F);
6672
 
    print_header(head, print_event_info, !last_stmt_event);
6673
 
    my_b_printf(head, "\t%s: table id %lu%s\n",
6674
 
                name, m_table_id,
6675
 
                last_stmt_event ? " flags: STMT_END_F" : "");
6676
 
    print_base64(body, print_event_info, !last_stmt_event);
6677
 
  }
6678
 
 
6679
 
  if (get_flags(STMT_END_F))
6680
 
  {
6681
 
    copy_event_cache_to_file_and_reinit(head, file);
6682
 
    copy_event_cache_to_file_and_reinit(body, file);
6683
 
  }
6684
 
}
6685
 
#endif
 
4741
 
6686
4742
 
6687
4743
/**************************************************************************
6688
4744
        Table_map_log_event member functions and support functions
6690
4746
 
6691
4747
/**
6692
4748
  @page How replication of field metadata works.
6693
 
  
6694
 
  When a table map is created, the master first calls 
6695
 
  Table_map_log_event::save_field_metadata() which calculates how many 
6696
 
  values will be in the field metadata. Only those fields that require the 
6697
 
  extra data are added. The method also loops through all of the fields in 
 
4749
 
 
4750
  When a table map is created, the master first calls
 
4751
  Table_map_log_event::save_field_metadata() which calculates how many
 
4752
  values will be in the field metadata. Only those fields that require the
 
4753
  extra data are added. The method also loops through all of the fields in
6698
4754
  the table calling the method Field::save_field_metadata() which returns the
6699
4755
  values for the field that will be saved in the metadata and replicated to
6700
4756
  the slave. Once all fields have been processed, the table map is written to
6701
4757
  the binlog adding the size of the field metadata and the field metadata to
6702
4758
  the end of the body of the table map.
6703
4759
 
6704
 
  When a table map is read on the slave, the field metadata is read from the 
6705
 
  table map and passed to the table_def class constructor which saves the 
6706
 
  field metadata from the table map into an array based on the type of the 
6707
 
  field. Field metadata values not present (those fields that do not use extra 
6708
 
  data) in the table map are initialized as zero (0). The array size is the 
 
4760
  When a table map is read on the slave, the field metadata is read from the
 
4761
  table map and passed to the table_def class constructor which saves the
 
4762
  field metadata from the table map into an array based on the type of the
 
4763
  field. Field metadata values not present (those fields that do not use extra
 
4764
  data) in the table map are initialized as zero (0). The array size is the
6709
4765
  same as the columns for the table on the slave.
6710
4766
 
6711
 
  Additionally, values saved for field metadata on the master are saved as a 
6712
 
  string of bytes (uchar) in the binlog. A field may require 1 or more bytes
6713
 
  to store the information. In cases where values require multiple bytes 
6714
 
  (e.g. values > 255), the endian-safe methods are used to properly encode 
 
4767
  Additionally, values saved for field metadata on the master are saved as a
 
4768
  string of bytes (unsigned char) in the binlog. A field may require 1 or more bytes
 
4769
  to store the information. In cases where values require multiple bytes
 
4770
  (e.g. values > 255), the endian-safe methods are used to properly encode
6715
4771
  the values on the master and decode them on the slave. When the field
6716
4772
  metadata values are captured on the slave, they are stored in an array of
6717
4773
  type uint16_t. This allows the least number of casts to prevent casting bugs
6718
4774
  when the field metadata is used in comparisons of field attributes. When
6719
4775
  the field metadata is used for calculating addresses in pointer math, the
6720
 
  type used is uint32_t. 
 
4776
  type used is uint32_t.
6721
4777
*/
6722
4778
 
6723
 
#if !defined(DRIZZLE_CLIENT)
6724
4779
/**
6725
4780
  Save the field metadata based on the real_type of the field.
6726
4781
  The metadata saved depends on the type of the field. Some fields
6727
4782
  store a single byte for pack_length() while others store two bytes
6728
4783
  for field_length (max length).
6729
 
  
 
4784
 
6730
4785
  @retval  0  Ok.
6731
4786
 
6732
4787
  @todo
6733
4788
  We may want to consider changing the encoding of the information.
6734
 
  Currently, the code attempts to minimize the number of bytes written to 
6735
 
  the tablemap. There are at least two other alternatives; 1) using 
 
4789
  Currently, the code attempts to minimize the number of bytes written to
 
4790
  the tablemap. There are at least two other alternatives; 1) using
6736
4791
  net_store_length() to store the data allowing it to choose the number of
6737
 
  bytes that are appropriate thereby making the code much easier to 
 
4792
  bytes that are appropriate thereby making the code much easier to
6738
4793
  maintain (only 1 place to change the encoding), or 2) use a fixed number
6739
4794
  of bytes for each field. The problem with option 1 is that net_store_length()
6740
4795
  will use one byte if the value < 251, but 3 bytes if it is > 250. Thus,
6743
4798
  encoded using 2 parts (e.g., pack_length, field_length) will be numerically
6744
4799
  > 250 therefore will use 3 bytes for eah value. The problem with option 2
6745
4800
  is less wasteful for space but does waste 1 byte for every field that does
6746
 
  not encode 2 parts. 
 
4801
  not encode 2 parts.
6747
4802
*/
6748
4803
int Table_map_log_event::save_field_metadata()
6749
4804
{
6752
4807
    index+= m_table->s->field[i]->save_field_metadata(&m_field_metadata[index]);
6753
4808
  return(index);
6754
4809
}
6755
 
#endif /* !defined(DRIZZLE_CLIENT) */
6756
4810
 
6757
4811
/*
6758
4812
  Constructor used to build an event for writing to the binary log.
6759
4813
  Mats says tbl->s lives longer than this event so it's ok to copy pointers
6760
4814
  (tbl->s->db etc) and not pointer content.
6761
4815
 */
6762
 
#if !defined(DRIZZLE_CLIENT)
6763
 
Table_map_log_event::Table_map_log_event(THD *thd, TABLE *tbl, ulong tid,
6764
 
                                         bool is_transactional __attribute__((unused)),
6765
 
                                         uint16_t flags)
6766
 
  : Log_event(thd, 0, true),
 
4816
Table_map_log_event::Table_map_log_event(Session *session, Table *tbl,
 
4817
                                         ulong tid, bool, uint16_t flags)
 
4818
  : Log_event(session, 0, true),
6767
4819
    m_table(tbl),
6768
4820
    m_dbnam(tbl->s->db.str),
6769
4821
    m_dblen(m_dbnam ? tbl->s->db.length : 0),
6779
4831
    m_null_bits(0),
6780
4832
    m_meta_memory(NULL)
6781
4833
{
6782
 
  assert(m_table_id != ~0UL);
 
4834
  assert(m_table_id != UINT32_MAX);
6783
4835
  /*
6784
4836
    In TABLE_SHARE, "db" and "table_name" are 0-terminated (see this comment in
6785
4837
    table.cc / alloc_table_share():
6797
4849
  m_data_size+= 1 + m_colcnt;   // COLCNT and column types
6798
4850
 
6799
4851
  /* If malloc fails, caught in is_valid() */
6800
 
  if ((m_memory= (uchar*) my_malloc(m_colcnt, MYF(MY_WME))))
 
4852
  if ((m_memory= (unsigned char*) malloc(m_colcnt)))
6801
4853
  {
6802
 
    m_coltype= reinterpret_cast<uchar*>(m_memory);
 
4854
    m_coltype= reinterpret_cast<unsigned char*>(m_memory);
6803
4855
    for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
6804
4856
      m_coltype[i]= m_table->field[i]->type();
6805
4857
  }
6810
4862
    that is not on the slave and is null and thus not in the row data during
6811
4863
    replication.
6812
4864
  */
6813
 
  uint num_null_bytes= (m_table->s->fields + 7) / 8;
 
4865
  uint32_t num_null_bytes= (m_table->s->fields + 7) / 8;
6814
4866
  m_data_size+= num_null_bytes;
6815
 
  m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
 
4867
  m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
6816
4868
                                 &m_null_bits, num_null_bytes,
6817
4869
                                 &m_field_metadata, (m_colcnt * 2),
6818
4870
                                 NULL);
6830
4882
    plus one or two bytes for number of elements in the field metadata array.
6831
4883
  */
6832
4884
  if (m_field_metadata_size > 255)
6833
 
    m_data_size+= m_field_metadata_size + 2; 
 
4885
    m_data_size+= m_field_metadata_size + 2;
6834
4886
  else
6835
 
    m_data_size+= m_field_metadata_size + 1; 
 
4887
    m_data_size+= m_field_metadata_size + 1;
6836
4888
 
6837
4889
  memset(m_null_bits, 0, num_null_bytes);
6838
4890
  for (unsigned int i= 0 ; i < m_table->s->fields ; ++i)
6840
4892
      m_null_bits[(i / 8)]+= 1 << (i % 8);
6841
4893
 
6842
4894
}
6843
 
#endif /* !defined(DRIZZLE_CLIENT) */
 
4895
 
6844
4896
 
6845
4897
/*
6846
4898
  Constructor used by slave to read the event from the binary log.
6847
4899
 */
6848
 
#if defined(HAVE_REPLICATION)
6849
 
Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
 
4900
Table_map_log_event::Table_map_log_event(const char *buf, uint32_t event_len,
6850
4901
                                         const Format_description_log_event
6851
4902
                                         *description_event)
6852
4903
 
6853
4904
  : Log_event(buf, description_event),
6854
 
#ifndef DRIZZLE_CLIENT
6855
4905
    m_table(NULL),
6856
 
#endif
6857
4906
    m_dbnam(NULL), m_dblen(0), m_tblnam(NULL), m_tbllen(0),
6858
4907
    m_colcnt(0), m_coltype(0),
6859
4908
    m_memory(NULL), m_table_id(ULONG_MAX), m_flags(0),
6882
4931
    post_start+= TM_FLAGS_OFFSET;
6883
4932
  }
6884
4933
 
6885
 
  assert(m_table_id != ~0UL);
 
4934
  assert(m_table_id != UINT32_MAX);
6886
4935
 
6887
4936
  m_flags= uint2korr(post_start);
6888
4937
 
6890
4939
  const char *const vpart= buf + common_header_len + post_header_len;
6891
4940
 
6892
4941
  /* Extract the length of the various parts from the buffer */
6893
 
  uchar const *const ptr_dblen= (uchar const*)vpart + 0;
6894
 
  m_dblen= *(uchar*) ptr_dblen;
 
4942
  unsigned char const *const ptr_dblen= (unsigned char const*)vpart + 0;
 
4943
  m_dblen= *(unsigned char*) ptr_dblen;
6895
4944
 
6896
4945
  /* Length of database name + counter + terminating null */
6897
 
  uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
6898
 
  m_tbllen= *(uchar*) ptr_tbllen;
 
4946
  unsigned char const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
 
4947
  m_tbllen= *(unsigned char*) ptr_tbllen;
6899
4948
 
6900
4949
  /* Length of table name + counter + terminating null */
6901
 
  uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
6902
 
  uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
 
4950
  unsigned char const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
 
4951
  unsigned char *ptr_after_colcnt= (unsigned char*) ptr_colcnt;
6903
4952
  m_colcnt= net_field_length(&ptr_after_colcnt);
6904
4953
 
6905
4954
  /* Allocate mem for all fields in one go. If fails, caught in is_valid() */
6906
 
  m_memory= (uchar*) my_multi_malloc(MYF(MY_WME),
 
4955
  m_memory= (unsigned char*) my_multi_malloc(MYF(MY_WME),
6907
4956
                                     &m_dbnam, (uint) m_dblen + 1,
6908
4957
                                     &m_tblnam, (uint) m_tbllen + 1,
6909
4958
                                     &m_coltype, (uint) m_colcnt,
6910
 
                                     NullS);
 
4959
                                     NULL);
6911
4960
 
6912
4961
  if (m_memory)
6913
4962
  {
6917
4966
    memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
6918
4967
 
6919
4968
    ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
6920
 
    bytes_read= ptr_after_colcnt - (uchar *)buf;
 
4969
    bytes_read= ptr_after_colcnt - (unsigned char *)buf;
6921
4970
    if (bytes_read < event_len)
6922
4971
    {
6923
4972
      m_field_metadata_size= net_field_length(&ptr_after_colcnt);
6924
4973
      assert(m_field_metadata_size <= (m_colcnt * 2));
6925
 
      uint num_null_bytes= (m_colcnt + 7) / 8;
6926
 
      m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
 
4974
      uint32_t num_null_bytes= (m_colcnt + 7) / 8;
 
4975
      m_meta_memory= (unsigned char *)my_multi_malloc(MYF(MY_WME),
6927
4976
                                     &m_null_bits, num_null_bytes,
6928
4977
                                     &m_field_metadata, m_field_metadata_size,
6929
4978
                                     NULL);
6930
4979
      memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
6931
 
      ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
 
4980
      ptr_after_colcnt= (unsigned char*)ptr_after_colcnt + m_field_metadata_size;
6932
4981
      memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
6933
4982
    }
6934
4983
  }
6935
4984
 
6936
4985
  return;
6937
4986
}
6938
 
#endif
6939
4987
 
6940
4988
Table_map_log_event::~Table_map_log_event()
6941
4989
{
6942
 
  my_free(m_meta_memory, MYF(MY_ALLOW_ZERO_PTR));
6943
 
  my_free(m_memory, MYF(MY_ALLOW_ZERO_PTR));
 
4990
  free(m_meta_memory);
 
4991
  free(m_memory);
6944
4992
}
6945
4993
 
6946
4994
/*
6954
5002
       4     Daisy-chaining RBR with SBR not possible
6955
5003
 */
6956
5004
 
6957
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
6958
5005
int Table_map_log_event::do_apply_event(Relay_log_info const *rli)
6959
5006
{
6960
 
  RPL_TABLE_LIST *table_list;
 
5007
  RPL_TableList *table_list;
6961
5008
  char *db_mem, *tname_mem;
6962
 
  size_t dummy_len;
 
5009
  Query_id &query_id= Query_id::get_query_id();
6963
5010
  void *memory;
6964
 
  assert(rli->sql_thd == thd);
 
5011
  assert(rli->sql_session == session);
6965
5012
 
6966
5013
  /* Step the query id to mark what columns that are actually used. */
6967
 
  pthread_mutex_lock(&LOCK_thread_count);
6968
 
  thd->query_id= next_query_id();
6969
 
  pthread_mutex_unlock(&LOCK_thread_count);
 
5014
  session->query_id= query_id.next();
6970
5015
 
6971
5016
  if (!(memory= my_multi_malloc(MYF(MY_WME),
6972
 
                                &table_list, (uint) sizeof(RPL_TABLE_LIST),
 
5017
                                &table_list, (uint) sizeof(RPL_TableList),
6973
5018
                                &db_mem, (uint) NAME_LEN + 1,
6974
5019
                                &tname_mem, (uint) NAME_LEN + 1,
6975
 
                                NullS)))
 
5020
                                NULL)))
6976
5021
    return(HA_ERR_OUT_OF_MEM);
6977
5022
 
6978
5023
  memset(table_list, 0, sizeof(*table_list));
6982
5027
  table_list->next_global= table_list->next_local= 0;
6983
5028
  table_list->table_id= m_table_id;
6984
5029
  table_list->updating= 1;
6985
 
  stpcpy(table_list->db, rpl_filter->get_rewrite_db(m_dbnam, &dummy_len));
6986
 
  stpcpy(table_list->table_name, m_tblnam);
 
5030
  strcpy(table_list->db, m_dbnam);
 
5031
  strcpy(table_list->table_name, m_tblnam);
6987
5032
 
6988
5033
  int error= 0;
6989
5034
 
6990
 
  if (!rpl_filter->db_ok(table_list->db) ||
6991
 
      (rpl_filter->is_on() && !rpl_filter->tables_ok("", table_list)))
6992
 
  {
6993
 
    my_free(memory, MYF(MY_WME));
6994
 
  }
6995
 
  else
6996
5035
  {
6997
5036
    /*
6998
 
      open_tables() reads the contents of thd->lex, so they must be
 
5037
      open_tables() reads the contents of session->lex, so they must be
6999
5038
      initialized, so we should call lex_start(); to be even safer, we
7000
5039
      call mysql_init_query() which does a more complete set of inits.
7001
5040
    */
7002
 
    lex_start(thd);
7003
 
    mysql_reset_thd_for_next_command(thd);
7004
 
    /*
7005
 
      Check if the slave is set to use SBR.  If so, it should switch
7006
 
      to using RBR until the end of the "statement", i.e., next
7007
 
      STMT_END_F or next error.
7008
 
    */
7009
 
    if (!thd->current_stmt_binlog_row_based &&
7010
 
        mysql_bin_log.is_open() && (thd->options & OPTION_BIN_LOG))
7011
 
    {
7012
 
      thd->set_current_stmt_binlog_row_based();
7013
 
    }
 
5041
    lex_start(session);
 
5042
    session->reset_for_next_command();
7014
5043
 
7015
5044
    /*
7016
5045
      Open the table if it is not already open and add the table to
7017
5046
      table map.  Note that for any table that should not be
7018
5047
      replicated, a filter is needed.
7019
5048
 
7020
 
      The creation of a new TABLE_LIST is used to up-cast the
7021
 
      table_list consisting of RPL_TABLE_LIST items. This will work
 
5049
      The creation of a new TableList is used to up-cast the
 
5050
      table_list consisting of RPL_TableList items. This will work
7022
5051
      since the only case where the argument to open_tables() is
7023
 
      changed, is when thd->lex->query_tables == table_list, i.e.,
 
5052
      changed, is when session->lex->query_tables == table_list, i.e.,
7024
5053
      when the statement requires prelocking. Since this is not
7025
5054
      executed when a statement is executed, this case will not occur.
7026
5055
      As a precaution, an assertion is added to ensure that the bad
7030
5059
      internally in the open_tables() function, hence we take a copy
7031
5060
      of the pointer to make sure that it's not lost.
7032
5061
    */
7033
 
    uint count;
7034
 
    assert(thd->lex->query_tables != table_list);
7035
 
    TABLE_LIST *tmp_table_list= table_list;
7036
 
    if ((error= open_tables(thd, &tmp_table_list, &count, 0)))
 
5062
    uint32_t count;
 
5063
    assert(session->lex->query_tables != table_list);
 
5064
    TableList *tmp_table_list= table_list;
 
5065
    if ((error= open_tables(session, &tmp_table_list, &count, 0)))
7037
5066
    {
7038
 
      if (thd->is_slave_error || thd->is_fatal_error)
 
5067
      if (session->is_slave_error || session->is_fatal_error)
7039
5068
      {
7040
5069
        /*
7041
5070
          Error reporting borrowed from Query_log_event with many excessive
7042
5071
          simplifications (we don't honour --slave-skip-errors)
7043
5072
        */
7044
 
        uint actual_error= thd->main_da.sql_errno();
 
5073
        uint32_t actual_error= session->main_da.sql_errno();
7045
5074
        rli->report(ERROR_LEVEL, actual_error,
7046
 
                    "Error '%s' on opening table `%s`.`%s`",
7047
 
                    (actual_error ? thd->main_da.message() :
7048
 
                     "unexpected success or fatal error"),
 
5075
                    _("Error '%s' on opening table `%s`.`%s`"),
 
5076
                    (actual_error
 
5077
                     ? session->main_da.message()
 
5078
                     : _("unexpected success or fatal error")),
7049
5079
                    table_list->db, table_list->table_name);
7050
 
        thd->is_slave_error= 1;
 
5080
        session->is_slave_error= 1;
7051
5081
      }
7052
5082
      goto err;
7053
5083
    }
7069
5099
      inside Relay_log_info::clear_tables_to_lock() by calling the
7070
5100
      table_def destructor explicitly.
7071
5101
    */
7072
 
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt, 
 
5102
    new (&table_list->m_tabledef) table_def(m_coltype, m_colcnt,
7073
5103
         m_field_metadata, m_field_metadata_size, m_null_bits);
7074
5104
    table_list->m_tabledef_valid= true;
7075
5105
 
7086
5116
  return(error);
7087
5117
 
7088
5118
err:
7089
 
  my_free(memory, MYF(MY_WME));
 
5119
  free(memory);
7090
5120
  return(error);
7091
5121
}
7092
5122
 
7106
5136
  return 0;
7107
5137
}
7108
5138
 
7109
 
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7110
5139
 
7111
 
#ifndef DRIZZLE_CLIENT
7112
5140
bool Table_map_log_event::write_data_header(IO_CACHE *file)
7113
5141
{
7114
 
  assert(m_table_id != ~0UL);
7115
 
  uchar buf[TABLE_MAP_HEADER_LEN];
 
5142
  assert(m_table_id != UINT32_MAX);
 
5143
  unsigned char buf[TABLE_MAP_HEADER_LEN];
7116
5144
  int6store(buf + TM_MAPID_OFFSET, (uint64_t)m_table_id);
7117
5145
  int2store(buf + TM_FLAGS_OFFSET, m_flags);
7118
5146
  return (my_b_safe_write(file, buf, TABLE_MAP_HEADER_LEN));
7126
5154
  assert(m_dblen < 128);
7127
5155
  assert(m_tbllen < 128);
7128
5156
 
7129
 
  uchar const dbuf[]= { (uchar) m_dblen };
7130
 
  uchar const tbuf[]= { (uchar) m_tbllen };
 
5157
  unsigned char const dbuf[]= { (unsigned char) m_dblen };
 
5158
  unsigned char const tbuf[]= { (unsigned char) m_tbllen };
7131
5159
 
7132
 
  uchar cbuf[sizeof(m_colcnt)];
7133
 
  uchar *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
 
5160
  unsigned char cbuf[sizeof(m_colcnt)];
 
5161
  unsigned char *const cbuf_end= net_store_length(cbuf, (size_t) m_colcnt);
7134
5162
  assert(static_cast<size_t>(cbuf_end - cbuf) <= sizeof(cbuf));
7135
5163
 
7136
5164
  /*
7137
5165
    Store the size of the field metadata.
7138
5166
  */
7139
 
  uchar mbuf[sizeof(m_field_metadata_size)];
7140
 
  uchar *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
 
5167
  unsigned char mbuf[sizeof(m_field_metadata_size)];
 
5168
  unsigned char *const mbuf_end= net_store_length(mbuf, m_field_metadata_size);
7141
5169
 
7142
5170
  return (my_b_safe_write(file, dbuf,      sizeof(dbuf)) ||
7143
 
          my_b_safe_write(file, (const uchar*)m_dbnam,   m_dblen+1) ||
 
5171
          my_b_safe_write(file, (const unsigned char*)m_dbnam,   m_dblen+1) ||
7144
5172
          my_b_safe_write(file, tbuf,      sizeof(tbuf)) ||
7145
 
          my_b_safe_write(file, (const uchar*)m_tblnam,  m_tbllen+1) ||
 
5173
          my_b_safe_write(file, (const unsigned char*)m_tblnam,  m_tbllen+1) ||
7146
5174
          my_b_safe_write(file, cbuf, (size_t) (cbuf_end - cbuf)) ||
7147
5175
          my_b_safe_write(file, m_coltype, m_colcnt) ||
7148
5176
          my_b_safe_write(file, mbuf, (size_t) (mbuf_end - mbuf)) ||
7149
5177
          my_b_safe_write(file, m_field_metadata, m_field_metadata_size),
7150
5178
          my_b_safe_write(file, m_null_bits, (m_colcnt + 7) / 8));
7151
5179
 }
7152
 
#endif
7153
5180
 
7154
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
7155
5181
 
7156
5182
/*
7157
5183
  Print some useful information for the SHOW BINARY LOG information
7158
5184
  field.
7159
5185
 */
7160
5186
 
7161
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
7162
5187
void Table_map_log_event::pack_info(Protocol *protocol)
7163
5188
{
7164
5189
    char buf[256];
7167
5192
                           m_table_id, m_dbnam, m_tblnam);
7168
5193
    protocol->store(buf, bytes, &my_charset_bin);
7169
5194
}
7170
 
#endif
7171
 
 
7172
 
 
7173
 
#endif
7174
 
 
7175
 
 
7176
 
#ifdef DRIZZLE_CLIENT
7177
 
void Table_map_log_event::print(FILE * /* unused */,
7178
 
                                PRINT_EVENT_INFO *print_event_info)
7179
 
{
7180
 
  if (!print_event_info->short_form)
7181
 
  {
7182
 
    print_header(&print_event_info->head_cache, print_event_info, true);
7183
 
    my_b_printf(&print_event_info->head_cache,
7184
 
                "\tTable_map: `%s`.`%s` mapped to number %lu\n",
7185
 
                m_dbnam, m_tblnam, m_table_id);
7186
 
    print_base64(&print_event_info->body_cache, print_event_info, true);
7187
 
  }
7188
 
}
7189
 
#endif
 
5195
 
7190
5196
 
7191
5197
/**************************************************************************
7192
5198
        Write_rows_log_event member functions
7195
5201
/*
7196
5202
  Constructor used to build an event for writing to the binary log.
7197
5203
 */
7198
 
#if !defined(DRIZZLE_CLIENT)
7199
 
Write_rows_log_event::Write_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
5204
Write_rows_log_event::Write_rows_log_event(Session *session_arg, Table *tbl_arg,
7200
5205
                                           ulong tid_arg,
7201
5206
                                           bool is_transactional)
7202
 
  : Rows_log_event(thd_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
 
5207
  : Rows_log_event(session_arg, tbl_arg, tid_arg, tbl_arg->write_set, is_transactional)
7203
5208
{
7204
5209
}
7205
 
#endif
7206
5210
 
7207
5211
/*
7208
5212
  Constructor used by slave to read the event from the binary log.
7209
5213
 */
7210
 
#ifdef HAVE_REPLICATION
7211
 
Write_rows_log_event::Write_rows_log_event(const char *buf, uint event_len,
 
5214
Write_rows_log_event::Write_rows_log_event(const char *buf, uint32_t event_len,
7212
5215
                                           const Format_description_log_event
7213
5216
                                           *description_event)
7214
5217
: Rows_log_event(buf, event_len, WRITE_ROWS_EVENT, description_event)
7215
5218
{
7216
5219
}
7217
 
#endif
7218
5220
 
7219
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7220
 
int 
 
5221
int
7221
5222
Write_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
7222
5223
{
7223
5224
  int error= 0;
7233
5234
      when writing rows, that is: new rows replace old rows.  We need to
7234
5235
      inform the storage engine that it should use this behaviour.
7235
5236
    */
7236
 
    
 
5237
 
7237
5238
    /* Tell the storage engine that we are using REPLACE semantics. */
7238
 
    thd->lex->duplicates= DUP_REPLACE;
7239
 
    
 
5239
    session->lex->duplicates= DUP_REPLACE;
 
5240
 
7240
5241
    /*
7241
5242
      Pretend we're executing a REPLACE command: this is needed for
7242
5243
      InnoDB since it is not (properly) checking the
7243
5244
      lex->duplicates flag.
7244
5245
    */
7245
 
    thd->lex->sql_command= SQLCOM_REPLACE;
7246
 
    /* 
 
5246
    session->lex->sql_command= SQLCOM_REPLACE;
 
5247
    /*
7247
5248
       Do not raise the error flag in case of hitting to an unique attribute
7248
5249
    */
7249
5250
    m_table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
7270
5271
  return error;
7271
5272
}
7272
5273
 
7273
 
int 
 
5274
int
7274
5275
Write_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
7275
5276
                                              int error)
7276
5277
{
7280
5281
    m_table->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
7281
5282
    m_table->file->extra(HA_EXTRA_WRITE_CANNOT_REPLACE);
7282
5283
    /*
7283
 
      resetting the extra with 
7284
 
      table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY); 
 
5284
      resetting the extra with
 
5285
      table->file->extra(HA_EXTRA_NO_IGNORE_NO_KEY);
7285
5286
      fires bug#27077
7286
5287
      explanation: file->reset() performs this duty
7287
5288
      ultimately. Still todo: fix
7294
5295
  return error? error : local_error;
7295
5296
}
7296
5297
 
7297
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7298
5298
 
7299
5299
/*
7300
5300
  Check if there are more UNIQUE keys after the given key.
7301
5301
*/
7302
5302
static int
7303
 
last_uniq_key(TABLE *table, uint keyno)
 
5303
last_uniq_key(Table *table, uint32_t keyno)
7304
5304
{
7305
5305
  while (++keyno < table->s->keys)
7306
5306
    if (table->key_info[keyno].flags & HA_NOSAME)
7337
5337
  Write the current row into event's table.
7338
5338
 
7339
5339
  The row is located in the row buffer, pointed by @c m_curr_row member.
7340
 
  Number of columns of the row is stored in @c m_width member (it can be 
7341
 
  different from the number of columns in the table to which we insert). 
7342
 
  Bitmap @c m_cols indicates which columns are present in the row. It is assumed 
 
5340
  Number of columns of the row is stored in @c m_width member (it can be
 
5341
  different from the number of columns in the table to which we insert).
 
5342
  Bitmap @c m_cols indicates which columns are present in the row. It is assumed
7343
5343
  that event's table is already open and pointed by @c m_table.
7344
5344
 
7345
 
  If the same record already exists in the table it can be either overwritten 
7346
 
  or an error is reported depending on the value of @c overwrite flag 
 
5345
  If the same record already exists in the table it can be either overwritten
 
5346
  or an error is reported depending on the value of @c overwrite flag
7347
5347
  (error reporting not yet implemented). Note that the matching record can be
7348
5348
  different from the row we insert if we use primary keys to identify records in
7349
5349
  the table.
7350
5350
 
7351
 
  The row to be inserted can contain values only for selected columns. The 
7352
 
  missing columns are filled with default values using @c prepare_record() 
 
5351
  The row to be inserted can contain values only for selected columns. The
 
5352
  missing columns are filled with default values using @c prepare_record()
7353
5353
  function. If a matching record is found in the table and @c overwritte is
7354
5354
  true, the missing columns are taken from it.
7355
5355
 
7356
5356
  @param  rli   Relay log info (needed for row unpacking).
7357
 
  @param  overwrite  
7358
 
                Shall we overwrite if the row already exists or signal 
 
5357
  @param  overwrite
 
5358
                Shall we overwrite if the row already exists or signal
7359
5359
                error (currently ignored).
7360
5360
 
7361
5361
  @returns Error code on failure, 0 on success.
7362
5362
 
7363
5363
  This method, if successful, sets @c m_curr_row_end pointer to point at the
7364
 
  next row in the rows buffer. This is done when unpacking the row to be 
 
5364
  next row in the rows buffer. This is done when unpacking the row to be
7365
5365
  inserted.
7366
5366
 
7367
 
  @note If a matching record is found, it is either updated using 
 
5367
  @note If a matching record is found, it is either updated using
7368
5368
  @c ha_update_row() or first deleted and then new record written.
7369
 
*/ 
 
5369
*/
7370
5370
 
7371
5371
int
7372
5372
Rows_log_event::write_row(const Relay_log_info *const rli,
7373
5373
                          const bool overwrite)
7374
5374
{
7375
 
  assert(m_table != NULL && thd != NULL);
 
5375
  assert(m_table != NULL && session != NULL);
7376
5376
 
7377
 
  TABLE *table= m_table;  // pointer to event's table
 
5377
  Table *table= m_table;  // pointer to event's table
7378
5378
  int error;
7379
5379
  int keynum;
7380
 
  auto_afree_ptr<char> key(NULL);
 
5380
  basic_string<unsigned char> key;
7381
5381
 
7382
5382
  /* fill table->record[0] with default values */
7383
5383
 
7393
5393
  */
7394
5394
  if ((error= prepare_record(table, &m_cols, m_width, true)))
7395
5395
    return(error);
7396
 
  
 
5396
 
7397
5397
  /* unpack row into table->record[0] */
7398
5398
  error= unpack_current_row(rli, &m_cols);
7399
5399
 
7400
5400
  // Temporary fix to find out why it fails [/Matz]
7401
5401
  memcpy(m_table->write_set->bitmap, m_cols.bitmap, (m_table->write_set->n_bits + 7) / 8);
7402
5402
 
7403
 
  /* 
 
5403
  /*
7404
5404
    Try to write record. If a corresponding record already exists in the table,
7405
5405
    we try to change it using ha_update_row() if possible. Otherwise we delete
7406
 
    it and repeat the whole process again. 
 
5406
    it and repeat the whole process again.
7407
5407
 
7408
 
    TODO: Add safety measures against infinite looping. 
 
5408
    TODO: Add safety measures against infinite looping.
7409
5409
   */
7410
5410
 
7411
5411
  while ((error= table->file->ha_write_row(table->record[0])))
7457
5457
        return(my_errno);
7458
5458
      }
7459
5459
 
7460
 
      if (key.get() == NULL)
7461
 
      {
7462
 
        key.assign(static_cast<char*>(my_alloca(table->s->max_unique_length)));
7463
 
        if (key.get() == NULL)
7464
 
        {
7465
 
          return(ENOMEM);
7466
 
        }
7467
 
      }
 
5460
      key.reserve(table->s->max_unique_length);
7468
5461
 
7469
 
      key_copy((uchar*)key.get(), table->record[0], table->key_info + keynum,
7470
 
               0);
 
5462
      key_copy(key, table->record[0], table->key_info + keynum, 0);
7471
5463
      error= table->file->index_read_idx_map(table->record[1], keynum,
7472
 
                                             (const uchar*)key.get(),
 
5464
                                             key.data(),
7473
5465
                                             HA_WHOLE_KEY,
7474
5466
                                             HA_READ_KEY_EXACT);
7475
5467
      if (error)
7486
5478
     */
7487
5479
 
7488
5480
    /*
7489
 
      If row is incomplete we will use the record found to fill 
7490
 
      missing columns.  
 
5481
      If row is incomplete we will use the record found to fill
 
5482
      missing columns.
7491
5483
    */
7492
5484
    if (!get_flags(COMPLETE_ROWS_F))
7493
5485
    {
7516
5508
      error=table->file->ha_update_row(table->record[1],
7517
5509
                                       table->record[0]);
7518
5510
      switch (error) {
7519
 
                
 
5511
 
7520
5512
      case HA_ERR_RECORD_IS_THE_SAME:
7521
5513
        error= 0;
7522
 
      
 
5514
 
7523
5515
      case 0:
7524
5516
        break;
7525
 
        
7526
 
      default:    
 
5517
 
 
5518
      default:
7527
5519
        table->file->print_error(error, MYF(0));
7528
5520
      }
7529
 
      
 
5521
 
7530
5522
      return(error);
7531
5523
    }
7532
5524
    else
7543
5535
  return(error);
7544
5536
}
7545
5537
 
7546
 
#endif
7547
 
 
7548
 
int 
 
5538
 
 
5539
int Rows_log_event::unpack_current_row(const Relay_log_info *const rli,
 
5540
                                         MY_BITMAP const *cols)
 
5541
{
 
5542
  assert(m_table);
 
5543
  ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
 
5544
  int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, cols,
 
5545
                                 &m_curr_row_end, &m_master_reclength);
 
5546
  if (m_curr_row_end > m_rows_end)
 
5547
    my_error(ER_SLAVE_CORRUPT_EVENT, MYF(0));
 
5548
  ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
 
5549
  return result;
 
5550
}
 
5551
 
 
5552
 
 
5553
int
7549
5554
Write_rows_log_event::do_exec_row(const Relay_log_info *const rli)
7550
5555
{
7551
5556
  assert(m_table != NULL);
7552
5557
  int error=
7553
5558
    write_row(rli,        /* if 1 then overwrite */
7554
5559
              bit_is_set(slave_exec_mode, SLAVE_EXEC_MODE_IDEMPOTENT) == 1);
7555
 
    
7556
 
  if (error && !thd->is_error())
 
5560
 
 
5561
  if (error && !session->is_error())
7557
5562
  {
7558
5563
    assert(0);
7559
5564
    my_error(ER_UNKNOWN_ERROR, MYF(0));
7560
5565
  }
7561
 
  
7562
 
  return error; 
7563
 
}
7564
 
 
7565
 
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7566
 
 
7567
 
#ifdef DRIZZLE_CLIENT
7568
 
void Write_rows_log_event::print(FILE *file, PRINT_EVENT_INFO* print_event_info)
7569
 
{
7570
 
  Rows_log_event::print_helper(file, print_event_info, "Write_rows");
7571
 
}
7572
 
#endif
 
5566
 
 
5567
  return error;
 
5568
}
 
5569
 
7573
5570
 
7574
5571
/**************************************************************************
7575
5572
        Delete_rows_log_event member functions
7576
5573
**************************************************************************/
7577
5574
 
7578
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7579
5575
/*
7580
5576
  Compares table->record[0] and table->record[1]
7581
5577
 
7582
5578
  Returns TRUE if different.
7583
5579
*/
7584
 
static bool record_compare(TABLE *table)
 
5580
static bool record_compare(Table *table)
7585
5581
{
7586
5582
  /*
7587
5583
    Need to set the X bit and the filler bits in both records since
7595
5591
    records. Check that the other engines also return correct records.
7596
5592
   */
7597
5593
  bool result= false;
7598
 
  uchar saved_x[2], saved_filler[2];
 
5594
  unsigned char saved_x[2], saved_filler[2];
7599
5595
 
7600
5596
  if (table->s->null_bytes > 0)
7601
5597
  {
7656
5652
/**
7657
5653
  Locate the current row in event's table.
7658
5654
 
7659
 
  The current row is pointed by @c m_curr_row. Member @c m_width tells how many 
7660
 
  columns are there in the row (this can be differnet from the number of columns 
7661
 
  in the table). It is assumed that event's table is already open and pointed 
 
5655
  The current row is pointed by @c m_curr_row. Member @c m_width tells how many
 
5656
  columns are there in the row (this can be differnet from the number of columns
 
5657
  in the table). It is assumed that event's table is already open and pointed
7662
5658
  by @c m_table.
7663
5659
 
7664
 
  If a corresponding record is found in the table it is stored in 
7665
 
  @c m_table->record[0]. Note that when record is located based on a primary 
 
5660
  If a corresponding record is found in the table it is stored in
 
5661
  @c m_table->record[0]. Note that when record is located based on a primary
7666
5662
  key, it is possible that the record found differs from the row being located.
7667
5663
 
7668
 
  If no key is specified or table does not have keys, a table scan is used to 
 
5664
  If no key is specified or table does not have keys, a table scan is used to
7669
5665
  find the row. In that case the row should be complete and contain values for
7670
 
  all columns. However, it can still be shorter than the table, i.e. the table 
7671
 
  can contain extra columns not present in the row. It is also possible that 
7672
 
  the table has fewer columns than the row being located. 
7673
 
 
7674
 
  @returns Error code on failure, 0 on success. 
7675
 
  
7676
 
  @post In case of success @c m_table->record[0] contains the record found. 
 
5666
  all columns. However, it can still be shorter than the table, i.e. the table
 
5667
  can contain extra columns not present in the row. It is also possible that
 
5668
  the table has fewer columns than the row being located.
 
5669
 
 
5670
  @returns Error code on failure, 0 on success.
 
5671
 
 
5672
  @post In case of success @c m_table->record[0] contains the record found.
7677
5673
  Also, the internal "cursor" of the table is positioned at the record found.
7678
5674
 
7679
5675
  @note If the engine allows random access of the records, a combination of
7680
 
  @c position() and @c rnd_pos() will be used. 
 
5676
  @c position() and @c rnd_pos() will be used.
7681
5677
 */
7682
5678
 
7683
5679
int Rows_log_event::find_row(const Relay_log_info *rli)
7684
5680
{
7685
5681
  assert(m_table && m_table->in_use != NULL);
7686
5682
 
7687
 
  TABLE *table= m_table;
 
5683
  Table *table= m_table;
7688
5684
  int error;
7689
5685
 
7690
5686
  /* unpack row - missing fields get default values */
7691
 
  prepare_record(table, &m_cols, m_width, false/* don't check errors */); 
 
5687
  prepare_record(table, &m_cols, m_width, false/* don't check errors */);
7692
5688
  error= unpack_current_row(rli, &m_cols);
7693
5689
 
7694
5690
  // Temporary fix to find out why it fails [/Matz]
7725
5721
  }
7726
5722
 
7727
5723
  // We can't use position() - try other methods.
7728
 
  
 
5724
 
7729
5725
  /*
7730
 
    Save copy of the record in table->record[1]. It might be needed 
 
5726
    Save copy of the record in table->record[1]. It might be needed
7731
5727
    later if linear search is used to find exact match.
7732
 
   */ 
7733
 
  store_record(table,record[1]);    
 
5728
   */
 
5729
  store_record(table,record[1]);
7734
5730
 
7735
5731
  if (table->s->keys > 0)
7736
5732
  {
7755
5751
    my_ptrdiff_t const pos=
7756
5752
      table->s->null_bytes > 0 ? table->s->null_bytes - 1 : 0;
7757
5753
    table->record[0][pos]= 0xFF;
7758
 
    
7759
 
    if ((error= table->file->index_read_map(table->record[0], m_key, 
 
5754
 
 
5755
    if ((error= table->file->index_read_map(table->record[0], m_key,
7760
5756
                                            HA_WHOLE_KEY,
7761
5757
                                            HA_READ_KEY_EXACT)))
7762
5758
    {
7787
5783
 
7788
5784
    /*
7789
5785
      In case key is not unique, we still have to iterate over records found
7790
 
      and find the one which is identical to the row given. A copy of the 
 
5786
      and find the one which is identical to the row given. A copy of the
7791
5787
      record we are looking for is stored in record[1].
7792
 
     */ 
 
5788
     */
7793
5789
    while (record_compare(table))
7794
5790
    {
7795
5791
      /*
7854
5850
      }
7855
5851
    }
7856
5852
    while (restart_count < 2 && record_compare(table));
7857
 
    
7858
 
    /* 
7859
 
      Note: above record_compare will take into accout all record fields 
 
5853
 
 
5854
    /*
 
5855
      Note: above record_compare will take into accout all record fields
7860
5856
      which might be incorrect in case a partial row was given in the event
7861
5857
     */
7862
5858
    table->file->ha_rnd_end();
7872
5868
  return(error);
7873
5869
}
7874
5870
 
7875
 
#endif
7876
5871
 
7877
5872
/*
7878
5873
  Constructor used to build an event for writing to the binary log.
7879
5874
 */
7880
5875
 
7881
 
#ifndef DRIZZLE_CLIENT
7882
 
Delete_rows_log_event::Delete_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
5876
Delete_rows_log_event::Delete_rows_log_event(Session *session_arg, Table *tbl_arg,
7883
5877
                                             ulong tid,
7884
5878
                                             bool is_transactional)
7885
 
  : Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
5879
  : Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
7886
5880
{
7887
5881
}
7888
 
#endif /* #if !defined(DRIZZLE_CLIENT) */
7889
5882
 
7890
5883
/*
7891
5884
  Constructor used by slave to read the event from the binary log.
7892
5885
 */
7893
 
#ifdef HAVE_REPLICATION
7894
 
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint event_len,
 
5886
Delete_rows_log_event::Delete_rows_log_event(const char *buf, uint32_t event_len,
7895
5887
                                             const Format_description_log_event
7896
5888
                                             *description_event)
7897
5889
  : Rows_log_event(buf, event_len, DELETE_ROWS_EVENT, description_event)
7898
5890
{
7899
5891
}
7900
 
#endif
7901
 
 
7902
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
7903
 
 
7904
 
int 
 
5892
 
 
5893
 
 
5894
int
7905
5895
Delete_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
7906
5896
{
7907
5897
  if ((m_table->file->ha_table_flags() & HA_PRIMARY_KEY_REQUIRED_FOR_POSITION) &&
7916
5906
  if (m_table->s->keys > 0)
7917
5907
  {
7918
5908
    // Allocate buffer for key searches
7919
 
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
5909
    m_key= (unsigned char*)malloc(m_table->key_info->key_length);
7920
5910
    if (!m_key)
7921
5911
      return HA_ERR_OUT_OF_MEM;
7922
5912
  }
7924
5914
  return 0;
7925
5915
}
7926
5916
 
7927
 
int 
7928
 
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
5917
int
 
5918
Delete_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
7929
5919
                                               int error)
7930
5920
{
7931
5921
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
7932
5922
  m_table->file->ha_index_or_rnd_end();
7933
 
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR));
 
5923
  free(m_key);
7934
5924
  m_key= NULL;
7935
5925
 
7936
5926
  return error;
7941
5931
  int error;
7942
5932
  assert(m_table != NULL);
7943
5933
 
7944
 
  if (!(error= find_row(rli))) 
7945
 
  { 
 
5934
  if (!(error= find_row(rli)))
 
5935
  {
7946
5936
    /*
7947
5937
      Delete the record found, located in record[0]
7948
5938
    */
7951
5941
  return error;
7952
5942
}
7953
5943
 
7954
 
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
7955
 
 
7956
 
#ifdef DRIZZLE_CLIENT
7957
 
void Delete_rows_log_event::print(FILE *file,
7958
 
                                  PRINT_EVENT_INFO* print_event_info)
7959
 
{
7960
 
  Rows_log_event::print_helper(file, print_event_info, "Delete_rows");
7961
 
}
7962
 
#endif
7963
 
 
7964
5944
 
7965
5945
/**************************************************************************
7966
5946
        Update_rows_log_event member functions
7969
5949
/*
7970
5950
  Constructor used to build an event for writing to the binary log.
7971
5951
 */
7972
 
#if !defined(DRIZZLE_CLIENT)
7973
 
Update_rows_log_event::Update_rows_log_event(THD *thd_arg, TABLE *tbl_arg,
 
5952
Update_rows_log_event::Update_rows_log_event(Session *session_arg, Table *tbl_arg,
7974
5953
                                             ulong tid,
7975
5954
                                             bool is_transactional)
7976
 
: Rows_log_event(thd_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
 
5955
: Rows_log_event(session_arg, tbl_arg, tid, tbl_arg->read_set, is_transactional)
7977
5956
{
7978
5957
  init(tbl_arg->write_set);
7979
5958
}
7994
5973
    }
7995
5974
  }
7996
5975
}
7997
 
#endif /* !defined(DRIZZLE_CLIENT) */
7998
5976
 
7999
5977
 
8000
5978
Update_rows_log_event::~Update_rows_log_event()
8001
5979
{
8002
 
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
8003
 
    m_cols_ai.bitmap= 0; // so no my_free in bitmap_free
 
5980
  if (m_cols_ai.bitmap == m_bitbuf_ai) // no malloc happened
 
5981
    m_cols_ai.bitmap= 0; // so no free in bitmap_free
8004
5982
  bitmap_free(&m_cols_ai); // To pair with bitmap_init().
8005
5983
}
8006
5984
 
8008
5986
/*
8009
5987
  Constructor used by slave to read the event from the binary log.
8010
5988
 */
8011
 
#ifdef HAVE_REPLICATION
8012
 
Update_rows_log_event::Update_rows_log_event(const char *buf, uint event_len,
 
5989
Update_rows_log_event::Update_rows_log_event(const char *buf, uint32_t event_len,
8013
5990
                                             const
8014
5991
                                             Format_description_log_event
8015
5992
                                             *description_event)
8016
5993
  : Rows_log_event(buf, event_len, UPDATE_ROWS_EVENT, description_event)
8017
5994
{
8018
5995
}
8019
 
#endif
8020
 
 
8021
 
#if !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION)
8022
 
 
8023
 
int 
 
5996
 
 
5997
 
 
5998
int
8024
5999
Update_rows_log_event::do_before_row_operations(const Slave_reporting_capability *const)
8025
6000
{
8026
6001
  if (m_table->s->keys > 0)
8027
6002
  {
8028
6003
    // Allocate buffer for key searches
8029
 
    m_key= (uchar*)my_malloc(m_table->key_info->key_length, MYF(MY_WME));
 
6004
    m_key= (unsigned char*)malloc(m_table->key_info->key_length);
8030
6005
    if (!m_key)
8031
6006
      return HA_ERR_OUT_OF_MEM;
8032
6007
  }
8036
6011
  return 0;
8037
6012
}
8038
6013
 
8039
 
int 
8040
 
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const, 
 
6014
int
 
6015
Update_rows_log_event::do_after_row_operations(const Slave_reporting_capability *const,
8041
6016
                                               int error)
8042
6017
{
8043
6018
  /*error= ToDo:find out what this should really be, this triggers close_scan in nbd, returning error?*/
8044
6019
  m_table->file->ha_index_or_rnd_end();
8045
 
  my_free(m_key, MYF(MY_ALLOW_ZERO_PTR)); // Free for multi_malloc
 
6020
  free(m_key); // Free for multi_malloc
8046
6021
  m_key= NULL;
8047
6022
 
8048
6023
  return error;
8049
6024
}
8050
6025
 
8051
 
int 
 
6026
int
8052
6027
Update_rows_log_event::do_exec_row(const Relay_log_info *const rli)
8053
6028
{
8054
6029
  assert(m_table != NULL);
8055
6030
 
8056
 
  int error= find_row(rli); 
 
6031
  int error= find_row(rli);
8057
6032
  if (error)
8058
6033
  {
8059
6034
    /*
8097
6072
  return error;
8098
6073
}
8099
6074
 
8100
 
#endif /* !defined(DRIZZLE_CLIENT) && defined(HAVE_REPLICATION) */
8101
 
 
8102
 
#ifdef DRIZZLE_CLIENT
8103
 
void Update_rows_log_event::print(FILE *file,
8104
 
                                  PRINT_EVENT_INFO* print_event_info)
8105
 
{
8106
 
  Rows_log_event::print_helper(file, print_event_info, "Update_rows");
8107
 
}
8108
 
#endif
8109
 
 
8110
 
 
8111
 
Incident_log_event::Incident_log_event(const char *buf, uint event_len,
 
6075
 
 
6076
Incident_log_event::Incident_log_event(const char *buf, uint32_t event_len,
8112
6077
                                       const Format_description_log_event *descr_event)
8113
6078
  : Log_event(buf, descr_event)
8114
6079
{
8149
6114
}
8150
6115
 
8151
6116
 
8152
 
#ifndef DRIZZLE_CLIENT
8153
6117
void Incident_log_event::pack_info(Protocol *protocol)
8154
6118
{
8155
6119
  char buf[256];
8162
6126
                    m_incident, description(), m_message.str);
8163
6127
  protocol->store(buf, bytes, &my_charset_bin);
8164
6128
}
8165
 
#endif
8166
 
 
8167
 
 
8168
 
#ifdef DRIZZLE_CLIENT
8169
 
void
8170
 
Incident_log_event::print(FILE *file,
8171
 
                          PRINT_EVENT_INFO *print_event_info)
8172
 
{
8173
 
  if (print_event_info->short_form)
8174
 
    return;
8175
 
 
8176
 
  Write_on_release_cache cache(&print_event_info->head_cache, file);
8177
 
  print_header(&cache, print_event_info, false);
8178
 
  my_b_printf(&cache, "\n# Incident: %s", description());
8179
 
}
8180
 
#endif
8181
 
 
8182
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
 
6129
 
 
6130
 
8183
6131
int
8184
6132
Incident_log_event::do_apply_event(Relay_log_info const *rli)
8185
6133
{
8189
6137
              m_message.length > 0 ? m_message.str : "<none>");
8190
6138
  return(1);
8191
6139
}
8192
 
#endif
 
6140
 
8193
6141
 
8194
6142
bool
8195
6143
Incident_log_event::write_data_header(IO_CACHE *file)
8196
6144
{
8197
 
  uchar buf[sizeof(int16_t)];
 
6145
  unsigned char buf[sizeof(int16_t)];
8198
6146
  int2store(buf, (int16_t) m_incident);
8199
6147
  return(my_b_safe_write(file, buf, sizeof(buf)));
8200
6148
}
8205
6153
  return(write_str(file, m_message.str, m_message.length));
8206
6154
}
8207
6155
 
8208
 
#if defined(HAVE_REPLICATION) && !defined(DRIZZLE_CLIENT)
8209
 
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint event_len,
 
6156
Heartbeat_log_event::Heartbeat_log_event(const char* buf, uint32_t event_len,
8210
6157
                    const Format_description_log_event* description_event)
8211
6158
  :Log_event(buf, description_event)
8212
6159
{
8215
6162
  set_if_smaller(ident_len,FN_REFLEN-1);
8216
6163
  log_ident= buf + header_size;
8217
6164
}
8218
 
#endif
8219
 
 
8220
 
 
8221
 
#ifdef DRIZZLE_CLIENT
8222
 
/**
8223
 
  The default values for these variables should be values that are
8224
 
  *incorrect*, i.e., values that cannot occur in an event.  This way,
8225
 
  they will always be printed for the first event.
8226
 
*/
8227
 
st_print_event_info::st_print_event_info()
8228
 
  :flags2_inited(0), sql_mode_inited(0),
8229
 
   auto_increment_increment(0),auto_increment_offset(0), charset_inited(0),
8230
 
   lc_time_names_number(~0),
8231
 
   charset_database_number(ILLEGAL_CHARSET_INFO_NUMBER),
8232
 
   thread_id(0), thread_id_printed(false),
8233
 
   base64_output_mode(BASE64_OUTPUT_UNSPEC), printed_fd_event(false)
8234
 
{
8235
 
  /*
8236
 
    Currently we only use static PRINT_EVENT_INFO objects, so zeroed at
8237
 
    program's startup, but these explicit memset() is for the day someone
8238
 
    creates dynamic instances.
8239
 
  */
8240
 
  memset(db, 0, sizeof(db));
8241
 
  memset(charset, 0, sizeof(charset));
8242
 
  memset(time_zone_str, 0, sizeof(time_zone_str));
8243
 
  delimiter[0]= ';';
8244
 
  delimiter[1]= 0;
8245
 
  myf const flags = MYF(MY_WME | MY_NABP);
8246
 
  open_cached_file(&head_cache, NULL, NULL, 0, flags);
8247
 
  open_cached_file(&body_cache, NULL, NULL, 0, flags);
8248
 
}
8249
 
#endif