Commit f8501224 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-17735 Assertion failure in row_parse_int() on first ADD/DROP COLUMN

row_ins_clust_index_entry_low(): Do not attempt to read an AUTO_INCREMENT
column value from a metadata record, because it does not make any sense.
Moreover, the field offset would be off by one in case the AUTO_INCREMENT
column is not part of the PRIMARY KEY, because the MDEV-15562 metadata
record would contain an extra field at index->first_user_field().

On MariaDB Server 10.3 after MDEV-11369, we would unnecessarily read
a dummy AUTO_INCREMENT value from the metadata record, but that value
would always be written as NULL or 0, so there is no problem.
parent 89337d51
...@@ -523,6 +523,17 @@ SELECT * FROM t1; ...@@ -523,6 +523,17 @@ SELECT * FROM t1;
i t i t
1 NULL 1 NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT AUTO_INCREMENT, b INT, KEY(a)) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 SET a=NULL;
ALTER TABLE t1 DROP COLUMN b;
ALTER TABLE t1 ADD COLUMN c INT NOT NULL DEFAULT 42;
INSERT INTO t1 SET a=NULL;
UPDATE t1 SET a=a+2;
SELECT * FROM t1;
a c
3 42
4 42
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -992,6 +1003,17 @@ SELECT * FROM t1; ...@@ -992,6 +1003,17 @@ SELECT * FROM t1;
i t i t
1 NULL 1 NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT AUTO_INCREMENT, b INT, KEY(a)) ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 SET a=NULL;
ALTER TABLE t1 DROP COLUMN b;
ALTER TABLE t1 ADD COLUMN c INT NOT NULL DEFAULT 42;
INSERT INTO t1 SET a=NULL;
UPDATE t1 SET a=a+2;
SELECT * FROM t1;
a c
3 42
4 42
DROP TABLE t1;
CREATE TABLE t1 CREATE TABLE t1
(id INT PRIMARY KEY, c2 INT UNIQUE, (id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'), c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
...@@ -1461,10 +1483,21 @@ SELECT * FROM t1; ...@@ -1461,10 +1483,21 @@ SELECT * FROM t1;
i t i t
1 NULL 1 NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT AUTO_INCREMENT, b INT, KEY(a)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 SET a=NULL;
ALTER TABLE t1 DROP COLUMN b;
ALTER TABLE t1 ADD COLUMN c INT NOT NULL DEFAULT 42;
INSERT INTO t1 SET a=NULL;
UPDATE t1 SET a=a+2;
SELECT * FROM t1;
a c
3 42
4 42
DROP TABLE t1;
disconnect analyze; disconnect analyze;
SELECT variable_value-@old_instant instants SELECT variable_value-@old_instant instants
FROM information_schema.global_status FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column'; WHERE variable_name = 'innodb_instant_alter_column';
instants instants
78 84
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
...@@ -397,6 +397,19 @@ ALTER TABLE t1 ADD COLUMN t TEXT; ...@@ -397,6 +397,19 @@ ALTER TABLE t1 ADD COLUMN t TEXT;
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-17735 Assertion failure in row_parse_int() on first ADD/DROP COLUMN
# when an AUTO_INCREMENT column is not in PRIMARY KEY
#
eval CREATE TABLE t1 (a INT AUTO_INCREMENT, b INT, KEY(a)) $engine;
INSERT INTO t1 SET a=NULL;
ALTER TABLE t1 DROP COLUMN b;
ALTER TABLE t1 ADD COLUMN c INT NOT NULL DEFAULT 42;
INSERT INTO t1 SET a=NULL;
UPDATE t1 SET a=a+2;
SELECT * FROM t1;
DROP TABLE t1;
dec $format; dec $format;
} }
disconnect analyze; disconnect analyze;
......
...@@ -2597,25 +2597,32 @@ row_ins_clust_index_entry_low( ...@@ -2597,25 +2597,32 @@ row_ins_clust_index_entry_low(
} else { } else {
index->set_modified(mtr); index->set_modified(mtr);
if (mode == BTR_MODIFY_LEAF if (UNIV_UNLIKELY(entry->is_metadata())) {
&& dict_index_is_online_ddl(index)) { ut_ad(index->is_instant());
mode = BTR_MODIFY_LEAF_ALREADY_S_LATCHED; ut_ad(!dict_index_is_online_ddl(index));
mtr_s_lock(dict_index_get_lock(index), &mtr); ut_ad(mode == BTR_MODIFY_TREE);
} } else {
if (mode == BTR_MODIFY_LEAF
&& dict_index_is_online_ddl(index)) {
mode = BTR_MODIFY_LEAF_ALREADY_S_LATCHED;
mtr_s_lock(dict_index_get_lock(index), &mtr);
}
if (unsigned ai = index->table->persistent_autoinc) { if (unsigned ai = index->table->persistent_autoinc) {
/* Prepare to persist the AUTO_INCREMENT value /* Prepare to persist the AUTO_INCREMENT value
from the index entry to PAGE_ROOT_AUTO_INC. */ from the index entry to PAGE_ROOT_AUTO_INC. */
const dfield_t* dfield = dtuple_get_nth_field( const dfield_t* dfield = dtuple_get_nth_field(
entry, ai - 1); entry, ai - 1);
auto_inc = dfield_is_null(dfield) if (!dfield_is_null(dfield)) {
? 0 auto_inc = row_parse_int(
: row_parse_int(static_cast<const byte*>( static_cast<const byte*>(
dfield->data), dfield->data),
dfield->len, dfield->len,
dfield->type.mtype, dfield->type.mtype,
dfield->type.prtype dfield->type.prtype
& DATA_UNSIGNED); & DATA_UNSIGNED);
}
}
} }
} }
......
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