mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +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:
@ -3008,8 +3008,7 @@ bool Type_handler::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3022,8 +3021,7 @@ bool Type_handler_null::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3037,8 +3035,7 @@ bool Type_handler_row::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3052,8 +3049,7 @@ bool Type_handler_temporal_result::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3067,8 +3063,7 @@ bool Type_handler_numeric::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3081,8 +3076,7 @@ bool Type_handler_newdecimal::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
@ -3096,28 +3090,26 @@ bool Type_handler_bit::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
def->charset= &my_charset_numeric;
|
||||
return def->prepare_stage1_bit(thd, mem_root, file, table_flags);
|
||||
return def->prepare_stage1_bit(thd, mem_root);
|
||||
}
|
||||
|
||||
bool Type_handler_typelib::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
def->prepare_stage1_typelib(thd, mem_root, file, table_flags);
|
||||
def->prepare_stage1_typelib(thd, mem_root, type);
|
||||
}
|
||||
|
||||
|
||||
@ -3125,14 +3117,13 @@ bool Type_handler_string_result::
|
||||
Column_definition_prepare_stage1(THD *thd,
|
||||
MEM_ROOT *mem_root,
|
||||
Column_definition *def,
|
||||
handler *file,
|
||||
ulonglong table_flags,
|
||||
column_definition_type_t type,
|
||||
const Column_derived_attributes
|
||||
*derived_attr)
|
||||
const
|
||||
{
|
||||
return def->prepare_charset_for_string(derived_attr) ||
|
||||
def->prepare_stage1_string(thd, mem_root, file, table_flags);
|
||||
def->prepare_stage1_string(thd, mem_root);
|
||||
}
|
||||
|
||||
|
||||
@ -3343,10 +3334,11 @@ bool Type_handler_bit::
|
||||
handler *file,
|
||||
ulonglong table_flags) const
|
||||
{
|
||||
/*
|
||||
We have sql_field->pack_flag already set here, see
|
||||
mysql_prepare_create_table().
|
||||
*/
|
||||
if (!(table_flags & HA_CAN_BIT_FIELD))
|
||||
{
|
||||
def->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
|
||||
def->create_length_to_internal_length_bit();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user