Skip to content

Commit 8911823

Browse files
author
Alexey Botchkov
committed
MDEV-26546 SIGSEGV's in spider_db_connect on SHOW TABLE and spider_db… …_mbase::connect (and SIGSEGV's in check_vcol_forward_refs and inline_mysql_mutex_lock)
Not the SPIDER issue - happens to INSERT DELAYED. the field::make_new_field does't copy the LONG_UNIQUE_HASH_FIELD flag to the new field. Though the Delayed_insert::get_local_table copies the field->vcol_info for this field. Ad a result the parse_vcol_defs doesn't create the expression for that column so the field->vcol_info->expr is NULL. Which leads to crash. Backported fix for this from 10.5 - the flagg added in the Delayed_insert::get_local_table. Another problem with the USING HASH key is thst the parse_vcol_defs modifies the table->keys content. Then the same parse_vcol_defs is called on the table copy that has keys already modified. Backported fix for that from 10.5 - key copying added tot the Delayed_insert::get_local_table. Finally - the created copy has to clear the expr_arena as this table is not in the thd->open_tables list so won't be cleared automatically.
1 parent 65cc89e commit 8911823

File tree

6 files changed

+83
-1
lines changed

6 files changed

+83
-1
lines changed

mysql-test/main/delayed.result

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,3 +510,12 @@ a b
510510
2 2
511511
3 3
512512
drop table t1;
513+
#
514+
# MDEV-26546 SIGSEGV's in spider_db_connect on SHOW TABLE and
515+
# spider_db_mbase::connect (and SIGSEGV's in check_vcol_forward_refs
516+
# and inline_mysql_mutex_lock)
517+
#
518+
CREATE TABLE t1 (c0 INT,UNIQUE (c0) USING HASH) ENGINE=MYISAM;
519+
INSERT DELAYED INTO t1 VALUES (0);
520+
INSERT DELAYED INTO t1 VALUES (0);
521+
DROP TABLE t1;

mysql-test/main/delayed.test

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -642,3 +642,15 @@ insert delayed into t1 values (3,3);
642642
flush tables t1;
643643
select * from t1;
644644
drop table t1;
645+
646+
--echo #
647+
--echo # MDEV-26546 SIGSEGV's in spider_db_connect on SHOW TABLE and
648+
--echo # spider_db_mbase::connect (and SIGSEGV's in check_vcol_forward_refs
649+
--echo # and inline_mysql_mutex_lock)
650+
--echo #
651+
652+
CREATE TABLE t1 (c0 INT,UNIQUE (c0) USING HASH) ENGINE=MYISAM;
653+
INSERT DELAYED INTO t1 VALUES (0);
654+
INSERT DELAYED INTO t1 VALUES (0);
655+
DROP TABLE t1;
656+

sql/field.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -706,7 +706,7 @@ class Field: public Value_source
706706
enum imagetype { itRAW, itMBR};
707707

708708
utype unireg_check;
709-
const uint32 field_length; // Length of field
709+
uint32 field_length; // Length of field
710710
uint32 flags;
711711
uint16 field_index; // field number in fields array
712712
uchar null_bit; // Bit used to test null bit

sql/sql_insert.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1288,6 +1288,10 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
12881288
thd->lex->current_select->first_cond_optimization= 0;
12891289
}
12901290

1291+
#ifndef EMBEDDED_LIBRARY
1292+
if (lock_type == TL_WRITE_DELAYED && table->expr_arena)
1293+
table->expr_arena->free_items();
1294+
#endif
12911295
DBUG_RETURN(FALSE);
12921296

12931297
abort:
@@ -1304,6 +1308,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
13041308
*/
13051309
for (Field **ptr= table_list->table->field ; *ptr ; ptr++)
13061310
(*ptr)->free();
1311+
if (table_list->table->expr_arena)
1312+
table_list->table->expr_arena->free_items();
13071313
}
13081314
#endif
13091315
if (table != NULL)
@@ -2663,6 +2669,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
26632669
(*field)->invisible= (*org_field)->invisible;
26642670
(*field)->orig_table= copy; // Remove connection
26652671
(*field)->move_field_offset(adjust_ptrs); // Point at copy->record[0]
2672+
(*field)->flags|= ((*org_field)->flags & LONG_UNIQUE_HASH_FIELD);
26662673
memdup_vcol(client_thd, (*field)->vcol_info);
26672674
memdup_vcol(client_thd, (*field)->default_value);
26682675
memdup_vcol(client_thd, (*field)->check_constraint);
@@ -2671,6 +2678,10 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd)
26712678
}
26722679
*field=0;
26732680

2681+
if (copy_keys_from_share(copy, client_thd->mem_root))
2682+
goto error;
2683+
2684+
26742685
if (share->virtual_fields || share->default_expressions ||
26752686
share->default_fields)
26762687
{

sql/table.cc

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3682,6 +3682,55 @@ static void print_long_unique_table(TABLE *table)
36823682
}
36833683
#endif
36843684

3685+
bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root)
3686+
{
3687+
TABLE_SHARE *share= outparam->s;
3688+
if (share->key_parts)
3689+
{
3690+
KEY *key_info, *key_info_end;
3691+
KEY_PART_INFO *key_part;
3692+
3693+
if (!multi_alloc_root(root, &key_info, share->keys*sizeof(KEY),
3694+
&key_part, share->ext_key_parts*sizeof(KEY_PART_INFO),
3695+
NullS))
3696+
return 1;
3697+
3698+
outparam->key_info= key_info;
3699+
3700+
memcpy(key_info, share->key_info, sizeof(*key_info)*share->keys);
3701+
memcpy(key_part, key_info->key_part, sizeof(*key_part)*share->ext_key_parts);
3702+
3703+
my_ptrdiff_t adjust_ptrs= PTR_BYTE_DIFF(key_part, key_info->key_part);
3704+
for (key_info_end= key_info + share->keys ;
3705+
key_info < key_info_end ;
3706+
key_info++)
3707+
{
3708+
key_info->table= outparam;
3709+
key_info->key_part= reinterpret_cast<KEY_PART_INFO*>
3710+
(reinterpret_cast<char*>(key_info->key_part) + adjust_ptrs);
3711+
if (key_info->algorithm == HA_KEY_ALG_LONG_HASH)
3712+
key_info->flags&= ~HA_NOSAME;
3713+
}
3714+
for (KEY_PART_INFO *key_part_end= key_part+share->ext_key_parts;
3715+
key_part < key_part_end;
3716+
key_part++)
3717+
{
3718+
Field *field= key_part->field= outparam->field[key_part->fieldnr - 1];
3719+
if (field->key_length() != key_part->length &&
3720+
!(field->flags & BLOB_FLAG))
3721+
{
3722+
/*
3723+
We are using only a prefix of the column as a key:
3724+
Create a new field for the key part that matches the index
3725+
*/
3726+
field= key_part->field=field->make_new_field(root, outparam, 0);
3727+
field->field_length= key_part->length;
3728+
}
3729+
}
3730+
}
3731+
return 0;
3732+
}
3733+
36853734
/*
36863735
Open a table based on a TABLE_SHARE
36873736

sql/table.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3214,6 +3214,7 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share,
32143214
uint ha_open_flags, TABLE *outparam,
32153215
bool is_create_table,
32163216
List<String> *partitions_to_open= NULL);
3217+
bool copy_keys_from_share(TABLE *outparam, MEM_ROOT *root);
32173218
bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
32183219
bool *error_reported, vcol_init_mode expr);
32193220
TABLE_SHARE *alloc_table_share(const char *db, const char *table_name,

0 commit comments

Comments
 (0)