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

MDEV-17815 Assertion failed in btr_node_ptr_max_size for CHAR(0)

btr_node_ptr_max_size(): Treat CHAR(0) from SQL as a special case.
The InnoDB internal SQL parser maps the type "CHAR" to DATA_VARCHAR,
but MariaDB does allow CHAR(0) with an empty value, and does enforce
the length limitation.
parent db1210f9
......@@ -75,10 +75,13 @@ t1_VARCHAR_10_BINARY VARCHAR(10) BINARY,
t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2),
t1_YEAR_4 YEAR(4)
t1_YEAR_4 YEAR(4),
t1_CHAR_0 CHAR(0),
t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
Warnings:
Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
INSERT INTO t1 () VALUES ();
SELECT
name,
CASE mtype
......@@ -109,6 +112,7 @@ t1_BINARY_100 DATA_FIXBINARY
t1_BIT_2 DATA_FIXBINARY UNSIGNED
t1_BIT_20 DATA_FIXBINARY UNSIGNED
t1_BLOB DATA_BLOB
t1_CHAR_0 DATA_CHAR
t1_CHAR_100 DATA_CHAR
t1_CHAR_100_BINARY DATA_MYSQL
t1_DATE DATA_INT
......@@ -131,6 +135,7 @@ t1_MEDIUMBLOB DATA_BLOB
t1_MEDIUMINT DATA_INT
t1_MEDIUMINT_UNSIGNED DATA_INT UNSIGNED
t1_MEDIUMTEXT DATA_BLOB
t1_MYSQL_0 DATA_MYSQL
t1_SET DATA_INT UNSIGNED
t1_SET_9 DATA_INT UNSIGNED
t1_SET_BINARY DATA_INT UNSIGNED
......@@ -153,3 +158,9 @@ t1_VARCHAR_500_BINARY DATA_VARMYSQL
t1_YEAR_2 DATA_INT UNSIGNED
t1_YEAR_4 DATA_INT UNSIGNED
DROP TABLE t1;
#
# MDEV-17815 Assertion failed in btr_node_ptr_max_size for CHAR(0)
#
CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('');
DROP TABLE t1;
......@@ -88,9 +88,13 @@ CREATE TABLE t1
t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2),
t1_YEAR_4 YEAR(4)
t1_YEAR_4 YEAR(4),
t1_CHAR_0 CHAR(0),
t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
INSERT INTO t1 () VALUES ();
SELECT
name,
CASE mtype
......@@ -116,3 +120,10 @@ WHERE name LIKE "t1\_%"
ORDER BY name;
DROP TABLE t1;
--echo #
--echo # MDEV-17815 Assertion failed in btr_node_ptr_max_size for CHAR(0)
--echo #
CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('');
DROP TABLE t1;
......@@ -753,6 +753,25 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
field_max_size = dict_col_get_max_size(col);
if (UNIV_UNLIKELY(!field_max_size)) {
switch (col->mtype) {
case DATA_CHAR:
case DATA_MYSQL:
/* CHAR(0) is a possible data type.
The InnoDB internal SQL parser maps
CHAR to DATA_VARCHAR, so DATA_CHAR (or
DATA_MYSQL) is only coming from the
MariaDB SQL layer. */
if (comp) {
/* Add a length byte, because
fixed-length empty field are
encoded as variable-length.
For ROW_FORMAT=REDUNDANT,
these bytes were added to
rec_max_size before this loop. */
rec_max_size++;
}
continue;
}
/* SYS_FOREIGN.ID is defined as CHAR in the
InnoDB internal SQL parser, which translates
into the incorrect VARCHAR(0). InnoDB does
......
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