Commit 883af99e authored by timour@askmonty.org's avatar timour@askmonty.org

MDEV-5104 crash in Item_field::used_tables with broken order by

Analysis:
st_select_lex_unit::prepare() computes can_skip_order_by as TRUE.
As a result join->prepare() gets called with order == NULL, and
doesn't do name resolution for the inner ORDER clause. Due to this
the prepare phase doesn't detect that the query references non-exiting
function and field.
  
Later join->optimize() calls update_used_tables() for a non-resolved
Item_field, which understandably has no Field object. This call results
in a crash.

Solution:
Resolve unnecessary ORDER BY clauses to detect if they reference non-exising
objects. Then remove such clauses from the JOIN object.
parent 94ad392f
...@@ -2407,4 +2407,9 @@ a ...@@ -2407,4 +2407,9 @@ a
200 200
set optimizer_switch=@save_optimizer_switch; set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-5104 crash in Item_field::used_tables with broken order by
#
(select 1 order by x(y)) order by 1;
ERROR 42S22: Unknown column 'y' in 'order clause'
# End of 5.3 tests # End of 5.3 tests
...@@ -193,7 +193,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -193,7 +193,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)))
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -200,7 +200,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -200,7 +200,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)))
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -196,7 +196,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -196,7 +196,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)))
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -199,7 +199,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -199,7 +199,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)))
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -196,7 +196,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra ...@@ -196,7 +196,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00 4 SUBQUERY t2 ALL NULL NULL NULL NULL 2 100.00
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
Warnings: Warnings:
Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)) order by `a`) Note 1003 (select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t2` where (`test`.`t2`.`b` = (select `test`.`t3`.`a` from `test`.`t3` order by 1 desc limit 1))) union (select `test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t4` where (`test`.`t4`.`b` = (select (max(`test`.`t2`.`a`) * 4) from `test`.`t2`)))
select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2; select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
......
...@@ -1595,4 +1595,11 @@ set optimizer_switch=@save_optimizer_switch; ...@@ -1595,4 +1595,11 @@ set optimizer_switch=@save_optimizer_switch;
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-5104 crash in Item_field::used_tables with broken order by
--echo #
--error ER_BAD_FIELD_ERROR
(select 1 order by x(y)) order by 1;
--echo # End of 5.3 tests --echo # End of 5.3 tests
...@@ -2928,6 +2928,7 @@ int subselect_single_select_engine::prepare() ...@@ -2928,6 +2928,7 @@ int subselect_single_select_engine::prepare()
select_lex->order_list.elements + select_lex->order_list.elements +
select_lex->group_list.elements, select_lex->group_list.elements,
select_lex->order_list.first, select_lex->order_list.first,
false,
select_lex->group_list.first, select_lex->group_list.first,
select_lex->having, select_lex->having,
NULL, select_lex, NULL, select_lex,
......
...@@ -556,8 +556,8 @@ int ...@@ -556,8 +556,8 @@ int
JOIN::prepare(Item ***rref_pointer_array, JOIN::prepare(Item ***rref_pointer_array,
TABLE_LIST *tables_init, TABLE_LIST *tables_init,
uint wild_num, COND *conds_init, uint og_num, uint wild_num, COND *conds_init, uint og_num,
ORDER *order_init, ORDER *group_init, ORDER *order_init, bool skip_order_by,
Item *having_init, ORDER *group_init, Item *having_init,
ORDER *proc_param_init, SELECT_LEX *select_lex_arg, ORDER *proc_param_init, SELECT_LEX *select_lex_arg,
SELECT_LEX_UNIT *unit_arg) SELECT_LEX_UNIT *unit_arg)
{ {
...@@ -672,6 +672,15 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -672,6 +672,15 @@ JOIN::prepare(Item ***rref_pointer_array,
ref_pointer_array= *rref_pointer_array; ref_pointer_array= *rref_pointer_array;
/* Resolve the ORDER BY that was skipped, then remove it. */
if (skip_order_by && select_lex != select_lex->master_unit()->global_parameters)
{
if (setup_order(thd, (*rref_pointer_array), tables_list, fields_list,
all_fields, select_lex->order_list.first))
DBUG_RETURN(-1);
select_lex->order_list.empty();
}
if (having) if (having)
{ {
nesting_map save_allow_sum_func= thd->lex->allow_sum_func; nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
...@@ -2952,7 +2961,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, ...@@ -2952,7 +2961,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
else else
{ {
if ((err= join->prepare(rref_pointer_array, tables, wild_num, if ((err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, conds, og_num, order, false, group, having,
proc_param, select_lex, unit))) proc_param, select_lex, unit)))
{ {
goto err; goto err;
...@@ -2976,7 +2985,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, ...@@ -2976,7 +2985,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
thd_proc_info(thd, "init"); thd_proc_info(thd, "init");
thd->lex->used_tables=0; thd->lex->used_tables=0;
if ((err= join->prepare(rref_pointer_array, tables, wild_num, if ((err= join->prepare(rref_pointer_array, tables, wild_num,
conds, og_num, order, group, having, proc_param, conds, og_num, order, false, group, having, proc_param,
select_lex, unit))) select_lex, unit)))
{ {
goto err; goto err;
......
...@@ -1294,8 +1294,8 @@ public: ...@@ -1294,8 +1294,8 @@ public:
} }
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
COND *conds, uint og_num, ORDER *order, ORDER *group, COND *conds, uint og_num, ORDER *order, bool skip_order_by,
Item *having, ORDER *proc_param, SELECT_LEX *select, ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select,
SELECT_LEX_UNIT *unit); SELECT_LEX_UNIT *unit);
bool prepare_stage2(); bool prepare_stage2();
int optimize(); int optimize();
......
...@@ -318,6 +318,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -318,6 +318,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
sl->group_list.elements, sl->group_list.elements,
can_skip_order_by ? can_skip_order_by ?
NULL : sl->order_list.first, NULL : sl->order_list.first,
can_skip_order_by,
sl->group_list.first, sl->group_list.first,
sl->having, sl->having,
(is_union_select ? NULL : (is_union_select ? NULL :
...@@ -501,7 +502,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -501,7 +502,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
0, 0, 0, 0,
global_parameters->order_list.elements, // og_num global_parameters->order_list.elements, // og_num
global_parameters->order_list.first, // order global_parameters->order_list.first, // order
NULL, NULL, NULL, false, NULL, NULL, NULL,
fake_select_lex, this); fake_select_lex, this);
fake_select_lex->table_list.empty(); fake_select_lex->table_list.empty();
} }
......
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