summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2018-01-24 20:37:36 +0200
committerMonty <monty@mariadb.org>2018-01-24 20:37:36 +0200
commit071f52839937bada46c53af23eb220e993c1e12d (patch)
treee53bb64e972065ba16f0374ff63cdc93922fe321
parent62740e02c8805da3bc0e04cef6933635d339dc91 (diff)
parent0dbe3dbe7929c209614ab5803084c101b433299c (diff)
downloadmariadb-git-071f52839937bada46c53af23eb220e993c1e12d.tar.gz
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Conflicts: mysql-test/r/sp.result mysql-test/t/sp.test
-rw-r--r--mysql-test/r/sp.result28
-rw-r--r--mysql-test/t/sp.test34
-rw-r--r--sql/item.cc34
-rw-r--r--sql/sql_parse.cc1
4 files changed, 84 insertions, 13 deletions
diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 527ea81c67e..911fd9dff1d 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -8186,6 +8186,34 @@ END
CALL 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;
+#
# Start of 10.3 tests
#
#
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 82ad655593a..aa960ee698e 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -9659,6 +9659,40 @@ CALL 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;
+
+--echo #
--echo # Start of 10.3 tests
--echo #
diff --git a/sql/item.cc b/sql/item.cc
index a753913a537..cc3543fe670 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -5460,7 +5460,7 @@ Item_field::fix_outer_field(THD *thd, Field **from_field, Item **reference)
*/
Name_resolution_context *last_checked_context= context;
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;
SELECT_LEX *select= 0;
/* Currently derived tables cannot be correlated */
@@ -5794,6 +5794,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
DBUG_ASSERT(fixed == 0);
Field *from_field= (Field *)not_found_field;
bool outer_fixed= false;
+ SELECT_LEX *select= thd->lex->current_select;
if (!field) // If field is not checked
{
@@ -5815,13 +5816,14 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
not_found_field)
{
int ret;
+
/* 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;
enum_resolution_type resolution;
Item** res= find_item_in_list(this,
- thd->lex->current_select->item_list,
+ select->item_list,
&counter, REPORT_EXCEPT_NOT_FOUND,
&resolution);
if (!res)
@@ -5853,7 +5855,7 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
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);
return 0;
}
@@ -5872,7 +5874,6 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (err)
return TRUE;
- SELECT_LEX *select= thd->lex->current_select;
thd->change_item_tree(reference,
select->context_analysis_place == IN_GROUP_BY &&
alias_name_used ? *rf->ref : rf);
@@ -5881,11 +5882,17 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
We can not "move" aggregate function in the place where
its arguments are not defined.
*/
- set_max_sum_func_level(thd, thd->lex->current_select);
+ set_max_sum_func_level(thd, select);
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)
goto error;
outer_fixed= TRUE;
@@ -5914,9 +5921,9 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
if (thd->lex->in_sum_func &&
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,
- thd->lex->current_select->nest_level);
+ select->nest_level);
/*
if it is not expression from merged VIEW we will set this field.
@@ -5982,11 +5989,12 @@ bool Item_field::fix_fields(THD *thd, Item **reference)
fix_session_vcol_expr_for_read(thd, field, field->vcol_info);
if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY &&
!outer_fixed && !thd->lex->in_sum_func &&
- thd->lex->current_select->cur_pos_in_select_list != UNDEF_POS &&
- thd->lex->current_select->join)
+ select &&
+ select->cur_pos_in_select_list != UNDEF_POS &&
+ select->join)
{
- thd->lex->current_select->join->non_agg_fields.push_back(this, thd->mem_root);
- marker= thd->lex->current_select->cur_pos_in_select_list;
+ select->join->non_agg_fields.push_back(this, thd->mem_root);
+ marker= select->cur_pos_in_select_list;
}
mark_non_agg_field:
/*
@@ -6023,7 +6031,7 @@ mark_non_agg_field:
if (outer_fixed)
thd->lex->in_sum_func->outer_fields.push_back(this, thd->mem_root);
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);
}
}
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index f54b768bf0c..c073adbceac 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -2903,6 +2903,7 @@ static bool do_execute_sp(THD *thd, sp_head *sp)
result of previous parsing.
*/
thd->lex->current_select= NULL;
+ thd->lex->in_sum_func= 0; // For Item_field::fix_fields()
/*
We never write CALL statements into binlog: