Commit b04b47d2 authored by Sergey Petrunya's avatar Sergey Petrunya

BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared...

BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
- If convert_join_subqueries_to_semijoins() decides to wrap Item_in_subselect in Item_in_optimizer, 
  it should do so in prep_on_expr/prep_where, too, as long as they are present.
  There seems to be two possibilities of how we arrive in this function:
  - prep_on_expr/prep_where==NULL, and will be set later by simplify_joins()
  - prep_on_expr/prep_where!=NULL, and it is a copy_and_or_structure()-made copy of on_expr/where.
  the latter can happen for some (but not all!) nested joins. This bug was that we didn't handle this case.
parent eece9adb
......@@ -1891,4 +1891,16 @@ LIMIT 100;
drop table t1,t2, t3;
set optimizer_switch=@tmp_830993;
set join_buffer_size= @tmp_830993_jbs;
#
# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
#
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int, b int) ;
PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
EXECUTE st1;
a a
EXECUTE st1;
a a
DROP TABLE t1, t2, t3;
set optimizer_switch=@subselect_sj_tmp;
......@@ -1902,6 +1902,18 @@ LIMIT 100;
drop table t1,t2, t3;
set optimizer_switch=@tmp_830993;
set join_buffer_size= @tmp_830993_jbs;
#
# BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
#
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int, b int) ;
PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
EXECUTE st1;
a a
EXECUTE st1;
a a
DROP TABLE t1, t2, t3;
set optimizer_switch=@subselect_sj_tmp;
#
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
......
......@@ -1722,5 +1722,18 @@ drop table t1,t2, t3;
set optimizer_switch=@tmp_830993;
set join_buffer_size= @tmp_830993_jbs;
--echo #
--echo # BUG##849717: Crash in Item_func::fix_fields on second execution of a prepared statement with semijoin
--echo #
CREATE TABLE t1 (a int);
CREATE TABLE t2 (a int);
CREATE TABLE t3 (a int, b int) ;
PREPARE st1 FROM "SELECT * FROM t2 LEFT JOIN t1 ON t2.a != 0 AND ('j','r') IN ( SELECT b,a FROM t3)";
EXECUTE st1;
EXECUTE st1;
DROP TABLE t1, t2, t3;
# The following command must be the last one the file
set optimizer_switch=@subselect_sj_tmp;
......@@ -886,12 +886,6 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
do_fix_fields))
DBUG_RETURN(TRUE);
in_subq->substitution= NULL;
#if 0
/*
Don't do the following, because the simplify_join() call is after this
call, and that call will save to prep_wher/prep_on_expr.
*/
/*
If this is a prepared statement, repeat the above operation for
prep_where (or prep_on_expr). Subquery-to-semijoin conversion is
......@@ -902,12 +896,15 @@ bool convert_join_subqueries_to_semijoins(JOIN *join)
tree= (in_subq->emb_on_expr_nest == NO_JOIN_NEST)?
&join->select_lex->prep_where :
&(in_subq->emb_on_expr_nest->prep_on_expr);
if (replace_where_subcondition(join, tree, replace_me, substitute,
/*
prep_on_expr/ prep_where may be NULL in some cases.
If that is the case, do nothing - simplify_joins() will copy
ON/WHERE expression into prep_on_expr/prep_where.
*/
if (*tree && replace_where_subcondition(join, tree, replace_me, substitute,
FALSE))
DBUG_RETURN(TRUE);
}
#endif
/*
Revert to the IN->EXISTS strategy in the rare case when the subquery could
not be flattened.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment