From 106f0b5798a2b5d13b7d67c3cc678fc0cc2184c2 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 5 Jun 2018 10:25:39 +0400 Subject: 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; --- sql/unireg.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'sql/unireg.cc') diff --git a/sql/unireg.cc b/sql/unireg.cc index a9b47c72a4f..6540e11578b 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -1082,9 +1082,8 @@ static bool make_empty_rec(THD *thd, uchar *buff, uint table_options, field->real_field_type() == MYSQL_TYPE_GEOMETRY)) { Item *expr= field->default_value->expr; - - int res= !expr->fixed && // may be already fixed if ALTER TABLE - expr->fix_fields(thd, &expr); + // may be already fixed if ALTER TABLE + int res= expr->fix_fields_if_needed(thd, &expr); if (!res) res= expr->save_in_field(regfield, 1); if (!res && (field->flags & BLOB_FLAG)) -- cgit v1.2.1