Commit 500379cf authored by Nikita Malyavin's avatar Nikita Malyavin Committed by Sergei Golubchik

unpack_row: unpack a correct number of fields

parent da277396
......@@ -1346,6 +1346,21 @@ c x
2 123456
3 123456
drop table t;
# Test that all the fields are unpacked.
create table t (a int, b int) engine=innodb;
insert into t values (NULL, 123), (NULL, 456);
set debug_sync= "alter_table_copy_end signal copy wait_for goon";
alter table t drop a, add primary key(b), algorithm=copy;
connection con1;
set debug_sync= "now wait_for copy";
update t set b = b + 100;
set debug_sync= "now signal goon";
connection default;
select * from t;
b
223
556
drop table t;
set debug_sync= reset;
disconnect con1;
disconnect con2;
......
......@@ -1527,6 +1527,24 @@ set debug_sync= "now signal goon";
select * from t;
drop table t;
--echo # Test that all the fields are unpacked.
create table t (a int, b int) engine=innodb;
insert into t values (NULL, 123), (NULL, 456);
set debug_sync= "alter_table_copy_end signal copy wait_for goon";
send alter table t drop a, add primary key(b), algorithm=copy;
--connection con1
set debug_sync= "now wait_for copy";
update t set b = b + 100;
set debug_sync= "now signal goon";
--connection default
--reap
select * from t;
drop table t;
set debug_sync= reset;
--disconnect con1
......
......@@ -228,24 +228,28 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
const TABLE *conv_table= rpl_data.conv_table;
DBUG_PRINT("debug", ("Table data: tabldef: %p, conv_table: %p",
tabledef, conv_table));
bool is_online_alter= rpl_data.is_online_alter();
DBUG_ASSERT(rgi);
for (field_ptr= begin_ptr; field_ptr < end_ptr && *field_ptr; ++field_ptr)
for (field_ptr= begin_ptr; field_ptr < end_ptr
/* In Online Alter conv_table can be wider than
original table, but we need to unpack it all. */
&& (*field_ptr || is_online_alter);
++field_ptr)
{
/*
If there is a conversion table, we pick up the field pointer to
the conversion table. If the conversion table or the field
pointer is NULL, no conversions are necessary.
*/
Field *conv_field=
conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL;
Field *const f=
conv_field ? conv_field : *field_ptr;
DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%ld)",
Field *conv_field= conv_table ? conv_table->field[i] : NULL;
Field *const f= conv_field ? conv_field : *field_ptr;
#ifdef DBUG_TRACE
Field *dbg= is_online_alter ? f : *field_ptr;
#endif
DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%u)",
conv_field ? "" : "not ",
(*field_ptr)->field_name.str,
(long) (field_ptr - begin_ptr)));
dbg->field_name.str, i));
DBUG_ASSERT(f != NULL);
/*
......@@ -254,7 +258,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
*/
if (bitmap_is_set(cols, (uint)(field_ptr - begin_ptr)))
{
if (!rpl_data.is_online_alter())
if (!is_online_alter)
(*field_ptr)->set_has_explicit_value();
if ((null_mask & 0xFF) == 0)
{
......@@ -351,7 +355,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
conv_field->sql_type(source_type);
conv_field->val_str(&value_string);
DBUG_PRINT("debug", ("Copying field '%s' of type '%s' with value '%s'",
(*field_ptr)->field_name.str,
dbg->field_name.str,
source_type.c_ptr_safe(), value_string.c_ptr_safe()));
#endif
copy.set(*field_ptr, f, TRUE);
......@@ -362,7 +366,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
(*field_ptr)->sql_type(target_type);
(*field_ptr)->val_str(&value_string);
DBUG_PRINT("debug", ("Value of field '%s' of type '%s' is now '%s'",
(*field_ptr)->field_name.str,
dbg->field_name.str,
target_type.c_ptr_safe(), value_string.c_ptr_safe()));
#endif
}
......@@ -442,7 +446,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
*current_row_end = pack_ptr;
if (master_reclength)
{
if (*field_ptr)
if (!is_online_alter && *field_ptr)
*master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]);
else
*master_reclength = table->s->reclength;
......
......@@ -12052,6 +12052,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
#ifdef HAVE_REPLICATION
if (online && error < 0)
{
MEM_UNDEFINED(from->record[0], from->s->rec_buff_length * 2);
MEM_UNDEFINED(to->record[0], to->s->rec_buff_length * 2);
thd_progress_next_stage(thd);
Table_map_log_event table_event(thd, from, from->s->table_map_id,
from->file->has_transactions());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment