diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-12 13:10:52 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-12-12 13:21:05 +0200 |
commit | e0aebf5cf1c705739a94fe2fecf0b0ed7eb4ba3a (patch) | |
tree | d4f3e5ea2fe0f78a410d8bab93fdaa8708e2c5c2 | |
parent | db1210f9399ba97f7ea8ad81ca4f208f99df25c4 (diff) | |
download | mariadb-git-e0aebf5cf1c705739a94fe2fecf0b0ed7eb4ba3a.tar.gz |
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.
-rw-r--r-- | mysql-test/suite/innodb/r/data_types.result | 13 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/data_types.test | 13 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 19 |
3 files changed, 43 insertions, 2 deletions
diff --git a/mysql-test/suite/innodb/r/data_types.result b/mysql-test/suite/innodb/r/data_types.result index 446d37527e5..4e919e37cee 100644 --- a/mysql-test/suite/innodb/r/data_types.result +++ b/mysql-test/suite/innodb/r/data_types.result @@ -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; diff --git a/mysql-test/suite/innodb/t/data_types.test b/mysql-test/suite/innodb/t/data_types.test index 0978146361c..c8e80c9db27 100644 --- a/mysql-test/suite/innodb/t/data_types.test +++ b/mysql-test/suite/innodb/t/data_types.test @@ -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; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 373328939c2..3f26803d14b 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -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 |