diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2018-04-12 14:55:43 +0200 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2018-04-25 08:47:43 +0200 |
commit | adaa891ae7113069e402b40637dd9ddbd96d27bc (patch) | |
tree | 8083565f0dc76edb97dac35b8c5aaf35bb95cbca /sql/opt_subselect.cc | |
parent | 7f6561225a469b6968683fe9099868a87dab8f31 (diff) | |
download | mariadb-git-adaa891ae7113069e402b40637dd9ddbd96d27bc.tar.gz |
MDEV-13699: Assertion `!new_field->field_name.str || strlen(new_field->field_name.str) == new_field->field_name.length' failed in create_tmp_table on 2nd execution of PS with semijoin
The problem was that SJ (semi-join) used secondary list (array) of subquery select list. The items there was prepared once then cleaned up (but not really freed from memory because it was made in statement memory).
Original list was not prepared after first execution because select was removed by conversion to SJ.
The solution is to use original list but prepare it first.
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r-- | sql/opt_subselect.cc | 24 |
1 files changed, 16 insertions, 8 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 1bda84bacd7..a7edd64e68b 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -3725,21 +3725,29 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab) SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info; THD *thd= tab->join->thd; /* First the calls come to the materialization function */ - //List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list; - + DBUG_ASSERT(sjm->is_used); /* Set up the table to write to, do as select_union::create_result_table does */ sjm->sjm_table_param.init(); sjm->sjm_table_param.bit_fields_as_long= TRUE; - //List_iterator<Item> it(item_list); SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select(); - Item **p_item= subq_select->ref_pointer_array; - Item **p_end= p_item + subq_select->item_list.elements; - //while((right_expr= it++)) - for(;p_item != p_end; p_item++) - sjm->sjm_table_cols.push_back(*p_item); + List_iterator<Item> it(subq_select->item_list); + Item *item; + while((item= it++)) + { + /* + This semi-join replaced the subquery (subq_select) and so on + re-executing it will not be prepared. To use the Items from its + select list we have to prepare (fix_fields) them + */ + if (!item->fixed && item->fix_fields(thd, it.ref())) + DBUG_RETURN(TRUE); + item= *(it.ref()); // it can be changed by fix_fields + DBUG_ASSERT(!item->name_length || item->name_length == strlen(item->name)); + sjm->sjm_table_cols.push_back(item, thd->mem_root); + } sjm->sjm_table_param.field_count= subq_select->item_list.elements; sjm->sjm_table_param.force_not_null_cols= TRUE; |