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, ...@@ -75,10 +75,13 @@ t1_VARCHAR_10_BINARY VARCHAR(10) BINARY,
t1_VARCHAR_500 VARCHAR(500), t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY, t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2), 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; ) ENGINE=InnoDB;
Warnings: Warnings:
Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
INSERT INTO t1 () VALUES ();
SELECT SELECT
name, name,
CASE mtype CASE mtype
...@@ -109,6 +112,7 @@ t1_BINARY_100 DATA_FIXBINARY ...@@ -109,6 +112,7 @@ t1_BINARY_100 DATA_FIXBINARY
t1_BIT_2 DATA_FIXBINARY UNSIGNED t1_BIT_2 DATA_FIXBINARY UNSIGNED
t1_BIT_20 DATA_FIXBINARY UNSIGNED t1_BIT_20 DATA_FIXBINARY UNSIGNED
t1_BLOB DATA_BLOB t1_BLOB DATA_BLOB
t1_CHAR_0 DATA_CHAR
t1_CHAR_100 DATA_CHAR t1_CHAR_100 DATA_CHAR
t1_CHAR_100_BINARY DATA_MYSQL t1_CHAR_100_BINARY DATA_MYSQL
t1_DATE DATA_INT t1_DATE DATA_INT
...@@ -131,6 +135,7 @@ t1_MEDIUMBLOB DATA_BLOB ...@@ -131,6 +135,7 @@ t1_MEDIUMBLOB DATA_BLOB
t1_MEDIUMINT DATA_INT t1_MEDIUMINT DATA_INT
t1_MEDIUMINT_UNSIGNED DATA_INT UNSIGNED t1_MEDIUMINT_UNSIGNED DATA_INT UNSIGNED
t1_MEDIUMTEXT DATA_BLOB t1_MEDIUMTEXT DATA_BLOB
t1_MYSQL_0 DATA_MYSQL
t1_SET DATA_INT UNSIGNED t1_SET DATA_INT UNSIGNED
t1_SET_9 DATA_INT UNSIGNED t1_SET_9 DATA_INT UNSIGNED
t1_SET_BINARY DATA_INT UNSIGNED t1_SET_BINARY DATA_INT UNSIGNED
...@@ -153,3 +158,9 @@ t1_VARCHAR_500_BINARY DATA_VARMYSQL ...@@ -153,3 +158,9 @@ t1_VARCHAR_500_BINARY DATA_VARMYSQL
t1_YEAR_2 DATA_INT UNSIGNED t1_YEAR_2 DATA_INT UNSIGNED
t1_YEAR_4 DATA_INT UNSIGNED t1_YEAR_4 DATA_INT UNSIGNED
DROP TABLE t1; 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 ...@@ -88,9 +88,13 @@ CREATE TABLE t1
t1_VARCHAR_500 VARCHAR(500), t1_VARCHAR_500 VARCHAR(500),
t1_VARCHAR_500_BINARY VARCHAR(500) BINARY, t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2), 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; ) ENGINE=InnoDB;
INSERT INTO t1 () VALUES ();
SELECT SELECT
name, name,
CASE mtype CASE mtype
...@@ -116,3 +120,10 @@ WHERE name LIKE "t1\_%" ...@@ -116,3 +120,10 @@ WHERE name LIKE "t1\_%"
ORDER BY name; ORDER BY name;
DROP TABLE t1; 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) ...@@ -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); field_max_size = dict_col_get_max_size(col);
if (UNIV_UNLIKELY(!field_max_size)) { 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 /* SYS_FOREIGN.ID is defined as CHAR in the
InnoDB internal SQL parser, which translates InnoDB internal SQL parser, which translates
into the incorrect VARCHAR(0). InnoDB does 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