1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

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().
This commit is contained in:
Alexander Barkov
2023-03-14 05:29:04 +04:00
parent 46a7603813
commit 4703638775
11 changed files with 221 additions and 137 deletions

View File

@@ -3962,8 +3962,7 @@ public:
virtual bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const;
@@ -4441,8 +4440,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -4756,8 +4754,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -5310,8 +5307,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -5414,8 +5410,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -5947,8 +5942,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -6791,8 +6785,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -6849,8 +6842,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;
@@ -7286,8 +7278,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root,
Column_definition *c,
handler *file,
ulonglong table_flags,
column_definition_type_t type,
const Column_derived_attributes
*derived_attr)
const override;