Skip to content

Commit

Permalink
MDEV-22563 Segfault on duplicate free of Item_func_in::array
Browse files Browse the repository at this point in the history
Same array instance in two Item_func_in instances. First Item_func_in
instance is freed on table close. Second one is freed on
cleanup_after_query().

get_copy() depends on copy ctor for copying an item and hence does
shallow copy for default copy ctor. Use build_clone() for deep copy of
Item_func_in.
  • Loading branch information
midenok committed May 15, 2020
1 parent 72789e4 commit a4996f9
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 1 deletion.
35 changes: 35 additions & 0 deletions mysql-test/main/alter_table.result
Original file line number Diff line number Diff line change
Expand Up @@ -2559,3 +2559,38 @@ drop view v1;
#
# End of 10.3 tests
#
#
# MDEV-22563 Segfault on duplicate free of Item_func_in::array
#
create or replace table person_principal (
person_id bigint not null,
insurant_id varchar(10) not null,
principal_id bigint not null,
principal_officer_id bigint not null,
nursing_degree tinyint null,
nursing_degree_valid_from date not null default cast(current_timestamp(6) as date),
carma_user_id bigint not null,
current_date_time timestamp(6) not null default current_timestamp(6) on update current_timestamp(6),
constraint pk_person_principal primary key (person_id asc),
constraint ck_person_principal_nursing_degree check (nursing_degree in (1,2,3,4,5)));
Warnings:
Warning 1280 Name 'pk_person_principal' ignored for PRIMARY key.
create or replace table person_principal_hist (
person_id bigint not null,
insurant_id varchar(10) not null,
principal_id bigint not null,
principal_officer_id bigint not null,
nursing_degree tinyint null,
nursing_degree_valid_from date not null default cast(now() as date),
carma_user_id bigint not null,
orig_date_time datetime(6) not null,
constraint pk_person_principal_hist primary key (person_id asc, orig_date_time asc),
constraint ck_person_principal_hist_nursing_degree check (nursing_degree in (1,2,3,4,5)));
Warnings:
Warning 1280 Name 'pk_person_principal_hist' ignored for PRIMARY key.
insert into person_principal (person_id, insurant_id, principal_id, principal_officer_id, nursing_degree, nursing_degree_valid_from, carma_user_id)
values (1, 'A123456789', 5, 1, 1, '2018-05-06', 1);
alter table person_principal add column if not exists date_mask tinyint null;
update person_principal set date_mask = 0;
alter table person_principal modify column date_mask tinyint not null;
drop tables person_principal_hist, person_principal;
35 changes: 35 additions & 0 deletions mysql-test/main/alter_table.test
Original file line number Diff line number Diff line change
Expand Up @@ -2076,3 +2076,38 @@ drop view v1;
--echo #
--echo # End of 10.3 tests
--echo #

--echo #
--echo # MDEV-22563 Segfault on duplicate free of Item_func_in::array
--echo #
create or replace table person_principal (
person_id bigint not null,
insurant_id varchar(10) not null,
principal_id bigint not null,
principal_officer_id bigint not null,
nursing_degree tinyint null,
nursing_degree_valid_from date not null default cast(current_timestamp(6) as date),
carma_user_id bigint not null,
current_date_time timestamp(6) not null default current_timestamp(6) on update current_timestamp(6),
constraint pk_person_principal primary key (person_id asc),
constraint ck_person_principal_nursing_degree check (nursing_degree in (1,2,3,4,5)));

create or replace table person_principal_hist (
person_id bigint not null,
insurant_id varchar(10) not null,
principal_id bigint not null,
principal_officer_id bigint not null,
nursing_degree tinyint null,
nursing_degree_valid_from date not null default cast(now() as date),
carma_user_id bigint not null,
orig_date_time datetime(6) not null,
constraint pk_person_principal_hist primary key (person_id asc, orig_date_time asc),
constraint ck_person_principal_hist_nursing_degree check (nursing_degree in (1,2,3,4,5)));

insert into person_principal (person_id, insurant_id, principal_id, principal_officer_id, nursing_degree, nursing_degree_valid_from, carma_user_id)
values (1, 'A123456789', 5, 1, 1, '2018-05-06', 1);
alter table person_principal add column if not exists date_mask tinyint null;
update person_principal set date_mask = 0;
alter table person_principal modify column date_mask tinyint not null;
drop tables person_principal_hist, person_principal;

2 changes: 1 addition & 1 deletion sql/field.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11396,7 +11396,7 @@ Virtual_column_info* Virtual_column_info::clone(THD *thd)
return NULL;
if (expr)
{
dst->expr= expr->get_copy(thd);
dst->expr= expr->build_clone(thd);
if (!dst->expr)
return NULL;
}
Expand Down
5 changes: 5 additions & 0 deletions sql/item.h
Original file line number Diff line number Diff line change
Expand Up @@ -1586,6 +1586,7 @@ class Item: public Value_source,
virtual bool is_order_clause_position() const { return false; }
/* cloning of constant items (0 if it is not const) */
virtual Item *clone_item(THD *thd) { return 0; }
/* deep copy item */
virtual Item* build_clone(THD *thd) { return get_copy(thd); }
virtual cond_result eq_cmp_result() const { return COND_OK; }
inline uint float_length(uint decimals_par) const
Expand Down Expand Up @@ -2031,6 +2032,10 @@ class Item: public Value_source,
virtual bool check_index_dependence(void *arg) { return 0; }
/*============== End of Item processor list ======================*/

/*
Does not guarantee deep copy (depends on copy ctor).
See build_clone() for deep copy.
*/
virtual Item *get_copy(THD *thd)=0;

bool cache_const_expr_analyzer(uchar **arg);
Expand Down

0 comments on commit a4996f9

Please sign in to comment.