Skip to content

Commit adaa891

Browse files
committed
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.
1 parent 7f65612 commit adaa891

File tree

4 files changed

+98
-8
lines changed

4 files changed

+98
-8
lines changed

mysql-test/r/subselect_sj.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3153,4 +3153,30 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
31533153
Warnings:
31543154
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
31553155
DROP TABLE t1,t2,t3,t4;
3156+
#
3157+
# MDEV-13699: Assertion `!new_field->field_name.str ||
3158+
# strlen(new_field->field_name.str) == new_field->field_name.length'
3159+
# failed in create_tmp_table on 2nd execution of PS with semijoin
3160+
#
3161+
CREATE TABLE t1 (a INT);
3162+
INSERT INTO t1 VALUES (1),(2);
3163+
CREATE TABLE t2 (b INT);
3164+
INSERT INTO t2 VALUES (3),(4);
3165+
CREATE TABLE t3 (c INT);
3166+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
3167+
INSERT INTO t3 VALUES (5),(6);
3168+
PREPARE stmt FROM
3169+
"SELECT * FROM t1
3170+
WHERE EXISTS (
3171+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
3172+
)";
3173+
EXECUTE stmt;
3174+
a
3175+
EXECUTE stmt;
3176+
a
3177+
EXECUTE stmt;
3178+
a
3179+
drop view v3;
3180+
drop table t1,t2,t3;
3181+
# End of 5.5 test
31563182
set optimizer_switch=@subselect_sj_tmp;

mysql-test/r/subselect_sj_jcl6.result

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3167,6 +3167,32 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
31673167
Warnings:
31683168
Note 1003 select `test`.`t1`.`c1` AS `c1`,`test`.`t2`.`c2` AS `c2`,`test`.`t4`.`c4` AS `c4` from `test`.`t1` left join (`test`.`t2` join `test`.`t4`) on(((`test`.`t2`.`c2` = `test`.`t1`.`c1`) and <in_optimizer>(`test`.`t1`.`c1`,<exists>(select `test`.`t3`.`c3` from `test`.`t3` where (<cache>(`test`.`t2`.`c2`) = `test`.`t3`.`c3`))))) where 1
31693169
DROP TABLE t1,t2,t3,t4;
3170+
#
3171+
# MDEV-13699: Assertion `!new_field->field_name.str ||
3172+
# strlen(new_field->field_name.str) == new_field->field_name.length'
3173+
# failed in create_tmp_table on 2nd execution of PS with semijoin
3174+
#
3175+
CREATE TABLE t1 (a INT);
3176+
INSERT INTO t1 VALUES (1),(2);
3177+
CREATE TABLE t2 (b INT);
3178+
INSERT INTO t2 VALUES (3),(4);
3179+
CREATE TABLE t3 (c INT);
3180+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
3181+
INSERT INTO t3 VALUES (5),(6);
3182+
PREPARE stmt FROM
3183+
"SELECT * FROM t1
3184+
WHERE EXISTS (
3185+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
3186+
)";
3187+
EXECUTE stmt;
3188+
a
3189+
EXECUTE stmt;
3190+
a
3191+
EXECUTE stmt;
3192+
a
3193+
drop view v3;
3194+
drop table t1,t2,t3;
3195+
# End of 5.5 test
31703196
set optimizer_switch=@subselect_sj_tmp;
31713197
#
31723198
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off

mysql-test/t/subselect_sj.test

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2841,5 +2841,35 @@ eval EXPLAIN EXTENDED $q2;
28412841

28422842
DROP TABLE t1,t2,t3,t4;
28432843

2844+
--echo #
2845+
--echo # MDEV-13699: Assertion `!new_field->field_name.str ||
2846+
--echo # strlen(new_field->field_name.str) == new_field->field_name.length'
2847+
--echo # failed in create_tmp_table on 2nd execution of PS with semijoin
2848+
--echo #
2849+
2850+
CREATE TABLE t1 (a INT);
2851+
INSERT INTO t1 VALUES (1),(2);
2852+
2853+
CREATE TABLE t2 (b INT);
2854+
INSERT INTO t2 VALUES (3),(4);
2855+
2856+
CREATE TABLE t3 (c INT);
2857+
CREATE ALGORITHM=MERGE VIEW v3 AS SELECT * FROM t3;
2858+
INSERT INTO t3 VALUES (5),(6);
2859+
2860+
PREPARE stmt FROM
2861+
"SELECT * FROM t1
2862+
WHERE EXISTS (
2863+
SELECT * FROM t2 WHERE t1.a IN ( SELECT c AS fld FROM v3 )
2864+
)";
2865+
EXECUTE stmt;
2866+
EXECUTE stmt;
2867+
EXECUTE stmt;
2868+
2869+
drop view v3;
2870+
drop table t1,t2,t3;
2871+
2872+
--echo # End of 5.5 test
2873+
28442874
# The following command must be the last one the file
28452875
set optimizer_switch=@subselect_sj_tmp;

sql/opt_subselect.cc

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3725,21 +3725,29 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
37253725
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
37263726
THD *thd= tab->join->thd;
37273727
/* First the calls come to the materialization function */
3728-
//List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
3729-
3728+
37303729
DBUG_ASSERT(sjm->is_used);
37313730
/*
37323731
Set up the table to write to, do as select_union::create_result_table does
37333732
*/
37343733
sjm->sjm_table_param.init();
37353734
sjm->sjm_table_param.bit_fields_as_long= TRUE;
3736-
//List_iterator<Item> it(item_list);
37373735
SELECT_LEX *subq_select= emb_sj_nest->sj_subq_pred->unit->first_select();
3738-
Item **p_item= subq_select->ref_pointer_array;
3739-
Item **p_end= p_item + subq_select->item_list.elements;
3740-
//while((right_expr= it++))
3741-
for(;p_item != p_end; p_item++)
3742-
sjm->sjm_table_cols.push_back(*p_item);
3736+
List_iterator<Item> it(subq_select->item_list);
3737+
Item *item;
3738+
while((item= it++))
3739+
{
3740+
/*
3741+
This semi-join replaced the subquery (subq_select) and so on
3742+
re-executing it will not be prepared. To use the Items from its
3743+
select list we have to prepare (fix_fields) them
3744+
*/
3745+
if (!item->fixed && item->fix_fields(thd, it.ref()))
3746+
DBUG_RETURN(TRUE);
3747+
item= *(it.ref()); // it can be changed by fix_fields
3748+
DBUG_ASSERT(!item->name_length || item->name_length == strlen(item->name));
3749+
sjm->sjm_table_cols.push_back(item, thd->mem_root);
3750+
}
37433751

37443752
sjm->sjm_table_param.field_count= subq_select->item_list.elements;
37453753
sjm->sjm_table_param.force_not_null_cols= TRUE;

0 commit comments

Comments
 (0)