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.
This commit is contained in:
parent
94ad392fd8
commit
883af99e7d
@ -2407,4 +2407,9 @@ a
|
||||
200
|
||||
set optimizer_switch=@save_optimizer_switch;
|
||||
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
|
||||
|
@ -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
|
||||
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
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 a from t3 where a<t2.a*4 order by 1 desc limit 1) a
|
||||
3 1
|
||||
|
@ -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
|
||||
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
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 a from t3 where a<t2.a*4 order by 1 desc limit 1) a
|
||||
3 1
|
||||
|
@ -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
|
||||
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
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 a from t3 where a<t2.a*4 order by 1 desc limit 1) a
|
||||
3 1
|
||||
|
@ -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
|
||||
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
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 a from t3 where a<t2.a*4 order by 1 desc limit 1) a
|
||||
3 1
|
||||
|
@ -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
|
||||
NULL UNION RESULT <union1,3> ALL NULL NULL NULL NULL NULL NULL
|
||||
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 a from t3 where a<t2.a*4 order by 1 desc limit 1) a
|
||||
3 1
|
||||
|
@ -1595,4 +1595,11 @@ set optimizer_switch=@save_optimizer_switch;
|
||||
|
||||
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
|
||||
|
@ -2928,6 +2928,7 @@ int subselect_single_select_engine::prepare()
|
||||
select_lex->order_list.elements +
|
||||
select_lex->group_list.elements,
|
||||
select_lex->order_list.first,
|
||||
false,
|
||||
select_lex->group_list.first,
|
||||
select_lex->having,
|
||||
NULL, select_lex,
|
||||
|
@ -556,8 +556,8 @@ int
|
||||
JOIN::prepare(Item ***rref_pointer_array,
|
||||
TABLE_LIST *tables_init,
|
||||
uint wild_num, COND *conds_init, uint og_num,
|
||||
ORDER *order_init, ORDER *group_init,
|
||||
Item *having_init,
|
||||
ORDER *order_init, bool skip_order_by,
|
||||
ORDER *group_init, Item *having_init,
|
||||
ORDER *proc_param_init, SELECT_LEX *select_lex_arg,
|
||||
SELECT_LEX_UNIT *unit_arg)
|
||||
{
|
||||
@ -671,7 +671,16 @@ JOIN::prepare(Item ***rref_pointer_array,
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
|
||||
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)
|
||||
{
|
||||
nesting_map save_allow_sum_func= thd->lex->allow_sum_func;
|
||||
@ -2952,7 +2961,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
else
|
||||
{
|
||||
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)))
|
||||
{
|
||||
goto err;
|
||||
@ -2976,7 +2985,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array,
|
||||
thd_proc_info(thd, "init");
|
||||
thd->lex->used_tables=0;
|
||||
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)))
|
||||
{
|
||||
goto err;
|
||||
|
@ -1294,8 +1294,8 @@ public:
|
||||
}
|
||||
|
||||
int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num,
|
||||
COND *conds, uint og_num, ORDER *order, ORDER *group,
|
||||
Item *having, ORDER *proc_param, SELECT_LEX *select,
|
||||
COND *conds, uint og_num, ORDER *order, bool skip_order_by,
|
||||
ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select,
|
||||
SELECT_LEX_UNIT *unit);
|
||||
bool prepare_stage2();
|
||||
int optimize();
|
||||
|
@ -318,6 +318,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
sl->group_list.elements,
|
||||
can_skip_order_by ?
|
||||
NULL : sl->order_list.first,
|
||||
can_skip_order_by,
|
||||
sl->group_list.first,
|
||||
sl->having,
|
||||
(is_union_select ? NULL :
|
||||
@ -501,7 +502,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
|
||||
0, 0,
|
||||
global_parameters->order_list.elements, // og_num
|
||||
global_parameters->order_list.first, // order
|
||||
NULL, NULL, NULL,
|
||||
false, NULL, NULL, NULL,
|
||||
fake_select_lex, this);
|
||||
fake_select_lex->table_list.empty();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user