summaryrefslogtreecommitdiff
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
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;
-rw-r--r--mysql-test/main/sp-row.result25
-rw-r--r--mysql-test/main/sp-row.test35
-rw-r--r--sql/item.cc24
-rw-r--r--sql/item.h23
-rw-r--r--sql/item_cmpfunc.cc12
-rw-r--r--sql/item_func.cc9
-rw-r--r--sql/item_row.cc3
-rw-r--r--sql/item_subselect.cc18
-rw-r--r--sql/item_sum.cc13
-rw-r--r--sql/item_windowfunc.cc4
-rw-r--r--sql/opt_subselect.cc24
-rw-r--r--sql/set_var.cc6
-rw-r--r--sql/sp_head.cc10
-rw-r--r--sql/sql_analyse.cc4
-rw-r--r--sql/sql_base.cc17
-rw-r--r--sql/sql_derived.cc4
-rw-r--r--sql/sql_get_diagnostics.cc3
-rw-r--r--sql/sql_handler.cc8
-rw-r--r--sql/sql_help.cc3
-rw-r--r--sql/sql_insert.cc2
-rw-r--r--sql/sql_lex.cc24
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_parse.cc8
-rw-r--r--sql/sql_partition.cc4
-rw-r--r--sql/sql_prepare.cc6
-rw-r--r--sql/sql_select.cc29
-rw-r--r--sql/sql_show.cc7
-rw-r--r--sql/sql_signal.cc13
-rw-r--r--sql/sql_trigger.cc3
-rw-r--r--sql/sql_view.cc2
-rw-r--r--sql/table.cc20
-rw-r--r--sql/unireg.cc5
32 files changed, 184 insertions, 186 deletions
diff --git a/mysql-test/main/sp-row.result b/mysql-test/main/sp-row.result
index ac09f7572c3..da8258d9ec4 100644
--- a/mysql-test/main/sp-row.result
+++ b/mysql-test/main/sp-row.result
@@ -2281,3 +2281,28 @@ t1 CREATE TABLE `t1` (
`int11` int(11) DEFAULT NULL,
`text1` text DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
+#
+# MDEV-16385 ROW SP variable is allowed in unexpected context
+#
+CREATE TABLE t1 (a INT);
+BEGIN NOT ATOMIC
+DECLARE row ROW(a INT);
+SELECT * FROM t1 ORDER BY row;
+END;
+$$
+ERROR 21000: Operand should contain 1 column(s)
+DROP TABLE t1;
+CREATE TABLE t1 (a INT);
+BEGIN NOT ATOMIC
+DECLARE row ROW(a INT);
+SELECT * FROM t1 HAVING row;
+END;
+$$
+ERROR 21000: Operand should contain 1 column(s)
+DROP TABLE t1;
+BEGIN NOT ATOMIC
+DECLARE a ROW(a INT);
+SELECT 1 LIKE 2 ESCAPE a;
+END;
+$$
+ERROR 21000: Operand should contain 1 column(s)
diff --git a/mysql-test/main/sp-row.test b/mysql-test/main/sp-row.test
index 837e24c89c0..3352c940cb6 100644
--- a/mysql-test/main/sp-row.test
+++ b/mysql-test/main/sp-row.test
@@ -1504,3 +1504,38 @@ BEGIN NOT ATOMIC
END;
$$
DELIMITER ;$$
+
+--echo #
+--echo # MDEV-16385 ROW SP variable is allowed in unexpected context
+--echo #
+
+CREATE TABLE t1 (a INT);
+DELIMITER $$;
+--error ER_OPERAND_COLUMNS
+BEGIN NOT ATOMIC
+ DECLARE row ROW(a INT);
+ SELECT * FROM t1 ORDER BY row;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT);
+DELIMITER $$;
+--error ER_OPERAND_COLUMNS
+BEGIN NOT ATOMIC
+ DECLARE row ROW(a INT);
+ SELECT * FROM t1 HAVING row;
+END;
+$$
+DELIMITER ;$$
+DROP TABLE t1;
+
+DELIMITER $$;
+--error ER_OPERAND_COLUMNS
+BEGIN NOT ATOMIC
+ DECLARE a ROW(a INT);
+ SELECT 1 LIKE 2 ESCAPE a;
+END;
+$$
+DELIMITER ;$$
diff --git a/sql/item.cc b/sql/item.cc
index 8fae773f487..dac68d1a4c7 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1827,6 +1827,7 @@ Item_field *Item_splocal::get_variable(sp_rcontext *ctx) const
bool Item_splocal::fix_fields(THD *thd, Item **ref)
{
+ DBUG_ASSERT(!fixed);
Item *item= get_variable(thd->spcont);
set_handler(item->type_handler());
return fix_fields_from_item(thd, ref, item);
@@ -1954,6 +1955,7 @@ bool Item_splocal::check_cols(uint n)
bool Item_splocal_row_field::fix_fields(THD *thd, Item **ref)
{
+ DBUG_ASSERT(!fixed);
Item *item= get_variable(thd->spcont)->element_index(m_field_idx);
return fix_fields_from_item(thd, ref, item);
}
@@ -2011,6 +2013,7 @@ bool Item_splocal_row_field::set_value(THD *thd, sp_rcontext *ctx, Item **it)
bool Item_splocal_row_field_by_name::fix_fields(THD *thd, Item **it)
{
+ DBUG_ASSERT(!fixed);
m_thd= thd;
if (get_rcontext(thd->spcont)->find_row_field_by_name_or_error(&m_field_idx,
m_var_idx,
@@ -2231,10 +2234,8 @@ bool Item_name_const::fix_fields(THD *thd, Item **ref)
String s(buf, sizeof(buf), &my_charset_bin);
s.length(0);
- if ((!value_item->fixed &&
- value_item->fix_fields(thd, &value_item)) ||
- (!name_item->fixed &&
- name_item->fix_fields(thd, &name_item)) ||
+ if (value_item->fix_fields_if_needed(thd, &value_item) ||
+ name_item->fix_fields_if_needed(thd, &name_item) ||
!value_item->const_item() ||
!name_item->const_item() ||
!(item_name= name_item->val_str(&s))) // Can't have a NULL name
@@ -9022,8 +9023,7 @@ bool Item_direct_view_ref::fix_fields(THD *thd, Item **reference)
bitmap_set_bit(fld->table->read_set, fld->field_index);
}
}
- else if (!(*ref)->fixed &&
- ((*ref)->fix_fields(thd, ref)))
+ else if ((*ref)->fix_fields_if_needed(thd, ref))
return TRUE;
if (Item_direct_ref::fix_fields(thd, reference))
@@ -9051,7 +9051,7 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
{
bool err;
/* outer_ref->check_cols() will be made in Item_direct_ref::fix_fields */
- if ((*ref) && !(*ref)->fixed && ((*ref)->fix_fields(thd, reference)))
+ if ((*ref) && (*ref)->fix_fields_if_needed(thd, reference))
return TRUE;
err= Item_direct_ref::fix_fields(thd, reference);
if (!outer_ref)
@@ -9290,7 +9290,7 @@ bool Item_default_value::fix_fields(THD *thd, Item **items)
fixed= 1;
return FALSE;
}
- if (!arg->fixed && arg->fix_fields(thd, &arg))
+ if (arg->fix_fields_if_needed(thd, &arg))
goto error;
@@ -9635,15 +9635,9 @@ bool Item_trigger_field::set_value(THD *thd, sp_rcontext * /*ctx*/, Item **it)
{
Item *item= thd->sp_prepare_func_item(it);
- if (!item)
+ if (!item || fix_fields_if_needed(thd, NULL))
return true;
- if (!fixed)
- {
- if (fix_fields(thd, NULL))
- return true;
- }
-
// NOTE: field->table->copy_blobs should be false here, but let's
// remember the value at runtime to avoid subtle bugs.
bool copy_blobs_saved= field->table->copy_blobs;
diff --git a/sql/item.h b/sql/item.h
index dcbe41de97f..10ce987e289 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -816,6 +816,23 @@ public:
void init_make_send_field(Send_field *tmp_field,enum enum_field_types type);
virtual void cleanup();
virtual void make_send_field(THD *thd, Send_field *field);
+
+ bool fix_fields_if_needed(THD *thd, Item **ref)
+ {
+ return fixed ? false : fix_fields(thd, ref);
+ }
+ bool fix_fields_if_needed_for_scalar(THD *thd, Item **ref)
+ {
+ return fix_fields_if_needed(thd, ref) || check_cols(1);
+ }
+ bool fix_fields_if_needed_for_bool(THD *thd, Item **ref)
+ {
+ return fix_fields_if_needed_for_scalar(thd, ref);
+ }
+ bool fix_fields_if_needed_for_order_by(THD *thd, Item **ref)
+ {
+ return fix_fields_if_needed_for_scalar(thd, ref);
+ }
virtual bool fix_fields(THD *, Item **);
/*
Fix after some tables has been pulled out. Basically re-calculate all
@@ -4941,8 +4958,7 @@ public:
bool fix_fields(THD *thd, Item **it)
{
- if ((!(*ref)->fixed && (*ref)->fix_fields(thd, ref)) ||
- (*ref)->check_cols(1))
+ if ((*ref)->fix_fields_if_needed_for_scalar(thd, ref))
return TRUE;
return Item_ref::fix_fields(thd, it);
}
@@ -4980,8 +4996,7 @@ public:
bool fix_fields(THD *thd, Item **it)
{
DBUG_ASSERT(ident->type() == FIELD_ITEM || ident->type() == REF_ITEM);
- if ((!ident->fixed && ident->fix_fields(thd, ref)) ||
- ident->check_cols(1))
+ if (ident->fix_fields_if_needed_for_scalar(thd, ref))
return TRUE;
set_properties();
return FALSE;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 76f4788c1cf..3034636dca3 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1242,7 +1242,7 @@ bool Item_in_optimizer::fix_left(THD *thd)
ref0= &(((Item_in_subselect *)args[1])->left_expr);
args[0]= ((Item_in_subselect *)args[1])->left_expr;
}
- if ((!(*ref0)->fixed && (*ref0)->fix_fields(thd, ref0)) ||
+ if ((*ref0)->fix_fields_if_needed(thd, ref0) ||
(!cache && !(cache= (*ref0)->get_cache(thd))))
DBUG_RETURN(1);
/*
@@ -1327,7 +1327,7 @@ bool Item_in_optimizer::fix_fields(THD *thd, Item **ref)
if (args[0]->maybe_null)
maybe_null=1;
- if (!args[1]->fixed && args[1]->fix_fields(thd, args+1))
+ if (args[1]->fix_fields_if_needed(thd, args + 1))
return TRUE;
if (!invisible_mode() &&
((sub && ((col= args[0]->cols()) != sub->engine->cols())) ||
@@ -4586,11 +4586,9 @@ Item_cond::fix_fields(THD *thd, Item **ref)
thd->restore_active_arena(arena, &backup);
}
- // item can be substituted in fix_fields
- if ((!item->fixed &&
- item->fix_fields(thd, li.ref())) ||
- (item= *li.ref())->check_cols(1))
+ if (item->fix_fields_if_needed_for_bool(thd, li.ref()))
return TRUE; /* purecov: inspected */
+ item= *li.ref(); // item can be substituted in fix_fields
used_tables_cache|= item->used_tables();
if (item->const_item() && !item->with_param &&
!item->is_expensive() && !cond_has_datetime_is_null(item))
@@ -5306,7 +5304,7 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref)
{
DBUG_ASSERT(fixed == 0);
if (Item_bool_func2::fix_fields(thd, ref) ||
- escape_item->fix_fields(thd, &escape_item) ||
+ escape_item->fix_fields_if_needed_for_scalar(thd, &escape_item) ||
fix_escape_item(thd, escape_item, &cmp_value1, escape_used_in_parsing,
cmp_collation.collation, &escape))
return TRUE;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index c291e897957..567c813de3c 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -360,7 +360,7 @@ Item_func::fix_fields(THD *thd, Item **ref)
We can't yet set item to *arg as fix_fields may change *arg
We shouldn't call fix_fields() twice, so check 'fixed' field first
*/
- if ((!(*arg)->fixed && (*arg)->fix_fields(thd, arg)))
+ if ((*arg)->fix_fields_if_needed(thd, arg))
return TRUE; /* purecov: inspected */
item= *arg;
@@ -3279,13 +3279,10 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
arg != arg_end ;
arg++,i++)
{
- if (!(*arg)->fixed &&
- (*arg)->fix_fields(thd, arg))
- DBUG_RETURN(1);
+ if ((*arg)->fix_fields_if_needed_for_scalar(thd, arg))
+ DBUG_RETURN(true);
// we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg;
- if (item->check_cols(1))
- DBUG_RETURN(TRUE);
/*
TODO: We should think about this. It is not always
right way just to set an UDF result to return my_charset_bin
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 74ea9ecc0c2..8233ba00f06 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -41,8 +41,7 @@ bool Item_row::fix_fields(THD *thd, Item **ref)
Item **arg, **arg_end;
for (arg= args, arg_end= args + arg_count; arg != arg_end ; arg++)
{
- if (!(*arg)->fixed &&
- (*arg)->fix_fields(thd, arg))
+ if ((*arg)->fix_fields_if_needed(thd, arg))
return TRUE;
// we can't assign 'item' before, because fix_fields() can change arg
Item *item= *arg;
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 143894ad949..4280a67e356 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -302,8 +302,7 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
engine->exclude();
substitution= 0;
thd->where= "checking transformed subquery";
- if (!(*ref)->fixed)
- res= (*ref)->fix_fields(thd, ref);
+ res= (*ref)->fix_fields_if_needed(thd, ref);
goto end;
}
@@ -2181,7 +2180,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
row_value_transformer?
*/
item->name= in_additional_cond;
- if (!item->fixed && item->fix_fields(thd, 0))
+ if (item->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true);
*where_item= item;
}
@@ -2504,7 +2503,7 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
if (*where_item)
{
- if (!(*where_item)->fixed && (*where_item)->fix_fields(thd, 0))
+ if ((*where_item)->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true);
(*where_item)->top_level_item();
}
@@ -2651,7 +2650,7 @@ bool Item_in_subselect::inject_in_to_exists_cond(JOIN *join_arg)
}
where_item= and_items(thd, join_arg->conds, where_item);
- if (!where_item->fixed && where_item->fix_fields(thd, 0))
+ if (where_item->fix_fields_if_needed(thd, 0))
DBUG_RETURN(true);
// TIMOUR TODO: call optimize_cond() for the new where clause
thd->change_item_tree(&select_lex->where, where_item);
@@ -3117,7 +3116,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
exp= optimizer;
}
upper_not->arguments()[0]= exp;
- if (!exp->fixed && exp->fix_fields(thd, upper_not->arguments()))
+ if (exp->fix_fields_if_needed(thd, upper_not->arguments()))
{
res= TRUE;
goto out;
@@ -3315,8 +3314,7 @@ bool Item_in_subselect::fix_fields(THD *thd_arg, Item **ref)
}
}
- if (left_expr && !left_expr->fixed &&
- left_expr->fix_fields(thd_arg, &left_expr))
+ if (left_expr && left_expr->fix_fields_if_needed(thd_arg, &left_expr))
goto err;
else
if (Item_subselect::fix_fields(thd_arg, ref))
@@ -4999,8 +4997,8 @@ bool subselect_hash_sj_engine::init(List<Item> *tmp_columns, uint subquery_id)
Repeat name resolution for 'cond' since cond is not part of any
clause of the query, and it is not 'fixed' during JOIN::prepare.
*/
- if (semi_join_conds && !semi_join_conds->fixed &&
- semi_join_conds->fix_fields(thd, (Item**)&semi_join_conds))
+ if (semi_join_conds &&
+ semi_join_conds->fix_fields_if_needed(thd, (Item**)&semi_join_conds))
DBUG_RETURN(TRUE);
/* Let our engine reuse this query plan for materialization. */
materialize_join= materialize_engine->join;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 5c2f8ab27b7..a47f3ad941d 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1129,7 +1129,7 @@ Item_sum_num::fix_fields(THD *thd, Item **ref)
maybe_null= sum_func() != COUNT_FUNC;
for (uint i=0 ; i < arg_count ; i++)
{
- if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
+ if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
m_with_subquery|= args[i]->with_subquery();
@@ -1156,14 +1156,11 @@ Item_sum_hybrid::fix_fields(THD *thd, Item **ref)
DBUG_ENTER("Item_sum_hybrid::fix_fields");
DBUG_ASSERT(fixed == 0);
- Item *item= args[0];
-
if (init_sum_func_check(thd))
DBUG_RETURN(TRUE);
// 'item' can be changed during fix_fields
- if ((!item->fixed && item->fix_fields(thd, args)) ||
- (item= args[0])->check_cols(1))
+ if (args[0]->fix_fields_if_needed_for_scalar(thd, &args[0]))
DBUG_RETURN(TRUE);
m_with_subquery= args[0]->with_subquery();
@@ -1298,7 +1295,7 @@ Item_sum_sp::fix_fields(THD *thd, Item **ref)
for (uint i= 0 ; i < arg_count ; i++)
{
- if (args[i]->fix_fields(thd, args + i) || args[i]->check_cols(1))
+ if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
set_if_bigger(decimals, args[i]->decimals);
m_with_subquery|= args[i]->with_subquery();
@@ -3909,9 +3906,7 @@ Item_func_group_concat::fix_fields(THD *thd, Item **ref)
for (i=0 ; i < arg_count ; i++)
{
- if ((!args[i]->fixed &&
- args[i]->fix_fields(thd, args + i)) ||
- args[i]->check_cols(1))
+ if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
m_with_subquery|= args[i]->with_subquery();
with_param|= args[i]->with_param;
diff --git a/sql/item_windowfunc.cc b/sql/item_windowfunc.cc
index 85ca8b0624e..a7f8ef09f08 100644
--- a/sql/item_windowfunc.cc
+++ b/sql/item_windowfunc.cc
@@ -327,10 +327,8 @@ bool Item_sum_hybrid_simple::fix_fields(THD *thd, Item **ref)
for (uint i= 0; i < arg_count; i++)
{
- Item *item= args[i];
// 'item' can be changed during fix_fields
- if ((!item->fixed && item->fix_fields(thd, args)) ||
- (item= args[i])->check_cols(1))
+ if (args[i]->fix_fields_if_needed_for_scalar(thd, &args[i]))
return TRUE;
}
Type_std_attributes::set(args[0]);
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index a04a67c9a3f..1cfdcc9c9b2 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -620,8 +620,8 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
char const *save_where= thd->where;
thd->where= "IN/ALL/ANY subquery";
- bool failure= !in_subs->left_expr->fixed &&
- in_subs->left_expr->fix_fields(thd, &in_subs->left_expr);
+ bool failure= in_subs->left_expr->fix_fields_if_needed(thd,
+ &in_subs->left_expr);
thd->lex->current_select= current;
thd->where= save_where;
if (failure)
@@ -1666,8 +1666,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/
SELECT_LEX *save_lex= thd->lex->current_select;
thd->lex->current_select=subq_lex;
- if (!subq_pred->left_expr->fixed &&
- subq_pred->left_expr->fix_fields(thd, &subq_pred->left_expr))
+ if (subq_pred->left_expr->fix_fields_if_needed(thd, &subq_pred->left_expr))
DBUG_RETURN(TRUE);
thd->lex->current_select=save_lex;
@@ -1777,8 +1776,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
to check for this at name resolution stage, but as a legacy of IN->EXISTS
we have in here).
*/
- if (!sj_nest->sj_on_expr->fixed &&
- sj_nest->sj_on_expr->fix_fields(thd, &sj_nest->sj_on_expr))
+ if (sj_nest->sj_on_expr->fix_fields_if_needed(thd, &sj_nest->sj_on_expr))
{
DBUG_RETURN(TRUE);
}
@@ -1804,9 +1802,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
emb_tbl_nest->on_expr= and_items(thd, emb_tbl_nest->on_expr,
sj_nest->sj_on_expr);
emb_tbl_nest->on_expr->top_level_item();
- if (!emb_tbl_nest->on_expr->fixed &&
- emb_tbl_nest->on_expr->fix_fields(thd,
- &emb_tbl_nest->on_expr))
+ if (emb_tbl_nest->on_expr->fix_fields_if_needed(thd,
+ &emb_tbl_nest->on_expr))
{
DBUG_RETURN(TRUE);
}
@@ -1822,9 +1819,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/
save_lex= thd->lex->current_select;
thd->lex->current_select=parent_join->select_lex;
- if (!parent_join->conds->fixed &&
- parent_join->conds->fix_fields(thd,
- &parent_join->conds))
+ if (parent_join->conds->fix_fields_if_needed(thd, &parent_join->conds))
{
DBUG_RETURN(1);
}
@@ -3724,7 +3719,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
re-executing it will not be prepared. To use the Items from its
select list we have to prepare (fix_fields) them
*/
- if (!item->fixed && item->fix_fields(thd, it.ref()))
+ if (item->fix_fields_if_needed(thd, it.ref()))
DBUG_RETURN(TRUE);
item= *(it.ref()); // it can be changed by fix_fields
DBUG_ASSERT(!item->name.length || item->name.length == strlen(item->name.str));
@@ -5572,8 +5567,7 @@ bool setup_jtbm_semi_joins(JOIN *join, List<TABLE_LIST> *join_list,
Item *sj_conds= hash_sj_engine->semi_join_conds;
(*join_where)= and_items(thd, *join_where, sj_conds);
- if (!(*join_where)->fixed)
- (*join_where)->fix_fields(thd, join_where);
+ (*join_where)->fix_fields_if_needed(thd, join_where);
}
table->table->maybe_null= MY_TEST(join->mixed_implicit_grouping);
}
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 7bf6b9f928d..c9dfeb3e211 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -768,8 +768,7 @@ int set_var::check(THD *thd)
if (!value)
return 0;
- if ((!value->fixed &&
- value->fix_fields(thd, &value)) || value->check_cols(1))
+ if (value->fix_fields_if_needed_for_scalar(thd, &value))
return -1;
if (var->check_update_type(value))
{
@@ -803,8 +802,7 @@ int set_var::light_check(THD *thd)
if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
return 1;
- if (value && ((!value->fixed && value->fix_fields(thd, &value)) ||
- value->check_cols(1)))
+ if (value && value->fix_fields_if_needed_for_scalar(thd, &value))
return -1;
return 0;
}
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);
diff --git a/sql/sql_analyse.cc b/sql/sql_analyse.cc
index 351ddb452d8..6626a054052 100644
--- a/sql/sql_analyse.cc
+++ b/sql/sql_analyse.cc
@@ -88,7 +88,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
else if (param->next)
{
// first parameter
- if (!(*param->item)->fixed && (*param->item)->fix_fields(thd, param->item))
+ if ((*param->item)->fix_fields_if_needed(thd, param->item))
{
DBUG_PRINT("info", ("fix_fields() for the first parameter failed"));
goto err;
@@ -107,7 +107,7 @@ proc_analyse_init(THD *thd, ORDER *param, select_result *result,
goto err;
}
// second parameter
- if (!(*param->item)->fixed && (*param->item)->fix_fields(thd, param->item))
+ if ((*param->item)->fix_fields_if_needed(thd, param->item))
{
DBUG_PRINT("info", ("fix_fields() for the second parameter failed"));
goto err;
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 64427af6319..80939cbe59b 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -5641,8 +5641,7 @@ find_field_in_natural_join(THD *thd, TABLE_LIST *table_ref, const char *name, si
calls fix_fields on that item), it's just a check during table
reopening for columns that was dropped by the concurrent connection.
*/
- if (!nj_col->table_field->fixed &&
- nj_col->table_field->fix_fields(thd, &ref))
+ if (nj_col->table_field->fix_fields_if_needed(thd, &ref))
{
DBUG_PRINT("info", ("column '%s' was dropped by the concurrent connection",
nj_col->table_field->name.str));
@@ -7343,8 +7342,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
if (make_pre_fix)
pre_fix->push_back(item, thd->stmt_arena->mem_root);
- if ((!item->fixed && item->fix_fields(thd, it.ref())) ||
- (item= *(it.ref()))->check_cols(1))
+ if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
{
thd->lex->current_select->is_item_list_lookup= save_is_item_list_lookup;
thd->lex->allow_sum_func= save_allow_sum_func;
@@ -7352,6 +7350,7 @@ bool setup_fields(THD *thd, Ref_ptr_array ref_pointer_array,
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
DBUG_RETURN(TRUE); /* purecov: inspected */
}
+ item= *(it.ref()); // Item might have changed in fix_fields()
if (!ref.is_null())
{
ref[0]= item;
@@ -7982,9 +7981,8 @@ bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
{
thd->where="on clause";
embedded->on_expr->mark_as_condition_AND_part(embedded);
- if ((!embedded->on_expr->fixed &&
- embedded->on_expr->fix_fields(thd, &embedded->on_expr)) ||
- embedded->on_expr->check_cols(1))
+ if (embedded->on_expr->fix_fields_if_needed_for_bool(thd,
+ &embedded->on_expr))
return TRUE;
}
/*
@@ -7994,7 +7992,7 @@ bool setup_on_expr(THD *thd, TABLE_LIST *table, bool is_update)
if (embedded->sj_subq_pred)
{
Item **left_expr= &embedded->sj_subq_pred->left_expr;
- if (!(*left_expr)->fixed && (*left_expr)->fix_fields(thd, left_expr))
+ if ((*left_expr)->fix_fields_if_needed(thd, left_expr))
return TRUE;
}
@@ -8092,8 +8090,7 @@ int setup_conds(THD *thd, TABLE_LIST *tables, List<TABLE_LIST> &leaves,
if ((*conds)->type() == Item::FIELD_ITEM && !derived)
wrap_ident(thd, conds);
(*conds)->mark_as_condition_AND_part(NO_JOIN_NEST);
- if ((!(*conds)->fixed && (*conds)->fix_fields(thd, conds)) ||
- (*conds)->check_cols(1))
+ if ((*conds)->fix_fields_if_needed_for_bool(thd, conds))
goto err_no_arena;
}
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index b9396c092ef..6a2e956fbf3 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -465,9 +465,7 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
derived->prep_on_expr= expr->copy_andor_structure(thd);
}
if (derived->on_expr &&
- ((!derived->on_expr->fixed &&
- derived->on_expr->fix_fields(thd, &derived->on_expr)) ||
- derived->on_expr->check_cols(1)))
+ derived->on_expr->fix_fields_if_needed_for_bool(thd, &derived->on_expr))
{
res= TRUE; /* purecov: inspected */
goto exit_merge;
diff --git a/sql/sql_get_diagnostics.cc b/sql/sql_get_diagnostics.cc
index 6a3cec79160..1b64819732c 100644
--- a/sql/sql_get_diagnostics.cc
+++ b/sql/sql_get_diagnostics.cc
@@ -217,8 +217,7 @@ Condition_information::aggregate(THD *thd, const Diagnostics_area *da)
DBUG_ENTER("Condition_information::aggregate");
/* Prepare the expression for evaluation. */
- if (!m_cond_number_expr->fixed &&
- m_cond_number_expr->fix_fields(thd, &m_cond_number_expr))
+ if (m_cond_number_expr->fix_fields_if_needed(thd, &m_cond_number_expr))
DBUG_RETURN(true);
cond_number= m_cond_number_expr->val_int();
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index faf9fcbe906..c2f161d507d 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -630,8 +630,7 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
/* This can only be true for temp tables */
if (table->query_id != thd->query_id)
cond->cleanup(); // File was reopened
- if ((!cond->fixed &&
- cond->fix_fields(thd, &cond)) || cond->check_cols(1))
+ if (cond->fix_fields_if_needed_for_bool(thd, &cond))
return 1;
}
@@ -695,10 +694,9 @@ mysql_ha_fix_cond_and_key(SQL_HANDLER *handler,
{
my_bitmap_map *old_map;
/* note that 'item' can be changed by fix_fields() call */
- if ((!item->fixed &&
- item->fix_fields(thd, it_ke.ref())) ||
- (item= *it_ke.ref())->check_cols(1))
+ if (item->fix_fields_if_needed_for_scalar(thd, it_ke.ref()))
return 1;
+ item= *it_ke.ref();
if (item->used_tables() & ~(RAND_TABLE_BIT | PARAM_TABLE_BIT))
{
my_error(ER_WRONG_ARGUMENTS,MYF(0),"HANDLER ... READ");
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 085e54dbc90..aa9f3fedd6d 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -611,8 +611,7 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
TABLE *table, int *error)
{
- if (!cond->fixed)
- cond->fix_fields(thd, &cond); // can never fail
+ cond->fix_fields_if_needed(thd, &cond); // can never fail
/* Assume that no indexes cover all required fields */
table->covering_keys.clear_all();
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 4187cb19c59..a60a6f2975e 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -1317,7 +1317,7 @@ static bool check_view_insertability(THD * thd, TABLE_LIST *view)
/* check simplicity and prepare unique test of view */
for (trans= trans_start; trans != trans_end; trans++)
{
- if (!trans->item->fixed && trans->item->fix_fields(thd, &trans->item))
+ if (trans->item->fix_fields_if_needed(thd, &trans->item))
{
thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE);
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index fc1af9837a9..39cf4cd1e46 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2682,15 +2682,9 @@ ha_rows st_select_lex::get_offset()
if (offset_limit)
{
// see comment for st_select_lex::get_limit()
- bool fix_fields_successful= true;
- if (!offset_limit->fixed)
- {
- fix_fields_successful= !offset_limit->fix_fields(master_unit()->thd,
- NULL);
-
- DBUG_ASSERT(fix_fields_successful);
- }
- val= fix_fields_successful ? offset_limit->val_uint() : HA_POS_ERROR;
+ bool err= offset_limit->fix_fields_if_needed(master_unit()->thd, NULL);
+ DBUG_ASSERT(!err);
+ val= err ? HA_POS_ERROR : offset_limit->val_uint();
}
return (ha_rows)val;
@@ -2729,15 +2723,9 @@ ha_rows st_select_lex::get_limit()
fix_fields() implementation. Also added runtime check against a result
of fix_fields() in order to handle error condition in non-debug build.
*/
- bool fix_fields_successful= true;
- if (!select_limit->fixed)
- {
- fix_fields_successful= !select_limit->fix_fields(master_unit()->thd,
- NULL);
-
- DBUG_ASSERT(fix_fields_successful);
- }
- val= fix_fields_successful ? select_limit->val_uint() : HA_POS_ERROR;
+ bool err= select_limit->fix_fields_if_needed(master_unit()->thd, NULL);
+ DBUG_ASSERT(!err);
+ val= err ? HA_POS_ERROR : select_limit->val_uint();
}
return (ha_rows)val;
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e5ca2d42210..70caa3b92b9 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3328,7 +3328,7 @@ public:
List_iterator_fast<Item> param_it(prepared_stmt_params);
while (Item *param= param_it++)
{
- if (param->fix_fields(thd, 0) || param->check_cols(1))
+ if (param->fix_fields_if_needed_for_scalar(thd, 0))
return true;
}
return false;
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 46a1ad22002..a1307fb0b09 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3709,8 +3709,7 @@ mysql_execute_command(THD *thd)
Item **it= lex->value_list.head_ref();
if (!(*it)->basic_const_item() ||
- (!(*it)->fixed && (*it)->fix_fields(lex->thd, it)) ||
- (*it)->check_cols(1))
+ (*it)->fix_fields_if_needed_for_scalar(lex->thd, it))
{
my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
MYF(0));
@@ -3819,8 +3818,7 @@ mysql_execute_command(THD *thd)
goto error;
/* PURGE MASTER LOGS BEFORE 'data' */
it= (Item *)lex->value_list.head();
- if ((!it->fixed && it->fix_fields(lex->thd, &it)) ||
- it->check_cols(1))
+ if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
{
my_error(ER_WRONG_ARGUMENTS, MYF(0), "PURGE LOGS BEFORE");
goto error;
@@ -5680,7 +5678,7 @@ end_with_restore_list:
if (lex->kill_type == KILL_TYPE_ID || lex->kill_type == KILL_TYPE_QUERY)
{
Item *it= (Item *)lex->value_list.head();
- if ((!it->fixed && it->fix_fields(lex->thd, &it)) || it->check_cols(1))
+ if (it->fix_fields_if_needed_for_scalar(lex->thd, &it))
{
my_message(ER_SET_CONSTANTS_ONLY, ER_THD(thd, ER_SET_CONSTANTS_ONLY),
MYF(0));
diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc
index c0ff1c54549..ffe632d5409 100644
--- a/sql/sql_partition.cc
+++ b/sql/sql_partition.cc
@@ -146,7 +146,7 @@ Item* convert_charset_partition_constant(Item *item, CHARSET_INFO *cs)
item= item->safe_charset_converter(thd, cs);
context->table_list= NULL;
thd->where= "convert character set partition constant";
- if (!item || item->fix_fields(thd, (Item**)NULL))
+ if (item->fix_fields_if_needed(thd, (Item**)NULL))
item= NULL;
thd->where= save_where;
context->table_list= save_list;
@@ -859,7 +859,7 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func;
thd->lex->allow_sum_func= 0;
- if (likely(!(error= func_expr->fix_fields(thd, (Item**)&func_expr))))
+ if (likely(!(error= func_expr->fix_fields_if_needed(thd, (Item**)&func_expr))))
func_expr->walk(&Item::post_fix_fields_part_expr_processor, 0, NULL);
/*
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index d4c96ebc535..fd526f9a660 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1656,8 +1656,7 @@ static bool mysql_test_call_fields(Prepared_statement *stmt,
while ((item= it++))
{
- if ((!item->fixed && item->fix_fields(thd, it.ref())) ||
- item->check_cols(1))
+ if (item->fix_fields_if_needed_for_scalar(thd, it.ref()))
goto err;
}
DBUG_RETURN(FALSE);
@@ -2665,8 +2664,7 @@ end:
bool LEX::get_dynamic_sql_string(LEX_CSTRING *dst, String *buffer)
{
- if (prepared_stmt_code->fix_fields(thd, NULL) ||
- prepared_stmt_code->check_cols(1))
+ if (prepared_stmt_code->fix_fields_if_needed_for_scalar(thd, NULL))
return true;
const String *str= prepared_stmt_code->val_str(buffer);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 215803c2637..52041cca0d6 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -531,7 +531,7 @@ fix_inner_refs(THD *thd, List<Item> &all_fields, SELECT_LEX *select,
ref->outer_ref= new_ref;
ref->ref= &ref->outer_ref;
- if (!ref->fixed && ref->fix_fields(thd, 0))
+ if (ref->fix_fields_if_needed(thd, 0))
return TRUE;
thd->lex->used_tables|= item->used_tables();
thd->lex->current_select->select_list_tables|= item->used_tables();
@@ -1140,9 +1140,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
if (having->type() == Item::REF_ITEM &&
((Item_ref *)having)->ref_type() == Item_ref::REF)
wrap_ident(thd, &having);
- bool having_fix_rc= (!having->fixed &&
- (having->fix_fields(thd, &having) ||
- having->check_cols(1)));
+ bool having_fix_rc= having->fix_fields_if_needed_for_bool(thd, &having);
select_lex->having_fix_field= 0;
if (unlikely(having_fix_rc || thd->is_error()))
@@ -2667,10 +2665,10 @@ bool JOIN::add_having_as_table_cond(JOIN_TAB *tab)
sort_table_cond)))
DBUG_RETURN(true);
}
- if (tab->select->cond && !tab->select->cond->fixed)
- tab->select->cond->fix_fields(thd, 0);
- if (tab->pre_idx_push_select_cond && !tab->pre_idx_push_select_cond->fixed)
- tab->pre_idx_push_select_cond->fix_fields(thd, 0);
+ if (tab->select->cond)
+ tab->select->cond->fix_fields_if_needed(thd, 0);
+ if (tab->pre_idx_push_select_cond)
+ tab->pre_idx_push_select_cond->fix_fields_if_needed(thd, 0);
tab->select->pre_idx_push_select_cond= tab->pre_idx_push_select_cond;
tab->set_select_cond(tab->select->cond, __LINE__);
tab->select_cond->top_level_item();
@@ -9340,7 +9338,7 @@ bool JOIN::inject_cond_into_where(Item *injected_cond)
}
where_item= and_items(thd, conds, where_item);
- if (!where_item->fixed && where_item->fix_fields(thd, 0))
+ if (where_item->fix_fields_if_needed(thd, 0))
return true;
thd->change_item_tree(&select_lex->where, where_item);
select_lex->where->top_level_item();
@@ -22896,8 +22894,8 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
original field name, we should additionally check if we have conflict
for this name (in case if we would perform lookup in all tables).
*/
- if (resolution == RESOLVED_BEHIND_ALIAS && !order_item->fixed &&
- order_item->fix_fields(thd, order->item))
+ if (resolution == RESOLVED_BEHIND_ALIAS &&
+ order_item->fix_fields_if_needed_for_order_by(thd, order->item))
return TRUE;
/* Lookup the current GROUP field in the FROM clause. */
@@ -22978,11 +22976,10 @@ find_order_in_list(THD *thd, Ref_ptr_array ref_pointer_array,
We check order_item->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called.
*/
- if (!order_item->fixed &&
- (order_item->fix_fields(thd, order->item) ||
- (order_item= *order->item)->check_cols(1) ||
- thd->is_error()))
+ if (order_item->fix_fields_if_needed_for_order_by(thd, order->item) ||
+ thd->is_error())
return TRUE; /* Wrong field. */
+ order_item= *order->item; // Item can change during fix_fields()
if (!add_to_all_fields)
return FALSE;
@@ -24280,7 +24277,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
{
Item *new_cond= and_conds(thd, cond_copy,
join_tab->select->pre_idx_push_select_cond);
- if (!new_cond->fixed && new_cond->fix_fields(thd, &new_cond))
+ if (new_cond->fix_fields_if_needed(thd, &new_cond))
error= 1;
join_tab->pre_idx_push_select_cond=
join_tab->select->pre_idx_push_select_cond= new_cond;
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index f8702657be7..224e6f0e411 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -8455,8 +8455,7 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
Field_translator *end= table_list->field_translation_end;
for (transl= table_list->field_translation; transl < end; transl++)
{
- if (!transl->item->fixed &&
- transl->item->fix_fields(thd, &transl->item))
+ if (transl->item->fix_fields_if_needed(thd, &transl->item))
DBUG_RETURN(1);
}
DBUG_RETURN(0);
@@ -8473,10 +8472,8 @@ int mysql_schema_table(THD *thd, LEX *lex, TABLE_LIST *table_list)
{
transl->item= item;
transl->name= item->name;
- if (!item->fixed && item->fix_fields(thd, &transl->item))
- {
+ if (item->fix_fields_if_needed(thd, &transl->item))
DBUG_RETURN(1);
- }
}
table_list->field_translation= org_transl;
table_list->field_translation_end= transl;
diff --git a/sql/sql_signal.cc b/sql/sql_signal.cc
index 7a28ba65ba2..a92d40f6bb3 100644
--- a/sql/sql_signal.cc
+++ b/sql/sql_signal.cc
@@ -218,16 +218,9 @@ int Sql_cmd_common_signal::eval_signal_informations(THD *thd, Sql_condition *con
i <= LAST_DIAG_SET_PROPERTY;
i++)
{
- set= m_set_signal_information.m_item[i];
- if (set)
- {
- if (! set->fixed)
- {
- if (set->fix_fields(thd, & set))
- goto end;
- m_set_signal_information.m_item[i]= set;
- }
- }
+ if ((set= m_set_signal_information.m_item[i]) &&
+ set->fix_fields_if_needed(thd, &m_set_signal_information.m_item[i]))
+ goto end;
}
/*
diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc
index 6961f821a0a..df3a2dc9c04 100644
--- a/sql/sql_trigger.cc
+++ b/sql/sql_trigger.cc
@@ -797,8 +797,7 @@ bool Table_triggers_list::create_trigger(THD *thd, TABLE_LIST *tables,
*/
trg_field->setup_field(thd, table, NULL);
- if (!trg_field->fixed &&
- trg_field->fix_fields(thd, (Item **)0))
+ if (trg_field->fix_fields_if_needed(thd, (Item **)0))
DBUG_RETURN(true);
}
diff --git a/sql/sql_view.cc b/sql/sql_view.cc
index 6679334552b..783c655d007 100644
--- a/sql/sql_view.cc
+++ b/sql/sql_view.cc
@@ -1938,7 +1938,7 @@ bool check_key_in_view(THD *thd, TABLE_LIST *view)
DBUG_PRINT("info", ("thd->column_usage: %d", thd->column_usage));
for (Field_translator *fld= trans; fld < end_of_trans; fld++)
{
- if (!fld->item->fixed && fld->item->fix_fields(thd, &fld->item))
+ if (fld->item->fix_fields_if_needed(thd, &fld->item))
{
thd->column_usage= saved_column_usage;
DBUG_RETURN(TRUE);
diff --git a/sql/table.cc b/sql/table.cc
index 4bfe726980e..58e0c0a9189 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -4886,10 +4886,8 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
{
if (where->fixed)
where->update_used_tables();
- if (!where->fixed && where->fix_fields(thd, &where))
- {
+ else if (where->fix_fields(thd, &where))
DBUG_RETURN(TRUE);
- }
/*
check that it is not VIEW in which we insert with INSERT SELECT
@@ -4919,12 +4917,12 @@ bool TABLE_LIST::prep_where(THD *thd, Item **conds,
}
if (tbl == 0)
{
- if (*conds && !(*conds)->fixed)
- res= (*conds)->fix_fields(thd, conds);
+ if (*conds)
+ res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
if (!res)
*conds= and_conds(thd, *conds, where->copy_andor_structure(thd));
- if (*conds && !(*conds)->fixed && !res)
- res= (*conds)->fix_fields(thd, conds);
+ if (*conds && !res)
+ res= (*conds)->fix_fields_if_needed_for_bool(thd, conds);
}
if (arena)
thd->restore_active_arena(arena, &backup);
@@ -5071,12 +5069,8 @@ bool TABLE_LIST::prep_check_option(THD *thd, uint8 check_opt_type)
{
const char *save_where= thd->where;
thd->where= "check option";
- if ((!check_option->fixed &&
- check_option->fix_fields(thd, &check_option)) ||
- check_option->check_cols(1))
- {
+ if (check_option->fix_fields_if_needed_for_bool(thd, &check_option))
DBUG_RETURN(TRUE);
- }
thd->where= save_where;
}
DBUG_RETURN(FALSE);
@@ -8933,7 +8927,7 @@ bool Vers_history_point::resolve_unit(THD *thd)
{
if (!item)
return false;
- if (!item->fixed && item->fix_fields(thd, &item))
+ if (item->fix_fields_if_needed(thd, &item))
return true;
return item->this_item()->type_handler_for_system_time()->
Vers_history_point_resolve_unit(thd, this);
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))