Commit abd73373 authored by Nikita Malyavin's avatar Nikita Malyavin

unpack_row: unpack a correct number of fields

parent 949a4f5f
...@@ -1346,6 +1346,21 @@ c x ...@@ -1346,6 +1346,21 @@ c x
2 123456 2 123456
3 123456 3 123456
drop table t; 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; set debug_sync= reset;
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
......
...@@ -1527,6 +1527,24 @@ set debug_sync= "now signal goon"; ...@@ -1527,6 +1527,24 @@ set debug_sync= "now signal goon";
select * from t; select * from t;
drop table 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; set debug_sync= reset;
--disconnect con1 --disconnect con1
......
...@@ -228,24 +228,28 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, ...@@ -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; const TABLE *conv_table= rpl_data.conv_table;
DBUG_PRINT("debug", ("Table data: tabldef: %p, conv_table: %p", DBUG_PRINT("debug", ("Table data: tabldef: %p, conv_table: %p",
tabledef, conv_table)); tabledef, conv_table));
bool is_online_alter= rpl_data.is_online_alter();
DBUG_ASSERT(rgi); 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 If there is a conversion table, we pick up the field pointer to
the conversion table. If the conversion table or the field the conversion table. If the conversion table or the field
pointer is NULL, no conversions are necessary. pointer is NULL, no conversions are necessary.
*/ */
Field *conv_field= Field *conv_field= conv_table ? conv_table->field[i] : NULL;
conv_table ? conv_table->field[field_ptr - begin_ptr] : NULL; Field *const f= conv_field ? conv_field : *field_ptr;
Field *const f= #ifdef DBUG_TRACE
conv_field ? conv_field : *field_ptr; Field *dbg= is_online_alter ? f : *field_ptr;
DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%ld)", #endif
DBUG_PRINT("debug", ("Conversion %srequired for field '%s' (#%u)",
conv_field ? "" : "not ", conv_field ? "" : "not ",
(*field_ptr)->field_name.str, dbg->field_name.str, i));
(long) (field_ptr - begin_ptr)));
DBUG_ASSERT(f != NULL); DBUG_ASSERT(f != NULL);
/* /*
...@@ -254,7 +258,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, ...@@ -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 (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(); (*field_ptr)->set_has_explicit_value();
if ((null_mask & 0xFF) == 0) if ((null_mask & 0xFF) == 0)
{ {
...@@ -351,7 +355,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, ...@@ -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->sql_type(source_type);
conv_field->val_str(&value_string); conv_field->val_str(&value_string);
DBUG_PRINT("debug", ("Copying field '%s' of type '%s' with value '%s'", 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())); source_type.c_ptr_safe(), value_string.c_ptr_safe()));
#endif #endif
copy.set(*field_ptr, f, TRUE); copy.set(*field_ptr, f, TRUE);
...@@ -362,7 +366,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, ...@@ -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)->sql_type(target_type);
(*field_ptr)->val_str(&value_string); (*field_ptr)->val_str(&value_string);
DBUG_PRINT("debug", ("Value of field '%s' of type '%s' is now '%s'", 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())); target_type.c_ptr_safe(), value_string.c_ptr_safe()));
#endif #endif
} }
...@@ -442,7 +446,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt, ...@@ -442,7 +446,7 @@ int unpack_row(const rpl_group_info *rgi, TABLE *table, uint const colcnt,
*current_row_end = pack_ptr; *current_row_end = pack_ptr;
if (master_reclength) if (master_reclength)
{ {
if (*field_ptr) if (!is_online_alter && *field_ptr)
*master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]); *master_reclength = (ulong)((*field_ptr)->ptr - table->record[0]);
else else
*master_reclength = table->s->reclength; *master_reclength = table->s->reclength;
......
...@@ -12050,6 +12050,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to, ...@@ -12050,6 +12050,8 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
#ifdef HAVE_REPLICATION #ifdef HAVE_REPLICATION
if (online && error < 0) 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); thd_progress_next_stage(thd);
Table_map_log_event table_event(thd, from, from->s->table_map_id, Table_map_log_event table_event(thd, from, from->s->table_map_id,
from->file->has_transactions()); 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