summaryrefslogtreecommitdiff
path: root/mysql-test/main
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2023-03-14 05:29:04 +0400
committerAlexander Barkov <bar@mariadb.com>2023-03-14 11:50:52 +0400
commit47036387756d465c68ac4360eb031e78f48d9e58 (patch)
treed3247b160bd297c99b8bb00d83832cd59f6e3eb0 /mysql-test/main
parent46a7603813e74b48e948a5287c40a93fbb5bbf4d (diff)
downloadmariadb-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.result21
-rw-r--r--mysql-test/main/partition_charset.test20
-rw-r--r--mysql-test/main/partition_utf8-debug.result2
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'