Commit fe9092a8 authored by Sergei Golubchik's avatar Sergei Golubchik

MDEV-35029 ASAN errors in Lex_ident<Compare_ident_ci>::is_valid_ident upon DDL...

MDEV-35029 ASAN errors in Lex_ident<Compare_ident_ci>::is_valid_ident upon DDL on table with vector index

in ALTER TABLE or CREATE TABLE LIKE, a create a copy of key->option_list,
because it can be extended later on the thd->mem_root, so it has
to be a copy
parent e537e447
......@@ -24,3 +24,18 @@ set global mhnsw_cache_size = 1048576;
insert into t values (2,x'00000000');
drop table t;
set global mhnsw_cache_size = default;
#
# MDEV-35029 ASAN errors in Lex_ident<Compare_ident_ci>::is_valid_ident upon DDL on table with vector index
#
create table t (a int, v blob not null, vector key (v) distance_function=euclidean);
show create table t;
Table Create Table
t CREATE TABLE `t` (
`a` int(11) DEFAULT NULL,
`v` blob NOT NULL,
VECTOR KEY `v` (`v`) `distance_function`=euclidean
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci
set session mhnsw_max_edges_per_node = @@mhnsw_max_edges_per_node + 1;
create table t2 like t;
alter table t force;
drop table t, t2;
......@@ -31,3 +31,13 @@ insert into t values (2,x'00000000');
drop table t;
set global mhnsw_cache_size = default;
--echo #
--echo # MDEV-35029 ASAN errors in Lex_ident<Compare_ident_ci>::is_valid_ident upon DDL on table with vector index
--echo #
create table t (a int, v blob not null, vector key (v) distance_function=euclidean);
show create table t;
set session mhnsw_max_edges_per_node = @@mhnsw_max_edges_per_node + 1;
create table t2 like t;
alter table t force;
drop table t, t2;
......@@ -8321,6 +8321,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
List<Key> new_key_list;
List<FOREIGN_KEY_INFO> fk_list;
List<Alter_rename_key> rename_key_list(alter_info->alter_rename_key_list);
MEM_ROOT *root= thd->mem_root;
/*
Create a deep copy of the list of visibility for indexes, as it will be
......@@ -8328,9 +8329,9 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
*/
List<Alter_index_ignorability>
alter_index_ignorability_list(alter_info->alter_index_ignorability_list,
thd->mem_root);
root);
list_copy_and_replace_each_value(alter_index_ignorability_list, thd->mem_root);
list_copy_and_replace_each_value(alter_index_ignorability_list, root);
List_iterator<Alter_drop> drop_it(alter_info->drop_list);
List_iterator<Create_field> def_it(alter_info->create_list);
......@@ -8409,7 +8410,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
column_rename_param.db_name= table->s->db;
column_rename_param.table_name= table->s->table_name;
if (column_rename_param.fields.copy(&alter_info->create_list, thd->mem_root))
if (column_rename_param.fields.copy(&alter_info->create_list, root))
DBUG_RETURN(1); // OOM
restore_record(table, s->default_values); // Empty record for DEFAULT
......@@ -8421,7 +8422,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
DBUG_RETURN(1);
if (merge_engine_options(table->s->option_list, create_info->option_list,
&create_info->option_list, thd->mem_root))
&create_info->option_list, root))
DBUG_RETURN(1);
table->file->get_foreign_key_list(thd, &fk_list);
......@@ -8464,7 +8465,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (table->s->tmp_table == NO_TMP_TABLE)
{
if (alter_info->drop_stat_fields.push_back(field, thd->mem_root))
if (alter_info->drop_stat_fields.push_back(field, root))
DBUG_RETURN(true);
}
dropped_sys_vers_fields|= field->flags;
......@@ -8488,7 +8489,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (table->s->tmp_table == NO_TMP_TABLE)
{
if (alter_info->drop_stat_fields.push_back(field, thd->mem_root))
if (alter_info->drop_stat_fields.push_back(field, root))
DBUG_RETURN(true);
}
continue;
......@@ -8509,7 +8510,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
Note that columns with AFTER clauses are added to the end
of the list for now. Their positions will be corrected later.
*/
new_create_list.push_back(def, thd->mem_root);
new_create_list.push_back(def, root);
if (field->stored_in_db() != def->stored_in_db())
{
my_error(ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN, MYF(0));
......@@ -8541,7 +8542,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
!(alter_info->flags & ALTER_DROP_SYSTEM_VERSIONING))
{
/* "dropping" a versioning field only hides it from the user */
def= new (thd->mem_root) Create_field(thd, field, field);
def= new (root) Create_field(thd, field, field);
def->invisible= INVISIBLE_SYSTEM;
alter_info->flags|= ALTER_CHANGE_COLUMN;
if (field->flags & VERS_ROW_START)
......@@ -8553,7 +8554,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
create_info->vers_info.period.end=
create_info->vers_info.as_row.end=
def->field_name= Vers_parse_info::default_end;
new_create_list.push_back(def, thd->mem_root);
new_create_list.push_back(def, root);
dropped_sys_vers_fields|= field->flags;
drop_it.remove();
}
......@@ -8563,8 +8564,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
This field was not dropped and not changed, add it to the list
for the new table.
*/
def= new (thd->mem_root) Create_field(thd, field, field);
new_create_list.push_back(def, thd->mem_root);
def= new (root) Create_field(thd, field, field);
new_create_list.push_back(def, root);
alter_it.rewind(); // Change default if ALTER
Alter_column *alter;
while ((alter=alter_it++))
......@@ -8610,8 +8611,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
else
{
DBUG_ASSERT(field->invisible == INVISIBLE_SYSTEM);
def= new (thd->mem_root) Create_field(thd, field, field);
new_create_tail.push_back(def, thd->mem_root);
def= new (root) Create_field(thd, field, field);
new_create_tail.push_back(def, root);
}
}
......@@ -8670,11 +8671,11 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
} /* if (def->change.str) */
} /* while (def) */
} /* if (part_field_list || subpart_field_list) */
// Force reopen because new column name is on thd->mem_root
// Force reopen because new column name is on root
table->mark_table_for_reopen();
} /* if (part_info) */
#endif
// Force reopen because new column name is on thd->mem_root
// Force reopen because new column name is on root
table->mark_table_for_reopen();
}
......@@ -8738,7 +8739,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
alter_ctx->error_if_not_empty= TRUE;
}
if (!def->after.str)
new_create_list.push_back(def, thd->mem_root);
new_create_list.push_back(def, root);
else
{
if (def->change.str)
......@@ -8765,7 +8766,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
if (def->after.str == first_keyword)
new_create_list.push_front(def, thd->mem_root);
new_create_list.push_front(def, root);
else
{
find_it.rewind();
......@@ -8846,7 +8847,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (table->s->tmp_table == NO_TMP_TABLE)
{
if (alter_info->add_stat_drop_index(key_info, FALSE, thd->mem_root))
if (alter_info->add_stat_drop_index(key_info, FALSE, root))
DBUG_RETURN(true);
if (primary_key)
{
......@@ -8857,8 +8858,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
tab_key_info->user_defined_key_parts !=
tab_key_info->ext_key_parts)
{
if (alter_info->add_stat_drop_index(tab_key_info, TRUE,
thd->mem_root))
if (alter_info->add_stat_drop_index(tab_key_info, TRUE, root))
DBUG_RETURN(true);
}
}
......@@ -8902,8 +8902,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (cmp(&rename_key->old_name, &rename_key->new_name))
{
/* Key was renamed */
alter_info->add_stat_rename_index(key_info, &rename_key->new_name,
thd->mem_root);
alter_info->add_stat_rename_index(key_info, &rename_key->new_name, root);
}
rename_key_it.remove();
......@@ -9005,10 +9004,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
key_part_length= 0; // Use whole field
}
key_part_length /= kfield->charset()->mbmaxlen;
Key_part_spec *kps= new (thd->mem_root) Key_part_spec(&cfield->field_name,
Key_part_spec *kps= new (root) Key_part_spec(&cfield->field_name,
key_part_length, true);
kps->asc= !(key_part->key_part_flag & HA_REVERSE_SORT);
key_parts.push_back(kps, thd->mem_root);
key_parts.push_back(kps, root);
if (!(cfield->invisible == INVISIBLE_SYSTEM && cfield->vers_sys_field()))
user_keyparts= true;
}
......@@ -9016,14 +9015,13 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
if (delete_index_stat)
{
if (alter_info->add_stat_drop_index(key_info, FALSE, thd->mem_root))
if (alter_info->add_stat_drop_index(key_info, FALSE, root))
DBUG_RETURN(true);
}
else if (alter_ctx->modified_primary_key &&
key_info->user_defined_key_parts != key_info->ext_key_parts)
{
if (alter_info->add_stat_drop_index(key_info, FALSE,
thd->mem_root))
if (alter_info->add_stat_drop_index(key_info, FALSE, root))
DBUG_RETURN(true);
}
}
......@@ -9042,6 +9040,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
Key *key;
enum Key::Keytype key_type;
LEX_CSTRING tmp_name;
engine_option_value *option_list;
bzero((char*) &key_create_info, sizeof(key_create_info));
if (key_info->algorithm == HA_KEY_ALG_LONG_HASH)
key_info->algorithm= HA_KEY_ALG_UNDEF;
......@@ -9101,15 +9101,18 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
}
if (merge_engine_options(key_info->option_list, 0, &option_list, root))
goto err;
tmp_name= key_name;
/* We dont need LONG_UNIQUE_HASH_FIELD flag because it will be autogenerated */
key= new (thd->mem_root) Key(key_type, &tmp_name, &key_create_info,
key_info->flags & HA_GENERATED_KEY,
&key_parts, key_info->option_list, DDL_options());
key= new (root) Key(key_type, &tmp_name, &key_create_info,
key_info->flags & HA_GENERATED_KEY, &key_parts,
option_list, DDL_options());
key->without_overlaps= key_info->without_overlaps;
key->period= table->s->period.name;
key->old= true;
new_key_list.push_back(key, thd->mem_root);
new_key_list.push_back(key, root);
}
if (long_hash_key)
{
......@@ -9130,15 +9133,15 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
continue;
List<Key_part_spec> cols, ref_cols;
for (LEX_CSTRING &c : fk.foreign_fields)
cols.push_back(new (thd->mem_root) Key_part_spec(&c, 0));
cols.push_back(new (root) Key_part_spec(&c, 0));
for (LEX_CSTRING &c : fk.referenced_fields)
ref_cols.push_back(new (thd->mem_root) Key_part_spec(&c, 0));
auto key= new (thd->mem_root)
ref_cols.push_back(new (root) Key_part_spec(&c, 0));
auto key= new (root)
Foreign_key(fk.foreign_id, &cols, fk.foreign_id, fk.referenced_db,
fk.referenced_table, &ref_cols, fk.delete_method, fk.update_method,
Foreign_key::FK_MATCH_UNDEF, DDL_options());
key->old= true;
new_key_list.push_back(key, thd->mem_root);
new_key_list.push_back(key, root);
}
}
{
......@@ -9148,7 +9151,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
if (key->type == Key::FOREIGN_KEY &&
((Foreign_key *)key)->validate(new_create_list))
goto err;
new_key_list.push_back(key, thd->mem_root);
new_key_list.push_back(key, root);
if (key->name.str &&
key->name.streq(primary_key_name))
{
......@@ -9253,10 +9256,10 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
{
check->expr->walk(&Item::rename_fields_processor, 1,
&column_rename_param);
// Force reopen because new column name is on thd->mem_root
// Force reopen because new column name is on root
table->mark_table_for_reopen();
}
new_constraint_list.push_back(check, thd->mem_root);
new_constraint_list.push_back(check, root);
}
}
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment