Commit 0dbe3dbe authored by Monty's avatar Monty

MDEV-15057 Crash when using an unknown identifier as an SP parameter

It crashed because we accessed lex->current_select when
it was a NULL, which is the case for SP parameters or
local variables.
parent c269f1d6
...@@ -8184,3 +8184,31 @@ END ...@@ -8184,3 +8184,31 @@ END
| |
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
#
# MDEV-15057 Crash when using an unknown identifier as an SP parameter
#
CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT 1;
CALL p1(a);
ERROR 42S22: Unknown column 'a' in 'field list'
drop procedure p1;
CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT a|
CREATE OR REPLACE PROCEDURE p2 ()
BEGIN
DECLARE name VARCHAR(10);
SET name="hello";
call p1(name);
END|
CREATE OR REPLACE PROCEDURE p3 ()
BEGIN
DECLARE name VARCHAR(10);
SET name="hello";
call p1(name2);
END|
call p2();
a
hello
call p3();
ERROR 42S22: Unknown column 'name2' in 'field list'
drop procedure p1;
drop procedure p2;
drop procedure p3;
...@@ -9658,3 +9658,36 @@ DELIMITER ;| ...@@ -9658,3 +9658,36 @@ DELIMITER ;|
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
--echo #
--echo # MDEV-15057 Crash when using an unknown identifier as an SP parameter
--echo #
CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT 1;
--error ER_BAD_FIELD_ERROR
CALL p1(a);
drop procedure p1;
DELIMITER |;
CREATE OR REPLACE PROCEDURE p1 (a VARCHAR(10)) SELECT a|
CREATE OR REPLACE PROCEDURE p2 ()
BEGIN
DECLARE name VARCHAR(10);
SET name="hello";
call p1(name);
END|
CREATE OR REPLACE PROCEDURE p3 ()
BEGIN
DECLARE name VARCHAR(10);
SET name="hello";
call p1(name2);
END|
DELIMITER ;|
call p2();
--error ER_BAD_FIELD_ERROR
call p3();
drop procedure p1;
drop procedure p2;
drop procedure p3;
...@@ -5132,7 +5132,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference) ...@@ -5132,7 +5132,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/ */
Name_resolution_context *last_checked_context= context; Name_resolution_context *last_checked_context= context;
Item **ref= (Item **) not_found_item; Item **ref= (Item **) not_found_item;
SELECT_LEX *current_sel= (SELECT_LEX *) thd->lex->current_select; SELECT_LEX *current_sel= thd->lex->current_select;
Name_resolution_context *outer_context= 0; Name_resolution_context *outer_context= 0;
SELECT_LEX *select= 0; SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */ /* Currently derived tables cannot be correlated */
...@@ -5465,6 +5465,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5465,6 +5465,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0); DBUG_ASSERT(fixed == 0);
Field *from_field= (Field *)not_found_field; Field *from_field= (Field *)not_found_field;
bool outer_fixed= false; bool outer_fixed= false;
SELECT_LEX *select= thd->lex->current_select;
if (!field) // If field is not checked if (!field) // If field is not checked
{ {
...@@ -5486,13 +5487,14 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5486,13 +5487,14 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
not_found_field) not_found_field)
{ {
int ret; int ret;
/* Look up in current select's item_list to find aliased fields */ /* Look up in current select's item_list to find aliased fields */
if (thd->lex->current_select->is_item_list_lookup) if (select && select->is_item_list_lookup)
{ {
uint counter; uint counter;
enum_resolution_type resolution; enum_resolution_type resolution;
Item** res= find_item_in_list(this, Item** res= find_item_in_list(this,
thd->lex->current_select->item_list, select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND, &counter, REPORT_EXCEPT_NOT_FOUND,
&resolution); &resolution);
if (!res) if (!res)
...@@ -5524,7 +5526,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5524,7 +5526,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where We can not "move" aggregate function in the place where
its arguments are not defined. its arguments are not defined.
*/ */
set_max_sum_func_level(thd, thd->lex->current_select); set_max_sum_func_level(thd, select);
set_field(new_field); set_field(new_field);
return 0; return 0;
} }
...@@ -5544,7 +5546,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5544,7 +5546,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (err) if (err)
return TRUE; return TRUE;
SELECT_LEX *select= thd->lex->current_select;
thd->change_item_tree(reference, thd->change_item_tree(reference,
select->context_analysis_place == IN_GROUP_BY && select->context_analysis_place == IN_GROUP_BY &&
alias_name_used ? *rf->ref : rf); alias_name_used ? *rf->ref : rf);
...@@ -5553,11 +5554,17 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5553,11 +5554,17 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where We can not "move" aggregate function in the place where
its arguments are not defined. its arguments are not defined.
*/ */
set_max_sum_func_level(thd, thd->lex->current_select); set_max_sum_func_level(thd, select);
return FALSE; return FALSE;
} }
} }
} }
if (!select)
{
my_error(ER_BAD_FIELD_ERROR, MYF(0), full_name(), thd->where);
goto error;
}
if ((ret= fix_outer_field(thd, &from_field, reference)) < 0) if ((ret= fix_outer_field(thd, &from_field, reference)) < 0)
goto error; goto error;
outer_fixed= TRUE; outer_fixed= TRUE;
...@@ -5586,9 +5593,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5586,9 +5593,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (thd->lex->in_sum_func && if (thd->lex->in_sum_func &&
thd->lex->in_sum_func->nest_level == thd->lex->in_sum_func->nest_level ==
thd->lex->current_select->nest_level) select->nest_level)
set_if_bigger(thd->lex->in_sum_func->max_arg_level, set_if_bigger(thd->lex->in_sum_func->max_arg_level,
thd->lex->current_select->nest_level); select->nest_level);
/* /*
if it is not expression from merged VIEW we will set this field. if it is not expression from merged VIEW we will set this field.
...@@ -5654,11 +5661,12 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5654,11 +5661,12 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
fix_session_vcol_expr_for_read(thd, field, field->vcol_info); fix_session_vcol_expr_for_read(thd, field, field->vcol_info);
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed && !thd->lex->in_sum_func && !outer_fixed && !thd->lex->in_sum_func &&
thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS && select &&
thd->lex->current_select->join) select->cur_pos_in_select_list != UNDEF_POS &&
select->join)
{ {
thd->lex->current_select->join->non_agg_fields.push_back(this, thd->mem_root); select->join->non_agg_fields.push_back(this, thd->mem_root);
marker= thd->lex->current_select->cur_pos_in_select_list; marker= select->cur_pos_in_select_list;
} }
mark_non_agg_field: mark_non_agg_field:
/* /*
...@@ -5695,7 +5703,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference) ...@@ -5695,7 +5703,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (outer_fixed) if (outer_fixed)
thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root); thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
else if (thd->lex->in_sum_func->nest_level != else if (thd->lex->in_sum_func->nest_level !=
thd->lex->current_select->nest_level) select->nest_level)
select_lex->set_non_agg_field_used(true); select_lex->set_non_agg_field_used(true);
} }
} }
......
...@@ -2881,6 +2881,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp) ...@@ -2881,6 +2881,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
result of previous parsing. result of previous parsing.
*/ */
thd->lex->current_select= NULL; thd->lex->current_select= NULL;
thd->lex->in_sum_func= 0; // For Item_field::fix_fields()
/* /*
We never write CALL statements into binlog: We never write CALL statements into binlog:
......
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