MDEV-7911: crash in Item_cond::eval_not_null_tables
convert_subq_to_sj() must check the results of in_equality->fix_fields() call. It can fail in a meaningful way when e.g. we're trying to compare columns with incompatible collations.
This commit is contained in:
parent
f1f8adf098
commit
e428c809d7
@ -2986,4 +2986,13 @@ pk1 i1 i2 c2 pk3 i3 c3
|
|||||||
SET join_cache_level=@tmp_mdev5059;
|
SET join_cache_level=@tmp_mdev5059;
|
||||||
set optimizer_switch=@tmp_os_mdev5059;
|
set optimizer_switch=@tmp_os_mdev5059;
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
#
|
||||||
|
# MDEV-7911: crash in Item_cond::eval_not_null_tables
|
||||||
|
#
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1 values(1),(2),(3),(null);
|
||||||
|
explain
|
||||||
|
select 1 from t1 where _cp932 "1" in (select '1' from t1);
|
||||||
|
ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='
|
||||||
|
drop table t1;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@ -3000,6 +3000,15 @@ pk1 i1 i2 c2 pk3 i3 c3
|
|||||||
SET join_cache_level=@tmp_mdev5059;
|
SET join_cache_level=@tmp_mdev5059;
|
||||||
set optimizer_switch=@tmp_os_mdev5059;
|
set optimizer_switch=@tmp_os_mdev5059;
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
#
|
||||||
|
# MDEV-7911: crash in Item_cond::eval_not_null_tables
|
||||||
|
#
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1 values(1),(2),(3),(null);
|
||||||
|
explain
|
||||||
|
select 1 from t1 where _cp932 "1" in (select '1' from t1);
|
||||||
|
ERROR HY000: Illegal mix of collations (cp932_japanese_ci,COERCIBLE) and (latin1_swedish_ci,COERCIBLE) for operation '='
|
||||||
|
drop table t1;
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
#
|
#
|
||||||
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
# BUG#49129: Wrong result with IN-subquery with join_cache_level=6 and firstmatch=off
|
||||||
|
@ -2689,5 +2689,16 @@ SET join_cache_level=@tmp_mdev5059;
|
|||||||
set optimizer_switch=@tmp_os_mdev5059;
|
set optimizer_switch=@tmp_os_mdev5059;
|
||||||
DROP TABLE t1,t2,t3,t4;
|
DROP TABLE t1,t2,t3,t4;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-7911: crash in Item_cond::eval_not_null_tables
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
create table t1(a int);
|
||||||
|
insert into t1 values(1),(2),(3),(null);
|
||||||
|
--error ER_CANT_AGGREGATE_2COLLATIONS
|
||||||
|
explain
|
||||||
|
select 1 from t1 where _cp932 "1" in (select '1' from t1);
|
||||||
|
drop table t1;
|
||||||
|
|
||||||
# The following command must be the last one the file
|
# The following command must be the last one the file
|
||||||
set optimizer_switch=@subselect_sj_tmp;
|
set optimizer_switch=@subselect_sj_tmp;
|
||||||
|
@ -1610,9 +1610,20 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
|
sj_nest->sj_on_expr= and_items(sj_nest->sj_on_expr, item_eq);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Fix the created equality and AND */
|
/*
|
||||||
if (!sj_nest->sj_on_expr->fixed)
|
Fix the created equality and AND
|
||||||
sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
|
|
||||||
|
Note that fix_fields() can actually fail in a meaningful way here. One
|
||||||
|
example is when the IN-equality is not valid, because it compares columns
|
||||||
|
with incompatible collations. (One can argue it would be more appropriate
|
||||||
|
to check for this at name resolution stage, but as a legacy of IN->EXISTS
|
||||||
|
we have in here).
|
||||||
|
*/
|
||||||
|
if (!sj_nest->sj_on_expr->fixed &&
|
||||||
|
sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Walk through sj nest's WHERE and ON expressions and call
|
Walk through sj nest's WHERE and ON expressions and call
|
||||||
@ -1631,12 +1642,15 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
/* Inject sj_on_expr into the parent's WHERE or ON */
|
/* Inject sj_on_expr into the parent's WHERE or ON */
|
||||||
if (emb_tbl_nest)
|
if (emb_tbl_nest)
|
||||||
{
|
{
|
||||||
emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
|
emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
|
||||||
sj_nest->sj_on_expr);
|
sj_nest->sj_on_expr);
|
||||||
emb_tbl_nest->on_expr->top_level_item();
|
emb_tbl_nest->on_expr->top_level_item();
|
||||||
if (!emb_tbl_nest->on_expr->fixed)
|
if (!emb_tbl_nest->on_expr->fixed &&
|
||||||
emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
|
emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
|
||||||
&emb_tbl_nest->on_expr);
|
&emb_tbl_nest->on_expr))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1649,8 +1663,12 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
|
|||||||
*/
|
*/
|
||||||
save_lex= thd->lex->current_select;
|
save_lex= thd->lex->current_select;
|
||||||
thd->lex->current_select=parent_join->select_lex;
|
thd->lex->current_select=parent_join->select_lex;
|
||||||
if (!parent_join->conds->fixed)
|
if (!parent_join->conds->fixed &&
|
||||||
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
|
parent_join->conds->fix_fields(parent_join->thd,
|
||||||
|
&parent_join->conds))
|
||||||
|
{
|
||||||
|
DBUG_RETURN(1);
|
||||||
|
}
|
||||||
thd->lex->current_select=save_lex;
|
thd->lex->current_select=save_lex;
|
||||||
parent_join->select_lex->where= parent_join->conds;
|
parent_join->select_lex->where= parent_join->conds;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user