MDEV-22637 Rollback of insert fails when column reorder happens

- During column reorder table rebuild, rollback of insert fails.
Reason is that InnoDB tries to fetch the column position from
new clustered index and it exceeds default column value tuple fields.
So InnoDB should use the table column position while searching for
defaults column value.
This commit is contained in:
Thirunarayanan Balathandayuthapani 2020-05-25 21:42:26 +05:30
parent ecc7f305dd
commit 7476e8c7cd
3 changed files with 73 additions and 5 deletions

View File

@ -148,3 +148,41 @@ SELECT * FROM t1;
a b d
1 NULL NULL
DROP TABLE t1;
#
# MDEV-22637 Rollback of insert fails when column reorder happens
#
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_TRANS_TABLES', '');
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_ALL_TABLES', '');
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100), f4 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "This is column2", "This is column3",
"This is column4");
set DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
ALTER TABLE t1 ADD COLUMN f6 int after f3, add primary key(f6, f4(3), f3(3));
connect con1,localhost,root,,;
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
BEGIN;
INSERT INTO t1(f1, f2) VALUES(2, "This is column2 value");
ROLLBACK;
set DEBUG_SYNC = 'now SIGNAL insert_done';
connection default;
Warnings:
Warning 1265 Data truncated for column 'f3' at row 3
Warning 1265 Data truncated for column 'f4' at row 3
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`f1` int(11) NOT NULL,
`f2` char(100) DEFAULT NULL,
`f3` char(100) NOT NULL,
`f6` int(11) NOT NULL,
`f4` char(100) NOT NULL,
PRIMARY KEY (`f6`,`f4`(3),`f3`(3))
) ENGINE=InnoDB DEFAULT CHARSET=latin1
SELECT COUNT(*) FROM t1;
COUNT(*)
1
disconnect con1;
DROP TABLE t1;
SET DEBUG_SYNC = 'RESET';
SET SQL_MODE=DEFAULT;

View File

@ -196,3 +196,30 @@ SHOW CREATE TABLE t1;
UPDATE t1 SET d=NULL;
SELECT * FROM t1;
DROP TABLE t1;
--echo #
--echo # MDEV-22637 Rollback of insert fails when column reorder happens
--echo #
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_TRANS_TABLES', '');
SET @@SQL_MODE = REPLACE(@@SQL_MODE, 'STRICT_ALL_TABLES', '');
CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(100),
f3 CHAR(100), f4 CHAR(100))ENGINE=InnoDB;
INSERT INTO t1 VALUES(1, "This is column2", "This is column3",
"This is column4");
set DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL scanned WAIT_FOR insert_done';
--send ALTER TABLE t1 ADD COLUMN f6 int after f3, add primary key(f6, f4(3), f3(3))
connect(con1,localhost,root,,);
SET DEBUG_SYNC = 'now WAIT_FOR scanned';
BEGIN;
INSERT INTO t1(f1, f2) VALUES(2, "This is column2 value");
ROLLBACK;
set DEBUG_SYNC = 'now SIGNAL insert_done';
connection default;
reap;
SHOW CREATE TABLE t1;
SELECT COUNT(*) FROM t1;
disconnect con1;
DROP TABLE t1;
SET DEBUG_SYNC = 'RESET';
SET SQL_MODE=DEFAULT;

View File

@ -1173,14 +1173,15 @@ row_log_table_get_pk_col(
return(DB_INVALID_NULL);
}
ulint n_default_cols = i - DATA_N_SYS_COLS;
unsigned col_no= ifield->col->ind;
ut_ad(col_no < log->defaults->n_fields);
field = static_cast<const byte*>(
log->defaults->fields[n_default_cols].data);
log->defaults->fields[col_no].data);
if (!field) {
return(DB_INVALID_NULL);
}
len = log->defaults->fields[i - DATA_N_SYS_COLS].len;
len = log->defaults->fields[col_no].len;
}
if (rec_offs_nth_extern(offsets, i)) {
@ -1659,10 +1660,12 @@ blob_done:
const dfield_t& default_field
= log->defaults->fields[col_no];
Field* field = log->old_table->field[col_no];
Field* field = log->old_table->field[col->ind];
field->set_warning(Sql_condition::WARN_LEVEL_WARN,
WARN_DATA_TRUNCATED, 1, ulong(log->n_rows));
WARN_DATA_TRUNCATED, 1,
ulong(log->n_rows));
if (!log->allow_not_null) {
/* We got a NULL value for a NOT NULL column. */