1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

unpack_row: unpack a correct number of fields

This commit is contained in:
Nikita Malyavin
2023-05-04 01:48:38 +03:00
committed by Sergei Golubchik
parent da277396bd
commit 500379cf49
4 changed files with 52 additions and 13 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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,
*/ */
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,
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,
(*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,
*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;

View File

@@ -12052,6 +12052,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());