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.
parent ecc7f305
...@@ -148,3 +148,41 @@ SELECT * FROM t1; ...@@ -148,3 +148,41 @@ SELECT * FROM t1;
a b d a b d
1 NULL NULL 1 NULL NULL
DROP TABLE t1; 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;
...@@ -196,3 +196,30 @@ SHOW CREATE TABLE t1; ...@@ -196,3 +196,30 @@ SHOW CREATE TABLE t1;
UPDATE t1 SET d=NULL; UPDATE t1 SET d=NULL;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE 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;
...@@ -1173,14 +1173,15 @@ row_log_table_get_pk_col( ...@@ -1173,14 +1173,15 @@ row_log_table_get_pk_col(
return(DB_INVALID_NULL); 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*>( field = static_cast<const byte*>(
log->defaults->fields[n_default_cols].data); log->defaults->fields[col_no].data);
if (!field) { if (!field) {
return(DB_INVALID_NULL); 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)) { if (rec_offs_nth_extern(offsets, i)) {
...@@ -1659,10 +1660,12 @@ row_log_table_apply_convert_mrec( ...@@ -1659,10 +1660,12 @@ row_log_table_apply_convert_mrec(
const dfield_t& default_field const dfield_t& default_field
= log->defaults->fields[col_no]; = 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, 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) { if (!log->allow_not_null) {
/* We got a NULL value for a NOT NULL column. */ /* We got a NULL value for a NOT NULL column. */
......
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