diff options
author | Aleksey Midenkov <midenok@gmail.com> | 2020-05-15 16:17:15 +0300 |
---|---|---|
committer | Aleksey Midenkov <midenok@gmail.com> | 2020-05-15 16:17:15 +0300 |
commit | a4996f951d731322acc63033646d950ddbb0f60c (patch) | |
tree | a82b31076a630e302e26892e653597d47a749ad2 | |
parent | 72789e4b2b0f631635297c6bc785c7364d60ca9f (diff) | |
download | mariadb-git-a4996f951d731322acc63033646d950ddbb0f60c.tar.gz |
MDEV-22563 Segfault on duplicate free of Item_func_in::array
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.
-rw-r--r-- | mysql-test/main/alter_table.result | 35 | ||||
-rw-r--r-- | mysql-test/main/alter_table.test | 35 | ||||
-rw-r--r-- | sql/field.cc | 2 | ||||
-rw-r--r-- | sql/item.h | 5 |
4 files changed, 76 insertions, 1 deletions
diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 3d21b5c350d..8e8b4362ed8 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -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; diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index dc6983da38b..f090df56e5f 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -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; + diff --git a/sql/field.cc b/sql/field.cc index 5d946ef5d0c..9d118a15748 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -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; } diff --git a/sql/item.h b/sql/item.h index 54eaaaf8743..b83b997323d 100644 --- a/sql/item.h +++ b/sql/item.h @@ -1586,6 +1586,7 @@ public: 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 @@ -2031,6 +2032,10 @@ public: 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); |