diff --git a/sql/item.cc b/sql/item.cc index d3d2206d02c..b4c416e7741 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -379,6 +379,12 @@ Item_field::Item_field(THD *thd, Field *f) orig_db_name= thd->strdup(db_name); orig_table_name= thd->strdup(table_name); orig_field_name= thd->strdup(field_name); + /* + We don't restore 'name' in cleanup because it's not changed + during execution. Still we need it to point to persistent + memory if this item is to be reused. + */ + name= (char*) orig_field_name; } set_field(f); } @@ -406,6 +412,20 @@ void Item_field::set_field(Field *field_par) fixed= 1; } + +/* + Reset this item to point to a field from the new temporary table. + This is used when we create a new temporary table for each execution + of prepared statement. +*/ + +void Item_field::reset_field(Field *f) +{ + set_field(f); + /* 'name' is pointing at field->field_name of old field */ + name= (char*) f->field_name; +} + const char *Item_ident::full_name() const { char *tmp; diff --git a/sql/item.h b/sql/item.h index b3142ec4b06..116dc86390c 100644 --- a/sql/item.h +++ b/sql/item.h @@ -348,6 +348,7 @@ public: class Item_field :public Item_ident { + void set_field(Field *field); public: Field *field,*result_field; @@ -369,7 +370,7 @@ public: /* If this constructor is used, fix_fields() won't work, because db_name, table_name and column_name are unknown. It's necessary to call - set_field() before fix_fields() for all fields created this way. + reset_field() before fix_fields() for all fields created this way. */ Item_field(Field *field); enum Type type() const { return FIELD_ITEM; } @@ -381,7 +382,7 @@ public: longlong val_int_result(); String *str_result(String* tmp); bool send(Protocol *protocol, String *str_arg); - void set_field(Field *field); + void reset_field(Field *f); bool fix_fields(THD *, struct st_table_list *, Item **); void make_field(Send_field *tmp_field); int save_in_field(Field *field,bool no_conversions); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index cd1127f9683..44004e1238d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -360,7 +360,7 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, { Item_field *item_field= (Item_field*) it++; DBUG_ASSERT(item_field); - item_field->set_field(*field); + item_field->reset_field(*field); } } }