summaryrefslogtreecommitdiff
path: root/sql/log_event.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/log_event.cc')
-rw-r--r--sql/log_event.cc237
1 files changed, 144 insertions, 93 deletions
diff --git a/sql/log_event.cc b/sql/log_event.cc
index 66f1d6bc790..097cbe8da9d 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -1,6 +1,6 @@
/*
Copyright (c) 2000, 2019, Oracle and/or its affiliates.
- Copyright (c) 2009, 2019, MariaDB
+ Copyright (c) 2009, 2020, MariaDB
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -1040,9 +1040,14 @@ row_log_event_uncompress(const Format_description_log_event *description_event,
uint32 binlog_get_uncompress_len(const char *buf)
{
- DBUG_ASSERT((buf[0] & 0xe0) == 0x80);
- uint32 lenlen = buf[0] & 0x07;
uint32 len = 0;
+ uint32 lenlen = 0;
+
+ if ((buf == NULL) || ((buf[0] & 0xe0) != 0x80))
+ return len;
+
+ lenlen = buf[0] & 0x07;
+
switch(lenlen)
{
case 1:
@@ -2032,7 +2037,7 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len,
else
DBUG_RETURN(NULL);
#else
- *error= ER(ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
+ *error= ER_THD_OR_DEFAULT(current_thd, ER_BINLOG_READ_EVENT_CHECKSUM_FAILURE);
sql_print_error("%s", *error);
DBUG_RETURN(NULL);
#endif
@@ -2994,13 +2999,20 @@ log_event_print_value(IO_CACHE *file, const uchar *ptr,
"Not enough metadata to display the value. ");
break;
+ case MYSQL_TYPE_GEOMETRY:
+ strmake(typestr, "GEOMETRY", typestr_length);
+ if (!ptr)
+ goto return_null;
+
+ length= uint4korr(ptr);
+ my_b_write_quoted(file, ptr + meta, length);
+ return length + meta;
+
default:
{
- char tmp[5];
- my_snprintf(tmp, sizeof(tmp), "%04x", meta);
- my_b_printf(file,
- "!! Don't know how to handle column type=%d meta=%d (%s)",
- type, meta, tmp);
+ fprintf(stderr,
+ "\nError: Don't know how to handle column type: %d meta: %d (%04x)\n",
+ type, meta, meta);
}
break;
}
@@ -3179,7 +3191,7 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf
Table_map_log_event *map;
table_def *td;
DYNAMIC_ARRAY rows_arr;
- uchar *swap_buff1, *swap_buff2;
+ uchar *swap_buff1;
uchar *rows_pos= rows_buff + m_rows_before_size;
if (!(map= print_event_info->m_table_map.get_table(m_table_id)) ||
@@ -3228,7 +3240,7 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf
}
value+= length2;
- swap_buff2= (uchar *) my_malloc(length2, MYF(0));
+ void *swap_buff2= my_malloc(length2, MYF(0));
if (!swap_buff2)
{
fprintf(stderr, "\nError: Out of memory. "
@@ -3236,21 +3248,14 @@ void Rows_log_event::change_to_flashback_event(PRINT_EVENT_INFO *print_event_inf
exit(1);
}
memcpy(swap_buff2, start_pos + length1, length2); // WHERE part
- }
- if (ev_type == UPDATE_ROWS_EVENT ||
- ev_type == UPDATE_ROWS_EVENT_V1)
- {
/* Swap SET and WHERE part */
memcpy(start_pos, swap_buff2, length2);
memcpy(start_pos + length2, swap_buff1, length1);
+ my_free(swap_buff2);
}
- /* Free tmp buffers */
my_free(swap_buff1);
- if (ev_type == UPDATE_ROWS_EVENT ||
- ev_type == UPDATE_ROWS_EVENT_V1)
- my_free(swap_buff2);
/* Copying one row into a buff, and pushing into the array */
LEX_STRING one_row;
@@ -3581,7 +3586,7 @@ void Log_event::print_base64(IO_CACHE* file,
#ifdef WHEN_FLASHBACK_REVIEW_READY
ev->need_flashback_review= need_flashback_review;
if (print_event_info->verbose)
- ev->print_verbose(file, print_event_info);
+ ev->print_verbose(&print_event_info->tail_cache, print_event_info);
else
{
IO_CACHE tmp_cache;
@@ -3591,18 +3596,7 @@ void Log_event::print_base64(IO_CACHE* file,
}
#else
if (print_event_info->verbose)
- {
- /*
- Verbose event printout can't start before encoded data
- got enquoted. This is done at this point though multi-row
- statement remain vulnerable.
- TODO: fix MDEV-10362 to remove this workaround.
- */
- if (print_event_info->base64_output_mode !=
- BASE64_OUTPUT_DECODE_ROWS)
- my_b_printf(file, "'%s\n", print_event_info->delimiter);
- ev->print_verbose(file, print_event_info);
- }
+ ev->print_verbose(&print_event_info->tail_cache, print_event_info);
#endif
delete ev;
}
@@ -4207,7 +4201,7 @@ get_str_len_and_pointer(const Log_event::Byte **src,
const Log_event::Byte *end)
{
if (*src >= end)
- return -1; // Will be UINT_MAX in two-complement arithmetics
+ return -1; // Will be UINT_MAX in two-complement arithmetic
uint length= **src;
if (length > 0)
{
@@ -4255,6 +4249,18 @@ code_name(int code)
}
#endif
+#define VALIDATE_BYTES_READ(CUR_POS, START, EVENT_LEN) \
+ do { \
+ uchar *cur_pos= (uchar *)CUR_POS; \
+ uchar *start= (uchar *)START; \
+ uint len= EVENT_LEN; \
+ uint bytes_read= (uint)(cur_pos - start); \
+ DBUG_PRINT("info", ("Bytes read: %u event_len:%u.\n",\
+ bytes_read, len)); \
+ if (bytes_read >= len) \
+ DBUG_VOID_RETURN; \
+ } while (0)
+
/**
Macro to check that there is enough space to read from memory.
@@ -4265,7 +4271,6 @@ code_name(int code)
#define CHECK_SPACE(PTR,END,CNT) \
do { \
DBUG_PRINT("info", ("Read %s", code_name(pos[-1]))); \
- DBUG_ASSERT((PTR) + (CNT) <= (END)); \
if ((PTR) + (CNT) > (END)) { \
DBUG_PRINT("info", ("query= 0")); \
query= 0; \
@@ -4562,7 +4567,7 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
/* A 2nd variable part; this is common to all versions */
memcpy((char*) start, end, data_len); // Copy db and query
- start[data_len]= '\0'; // End query with \0 (For safetly)
+ start[data_len]= '\0'; // End query with \0 (For safety)
db= (char *)start;
query= (char *)(start + db_len + 1);
q_len= data_len - db_len -1;
@@ -4578,7 +4583,9 @@ Query_log_event::Query_log_event(const char* buf, uint event_len,
uint32 max_length= uint32(event_len - ((const char*)(end + db_len + 1) -
(buf - common_header_len)));
- if (q_len != max_length)
+ if (q_len != max_length ||
+ (event_len < uint((const char*)(end + db_len + 1) -
+ (buf - common_header_len))))
{
q_len= 0;
query= NULL;
@@ -5572,7 +5579,7 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
}
}
#ifdef WITH_WSREP
- else if (WSREP_ON && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
+ else if (WSREP(thd) && wsrep_mysql_replication_bundle && opt_slave_domain_parallel_threads == 0 &&
thd->wsrep_mysql_replicated > 0 &&
(is_begin() || is_commit()))
{
@@ -5586,7 +5593,7 @@ Query_log_event::do_shall_skip(rpl_group_info *rgi)
thd->wsrep_mysql_replicated = 0;
}
}
-#endif
+#endif /* WITH_WSREP */
DBUG_RETURN(Log_event::do_shall_skip(rgi));
}
@@ -6214,7 +6221,7 @@ int Format_description_log_event::do_update_pos(rpl_group_info *rgi)
If we do not skip stepping the group log position (and the
server id was changed when restarting the server), it might well
be that we start executing at a position that is invalid, e.g.,
- at a Rows_log_event or a Query_log_event preceeded by a
+ at a Rows_log_event or a Query_log_event preceded by a
Intvar_log_event instead of starting at a Table_map_log_event or
the Intvar_log_event respectively.
*/
@@ -6326,7 +6333,7 @@ Format_description_log_event::is_version_before_checksum(const master_version_sp
@return the version-safe checksum alg descriptor where zero
designates no checksum, 255 - the orginator is
- checksum-unaware (effectively no checksum) and the actuall
+ checksum-unaware (effectively no checksum) and the actual
[1-254] range alg descriptor.
*/
enum enum_binlog_checksum_alg get_checksum_alg(const char* buf, ulong len)
@@ -6713,6 +6720,8 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
{
DBUG_ENTER("Load_log_event::copy_log_event");
uint data_len;
+ if ((int) event_len <= body_offset)
+ DBUG_RETURN(1);
char* buf_end = (char*)buf + event_len;
/* this is the beginning of the post-header */
const char* data_head = buf + description_event->common_header_len;
@@ -6722,9 +6731,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
table_name_len = (uint)data_head[L_TBL_LEN_OFFSET];
db_len = (uint)data_head[L_DB_LEN_OFFSET];
num_fields = uint4korr(data_head + L_NUM_FIELDS_OFFSET);
-
- if ((int) event_len < body_offset)
- DBUG_RETURN(1);
+
/*
Sql_ex.init() on success returns the pointer to the first byte after
the sql_ex structure, which is the start of field lengths array.
@@ -6733,7 +6740,7 @@ int Load_log_event::copy_log_event(const char *buf, ulong event_len,
buf_end,
(uchar)buf[EVENT_TYPE_OFFSET] != LOAD_EVENT)))
DBUG_RETURN(1);
-
+
data_len = event_len - body_offset;
if (num_fields > data_len) // simple sanity check against corruption
DBUG_RETURN(1);
@@ -7032,7 +7039,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi,
/*
When replication is running fine, if it was DUP_ERROR on the
master then we could choose IGNORE here, because if DUP_ERROR
- suceeded on master, and data is identical on the master and slave,
+ succeeded on master, and data is identical on the master and slave,
then there should be no uniqueness errors on slave, so IGNORE is
the same as DUP_ERROR. But in the unlikely case of uniqueness errors
(because the data on the master and slave happen to be different
@@ -7273,7 +7280,7 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
uint8 post_header_len= description_event->post_header_len[ROTATE_EVENT-1];
uint ident_offset;
- if (event_len < LOG_EVENT_MINIMAL_HEADER_LEN)
+ if (event_len < (uint)(LOG_EVENT_MINIMAL_HEADER_LEN + post_header_len))
DBUG_VOID_RETURN;
buf+= LOG_EVENT_MINIMAL_HEADER_LEN;
pos= post_header_len ? uint8korr(buf + R_POS_OFFSET) : 4;
@@ -7569,7 +7576,7 @@ Gtid_log_event::Gtid_log_event(THD *thd_arg, uint64 seq_no_arg,
/*
Used to record GTID while sending binlog to slave, without having to
- fully contruct every Gtid_log_event() needlessly.
+ fully construct every Gtid_log_event() needlessly.
*/
bool
Gtid_log_event::peek(const char *event_start, size_t event_len,
@@ -8092,7 +8099,7 @@ Gtid_list_log_event::print(FILE *file, PRINT_EVENT_INFO *print_event_info)
/*
Used to record gtid_list event while sending binlog to slave, without having to
- fully contruct the event object.
+ fully construct the event object.
*/
bool
Gtid_list_log_event::peek(const char *event_start, uint32 event_len,
@@ -8172,7 +8179,7 @@ Intvar_log_event::Intvar_log_event(const char* buf,
const Format_description_log_event* description_event)
:Log_event(buf, description_event)
{
- /* The Post-Header is empty. The Varible Data part begins immediately. */
+ /* The Post-Header is empty. The Variable Data part begins immediately. */
buf+= description_event->common_header_len +
description_event->post_header_len[INTVAR_EVENT-1];
type= buf[I_TYPE_OFFSET];
@@ -8549,8 +8556,16 @@ int Xid_log_event::do_apply_event(rpl_group_info *rgi)
res= trans_commit(thd); /* Automatically rolls back on error. */
thd->mdl_context.release_transactional_locks();
+#ifdef WITH_WSREP
+ if (WSREP(thd)) mysql_mutex_lock(&thd->LOCK_thd_data);
+ if ((!res || (WSREP(thd) && thd->wsrep_conflict_state == MUST_REPLAY)) && sub_id)
+#else
if (!res && sub_id)
+#endif /* WITH_WSREP */
rpl_global_gtid_slave_state->update_state_hash(sub_id, &gtid, rgi);
+#ifdef WITH_WSREP
+ if (WSREP(thd)) mysql_mutex_unlock(&thd->LOCK_thd_data);
+#endif /* WITH_WSREP */
/*
Increment the global status commit count variable
@@ -8571,7 +8586,7 @@ Xid_log_event::do_shall_skip(rpl_group_info *rgi)
DBUG_RETURN(Log_event::EVENT_SKIP_COUNT);
}
#ifdef WITH_WSREP
- else if (wsrep_mysql_replication_bundle && WSREP_ON &&
+ else if (WSREP(thd) && wsrep_mysql_replication_bundle &&
opt_slave_domain_parallel_threads == 0)
{
if (++thd->wsrep_mysql_replicated < (int)wsrep_mysql_replication_bundle)
@@ -8783,6 +8798,11 @@ User_var_log_event(const char* buf, uint event_len,
we keep the flags set to UNDEF_F.
*/
size_t bytes_read= (val + val_len) - buf_start;
+ if (bytes_read > event_len)
+ {
+ error= true;
+ goto err;
+ }
if ((data_written - bytes_read) > 0)
{
flags= (uint) *(buf + UV_VAL_IS_NULL + UV_VAL_TYPE_SIZE +
@@ -9397,7 +9417,7 @@ void Create_file_log_event::pack_info(Protocol *protocol)
/**
Create_file_log_event::do_apply_event()
- Constructor for Create_file_log_event to intantiate an event
+ Constructor for Create_file_log_event to instantiate an event
from the relay log on the slave.
@retval
@@ -10204,6 +10224,8 @@ const char *sql_ex_info::init(const char *buf, const char *buf_end,
}
else
{
+ if (buf_end - buf < 7)
+ return 0; // Wrong data
field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1;
field_term = buf++; // Use first byte in string
enclosed= buf++;
@@ -10346,9 +10368,16 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
uint8 const common_header_len= description_event->common_header_len;
Log_event_type event_type= (Log_event_type)(uchar)buf[EVENT_TYPE_OFFSET];
m_type= event_type;
-
+ m_cols_ai.bitmap= 0;
+
uint8 const post_header_len= description_event->post_header_len[event_type-1];
+ if (event_len < (uint)(common_header_len + post_header_len))
+ {
+ m_cols.bitmap= 0;
+ DBUG_VOID_RETURN;
+ }
+
DBUG_PRINT("enter",("event_len: %u common_header_len: %d "
"post_header_len: %d",
event_len, common_header_len,
@@ -10380,7 +10409,14 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
which includes length bytes
*/
var_header_len= uint2korr(post_start);
- assert(var_header_len >= 2);
+ /* Check length and also avoid out of buffer read */
+ if (var_header_len < 2 ||
+ event_len < static_cast<unsigned int>(var_header_len +
+ (post_start - buf)))
+ {
+ m_cols.bitmap= 0;
+ DBUG_VOID_RETURN;
+ }
var_header_len-= 2;
/* Iterate over var-len header, extracting 'chunks' */
@@ -10431,7 +10467,7 @@ Rows_log_event::Rows_log_event(const char *buf, uint event_len,
DBUG_VOID_RETURN;
}
- /* if my_bitmap_init fails, catched in is_valid() */
+ /* if my_bitmap_init fails, caught in is_valid() */
if (likely(!my_bitmap_init(&m_cols,
m_width <= sizeof(m_bitbuf)*8 ? m_bitbuf : NULL,
m_width,
@@ -10848,7 +10884,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
*/
{
- DBUG_PRINT("debug", ("Checking compability of tables to lock - tables_to_lock: %p",
+ DBUG_PRINT("debug", ("Checking compatibility of tables to lock - tables_to_lock: %p",
rgi->tables_to_lock));
/**
@@ -10903,7 +10939,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi)
ptr->table->s->table_name.str));
/*
We should not honour --slave-skip-errors at this point as we are
- having severe errors which should not be skiped.
+ having severe errors which should not be skipped.
*/
thd->is_slave_error= 1;
/* remove trigger's tables */
@@ -11284,7 +11320,7 @@ static int rows_event_stmt_cleanup(rpl_group_info *rgi, THD * thd)
/**
The method either increments the relay log position or
commits the current statement and increments the master group
- possition if the event is STMT_END_F flagged and
+ position if the event is STMT_END_F flagged and
the statement corresponds to the autocommit query (i.e replicated
without wrapping in BEGIN/COMMIT)
@@ -11430,7 +11466,7 @@ public:
/**
Print an event "body" cache to @c file possibly in two fragments.
- Each fragement is optionally per @c do_wrap to produce an SQL statement.
+ Each fragment is optionally per @c do_wrap to produce an SQL statement.
@param file a file to print to
@param body the "body" IO_CACHE of event
@@ -11498,11 +11534,8 @@ void copy_cache_to_string_wrapped(IO_CACHE *cache,
str_tmp.length= sprintf(str_tmp.str, fmt_frag, 1);
ret.append(&str_tmp);
ret.append(cache, uint32(cache->end_of_file - (cache_size/2 + 1)));
- if (!is_verbose)
- {
- str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter);
- ret.append(&str_tmp);
- }
+ str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter);
+ ret.append(&str_tmp);
str_tmp.length= sprintf(str_tmp.str, "BINLOG @binlog_fragment_0, @binlog_fragment_1%s\n",
delimiter);
ret.append(&str_tmp);
@@ -11512,11 +11545,8 @@ void copy_cache_to_string_wrapped(IO_CACHE *cache,
str_tmp.length= sprintf(str_tmp.str, str_binlog);
ret.append(&str_tmp);
ret.append(cache, (uint32) cache->end_of_file);
- if (!is_verbose)
- {
- str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter);
- ret.append(&str_tmp);
- }
+ str_tmp.length= sprintf(str_tmp.str, fmt_delim, delimiter);
+ ret.append(&str_tmp);
}
to->length= ret.length();
@@ -11565,6 +11595,7 @@ void Rows_log_event::print_helper(FILE *file,
{
IO_CACHE *const head= &print_event_info->head_cache;
IO_CACHE *const body= &print_event_info->body_cache;
+ IO_CACHE *const tail= &print_event_info->tail_cache;
#ifdef WHEN_FLASHBACK_REVIEW_READY
IO_CACHE *const sql= &print_event_info->review_sql_cache;
#endif
@@ -11606,6 +11637,13 @@ void Rows_log_event::print_helper(FILE *file,
print_event_info->verbose);
output_buf.append(&tmp_str);
my_free(tmp_str.str);
+ if (copy_event_cache_to_string_and_reinit(tail, &tmp_str))
+ {
+ tail->error= -1;
+ return;
+ }
+ output_buf.append(&tmp_str);
+ my_free(tmp_str.str);
}
}
#endif
@@ -11942,14 +11980,12 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
m_data_size(0), m_field_metadata(0), m_field_metadata_size(0),
m_null_bits(0), m_meta_memory(NULL)
{
- unsigned int bytes_read= 0;
DBUG_ENTER("Table_map_log_event::Table_map_log_event(const char*,uint,...)");
uint8 common_header_len= description_event->common_header_len;
uint8 post_header_len= description_event->post_header_len[TABLE_MAP_EVENT-1];
DBUG_PRINT("info",("event_len: %u common_header_len: %d post_header_len: %d",
event_len, common_header_len, post_header_len));
-
/*
Don't print debug messages when running valgrind since they can
trigger false warnings.
@@ -11958,10 +11994,14 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
DBUG_DUMP("event buffer", (uchar*) buf, event_len);
#endif
+ if (event_len < (uint)(common_header_len + post_header_len))
+ DBUG_VOID_RETURN;
+
/* Read the post-header */
const char *post_start= buf + common_header_len;
post_start+= TM_MAPID_OFFSET;
+ VALIDATE_BYTES_READ(post_start, buf, event_len);
if (post_header_len == 6)
{
/* Master is of an intermediate source tree before 5.1.4. Id is 4 bytes */
@@ -11984,15 +12024,18 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
/* Extract the length of the various parts from the buffer */
uchar const *const ptr_dblen= (uchar const*)vpart + 0;
+ VALIDATE_BYTES_READ(ptr_dblen, buf, event_len);
m_dblen= *(uchar*) ptr_dblen;
/* Length of database name + counter + terminating null */
uchar const *const ptr_tbllen= ptr_dblen + m_dblen + 2;
+ VALIDATE_BYTES_READ(ptr_tbllen, buf, event_len);
m_tbllen= *(uchar*) ptr_tbllen;
/* Length of table name + counter + terminating null */
uchar const *const ptr_colcnt= ptr_tbllen + m_tbllen + 2;
uchar *ptr_after_colcnt= (uchar*) ptr_colcnt;
+ VALIDATE_BYTES_READ(ptr_after_colcnt, buf, event_len);
m_colcnt= net_field_length(&ptr_after_colcnt);
DBUG_PRINT("info",("m_dblen: %lu off: %ld m_tbllen: %lu off: %ld m_colcnt: %lu off: %ld",
@@ -12015,23 +12058,27 @@ Table_map_log_event::Table_map_log_event(const char *buf, uint event_len,
memcpy(m_coltype, ptr_after_colcnt, m_colcnt);
ptr_after_colcnt= ptr_after_colcnt + m_colcnt;
- bytes_read= (uint) (ptr_after_colcnt - (uchar *)buf);
- DBUG_PRINT("info", ("Bytes read: %d.\n", bytes_read));
- if (bytes_read < event_len)
+ VALIDATE_BYTES_READ(ptr_after_colcnt, buf, event_len);
+ m_field_metadata_size= net_field_length(&ptr_after_colcnt);
+ if(m_field_metadata_size <= (m_colcnt * 2))
{
- m_field_metadata_size= net_field_length(&ptr_after_colcnt);
- DBUG_ASSERT(m_field_metadata_size <= (m_colcnt * 2));
uint num_null_bytes= (m_colcnt + 7) / 8;
m_meta_memory= (uchar *)my_multi_malloc(MYF(MY_WME),
- &m_null_bits, num_null_bytes,
- &m_field_metadata, m_field_metadata_size,
- NULL);
+ &m_null_bits, num_null_bytes,
+ &m_field_metadata, m_field_metadata_size,
+ NULL);
memcpy(m_field_metadata, ptr_after_colcnt, m_field_metadata_size);
ptr_after_colcnt= (uchar*)ptr_after_colcnt + m_field_metadata_size;
memcpy(m_null_bits, ptr_after_colcnt, num_null_bytes);
}
+ else
+ {
+ m_coltype= NULL;
+ my_free(m_memory);
+ m_memory= NULL;
+ DBUG_VOID_RETURN;
+ }
}
-
DBUG_VOID_RETURN;
}
#endif
@@ -13136,7 +13183,7 @@ record_compare_exit:
Find the best key to use when locating the row in @c find_row().
A primary key is preferred if it exists; otherwise a unique index is
- preferred. Else we pick the index with the smalles rec_per_key value.
+ preferred. Else we pick the index with the smallest rec_per_key value.
If a suitable key is found, set @c m_key, @c m_key_nr and @c m_key_info
member fields appropriately.
@@ -13269,7 +13316,7 @@ static int row_not_found_error(rpl_group_info *rgi)
Locate the current row in event's table.
The current row is pointed by @c m_curr_row. Member @c m_width tells
- how many columns are there in the row (this can be differnet from
+ how many columns are there in the row (this can be different from
the number of columns in the table). It is assumed that event's
table is already open and pointed by @c m_table.
@@ -13310,7 +13357,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
rpl_row_tabledefs.test specifies that
if the extra field on the slave does not have a default value
and this is okay with Delete or Update events.
- Todo: fix wl3228 hld that requires defauls for all types of events
+ Todo: fix wl3228 hld that requires defaults for all types of events
*/
prepare_record(table, m_width, FALSE);
@@ -13554,7 +13601,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi)
while (record_compare(table));
/*
- Note: above record_compare will take into accout all record fields
+ Note: above record_compare will take into account all record fields
which might be incorrect in case a partial row was given in the event
*/
@@ -13565,7 +13612,6 @@ end:
if (is_table_scan || is_index_scan)
issue_long_find_row_warning(get_general_type_code(), m_table->alias.c_ptr(),
is_index_scan, rgi);
- table->default_column_bitmaps();
DBUG_RETURN(error);
}
@@ -13797,9 +13843,12 @@ void Update_rows_log_event::init(MY_BITMAP const *cols)
Update_rows_log_event::~Update_rows_log_event()
{
- if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
- m_cols_ai.bitmap= 0; // so no my_free in my_bitmap_free
- my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init().
+ if (m_cols_ai.bitmap)
+ {
+ if (m_cols_ai.bitmap == m_bitbuf_ai) // no my_malloc happened
+ m_cols_ai.bitmap= 0; // so no my_free in my_bitmap_free
+ my_bitmap_free(&m_cols_ai); // To pair with my_bitmap_init().
+ }
}
@@ -13876,6 +13925,12 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
#endif /* WSREP_PROC_INFO */
thd_proc_info(thd, message);
+ // Temporary fix to find out why it fails [/Matz]
+ memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
+ memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
+
+ m_table->mark_columns_per_binlog_row_image();
+
int error= find_row(rgi);
if (error)
{
@@ -13945,12 +14000,7 @@ Update_rows_log_event::do_exec_row(rpl_group_info *rgi)
error= HA_ERR_GENERIC; // in case if error is not set yet
goto err;
}
-
- // Temporary fix to find out why it fails [/Matz]
- memcpy(m_table->read_set->bitmap, m_cols.bitmap, (m_table->read_set->n_bits + 7) / 8);
- memcpy(m_table->write_set->bitmap, m_cols_ai.bitmap, (m_table->write_set->n_bits + 7) / 8);
-
- m_table->mark_columns_per_binlog_row_image();
+
error= m_table->file->ha_update_row(m_table->record[1], m_table->record[0]);
if (error == HA_ERR_RECORD_IS_THE_SAME)
error= 0;
@@ -14264,6 +14314,7 @@ st_print_event_info::st_print_event_info()
myf const flags = MYF(MY_WME | MY_NABP);
open_cached_file(&head_cache, NULL, NULL, 0, flags);
open_cached_file(&body_cache, NULL, NULL, 0, flags);
+ open_cached_file(&tail_cache, NULL, NULL, 0, flags);
#ifdef WHEN_FLASHBACK_REVIEW_READY
open_cached_file(&review_sql_cache, NULL, NULL, 0, flags);
#endif