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
|
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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;
|
|||||||
|
|
||||||
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()
|
|||||||
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
|
|||||||
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)
|
||||||
{
|
{
|
||||||
@ -671,7 +671,16 @@ JOIN::prepare(Item ***rref_pointer_array,
|
|||||||
DBUG_RETURN(-1); /* purecov: inspected */
|
DBUG_RETURN(-1); /* purecov: inspected */
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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:
|
|||||||
}
|
}
|
||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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();
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user