summaryrefslogtreecommitdiff
path: root/sql/sp_head.cc
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2018-06-05 10:25:39 +0400
committerAlexander Barkov <bar@mariadb.com>2018-06-05 10:25:39 +0400
commit106f0b5798a2b5d13b7d67c3cc678fc0cc2184c2 (patch)
tree051be6f9936bb23d3db3e3591016e09de159f19c /sql/sp_head.cc
parentb50685af82508ca1cc83e1743dff527770e6e64b (diff)
downloadmariadb-git-106f0b5798a2b5d13b7d67c3cc678fc0cc2184c2.tar.gz
MDEV-16385 ROW SP variable is allowed in unexpected context
The problem described in the bug report happened because the code did not test check_cols(1) after fix_fields() in a few places. Additionally, fix_fields() could be called multiple times for SP variables, because they are all fixed at a early stage in append_for_log(). Solution: 1. Adding a few helper methods - fix_fields_if_needed() - fix_fields_if_needed_for_scalar() - fix_fields_if_needed_for_bool() - fix_fields_if_needed_for_order_by() and using it in many cases instead of fix_fields() where the "fixed" status is not definitely known to be "false". 2. Adding DBUG_ASSERT(!fixed) into Item_splocal*::fix_fields() to catch double execution. 3. Adding tests. As a good side effect, the patch removes a lot of duplicate code (~60 lines): if (!item->fixed && item->fix_fields(..) && item->check_cols(1)) return true;
Diffstat (limited to 'sql/sp_head.cc')
-rw-r--r--sql/sp_head.cc10
1 files changed, 4 insertions, 6 deletions
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 3ec234759e3..3a9e83d9d09 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -99,7 +99,7 @@ sp_map_item_type(const Type_handler *handler)
bool Item_splocal::append_for_log(THD *thd, String *str)
{
- if (fix_fields(thd, NULL))
+ if (fix_fields_if_needed(thd, NULL))
return true;
if (limit_clause_param)
@@ -137,7 +137,7 @@ bool Item_splocal::append_value_for_log(THD *thd, String *str)
bool Item_splocal_row_field::append_for_log(THD *thd, String *str)
{
- if (fix_fields(thd, NULL))
+ if (fix_fields_if_needed(thd, NULL))
return true;
if (limit_clause_param)
@@ -373,16 +373,14 @@ Item *THD::sp_prepare_func_item(Item **it_addr, uint cols)
Item *THD::sp_fix_func_item(Item **it_addr)
{
DBUG_ENTER("THD::sp_fix_func_item");
- if (!(*it_addr)->fixed &&
- (*it_addr)->fix_fields(this, it_addr))
+ if ((*it_addr)->fix_fields_if_needed(this, it_addr))
{
DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL);
}
it_addr= (*it_addr)->this_item_addr(this, it_addr);
- if (!(*it_addr)->fixed &&
- (*it_addr)->fix_fields(this, it_addr))
+ if ((*it_addr)->fix_fields_if_needed(this, it_addr))
{
DBUG_PRINT("info", ("fix_fields() failed"));
DBUG_RETURN(NULL);