1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +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

@ -20,3 +20,24 @@ create table t1 (a varchar(1), primary key (a))
partition by list (ascii(a)) partition by list (ascii(a))
(partition p1 values in (65)); (partition p1 values in (65));
ERROR HY000: This partition function is not allowed 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
#

View File

@ -27,3 +27,23 @@ partition by list (ascii(a))
#insert into t1 values ('A'); #insert into t1 values ('A');
#replace into t1 values ('A'); #replace into t1 values ('A');
#drop table t1; #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 #

View File

@ -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))); PARTITION BY LIST COLUMNS (a) (PARTITION p0 VALUES IN (FROM_DAYS(100)));
Warnings: Warnings:
Note 1003 PARTITION BY LIST COLUMNS(`a`) 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'; SELECT PARTITION_DESCRIPTION FROM INFORMATION_SCHEMA.PARTITIONS WHERE TABLE_NAME='t1';
PARTITION_DESCRIPTION PARTITION_DESCRIPTION
'0000-00-00' '0000-00-00'

View File

@ -5377,7 +5377,7 @@ public:
bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root); bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root);
bool prepare_stage1(THD *thd, MEM_ROOT *mem_root, bool prepare_stage1(THD *thd, MEM_ROOT *mem_root,
handler *file, ulonglong table_flags, column_definition_type_t type,
const Column_derived_attributes *derived_attr); const Column_derived_attributes *derived_attr);
void prepare_stage1_simple(CHARSET_INFO *cs) void prepare_stage1_simple(CHARSET_INFO *cs)
{ {
@ -5385,11 +5385,9 @@ public:
create_length_to_internal_length_simple(); create_length_to_internal_length_simple();
} }
bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root, bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root,
handler *file, ulonglong table_flags); column_definition_type_t deftype);
bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root, bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root);
handler *file, ulonglong table_flags); bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root);
bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
handler *file, ulonglong table_flags);
bool bulk_alter(const Column_derived_attributes *derived_attr, bool bulk_alter(const Column_derived_attributes *derived_attr,
const Column_bulk_alter_attributes *bulk_attr) const Column_bulk_alter_attributes *bulk_attr)

View File

@ -787,8 +787,9 @@ bool Create_json_table::add_json_table_fields(THD *thd, TABLE *table,
*/ */
sql_f->length= sql_f->char_length; sql_f->length= sql_f->char_length;
if (sql_f->prepare_stage1(thd, thd->mem_root, table->file, if (sql_f->prepare_stage1(thd, thd->mem_root,
table->file->ha_table_flags(), &da)) COLUMN_DEFINITION_TABLE_FIELD,
&da))
goto err_exit; goto err_exit;
while ((jc2= it2++) != jc) while ((jc2= it2++) != jc)

View File

@ -2395,17 +2395,16 @@ static void check_duplicate_key(THD *thd, const Key *key, const KEY *key_info,
bool Column_definition::prepare_stage1_typelib(THD *thd, bool Column_definition::prepare_stage1_typelib(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
handler *file, column_definition_type_t deftype)
ulonglong table_flags)
{ {
/* /*
Pass the last parameter to prepare_interval_field() as follows: Pass the last parameter to prepare_interval_field() as follows:
- If we are preparing for an SP variable (file is NULL), we pass "false", - If we are preparing for an SP variable, we pass "false",
to force allocation and full copying of TYPELIB values on the given to force allocation and full copying of TYPELIB values on the given
mem_root, even if no character set conversion is needed. This is needed mem_root, even if no character set conversion is needed. This is needed
because a life cycle of an SP variable is longer than the current query. because a life cycle of an SP variable is longer than the current query.
- If we are preparing for a CREATE TABLE, (file != NULL), we pass "true". - If we are preparing for a CREATE TABLE, we pass "true".
This will create the typelib in runtime memory - we will free the This will create the typelib in runtime memory - we will free the
occupied memory at the same time when we free this occupied memory at the same time when we free this
sql_field -- at the end of execution. sql_field -- at the end of execution.
@ -2413,11 +2412,11 @@ bool Column_definition::prepare_stage1_typelib(THD *thd,
values in "interval" in cases when no character conversion is needed, values in "interval" in cases when no character conversion is needed,
to avoid extra copying. to avoid extra copying.
*/ */
if (prepare_interval_field(mem_root, file != NULL)) if (prepare_interval_field(mem_root,
deftype == COLUMN_DEFINITION_TABLE_FIELD))
return true; // E.g. wrong values with commas: SET('a,b') return true; // E.g. wrong values with commas: SET('a,b')
create_length_to_internal_length_typelib(); create_length_to_internal_length_typelib();
DBUG_ASSERT(file || !default_value); // SP variables have no default_value
if (default_value && default_value->expr->basic_const_item()) if (default_value && default_value->expr->basic_const_item())
{ {
if ((charset != default_value->expr->collation.collation && if ((charset != default_value->expr->collation.collation &&
@ -2430,14 +2429,11 @@ bool Column_definition::prepare_stage1_typelib(THD *thd,
bool Column_definition::prepare_stage1_string(THD *thd, bool Column_definition::prepare_stage1_string(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root)
handler *file,
ulonglong table_flags)
{ {
create_length_to_internal_length_string(); create_length_to_internal_length_string();
if (prepare_blob_field(thd)) if (prepare_blob_field(thd))
return true; return true;
DBUG_ASSERT(file || !default_value); // SP variables have no default_value
/* /*
Convert the default value from client character Convert the default value from client character
set into the column character set if necessary. set into the column character set if necessary.
@ -2457,13 +2453,9 @@ bool Column_definition::prepare_stage1_string(THD *thd,
bool Column_definition::prepare_stage1_bit(THD *thd, bool Column_definition::prepare_stage1_bit(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root)
handler *file,
ulonglong table_flags)
{ {
pack_flag= FIELDFLAG_NUMBER; pack_flag= FIELDFLAG_NUMBER;
if (!(table_flags & HA_CAN_BIT_FIELD))
pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
create_length_to_internal_length_bit(); create_length_to_internal_length_bit();
return false; return false;
} }
@ -2471,14 +2463,15 @@ bool Column_definition::prepare_stage1_bit(THD *thd,
bool Column_definition::prepare_stage1(THD *thd, bool Column_definition::prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
handler *file, column_definition_type_t deftype,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
{ {
// SP variables have no default_value
DBUG_ASSERT(deftype == COLUMN_DEFINITION_TABLE_FIELD || !default_value);
return type_handler()->Column_definition_prepare_stage1(thd, mem_root, return type_handler()->Column_definition_prepare_stage1(thd, mem_root,
this, file, this, deftype,
table_flags,
derived_attr); derived_attr);
} }
@ -2702,10 +2695,77 @@ key_add_part_check_null(const handler *file, KEY *key_info,
/* /*
Preparation for table creation Prepare for a table creation.
Stage 1: prepare the field list.
*/
static bool mysql_prepare_create_table_stage1(THD *thd,
HA_CREATE_INFO *create_info,
Alter_info *alter_info)
{
DBUG_ENTER("mysql_prepare_create_table_stage1");
const Column_derived_attributes dattr(create_info->default_table_charset);
const Column_bulk_alter_attributes
battr(create_info->alter_table_convert_to_charset);
Create_field *sql_field;
List_iterator_fast<Create_field> it(alter_info->create_list);
DBUG_EXECUTE_IF("test_pseudo_invisible",{
mysql_add_invisible_field(thd, &alter_info->create_list,
"invisible", &type_handler_slong, INVISIBLE_SYSTEM,
new (thd->mem_root)Item_int(thd, 9));
});
DBUG_EXECUTE_IF("test_completely_invisible",{
mysql_add_invisible_field(thd, &alter_info->create_list,
"invisible", &type_handler_slong, INVISIBLE_FULL,
new (thd->mem_root)Item_int(thd, 9));
});
DBUG_EXECUTE_IF("test_invisible_index",{
LEX_CSTRING temp;
temp.str= "invisible";
temp.length= strlen("invisible");
mysql_add_invisible_index(thd, &alter_info->key_list
, &temp, Key::MULTIPLE);
});
for ( ; (sql_field=it++) ; )
{
/* Virtual fields are always NULL */
if (sql_field->vcol_info)
sql_field->flags&= ~NOT_NULL_FLAG;
/*
Initialize length from its original value (number of characters),
which was set in the parser. This is necessary if we're
executing a prepared statement for the second time.
*/
sql_field->length= sql_field->char_length;
if (sql_field->bulk_alter(&dattr, &battr))
DBUG_RETURN(true);
if (sql_field->prepare_stage1(thd, thd->mem_root,
COLUMN_DEFINITION_TABLE_FIELD,
&dattr))
DBUG_RETURN(true);
DBUG_ASSERT(sql_field->charset);
if (check_column_name(sql_field->field_name.str))
{
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name.str);
DBUG_RETURN(TRUE);
}
}
DBUG_RETURN(false);
}
/*
Preparation for table creation, final stage.
SYNOPSIS SYNOPSIS
mysql_prepare_create_table() mysql_prepare_create_table_finalize()
thd Thread object. thd Thread object.
create_info Create information (like MAX_ROWS). create_info Create information (like MAX_ROWS).
alter_info List of columns and indexes to create alter_info List of columns and indexes to create
@ -2728,11 +2788,12 @@ key_add_part_check_null(const handler *file, KEY *key_info,
*/ */
static int static int
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, mysql_prepare_create_table_finalize(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info, uint *db_options, Alter_info *alter_info, uint *db_options,
handler *file, KEY **key_info_buffer, handler *file, KEY **key_info_buffer,
uint *key_count, int create_table_mode, uint *key_count, int create_table_mode,
const LEX_CSTRING db, const LEX_CSTRING table_name) const LEX_CSTRING db,
const LEX_CSTRING table_name)
{ {
const char *key_name; const char *key_name;
Create_field *sql_field,*dup_field; Create_field *sql_field,*dup_field;
@ -2748,28 +2809,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
bool tmp_table= create_table_mode == C_ALTER_TABLE; bool tmp_table= create_table_mode == C_ALTER_TABLE;
const bool create_simple= thd->lex->create_simple(); const bool create_simple= thd->lex->create_simple();
bool is_hash_field_needed= false; bool is_hash_field_needed= false;
const Column_derived_attributes dattr(create_info->default_table_charset);
const Column_bulk_alter_attributes
battr(create_info->alter_table_convert_to_charset);
DBUG_ENTER("mysql_prepare_create_table"); DBUG_ENTER("mysql_prepare_create_table");
DBUG_EXECUTE_IF("test_pseudo_invisible",{
mysql_add_invisible_field(thd, &alter_info->create_list,
"invisible", &type_handler_slong, INVISIBLE_SYSTEM,
new (thd->mem_root)Item_int(thd, 9));
});
DBUG_EXECUTE_IF("test_completely_invisible",{
mysql_add_invisible_field(thd, &alter_info->create_list,
"invisible", &type_handler_slong, INVISIBLE_FULL,
new (thd->mem_root)Item_int(thd, 9));
});
DBUG_EXECUTE_IF("test_invisible_index",{
LEX_CSTRING temp;
temp.str= "invisible";
temp.length= strlen("invisible");
mysql_add_invisible_index(thd, &alter_info->key_list
, &temp, Key::MULTIPLE);
});
LEX_CSTRING* connect_string = &create_info->connect_string; LEX_CSTRING* connect_string = &create_info->connect_string;
if (connect_string->length != 0 && if (connect_string->length != 0 &&
connect_string->length > CONNECT_STRING_MAXLEN && connect_string->length > CONNECT_STRING_MAXLEN &&
@ -2804,42 +2845,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
for (field_no=0; (sql_field=it++) ; field_no++) for (field_no=0; (sql_field=it++) ; field_no++)
{ {
/* Virtual fields are always NULL */ if (!(sql_field->flags & NOT_NULL_FLAG))
if (sql_field->vcol_info) null_fields++;
sql_field->flags&= ~NOT_NULL_FLAG;
/*
Initialize length from its original value (number of characters),
which was set in the parser. This is necessary if we're
executing a prepared statement for the second time.
*/
sql_field->length= sql_field->char_length;
if (sql_field->bulk_alter(&dattr, &battr))
DBUG_RETURN(true);
if (sql_field->prepare_stage1(thd, thd->mem_root,
file, file->ha_table_flags(),
&dattr))
DBUG_RETURN(true);
DBUG_ASSERT(sql_field->charset);
if (sql_field->real_field_type() == MYSQL_TYPE_BIT && if (sql_field->real_field_type() == MYSQL_TYPE_BIT &&
file->ha_table_flags() & HA_CAN_BIT_FIELD) file->ha_table_flags() & HA_CAN_BIT_FIELD)
total_uneven_bit_length+= sql_field->length & 7; total_uneven_bit_length+= sql_field->length & 7;
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields++;
if (check_column_name(sql_field->field_name.str))
{
my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name.str);
DBUG_RETURN(TRUE);
}
/* Check if we have used the same field name before */ /* Check if we have used the same field name before */
for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++) for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
{ {
@ -3827,6 +3842,49 @@ without_overlaps_err:
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/*
Preparation for table creation
SYNOPSIS
mysql_prepare_create_table()
thd Thread object.
create_info Create information (like MAX_ROWS).
alter_info List of columns and indexes to create
db_options INOUT Table options (like HA_OPTION_PACK_RECORD).
file The handler for the new table.
key_info_buffer OUT An array of KEY structs for the indexes.
key_count OUT The number of elements in the array.
create_table_mode C_ORDINARY_CREATE, C_ALTER_TABLE,
C_CREATE_SELECT, C_ASSISTED_DISCOVERY
DESCRIPTION
Prepares the table and key structures for table creation.
NOTES
sets create_info->varchar if the table has a varchar
RETURN VALUES
FALSE OK
TRUE error
*/
static int
mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
Alter_info *alter_info, uint *db_options,
handler *file, KEY **key_info_buffer,
uint *key_count, int create_table_mode,
const LEX_CSTRING db,
const LEX_CSTRING table_name)
{
return mysql_prepare_create_table_stage1(thd, create_info, alter_info) ||
mysql_prepare_create_table_finalize(thd, create_info, alter_info,
db_options, file, key_info_buffer,
key_count, create_table_mode,
db, table_name);
}
/** /**
check comment length of table, column, index and partition check comment length of table, column, index and partition
@ -3955,7 +4013,8 @@ bool Column_definition::prepare_blob_field(THD *thd)
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root) bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
{ {
const Column_derived_attributes dattr(thd->variables.collation_database); const Column_derived_attributes dattr(thd->variables.collation_database);
return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY, &dattr) || return prepare_stage1(thd, mem_root,
COLUMN_DEFINITION_ROUTINE_LOCAL, &dattr) ||
prepare_stage2(NULL, HA_CAN_GEOMETRY); prepare_stage2(NULL, HA_CAN_GEOMETRY);
} }
@ -4050,6 +4109,9 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
DBUG_RETURN(NULL); DBUG_RETURN(NULL);
} }
if (mysql_prepare_create_table_stage1(thd, create_info, alter_info))
DBUG_RETURN(NULL);
db_options= create_info->table_options_with_row_type(); db_options= create_info->table_options_with_row_type();
if (unlikely(!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root, if (unlikely(!(file= get_new_handler((TABLE_SHARE*) 0, thd->mem_root,
@ -4266,9 +4328,10 @@ handler *mysql_create_frm_image(THD *thd, const LEX_CSTRING &db,
} }
#endif #endif
if (mysql_prepare_create_table(thd, create_info, alter_info, &db_options, if (mysql_prepare_create_table_finalize(thd, create_info,
file, key_info, key_count, alter_info, &db_options,
create_table_mode, db, table_name)) file, key_info, key_count,
create_table_mode, db, table_name))
goto err; goto err;
create_info->table_options=db_options; create_info->table_options=db_options;

View File

@ -3008,8 +3008,7 @@ bool Type_handler::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3022,8 +3021,7 @@ bool Type_handler_null::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3037,8 +3035,7 @@ bool Type_handler_row::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3052,8 +3049,7 @@ bool Type_handler_temporal_result::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3067,8 +3063,7 @@ bool Type_handler_numeric::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3081,8 +3076,7 @@ bool Type_handler_newdecimal::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
@ -3096,28 +3090,26 @@ bool Type_handler_bit::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
{ {
def->charset= &my_charset_numeric; 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:: bool Type_handler_typelib::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
{ {
return def->prepare_charset_for_string(derived_attr) || 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, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const const
{ {
return def->prepare_charset_for_string(derived_attr) || 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, handler *file,
ulonglong table_flags) const ulonglong table_flags) const
{ {
/* if (!(table_flags & HA_CAN_BIT_FIELD))
We have sql_field->pack_flag already set here, see {
mysql_prepare_create_table(). def->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
*/ def->create_length_to_internal_length_bit();
}
return false; return false;
} }

View File

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

View File

@ -382,8 +382,8 @@ public:
} }
bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root,
Column_definition *def, handler *file, Column_definition *def,
ulonglong table_flags, column_definition_type_t type,
const Column_derived_attributes *derived_attr) const Column_derived_attributes *derived_attr)
const override const override
{ {

View File

@ -280,8 +280,7 @@ bool Type_handler_geometry::
Column_definition_prepare_stage1(THD *thd, Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *def, Column_definition *def,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) const *derived_attr) const
{ {

View File

@ -108,8 +108,7 @@ public:
bool Column_definition_prepare_stage1(THD *thd, bool Column_definition_prepare_stage1(THD *thd,
MEM_ROOT *mem_root, MEM_ROOT *mem_root,
Column_definition *c, Column_definition *c,
handler *file, column_definition_type_t type,
ulonglong table_flags,
const Column_derived_attributes const Column_derived_attributes
*derived_attr) *derived_attr)
const override; const override;