diff options
author | Alexander Barkov <bar@mariadb.com> | 2023-03-14 05:29:04 +0400 |
---|---|---|
committer | Alexander Barkov <bar@mariadb.com> | 2023-03-14 11:50:52 +0400 |
commit | 47036387756d465c68ac4360eb031e78f48d9e58 (patch) | |
tree | d3247b160bd297c99b8bb00d83832cd59f6e3eb0 /mysql-test/main | |
parent | 46a7603813e74b48e948a5287c40a93fbb5bbf4d (diff) | |
download | mariadb-git-47036387756d465c68ac4360eb031e78f48d9e58.tar.gz |
MDEV-30805 SIGSEGV in my_convert and UBSAN: member access within null pointer of type 'const struct MY_CHARSET_HANDLER' in my_convert
Type_handler::partition_field_append_value() erroneously
passed the address of my_collation_contextually_typed_binary
to conversion functions copy_and_convert() and my_convert().
This happened because generate_partition_syntax_for_frm()
was called from mysql_create_frm_image() in the stage when
the fields in List<Create_field> can still contain unresolved
contextual collations, like "binary" in the reported crash scenario:
ALTER TABLE t CHANGE COLUMN a a CHAR BINARY;
Fix:
1. Splitting mysql_prepare_create_table() into two parts:
- mysql_prepare_create_table_stage1() interates through
List<Create_field> and calls Create_field::prepare_stage1(),
which performs basic attribute initialization, including
context collation resolution.
- mysql_prepare_create_table_finalize() - the rest of the
old mysql_prepare_create_table() code.
2. Changing mysql_create_frm_image():
It now calls:
- mysql_prepare_create_table_stage1() in the very
beginning, before the partition related code.
- mysql_prepare_create_table_finalize() in the end,
instead of the old mysql_prepare_create_table() call
3. Adding mysql_prepare_create_table() as a wrapper
for two calls:
mysql_prepare_create_table_stage1() ||
mysql_prepare_create_table_finalize()
so the code stays unchanged in the other places
where mysql_prepare_create_table() was used.
4. Changing prototype for Type_handler::Column_definition_prepare_stage1()
Removing arguments:
- handler *file
- ulonglong table_flags
Adding a new argument instead:
- column_definition_type_t type
This allows to call Column_definition_prepare_stage1() and
therefore to call mysql_prepare_create_table_stage1()
before instantiation of a handler.
This simplifies the code, because in case of a partitioned table,
mysql_create_frm_image() creates a handler of the underlying
partition first, the frees it and created a ha_partition
instance instead.
mysql_prepare_create_table() before the fix was called with the final
(ha_partition) handler.
5. Moving parts of Column_definition_prepare_stage1() which
need a pointer to handler and table_flags to
Column_definition_prepare_stage2().
Diffstat (limited to 'mysql-test/main')
-rw-r--r-- | mysql-test/main/partition_charset.result | 21 | ||||
-rw-r--r-- | mysql-test/main/partition_charset.test | 20 | ||||
-rw-r--r-- | mysql-test/main/partition_utf8-debug.result | 2 |
3 files changed, 42 insertions, 1 deletions
diff --git a/mysql-test/main/partition_charset.result b/mysql-test/main/partition_charset.result index f8f75e8bee7..a0019dd8fc3 100644 --- a/mysql-test/main/partition_charset.result +++ b/mysql-test/main/partition_charset.result @@ -20,3 +20,24 @@ create table t1 (a varchar(1), primary key (a)) partition by list (ascii(a)) (partition p1 values in (65)); ERROR HY000: This partition function is not allowed +# +# Start of 10.9 tests +# +# +# MDEV-30805 SIGSEGV in my_convert and UBSAN: member access within null pointer of type 'const struct MY_CHARSET_HANDLER' in my_convert +# +CREATE TABLE t1 (a CHAR CHARACTER SET ucs2) +PARTITION BY RANGE COLUMNS (a) +(PARTITION p0 VALUES LESS THAN ('a')); +ALTER TABLE t1 CHANGE COLUMN a a CHAR BINARY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` char(1) CHARACTER SET latin1 COLLATE latin1_bin DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci + PARTITION BY RANGE COLUMNS(`a`) +(PARTITION `p0` VALUES LESS THAN ('a') ENGINE = MyISAM) +DROP TABLE t1; +# +# End of 10.9 tests +# diff --git a/mysql-test/main/partition_charset.test b/mysql-test/main/partition_charset.test index 6842e5268fa..b8a17ce4fca 100644 --- a/mysql-test/main/partition_charset.test +++ b/mysql-test/main/partition_charset.test @@ -27,3 +27,23 @@ partition by list (ascii(a)) #insert into t1 values ('A'); #replace into t1 values ('A'); #drop table t1; + +--echo # +--echo # Start of 10.9 tests +--echo # + +--echo # +--echo # MDEV-30805 SIGSEGV in my_convert and UBSAN: member access within null pointer of type 'const struct MY_CHARSET_HANDLER' in my_convert +--echo # + +CREATE TABLE t1 (a CHAR CHARACTER SET ucs2) + PARTITION BY RANGE COLUMNS (a) + (PARTITION p0 VALUES LESS THAN ('a')); +ALTER TABLE t1 CHANGE COLUMN a a CHAR BINARY; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # End of 10.9 tests +--echo # + diff --git a/mysql-test/main/partition_utf8-debug.result b/mysql-test/main/partition_utf8-debug.result index db1396198ab..2b4982a3dcc 100644 --- a/mysql-test/main/partition_utf8-debug.result +++ b/mysql-test/main/partition_utf8-debug.result @@ -77,7 +77,7 @@ CREATE OR REPLACE TABLE t1 (a DATE) CHARACTER SET utf8 PARTITION BY LIST COLUMNS (a) (PARTITION p0 VALUES IN (FROM_DAYS(100))); Warnings: Note 1003 PARTITION BY LIST COLUMNS(`a`) -(PARTITION `p0` VALUES IN (_utf8mb3 0x303030302d30302d3030) ENGINE = MyISAM) +(PARTITION `p0` VALUES IN (_latin1 0x303030302d30302d3030) ENGINE = MyISAM) SELECT PARTITION_DESCRIPTION FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1'; PARTITION_DESCRIPTION '0000-00-00' |