summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-02-05 11:12:10 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2020-02-05 11:12:10 +0200
commit2acc6f2d95d31f4ea82de8a66c5f2f7fd6583a16 (patch)
tree89a3c4e7ab169f09a478b4e311b9b81f6ac605ed
parenta56f78243ee06167b5baf8255d3866099f3a3936 (diff)
downloadmariadb-git-2acc6f2d95d31f4ea82de8a66c5f2f7fd6583a16.tar.gz
MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
row_log_table_get_pk_old_col(): For replacing a NULL value for a column of the being-added primary key, look up the correct default value, even if columns had been instantly reordered or dropped earlier. This ought to have been broken ever since commit 0e5a4ac2532c64a545796c787354dc41d61d0e62 (MDEV-15562).
-rw-r--r--mysql-test/suite/innodb/r/instant_alter_debug.result24
-rw-r--r--mysql-test/suite/innodb/t/instant_alter_debug.test26
-rw-r--r--storage/innobase/row/row0log.cc15
3 files changed, 61 insertions, 4 deletions
diff --git a/mysql-test/suite/innodb/r/instant_alter_debug.result b/mysql-test/suite/innodb/r/instant_alter_debug.result
index 72c9a85e369..9fcb8b05a34 100644
--- a/mysql-test/suite/innodb/r/instant_alter_debug.result
+++ b/mysql-test/suite/innodb/r/instant_alter_debug.result
@@ -343,6 +343,30 @@ UPDATE t1 SET b = 1;
SET DEBUG_SYNC='now SIGNAL update';
connection con2;
connection default;
+DROP TABLE t1;
+#
+# MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
+#
+CREATE TABLE t1 (a INT, b INT, c INT, col INT) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES ();
+ALTER TABLE t1 DROP b, DROP c, DROP col;
+ALTER TABLE t1 ADD COLUMN col INT;
+ALTER TABLE t1 DROP a, DROP col, ADD COLUMN b INT;
+connection con2;
+SET SQL_MODE= '';
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR dml';
+ALTER TABLE t1 ADD PRIMARY KEY(b);
+connection default;
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+UPDATE t1 SET b = 1;
+SET DEBUG_SYNC = 'now SIGNAL dml';
+connection con2;
+Warnings:
+Warning 1265 Data truncated for column 'b' at row 1
+connection default;
+SELECT * FROM t1;
+b
+1
SET DEBUG_SYNC='RESET';
disconnect con2;
DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/instant_alter_debug.test b/mysql-test/suite/innodb/t/instant_alter_debug.test
index 22452c78f4d..fe80de2ca51 100644
--- a/mysql-test/suite/innodb/t/instant_alter_debug.test
+++ b/mysql-test/suite/innodb/t/instant_alter_debug.test
@@ -385,6 +385,32 @@ SET DEBUG_SYNC='now SIGNAL update';
--reap
--connection default
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-21658 Error on online ADD PRIMARY KEY after instant DROP/reorder
+--echo #
+
+CREATE TABLE t1 (a INT, b INT, c INT, col INT) ENGINE=InnoDB;
+INSERT INTO t1 () VALUES ();
+ALTER TABLE t1 DROP b, DROP c, DROP col;
+ALTER TABLE t1 ADD COLUMN col INT;
+ALTER TABLE t1 DROP a, DROP col, ADD COLUMN b INT;
+
+--connection con2
+SET SQL_MODE= '';
+SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR dml';
+send ALTER TABLE t1 ADD PRIMARY KEY(b);
+
+--connection default
+SET DEBUG_SYNC = 'now WAIT_FOR scanned';
+UPDATE t1 SET b = 1;
+SET DEBUG_SYNC = 'now SIGNAL dml';
+--connection con2
+reap;
+--connection default
+SELECT * FROM t1;
+
SET DEBUG_SYNC='RESET';
--disconnect con2
DROP TABLE t1;
diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc
index 91879068c17..0fd3f840fcf 100644
--- a/storage/innobase/row/row0log.cc
+++ b/storage/innobase/row/row0log.cc
@@ -1137,6 +1137,7 @@ row_log_table_get_pk_old_col(
/** Maps an old table column of a PRIMARY KEY column.
@param[in] ifield clustered index field in the new table (after
ALTER TABLE)
+@param[in] index the clustered index of ifield
@param[in,out] dfield clustered index tuple field in the new table
@param[in,out] heap memory heap for allocating dfield contents
@param[in] rec clustered index leaf page record in the old
@@ -1152,6 +1153,7 @@ static
dberr_t
row_log_table_get_pk_col(
const dict_field_t* ifield,
+ const dict_index_t* index,
dfield_t* dfield,
mem_heap_t* heap,
const rec_t* rec,
@@ -1175,14 +1177,19 @@ row_log_table_get_pk_col(
return(DB_INVALID_NULL);
}
- ulint n_default_cols = i - DATA_N_SYS_COLS;
+ ulint new_i = dict_col_get_clust_pos(ifield->col, index);
+
+ if (UNIV_UNLIKELY(new_i >= log->defaults->n_fields)) {
+ ut_ad(0);
+ return DB_INVALID_NULL;
+ }
field = static_cast<const byte*>(
- log->defaults->fields[n_default_cols].data);
+ log->defaults->fields[new_i].data);
if (!field) {
return(DB_INVALID_NULL);
}
- len = log->defaults->fields[i - DATA_N_SYS_COLS].len;
+ len = log->defaults->fields[new_i].len;
}
if (rec_offs_nth_extern(offsets, i)) {
@@ -1341,7 +1348,7 @@ row_log_table_get_pk(
}
log->error = row_log_table_get_pk_col(
- ifield, dfield, *heap,
+ ifield, new_index, dfield, *heap,
rec, offsets, i, zip_size, max_len,
log);