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;
i t
1 NULL
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
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -992,6 +1003,17 @@ SELECT * FROM t1;
i t
1 NULL
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
(id INT PRIMARY KEY, c2 INT UNIQUE,
c3 POINT NOT NULL DEFAULT ST_GeomFromText('POINT(3 4)'),
......@@ -1461,10 +1483,21 @@ SELECT * FROM t1;
i t
1 NULL
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;
SELECT variable_value-@old_instant instants
FROM information_schema.global_status
WHERE variable_name = 'innodb_instant_alter_column';
instants
78
84
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
......@@ -397,6 +397,19 @@ ALTER TABLE t1 ADD COLUMN t TEXT;
SELECT * FROM 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;
}
disconnect analyze;
......
......@@ -2597,6 +2597,11 @@ row_ins_clust_index_entry_low(
} else {
index->set_modified(mtr);
if (UNIV_UNLIKELY(entry->is_metadata())) {
ut_ad(index->is_instant());
ut_ad(!dict_index_is_online_ddl(index));
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;
......@@ -2608,9 +2613,9 @@ row_ins_clust_index_entry_low(
from the index entry to PAGE_ROOT_AUTO_INC. */
const dfield_t* dfield = dtuple_get_nth_field(
entry, ai - 1);
auto_inc = dfield_is_null(dfield)
? 0
: row_parse_int(static_cast<const byte*>(
if (!dfield_is_null(dfield)) {
auto_inc = row_parse_int(
static_cast<const byte*>(
dfield->data),
dfield->len,
dfield->type.mtype,
......@@ -2618,6 +2623,8 @@ row_ins_clust_index_entry_low(
& DATA_UNSIGNED);
}
}
}
}
/* Note that we use PAGE_CUR_LE as the search mode, because then
the function will return in both low_match and up_match of the
......
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