From 8322eb0aaaf410819da5eaa95ecd5e3b6ce3c2b0 Mon Sep 17 00:00:00 2001
From: unknown <sergefp@mysql.com>
Date: Tue, 14 Dec 2004 03:36:19 +0300
Subject: [PATCH]  * Added comments and one assert  * Backport of safety
 measures from 5.0: make numeorous replaces:     s/item->fix_fields()/if
 (!item->fixed) item->fix_fields()

sql/item.cc:
   * More comments
   * Backport of safety measures from 5.0: make numeorous replaces:
      s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/item.h:
  Assert added
sql/item_cmpfunc.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/item_func.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/item_strfunc.h:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/item_subselect.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/item_sum.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/set_var.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/sql_base.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/sql_handler.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/sql_help.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
sql/sql_select.cc:
  Backport of safety measures from 5.0: make numeorous replaces:
    s/item->fix_fields()/if (!item->fixed) item->fix_fields()
---
 sql/item.cc           | 9 +++++----
 sql/item.h            | 1 +
 sql/item_cmpfunc.cc   | 6 ++++--
 sql/item_func.cc      | 4 ++--
 sql/item_strfunc.h    | 3 ++-
 sql/item_subselect.cc | 3 ++-
 sql/item_sum.cc       | 4 +++-
 sql/set_var.cc        | 6 ++++--
 sql/sql_base.cc       | 6 ++++--
 sql/sql_handler.cc    | 6 ++++--
 sql/sql_help.cc       | 3 ++-
 sql/sql_select.cc     | 3 ++-
 12 files changed, 35 insertions(+), 19 deletions(-)

diff --git a/sql/item.cc b/sql/item.cc
index aa67219ab53..92a15694e89 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -1490,8 +1490,9 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
 	}
         /*
           Here, a subset of actions performed by Item_ref::set_properties
-          is not enough. So we pass ptr to NULL into Item_[direct]_ref ctor,
-          so no initialization is performed, and call fix_fields() below.
+          is not enough. So we pass ptr to NULL into Item_[direct]_ref
+          constructor, so no initialization is performed, and call 
+          fix_fields() below.
         */
         Item *save= last->ref_pointer_array[counter];
         last->ref_pointer_array[counter]= NULL;
@@ -2291,7 +2292,7 @@ bool Item_default_value::fix_fields(THD *thd,
     fixed= 1;
     return 0;
   }
-  if (arg->fix_fields(thd, table_list, &arg))
+  if (!arg->fixed && arg->fix_fields(thd, table_list, &arg))
     return 1;
   
   if (arg->type() == REF_ITEM)
@@ -2338,7 +2339,7 @@ bool Item_insert_value::fix_fields(THD *thd,
 				   Item **items)
 {
   DBUG_ASSERT(fixed == 0);
-  if (arg->fix_fields(thd, table_list, &arg))
+  if (!arg->fixed && arg->fix_fields(thd, table_list, &arg))
     return 1;
 
   if (arg->type() == REF_ITEM)
diff --git a/sql/item.h b/sql/item.h
index 2411904a00f..71b92cd1efc 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -852,6 +852,7 @@ class Item_ref :public Item_ident
   Item_ref(Item **item, const char *table_name_par, const char *field_name_par)
     :Item_ident(NullS, table_name_par, field_name_par), ref(item)
   {
+    DBUG_ASSERT(item);
     if (*item)
       set_properties();
   }
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 26ed8f4e9c1..a135f08ae45 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -2374,8 +2374,10 @@ bool
 Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
 {
   DBUG_ASSERT(fixed == 0);
-  if (args[0]->fix_fields(thd, tables, args) || args[0]->check_cols(1) ||
-      args[1]->fix_fields(thd,tables, args + 1) || args[1]->check_cols(1))
+  if ((!args[0]->fixed &&
+       args[0]->fix_fields(thd, tables, args)) || args[0]->check_cols(1) ||
+      (!args[1]->fixed && 
+       args[1]->fix_fields(thd,tables, args + 1)) || args[1]->check_cols(1))
     return 1;					/* purecov: inspected */
   with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
   max_length= 1;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 8220db40ecb..2d939f47716 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -351,7 +351,6 @@ void Item_func::split_sum_func(THD *thd, Item **ref_pointer_array,
       uint el= fields.elements;
       ref_pointer_array[el]= item;
       Item *new_item= new Item_ref(ref_pointer_array + el, 0, item->name);
-      new_item->collation.set(item->collation);
       fields.push_front(item);
       ref_pointer_array[el]= item;
       thd->change_item_tree(arg, new_item);
@@ -1664,7 +1663,8 @@ udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
 	 arg != arg_end ;
 	 arg++,i++)
     {
-      if ((*arg)->fix_fields(thd, tables, arg))
+      if (!(*arg)->fixed && 
+          (*arg)->fix_fields(thd, tables, arg))
 	DBUG_RETURN(1);
       // we can't assign 'item' before, because fix_fields() can change arg
       Item *item= *arg;
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 8efe60bbd89..698536a61c7 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -397,7 +397,8 @@ class Item_func_make_set :public Item_str_func
   bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
   {
     DBUG_ASSERT(fixed == 0);
-    return (item->fix_fields(thd, tlist, &item) ||
+    return (!item->fixed &&
+            item->fix_fields(thd, tlist, &item) ||
 	    item->check_cols(1) ||
 	    Item_func::fix_fields(thd, tlist, ref));
   }
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index ffa3b072801..1d0f46fd196 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -766,7 +766,8 @@ Item_in_subselect::single_value_transformer(JOIN *join,
     // left expression belong to outer select
     SELECT_LEX *current= thd->lex->current_select, *up;
     thd->lex->current_select= up= current->return_after_parsing();
-    if (left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
+    if (!left_expr->fixed && 
+        left_expr->fix_fields(thd, up->get_table_list(), &left_expr))
     {
       thd->lex->current_select= current;
       goto err;
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 66d4fba205c..029a1fd6c48 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1918,7 +1918,9 @@ Item_func_group_concat::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
 
   for (i=0 ; i < arg_count ; i++)  
   {
-    if (args[i]->fix_fields(thd, tables, args + i) || args[i]->check_cols(1))
+    if ((!args[i]->fixed && 
+         args[i]->fix_fields(thd, tables, args + i)) ||
+        args[i]->check_cols(1))
       return 1;
     if (i < arg_count_field)
       maybe_null|= args[i]->maybe_null;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index b7f410c207d..d10ea3e11c1 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -2799,7 +2799,8 @@ int set_var::check(THD *thd)
     return 0;
   }
 
-  if (value->fix_fields(thd, 0, &value) || value->check_cols(1))
+  if ((!value->fixed && 
+       value->fix_fields(thd, 0, &value)) || value->check_cols(1))
     return -1;
   if (var->check_update_type(value->result_type()))
   {
@@ -2834,7 +2835,8 @@ int set_var::light_check(THD *thd)
   if (type == OPT_GLOBAL && check_global_access(thd, SUPER_ACL))
     return 1;
 
-  if (value && (value->fix_fields(thd, 0, &value) || value->check_cols(1)))
+  if (value && ((!value->fixed && value->fix_fields(thd, 0, &value)) ||
+                value->check_cols(1)))
     return -1;
   return 0;
 }
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 05b11646cd7..5c71049e565 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -2684,7 +2684,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
             thd->restore_backup_item_arena(arena, &backup);
           if (*conds && !(*conds)->fixed)
           {
-            if ((*conds)->fix_fields(thd, tables, conds))
+            if (!(*conds)->fixed && 
+                (*conds)->fix_fields(thd, tables, conds))
               DBUG_RETURN(1);
           }
         }
@@ -2696,7 +2697,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
             thd->restore_backup_item_arena(arena, &backup);
           if (table->on_expr && !table->on_expr->fixed)
           {
-            if (table->on_expr->fix_fields(thd, tables, &table->on_expr))
+            if (!table->on_expr->fixed && 
+                table->on_expr->fix_fields(thd, tables, &table->on_expr))
              DBUG_RETURN(1);
           }
         }
diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc
index f98bb0a9131..f250a00eca1 100644
--- a/sql/sql_handler.cc
+++ b/sql/sql_handler.cc
@@ -429,7 +429,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
   }
   tables->table=table;
 
-  if (cond && (cond->fix_fields(thd, tables, &cond) || cond->check_cols(1)))
+  if (cond && ((!cond->fixed && 
+              cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1)))
     goto err0;
 
   table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it
@@ -516,7 +517,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
       for (key_len=0 ; (item=it_ke++) ; key_part++)
       {
 	// 'item' can be changed by fix_fields() call
-	if (item->fix_fields(thd, tables, it_ke.ref()) ||
+	if ((!item->fixed && 
+             item->fix_fields(thd, tables, it_ke.ref())) ||
 	    (item= *it_ke.ref())->check_cols(1))
 	  goto err;
 	if (item->used_tables() & ~RAND_TABLE_BIT)
diff --git a/sql/sql_help.cc b/sql/sql_help.cc
index 04ecbbd43b9..0e0d32a922d 100644
--- a/sql/sql_help.cc
+++ b/sql/sql_help.cc
@@ -557,7 +557,8 @@ int send_variant_2_list(MEM_ROOT *mem_root, Protocol *protocol,
 SQL_SELECT *prepare_simple_select(THD *thd, Item *cond, TABLE_LIST *tables,
 				  TABLE *table, int *error)
 {
-  cond->fix_fields(thd, tables, &cond);	// can never fail
+  if (!cond->fixed)
+    cond->fix_fields(thd, tables, &cond);	// can never fail
   SQL_SELECT *res= make_select(table,0,0,cond,error);
   if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)))
   {
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f2499966815..2d701e668cf 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -8904,7 +8904,8 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
   if (thd->is_fatal_error)
     DBUG_RETURN(TRUE);
 
-  cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond);
+  if (!cond->fixed)
+    cond->fix_fields(thd,(TABLE_LIST *) 0, (Item**)&cond);
   if (join_tab->select)
   {
     error=(int) cond->add(join_tab->select->cond);
-- 
2.30.9