1
/* Copyright 2007 MySQL AB. All rights reserved.
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.
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.
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 */
16
#ifndef LOG_EVENT_OLD_H
17
#define LOG_EVENT_OLD_H
20
Need to include this file at the proper position of log_event.h
27
@brief This file contains classes handling old formats of row-based
31
Around 2007-10-31, I made these classes completely separated from
32
the new classes (before, there was a complex class hierarchy
33
involving multiple inheritance; see BUG#31581), by simply copying
34
and pasting the entire contents of Rows_log_event into
35
Old_rows_log_event and the entire contents of
36
{Write|Update|Delete}_rows_log_event into
37
{Write|Update|Delete}_rows_log_event_old. For clarity, I will keep
38
the comments marking which code was cut-and-pasted for some time.
39
With the classes collapsed into one, there is probably some
40
redundancy (maybe some methods can be simplified and/or removed),
41
but we keep them this way for now. /Sven
46
@class Old_rows_log_event
48
Base class for the three types of row-based events
49
{Write|Update|Delete}_row_log_event_old, with event type codes
50
PRE_GA_{WRITE|UPDATE|DELETE}_ROWS_EVENT. These events are never
51
created any more, except when reading a relay log created by an old
54
class Old_rows_log_event : public Log_event
56
/********** BEGIN CUT & PASTE FROM Rows_log_event **********/
59
Enumeration of the errors that can be returned.
63
ERR_OPEN_FAILURE = -1, /**< Failure to open table */
64
ERR_OK = 0, /**< No error */
65
ERR_TABLE_LIMIT_EXCEEDED = 1, /**< No more room for tables */
66
ERR_OUT_OF_MEM = 2, /**< Out of memory */
67
ERR_BAD_TABLE_DEF = 3, /**< Table definition does not match */
68
ERR_RBR_TO_SBR = 4 /**< daisy-chanining RBR to SBR not allowed */
72
These definitions allow you to combine the flags into an
73
appropriate flag set using the normal bitwise operators. The
74
implicit conversion from an enum-constant to an integer is
75
accepted by the compiler, which is then used to set the real set
80
/* Last event of a statement */
81
STMT_END_F = (1U << 0),
83
/* Value of the OPTION_NO_FOREIGN_KEY_CHECKS flag in thd->options */
84
NO_FOREIGN_KEY_CHECKS_F = (1U << 1),
86
/* Value of the OPTION_RELAXED_UNIQUE_CHECKS flag in thd->options */
87
RELAXED_UNIQUE_CHECKS_F = (1U << 2),
90
Indicates that rows in this event are complete, that is contain
91
values for all columns of the table.
93
COMPLETE_ROWS_F = (1U << 3)
96
typedef uint16 flag_set;
98
/* Special constants representing sets of flags */
104
virtual ~Old_rows_log_event();
106
void set_flags(flag_set flags_arg) { m_flags |= flags_arg; }
107
void clear_flags(flag_set flags_arg) { m_flags &= ~flags_arg; }
108
flag_set get_flags(flag_set flags_arg) const { return m_flags & flags_arg; }
110
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
111
virtual void pack_info(Protocol *protocol);
115
/* not for direct call, each derived has its own ::print() */
116
virtual void print(FILE *file, PRINT_EVENT_INFO *print_event_info)= 0;
120
int add_row_data(uchar *data, size_t length)
122
return do_add_row_data(data,length);
126
/* Member functions to implement superclass interface */
127
virtual int get_data_size();
129
MY_BITMAP const *get_cols() const { return &m_cols; }
130
size_t get_width() const { return m_width; }
131
ulong get_table_id() const { return m_table_id; }
134
virtual bool write_data_header(IO_CACHE *file);
135
virtual bool write_data_body(IO_CACHE *file);
136
virtual const char *get_db() { return m_table->s->db.str; }
139
Check that malloc() succeeded in allocating memory for the rows
140
buffer and the COLS vector. Checking that an Update_rows_log_event_old
141
is valid is done in the Update_rows_log_event_old::is_valid()
144
virtual bool is_valid() const
146
return m_rows_buf && m_cols.bitmap;
149
uint m_row_count; /* The number of rows added to the event */
153
The constructors are protected since you're supposed to inherit
154
this class, not create instances of this class.
157
Old_rows_log_event(THD*, TABLE*, ulong table_id,
158
MY_BITMAP const *cols, bool is_transactional);
160
Old_rows_log_event(const char *row_data, uint event_len,
161
Log_event_type event_type,
162
const Format_description_log_event *description_event);
165
void print_helper(FILE *, PRINT_EVENT_INFO *, char const *const name);
169
virtual int do_add_row_data(uchar *data, size_t length);
173
TABLE *m_table; /* The table the rows belong to */
175
ulong m_table_id; /* Table ID */
176
MY_BITMAP m_cols; /* Bitmap denoting columns available */
177
ulong m_width; /* The width of the columns bitmap */
179
ulong m_master_reclength; /* Length of record on master side */
181
/* Bit buffers in the same memory as the class */
182
uint32 m_bitbuf[128/(sizeof(uint32)*8)];
183
uint32 m_bitbuf_ai[128/(sizeof(uint32)*8)];
185
uchar *m_rows_buf; /* The rows in packed format */
186
uchar *m_rows_cur; /* One-after the end of the data */
187
uchar *m_rows_end; /* One-after the end of the allocated space */
189
flag_set m_flags; /* Flags for row-level events */
191
/* helper functions */
193
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
194
const uchar *m_curr_row; /* Start of the row being processed */
195
const uchar *m_curr_row_end; /* One-after the end of the current row */
196
uchar *m_key; /* Buffer to keep key value during searches */
198
int find_row(const Relay_log_info *const);
199
int write_row(const Relay_log_info *const, const bool);
201
// Unpack the current row into m_table->record[0]
202
int unpack_current_row(const Relay_log_info *const rli)
204
DBUG_ASSERT(m_table);
205
ASSERT_OR_RETURN_ERROR(m_curr_row < m_rows_end, HA_ERR_CORRUPT_EVENT);
206
int const result= ::unpack_row(rli, m_table, m_width, m_curr_row, &m_cols,
207
&m_curr_row_end, &m_master_reclength);
208
ASSERT_OR_RETURN_ERROR(m_curr_row_end <= m_rows_end, HA_ERR_CORRUPT_EVENT);
215
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
216
virtual int do_apply_event(Relay_log_info const *rli);
217
virtual int do_update_pos(Relay_log_info *rli);
218
virtual enum_skip_reason do_shall_skip(Relay_log_info *rli);
221
Primitive to prepare for a sequence of row executions.
225
Before doing a sequence of do_prepare_row() and do_exec_row()
226
calls, this member function should be called to prepare for the
227
entire sequence. Typically, this member function will allocate
228
space for any buffers that are needed for the two member
229
functions mentioned above.
233
The member function will return 0 if all went OK, or a non-zero
234
error code otherwise.
237
int do_before_row_operations(const Slave_reporting_capability *const log) = 0;
240
Primitive to clean up after a sequence of row executions.
244
After doing a sequence of do_prepare_row() and do_exec_row(),
245
this member function should be called to clean up and release
246
any allocated buffers.
248
The error argument, if non-zero, indicates an error which happened during
249
row processing before this function was called. In this case, even if
250
function is successful, it should return the error code given in the argument.
253
int do_after_row_operations(const Slave_reporting_capability *const log,
257
Primitive to do the actual execution necessary for a row.
260
The member function will do the actual execution needed to handle a row.
261
The row is located at m_curr_row. When the function returns,
262
m_curr_row_end should point at the next row (one byte after the end
266
0 if execution succeeded, 1 if execution failed.
269
virtual int do_exec_row(const Relay_log_info *const rli) = 0;
270
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
272
/********** END OF CUT & PASTE FROM Rows_log_event **********/
275
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
277
int do_apply_event(Old_rows_log_event*,const Relay_log_info*);
280
Primitive to prepare for a sequence of row executions.
284
Before doing a sequence of do_prepare_row() and do_exec_row()
285
calls, this member function should be called to prepare for the
286
entire sequence. Typically, this member function will allocate
287
space for any buffers that are needed for the two member
288
functions mentioned above.
292
The member function will return 0 if all went OK, or a non-zero
293
error code otherwise.
295
virtual int do_before_row_operations(TABLE *table) = 0;
298
Primitive to clean up after a sequence of row executions.
302
After doing a sequence of do_prepare_row() and do_exec_row(),
303
this member function should be called to clean up and release
304
any allocated buffers.
306
virtual int do_after_row_operations(TABLE *table, int error) = 0;
309
Primitive to prepare for handling one row in a row-level event.
313
The member function prepares for execution of operations needed for one
314
row in a row-level event by reading up data from the buffer containing
315
the row. No specific interpretation of the data is normally done here,
316
since SQL thread specific data is not available: that data is made
317
available for the do_exec function.
319
A pointer to the start of the next row, or NULL if the preparation
320
failed. Currently, preparation cannot fail, but don't rely on this
324
Error code, if something went wrong, 0 otherwise.
326
virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
327
uchar const *row_start,
328
uchar const **row_end) = 0;
331
Primitive to do the actual execution necessary for a row.
334
The member function will do the actual execution needed to handle a row.
337
0 if execution succeeded, 1 if execution failed.
340
virtual int do_exec_row(TABLE *table) = 0;
342
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
347
@class Write_rows_log_event_old
349
Old class for binlog events that write new rows to a table (event
350
type code PRE_GA_WRITE_ROWS_EVENT). Such events are never produced
351
by this version of the server, but they may be read from a relay log
352
created by an old server. New servers create events of class
353
Write_rows_log_event (event type code WRITE_ROWS_EVENT) instead.
355
class Write_rows_log_event_old : public Old_rows_log_event
357
/********** BEGIN CUT & PASTE FROM Write_rows_log_event **********/
359
#if !defined(MYSQL_CLIENT)
360
Write_rows_log_event_old(THD*, TABLE*, ulong table_id,
361
MY_BITMAP const *cols, bool is_transactional);
363
#ifdef HAVE_REPLICATION
364
Write_rows_log_event_old(const char *buf, uint event_len,
365
const Format_description_log_event *description_event);
367
#if !defined(MYSQL_CLIENT)
368
static bool binlog_row_logging_function(THD *thd, TABLE *table,
369
bool is_transactional,
372
const uchar *before_record
373
__attribute__((unused)),
374
const uchar *after_record)
376
return thd->binlog_write_row(table, is_transactional,
377
cols, fields, after_record);
383
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
386
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
387
virtual int do_before_row_operations(const Slave_reporting_capability *const);
388
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
389
virtual int do_exec_row(const Relay_log_info *const);
391
/********** END OF CUT & PASTE FROM Write_rows_log_event **********/
396
/* Support interface to THD::binlog_prepare_pending_rows_event */
397
TYPE_CODE = PRE_GA_WRITE_ROWS_EVENT
401
virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
403
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
404
// use old definition of do_apply_event()
405
virtual int do_apply_event(const Relay_log_info *rli)
406
{ return Old_rows_log_event::do_apply_event(this,rli); }
408
// primitives for old version of do_apply_event()
409
virtual int do_before_row_operations(TABLE *table);
410
virtual int do_after_row_operations(TABLE *table, int error);
411
virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
412
uchar const *row_start, uchar const **row_end);
413
virtual int do_exec_row(TABLE *table);
420
@class Update_rows_log_event_old
422
Old class for binlog events that modify existing rows to a table
423
(event type code PRE_GA_UPDATE_ROWS_EVENT). Such events are never
424
produced by this version of the server, but they may be read from a
425
relay log created by an old server. New servers create events of
426
class Update_rows_log_event (event type code UPDATE_ROWS_EVENT)
429
class Update_rows_log_event_old : public Old_rows_log_event
431
/********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/
434
Update_rows_log_event_old(THD*, TABLE*, ulong table_id,
435
MY_BITMAP const *cols,
436
bool is_transactional);
439
#ifdef HAVE_REPLICATION
440
Update_rows_log_event_old(const char *buf, uint event_len,
441
const Format_description_log_event *description_event);
444
#if !defined(MYSQL_CLIENT)
445
static bool binlog_row_logging_function(THD *thd, TABLE *table,
446
bool is_transactional,
449
const uchar *before_record,
450
const uchar *after_record)
452
return thd->binlog_update_row(table, is_transactional,
453
cols, fields, before_record, after_record);
459
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
462
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
463
virtual int do_before_row_operations(const Slave_reporting_capability *const);
464
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
465
virtual int do_exec_row(const Relay_log_info *const);
466
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
467
/********** END OF CUT & PASTE FROM Update_rows_log_event **********/
469
uchar *m_after_image, *m_memory;
474
/* Support interface to THD::binlog_prepare_pending_rows_event */
475
TYPE_CODE = PRE_GA_UPDATE_ROWS_EVENT
479
virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
481
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
482
// use old definition of do_apply_event()
483
virtual int do_apply_event(const Relay_log_info *rli)
484
{ return Old_rows_log_event::do_apply_event(this,rli); }
486
// primitives for old version of do_apply_event()
487
virtual int do_before_row_operations(TABLE *table);
488
virtual int do_after_row_operations(TABLE *table, int error);
489
virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
490
uchar const *row_start, uchar const **row_end);
491
virtual int do_exec_row(TABLE *table);
492
#endif /* !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION) */
497
@class Delete_rows_log_event_old
499
Old class for binlog events that delete existing rows from a table
500
(event type code PRE_GA_DELETE_ROWS_EVENT). Such events are never
501
produced by this version of the server, but they may be read from a
502
relay log created by an old server. New servers create events of
503
class Delete_rows_log_event (event type code DELETE_ROWS_EVENT)
506
class Delete_rows_log_event_old : public Old_rows_log_event
508
/********** BEGIN CUT & PASTE FROM Update_rows_log_event **********/
511
Delete_rows_log_event_old(THD*, TABLE*, ulong,
512
MY_BITMAP const *cols, bool is_transactional);
514
#ifdef HAVE_REPLICATION
515
Delete_rows_log_event_old(const char *buf, uint event_len,
516
const Format_description_log_event *description_event);
518
#if !defined(MYSQL_CLIENT)
519
static bool binlog_row_logging_function(THD *thd, TABLE *table,
520
bool is_transactional,
523
const uchar *before_record,
524
const uchar *after_record
525
__attribute__((unused)))
527
return thd->binlog_delete_row(table, is_transactional,
528
cols, fields, before_record);
534
void print(FILE *file, PRINT_EVENT_INFO *print_event_info);
537
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
538
virtual int do_before_row_operations(const Slave_reporting_capability *const);
539
virtual int do_after_row_operations(const Slave_reporting_capability *const,int);
540
virtual int do_exec_row(const Relay_log_info *const);
542
/********** END CUT & PASTE FROM Delete_rows_log_event **********/
544
uchar *m_after_image, *m_memory;
549
/* Support interface to THD::binlog_prepare_pending_rows_event */
550
TYPE_CODE = PRE_GA_DELETE_ROWS_EVENT
554
virtual Log_event_type get_type_code() { return (Log_event_type)TYPE_CODE; }
556
#if !defined(MYSQL_CLIENT) && defined(HAVE_REPLICATION)
557
// use old definition of do_apply_event()
558
virtual int do_apply_event(const Relay_log_info *rli)
559
{ return Old_rows_log_event::do_apply_event(this,rli); }
561
// primitives for old version of do_apply_event()
562
virtual int do_before_row_operations(TABLE *table);
563
virtual int do_after_row_operations(TABLE *table, int error);
564
virtual int do_prepare_row(THD*, Relay_log_info const*, TABLE*,
565
uchar const *row_start, uchar const **row_end);
566
virtual int do_exec_row(TABLE *table);