Commit 3eda03d0 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-21148: Assertion index->n_core_fields + n_add >= index->n_fields

Revert part of commit 6cedb671
because it turns out to be theoretically impossible to parse a
ROW_FORMAT=COMPACT or ROW_FORMAT=DYNAMIC metadata record where
the variable-length fields in the PRIMARY KEY have been written
as nonempty strings.
parent 4d4b2867
...@@ -318,8 +318,8 @@ ...@@ -318,8 +318,8 @@
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
-187 -193
+189 +195
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
# #
# MDEV-18266: Changing an index comment unnecessarily rebuilds index # MDEV-18266: Changing an index comment unnecessarily rebuilds index
...@@ -912,6 +912,19 @@ SELECT * FROM t1; ...@@ -912,6 +912,19 @@ SELECT * FROM t1;
b a vb b a vb
NULL barf NULL NULL barf NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=REDUNDANT;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 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)'),
...@@ -1769,6 +1782,19 @@ SELECT * FROM t1; ...@@ -1769,6 +1782,19 @@ SELECT * FROM t1;
b a vb b a vb
NULL barf NULL NULL barf NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=COMPACT;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=COMPACT;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 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)'),
...@@ -2626,12 +2652,25 @@ SELECT * FROM t1; ...@@ -2626,12 +2652,25 @@ SELECT * FROM t1;
b a vb b a vb
NULL barf NULL NULL barf NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
a b vb
fubar 42 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
187 193
SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency; SET GLOBAL innodb_purge_rseg_truncate_frequency= @saved_frequency;
# #
# MDEV-18266: Changing an index comment unnecessarily rebuilds index # MDEV-18266: Changing an index comment unnecessarily rebuilds index
......
...@@ -799,6 +799,21 @@ ALTER TABLE t1 ADD vb INT AS (b); ...@@ -799,6 +799,21 @@ ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1; SELECT * FROM t1;
DROP TABLE t1; DROP TABLE t1;
# MDEV-21148 Assertion failure index->n_core_fields + n_add >= index->n_fields
eval CREATE TABLE t1 (a INT, b TEXT, PRIMARY KEY(b(9))) $engine;
ALTER TABLE t1 ADD COLUMN c TEXT FIRST;
ALTER TABLE t1 ADD COLUMN d TEXT GENERATED ALWAYS AS (SUBSTR(b,1,499)) FIRST;
DROP TABLE t1;
eval CREATE TABLE t1(a CHAR(5), b INT, c CHAR(1), d CHAR(1), PRIMARY KEY(a,b))
DEFAULT CHARACTER SET utf8 $engine;
INSERT INTO t1 SET a='fubar',b=42;
ALTER TABLE t1 DROP c, DROP d, ALGORITHM=INSTANT;
# this evicts and reloads the table definition until MDEV-17468 is fixed
ALTER TABLE t1 ADD vb INT AS (b);
SELECT * FROM t1;
DROP TABLE t1;
dec $format; dec $format;
let $redundant_4k= 0; let $redundant_4k= 0;
} }
......
...@@ -500,28 +500,32 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr) ...@@ -500,28 +500,32 @@ static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
we must duplicate some logic here. */ we must duplicate some logic here. */
if (trx_id_offset) { if (trx_id_offset) {
} else if (index->table->not_redundant()) { } else if (index->table->not_redundant()) {
/* PRIMARY KEY columns can never be NULL. /* The PRIMARY KEY contains variable-length columns.
We can skip the null flag bitmap. */ For the metadata record, variable-length columns are
const byte* lens = rec - (REC_N_NEW_EXTRA_BYTES + 1) always written with zero length. The DB_TRX_ID will
- index->n_core_null_bytes; start right after any fixed-length columns. */
unsigned n_add = rec_get_n_add_field(lens);
ut_ad(index->n_core_fields + n_add >= index->n_fields); /* OK, before MDEV-21088 was fixed, for
lens -= n_add; variable-length encoded PRIMARY KEY column of
type CHAR, we wrote more than zero bytes. In
order to allow affected tables to be accessed,
it would be nice to determine the actual
length of each PRIMARY KEY column. However, to
be able to do that, we should determine the
size of the null-bit bitmap in the metadata
record. And we cannot know that before reading
the metadata BLOB, whose starting point we are
trying to find here. (Although the PRIMARY KEY
columns cannot be NULL, we would have to know
where the lengths of variable-length PRIMARY KEY
columns start.)
So, unfortunately we cannot help users who
were affected by MDEV-21088 on a ROW_FORMAT=COMPACT
or ROW_FORMAT=DYNAMIC table. */
for (uint i = index->n_uniq; i--; ) { for (uint i = index->n_uniq; i--; ) {
const dict_field_t& f = index->fields[i]; trx_id_offset += index->fields[i].fixed_len;
unsigned len = f.fixed_len;
if (!len) {
len = *lens--;
if ((len & 0x80)
&& DATA_BIG_COL(f.col)) {
/* 1exxxxxxx xxxxxxxx */
len &= 0x3f;
len <<= 8;
len |= *lens--;
}
}
trx_id_offset += len;
} }
} else if (rec_get_1byte_offs_flag(rec)) { } else if (rec_get_1byte_offs_flag(rec)) {
trx_id_offset = rec_1_get_field_end_info( trx_id_offset = rec_1_get_field_end_info(
......
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