summaryrefslogtreecommitdiff
path: root/sql/opt_subselect.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/opt_subselect.cc')
-rw-r--r--sql/opt_subselect.cc36
1 files changed, 27 insertions, 9 deletions
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index ca880e8fdaa..ebf640c2987 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -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);
}
}
- /* Fix the created equality and AND */
- if (!sj_nest->sj_on_expr->fixed)
- sj_nest->sj_on_expr->fix_fields(parent_join->thd, &sj_nest->sj_on_expr);
+ /*
+ Fix the created equality and AND
+
+ 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
@@ -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 */
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);
emb_tbl_nest->on_expr->top_level_item();
- if (!emb_tbl_nest->on_expr->fixed)
- emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
- &emb_tbl_nest->on_expr);
+ if (!emb_tbl_nest->on_expr->fixed &&
+ emb_tbl_nest->on_expr->fix_fields(parent_join->thd,
+ &emb_tbl_nest->on_expr))
+ {
+ DBUG_RETURN(TRUE);
+ }
}
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;
thd->lex->current_select=parent_join->select_lex;
- if (!parent_join->conds->fixed)
- parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
+ if (!parent_join->conds->fixed &&
+ parent_join->conds->fix_fields(parent_join->thd,
+ &parent_join->conds))
+ {
+ DBUG_RETURN(1);
+ }
thd->lex->current_select=save_lex;
parent_join->select_lex->where= parent_join->conds;
}