diff options
-rw-r--r-- | sql/item.cc | 18 | ||||
-rw-r--r-- | sql/item.h | 35 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 3 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 15 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/item_func.h | 10 | ||||
-rw-r--r-- | sql/item_row.cc | 2 | ||||
-rw-r--r-- | sql/item_row.h | 6 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 5 | ||||
-rw-r--r-- | sql/item_strfunc.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 17 | ||||
-rw-r--r-- | sql/item_subselect.h | 10 | ||||
-rw-r--r-- | sql/item_sum.cc | 26 | ||||
-rw-r--r-- | sql/item_sum.h | 17 | ||||
-rw-r--r-- | sql/mysql_priv.h | 5 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 20 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 10 |
17 files changed, 136 insertions, 67 deletions
diff --git a/sql/item.cc b/sql/item.cc index 417f05680cf..e364f095a70 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -920,6 +920,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Item_ref *rf; *ref= rf= new Item_ref(last->ref_pointer_array + counter, + ref, (char *)table_name, (char *)field_name); if (!rf) @@ -936,7 +937,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) if (last->having_fix_field) { Item_ref *rf; - *ref= rf= new Item_ref((where->db[0]?where->db:0), + *ref= rf= new Item_ref(ref, this, + (where->db[0]?where->db:0), (char *)where->alias, (char *)field_name); if (!rf) @@ -962,6 +964,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) return 0; } +void Item_field::cleanup() +{ + Item_ident::cleanup(); + field= 0; + result_field= 0; +} void Item::init_make_field(Send_field *tmp_field, enum enum_field_types field_type) @@ -1601,6 +1609,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) } +void Item_ref::cleanup() +{ + Item_ident::cleanup(); + if (hook_ptr) + *hook_ptr= orig_item; +} + + void Item_ref::print(String *str) { if (ref && *ref) diff --git a/sql/item.h b/sql/item.h index 5def1e2b710..e1318224498 100644 --- a/sql/item.h +++ b/sql/item.h @@ -290,6 +290,7 @@ public: bool get_time(TIME *ltime); bool is_null() { return field->is_null(); } Item *get_tmp_table_item(THD *thd); + void cleanup(); friend class Item_default_value; friend class Item_insert_value; }; @@ -498,7 +499,6 @@ public: set_name(name_par,0,cs); decimals=NOT_FIXED_DEC; } - ~Item_string() {} enum Type type() const { return STRING_ITEM; } double val() { @@ -565,7 +565,6 @@ class Item_varbinary :public Item { public: Item_varbinary(const char *str,uint str_length); - ~Item_varbinary() {} enum Type type() const { return VARBIN_ITEM; } double val() { return (double) Item_varbinary::val_int(); } longlong val_int(); @@ -602,20 +601,25 @@ public: class Item_ref :public Item_ident { public: - Field *result_field; /* Save result here */ + Field *result_field; /* Save result here */ Item **ref; - Item_ref(const char *db_par, const char *table_name_par, - const char *field_name_par) - :Item_ident(db_par,table_name_par,field_name_par),ref(0) {} - 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) {} + Item **hook_ptr; /* These two to restore */ + Item *orig_item; /* things in 'cleanup()' */ + Item_ref(Item **hook, Item *original,const char *db_par, + const char *table_name_par, const char *field_name_par) + :Item_ident(db_par,table_name_par,field_name_par),ref(0), hook_ptr(hook), + orig_item(original) {} + Item_ref(Item **item, Item **hook, + const char *table_name_par, const char *field_name_par) + :Item_ident(NullS,table_name_par,field_name_par), + ref(item), hook_ptr(hook), orig_item(hook ? *hook:0) {} // Constructor need to process subselect with temporary tables (see Item) - Item_ref(THD *thd, Item_ref &item) - :Item_ident(thd, item), ref(item.ref) {} + Item_ref(THD *thd, Item_ref &item, Item **hook) + :Item_ident(thd, item), ref(item.ref), + hook_ptr(hook), orig_item(hook ? *hook : 0) {} enum Type type() const { return REF_ITEM; } bool eq(const Item *item, bool binary_cmp) const { return ref && (*ref)->eq(item, binary_cmp); } - ~Item_ref() { if (ref && (*ref) && (*ref) != this) delete *ref; } double val() { double tmp=(*ref)->val_result(); @@ -660,6 +664,7 @@ public: } Item *real_item() { return *ref; } void print(String *str); + void cleanup(); }; class Item_in_subselect; @@ -670,7 +675,7 @@ protected: public: Item_ref_null_helper(Item_in_subselect* master, Item **item, const char *table_name_par, const char *field_name_par): - Item_ref(item, table_name_par, field_name_par), owner(master) {} + Item_ref(item, NULL, table_name_par, field_name_par), owner(master) {} double val(); longlong val_int(); String* val_str(String* s); @@ -734,7 +739,6 @@ public: name=item->name; cached_field_type= item->field_type(); } - ~Item_copy_string() { delete item; } enum Type type() const { return COPY_STR_ITEM; } enum Item_result result_type () const { return STRING_RESULT; } enum_field_types field_type() const { return cached_field_type; } @@ -982,6 +986,11 @@ public: bool check_cols(uint c); bool null_inside(); void bring_value(); + void cleanup() + { + Item_cache::cleanup(); + values= 0; + } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index a79ef21e97a..4b270c6aad0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -496,7 +496,6 @@ longlong Item_func_eq::val_int() return value == 0 ? 1 : 0; } - /* Same as Item_func_eq, but NULL = NULL */ void Item_func_equal::fix_length_and_dec() @@ -1754,7 +1753,7 @@ void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - li.replace(new Item_ref(ref_pointer_array + el, 0, item->name)); + li.replace(new Item_ref(ref_pointer_array + el, li.ref(), 0, item->name)); } item->update_used_tables(); used_tables_cache|=item->used_tables(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 541bc47557d..50c5449c1ec 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -197,11 +197,19 @@ public: class Item_bool_rowready_func2 :public Item_bool_func2 { + Item *orig_a, *orig_b; /* propagate_const can change parameters */ public: - Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b) + Item_bool_rowready_func2(Item *a,Item *b) :Item_bool_func2(a,b), + orig_a(a), orig_b(b) { allowed_arg_cols= a->cols(); } + void cleanup() + { + Item_bool_func2::cleanup(); + tmp_arg[0]= orig_a; + tmp_arg[1]= orig_b; + } }; class Item_func_not :public Item_bool_func @@ -705,10 +713,6 @@ class Item_func_in :public Item_int_func } longlong val_int(); void fix_length_and_dec(); - ~Item_func_in() - { - cleanup(); /* This is not called by Item::~Item() */ - } void cleanup() { delete array; @@ -888,7 +892,6 @@ public: Item_cond(THD *thd, Item_cond &item); Item_cond(List<Item> &nlist) :Item_bool_func(), list(nlist), abort_on_null(0) {} - ~Item_cond() { list.delete_elements(); } bool add(Item *item) { return list.push_back(item); } bool fix_fields(THD *, struct st_table_list *, Item **ref); diff --git a/sql/item_func.cc b/sql/item_func.cc index a251be402ce..33c443ac1c5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -252,7 +252,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - *arg= new Item_ref(ref_pointer_array + el, 0, item->name); + *arg= new Item_ref(ref_pointer_array + el, arg, 0, item->name); } } } diff --git a/sql/item_func.h b/sql/item_func.h index ac67b5a4065..634880db7ad 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -107,7 +107,6 @@ public: Item_func(List<Item> &list); // Constructor used for Item_cond_and/or (see Item comment) Item_func(THD *thd, Item_func &item); - ~Item_func() {} /* Nothing to do; Items are freed automaticly */ bool fix_fields(THD *,struct st_table_list *, Item **ref); table_map used_tables() const; table_map not_null_tables() const; @@ -755,7 +754,6 @@ public: Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {} Item_udf_func(udf_func *udf_arg, List<Item> &list) :Item_func(list), udf(udf_arg) {} - ~Item_udf_func() {} const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) { @@ -776,7 +774,6 @@ class Item_func_udf_float :public Item_udf_func Item_func_udf_float(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_float() {} longlong val_int() { return (longlong) Item_func_udf_float::val(); } double val(); String *val_str(String *str); @@ -790,7 +787,6 @@ public: Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_int() {} longlong val_int(); double val() { return (double) Item_func_udf_int::val_int(); } String *val_str(String *str); @@ -805,7 +801,6 @@ public: Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_udf_func(udf_arg,list) {} - ~Item_func_udf_str() {} String *val_str(String *); double val() { @@ -830,7 +825,6 @@ class Item_func_udf_float :public Item_real_func public: Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} Item_func_udf_float(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {} - ~Item_func_udf_float() {} double val() { return 0.0; } }; @@ -840,7 +834,6 @@ class Item_func_udf_int :public Item_int_func public: Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {} Item_func_udf_int(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {} - ~Item_func_udf_int() {} longlong val_int() { return 0; } }; @@ -850,7 +843,6 @@ class Item_func_udf_str :public Item_func public: Item_func_udf_str(udf_func *udf_arg) :Item_func() {} Item_func_udf_str(udf_func *udf_arg, List<Item> &list) :Item_func(list) {} - ~Item_func_udf_str() {} String *val_str(String *) { null_value=1; return 0; } double val() { null_value=1; return 0.0; } longlong val_int() { null_value=1; return 0; } @@ -997,7 +989,7 @@ public: Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b), join_key(0), ft_handler(0), table(0), master(0), concat(0) { } - ~Item_func_match() + void cleanup() { if (!master && ft_handler) { diff --git a/sql/item_row.cc b/sql/item_row.cc index 89b38c8a753..7f847bd1d4e 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -91,7 +91,7 @@ void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields) uint el= fields.elements; fields.push_front(*arg); ref_pointer_array[el]= *arg; - *arg= new Item_ref(ref_pointer_array + el, 0, (*arg)->name); + *arg= new Item_ref(ref_pointer_array + el, arg, 0, (*arg)->name); } } } diff --git a/sql/item_row.h b/sql/item_row.h index a09bd1a2c31..1b792f981fd 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -34,10 +34,14 @@ public: with_null(0) {} - ~Item_row() + void cleanup() { if (array_holder && items) + { sql_element_free(items); + items= 0; + array_holder= 0; + } } enum Type type() const { return ROW_ITEM; }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 3cb03d7ea49..b4580c79f9c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -616,7 +616,8 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, uint el= fields.elements; fields.push_front(separator); ref_pointer_array[el]= separator; - separator= new Item_ref(ref_pointer_array + el, 0, separator->name); + separator= new Item_ref(ref_pointer_array + el, + &separator, 0, separator->name); } Item_str_func::split_sum_func(ref_pointer_array, fields); } @@ -1709,7 +1710,7 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array, uint el= fields.elements; fields.push_front(item); ref_pointer_array[el]= item; - item= new Item_ref(ref_pointer_array + el, 0, item->name); + item= new Item_ref(ref_pointer_array + el, &item, 0, item->name); } Item_str_func::split_sum_func(ref_pointer_array, fields); } diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index 40b00cdd488..fd0afb19726 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -95,7 +95,6 @@ class Item_func_concat_ws :public Item_str_func public: Item_func_concat_ws(Item *a,List<Item> &list) :Item_str_func(list),separator(a) {} - ~Item_func_concat_ws() { delete separator; } String *val_str(String *); void fix_length_and_dec(); void update_used_tables(); @@ -409,7 +408,6 @@ class Item_func_make_set :public Item_str_func public: Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} - ~Item_func_make_set() { delete item; } String *val_str(String *str); bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 43775e1c96c..e0d9bcf3bd6 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -63,6 +63,11 @@ void Item_subselect::init(st_select_lex *select_lex, DBUG_VOID_RETURN; } +void Item_subselect::cleanup() +{ + Item_result_field::cleanup(); + engine->cleanup(); +} Item_subselect::~Item_subselect() { @@ -641,7 +646,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, As far as Item_ref_in_optimizer do not substitude itself on fix_fields we can use same item for all selects. */ - expr= new Item_ref((Item**)optimizer->get_cache(), + expr= new Item_ref((Item**)optimizer->get_cache(), + NULL, (char *)"<no matter>", (char *)in_left_expr_name); @@ -791,7 +797,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) (char *) "<list ref>"); func= eq_creator.create(new Item_ref((*optimizer->get_cache())-> - addr(i), + addr(i), + NULL, (char *)"<no matter>", (char *)in_left_expr_name), func); @@ -889,6 +896,12 @@ subselect_single_select_engine(st_select_lex *select, this->select_lex= select_lex; } +void subselect_single_select_engine::cleanup() +{ + prepared= 0; + optimized= 0; + executed= 0; +} subselect_union_engine::subselect_union_engine(st_select_lex_unit *u, select_subselect *result_arg, diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 8444dc7bf66..dc3d07540da 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -69,6 +69,7 @@ public: select_subselect *result); ~Item_subselect(); + void cleanup(); virtual void reset() { null_value= 1; @@ -199,6 +200,13 @@ public: {} + void cleanup() + { + Item_exists_subselect::cleanup(); + abort_on_null= 0; + transformed= 0; + upper_not= 0; + } subs_type substype() { return IN_SUBS; } void reset() { @@ -261,6 +269,7 @@ public: maybe_null= 0; } virtual ~subselect_engine() {}; // to satisfy compiler + virtual void cleanup() {} // set_thd should be called before prepare() void set_thd(THD *thd_arg) { thd= thd_arg; } @@ -290,6 +299,7 @@ public: subselect_single_select_engine(st_select_lex *select, select_subselect *result, Item_subselect *item); + void cleanup(); int prepare(); void fix_length_and_dec(Item_cache** row); int exec(); diff --git a/sql/item_sum.cc b/sql/item_sum.cc index f187650515a..84d00ce8732 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1082,8 +1082,9 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)), } -Item_sum_count_distinct::~Item_sum_count_distinct() +void Item_sum_count_distinct::cleanup() { + Item_sum_int::cleanup(); /* Free table and tree if they belong to this item (if item have not pointer to original item from which was made copy => it own its objects ) @@ -1095,6 +1096,7 @@ Item_sum_count_distinct::~Item_sum_count_distinct() delete tmp_table_param; if (use_tree) delete_tree(tree); + table= 0; } } @@ -1661,6 +1663,23 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, } +void Item_func_group_concat::cleanup() +{ + /* + Free table and tree if they belong to this item (if item have not pointer + to original item from which was made copy => it own its objects ) + */ + if (!original) + { + THD *thd= current_thd; + if (table) + free_tmp_table(thd, table); + delete tmp_table_param; + if (tree_mode) + delete_tree(tree); + } +} + Item_func_group_concat::~Item_func_group_concat() { /* @@ -1676,11 +1695,6 @@ Item_func_group_concat::~Item_func_group_concat() sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values); warning->set_msg(thd, warn_buff); } - if (table) - free_tmp_table(thd, table); - delete tmp_table_param; - if (tree_mode) - delete_tree(tree); } } diff --git a/sql/item_sum.h b/sql/item_sum.h index 8065218df97..dd180d42011 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -58,7 +58,11 @@ public: Item_sum(List<Item> &list); //Copy constructor, need to perform subselects with temporary tables Item_sum(THD *thd, Item_sum &item); - ~Item_sum() { result_field=0; } + void cleanup() + { + Item_result_field::cleanup(); + result_field=0; + } enum Type type() const { return SUM_FUNC_ITEM; } virtual enum Sumfunctype sum_func () const=0; @@ -235,7 +239,7 @@ class Item_sum_count_distinct :public Item_sum_int rec_offset(item.rec_offset), use_tree(item.use_tree), always_null(item.always_null) {} - ~Item_sum_count_distinct(); + void cleanup(); table_map used_tables() const { return used_table_cache; } enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; } @@ -523,7 +527,6 @@ public: { quick_group=0;} Item_udf_sum(THD *thd, Item_udf_sum &item) :Item_sum(thd, item), udf(item.udf) {} - ~Item_udf_sum() {} const char *func_name() const { return udf.name(); } bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { @@ -548,7 +551,6 @@ class Item_sum_udf_float :public Item_udf_sum :Item_udf_sum(udf_arg,list) {} Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_float() {} longlong val_int() { return (longlong) Item_sum_udf_float::val(); } double val(); String *val_str(String*str); @@ -565,7 +567,6 @@ public: :Item_udf_sum(udf_arg,list) {} Item_sum_udf_int(THD *thd, Item_sum_udf_int &item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_int() {} longlong val_int(); double val() { return (double) Item_sum_udf_int::val_int(); } String *val_str(String*str); @@ -583,7 +584,6 @@ public: :Item_udf_sum(udf_arg,list) {} Item_sum_udf_str(THD *thd, Item_sum_udf_str &item) :Item_udf_sum(thd, item) {} - ~Item_sum_udf_str() {} String *val_str(String *); double val() { @@ -612,7 +612,6 @@ class Item_sum_udf_float :public Item_sum_num Item_sum_udf_float(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_float() {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } double val() { return 0.0; } void clear() {} @@ -628,7 +627,6 @@ public: Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} Item_sum_udf_int(THD *thd, Item_sum_udf_int &item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_int() {} enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } longlong val_int() { return 0; } double val() { return 0; } @@ -645,7 +643,6 @@ public: Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} Item_sum_udf_str(THD *thd, Item_sum_udf_str &item) :Item_sum_num(thd, item) {} - ~Item_sum_udf_str() {} String *val_str(String *) { null_value=1; return 0; } double val() { null_value=1; return 0.0; } longlong val_int() { null_value=1; return 0; } @@ -734,6 +731,8 @@ class Item_func_group_concat : public Item_sum quick_group= item.quick_group; }; ~Item_func_group_concat(); + void cleanup(); + enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} const char *func_name() const { return "group_concat"; } enum Type type() const { return SUM_FUNC_ITEM; } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 15a99385285..d5a521dffe7 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -759,6 +759,11 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); uint check_word(TYPELIB *lib, const char *val, const char *end, const char **end_of_word); +/* sql_parse.cc */ +void free_items(Item *item); +void cleanup_items(Item *item); + + /* External variables */ diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 5d6ab165641..dd5825f27ac 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -756,7 +756,9 @@ static bool mysql_test_select_fields(Prepared_statement *stmt, JOIN *join= new JOIN(thd, fields, select_options, result); thd->used_tables= 0; // Updated by setup_fields - if (join->prepare(&select_lex->ref_pointer_array, tables, +// if (join->prepare(&select_lex->ref_pointer_array, tables, + if (join->prepare(&select_lex->ref_pointer_array, + (TABLE_LIST*)select_lex->table_list.first, wild_num, conds, og_num, order, group, having, proc, select_lex, unit)) DBUG_RETURN(1); @@ -925,6 +927,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) sl->prep_where= sl->where; } + cleanup_items(thd->free_list); stmt->set_statement(thd); thd->set_statement(&thd->stmt_backup); @@ -975,14 +978,10 @@ void mysql_stmt_execute(THD *thd, char *packet) DBUG_VOID_RETURN; } - /* - XXX: while thd->query_id is incremented for each command, stmt->query_id - holds query_id of prepare stage. Keeping old query_id seems to be more - natural, but differs from the way prepared statements work in 4.1: - */ - /* stmt->query_id= thd->query_id; */ + stmt->query_id= thd->query_id; thd->stmt_backup.set_statement(thd); thd->set_statement(stmt); + thd->free_list= 0; /* To make sure that all runtime data is stored in its own memory root and @@ -1006,6 +1005,11 @@ void mysql_stmt_execute(THD *thd, char *packet) if (sl->prep_where) sl->where= sl->prep_where->copy_andor_structure(thd); DBUG_ASSERT(sl->join == 0); + ORDER *order; + for (order=(ORDER *)sl->group_list.first ; order ; order=order->next) + order->item= (Item **)(order+1); + for (order=(ORDER *)sl->order_list.first ; order ; order=order->next) + order->item= (Item **)(order+1); } /* @@ -1042,6 +1046,8 @@ void mysql_stmt_execute(THD *thd, char *packet) if (!(specialflag & SPECIAL_NO_PRIOR)) my_pthread_setprio(pthread_self(), WAIT_PRIOR); + free_items(thd->free_list); + cleanup_items(stmt->free_list); free_root(&thd->mem_root, MYF(0)); thd->set_statement(&thd->stmt_backup); DBUG_VOID_RETURN; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 310d8a41be2..5fee5ab13a7 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -4486,7 +4486,7 @@ simple_ident: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,NullS,$1.str) : - (Item*) new Item_ref(NullS,NullS,$1.str); + (Item*) new Item_ref(0,0, NullS,NullS,$1.str); } | ident '.' ident { @@ -4502,7 +4502,7 @@ simple_ident: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$1.str,$3.str) : - (Item*) new Item_ref(NullS,$1.str,$3.str); + (Item*) new Item_ref(0,0,NullS,$1.str,$3.str); } | '.' ident '.' ident { @@ -4518,7 +4518,7 @@ simple_ident: $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || sel->get_in_sum_expr() > 0) ? (Item*) new Item_field(NullS,$2.str,$4.str) : - (Item*) new Item_ref(NullS,$2.str,$4.str); + (Item*) new Item_ref(0,0,NullS,$2.str,$4.str); } | ident '.' ident '.' ident { @@ -4536,8 +4536,8 @@ simple_ident: (Item*) new Item_field((YYTHD->client_capabilities & CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str, $5.str) : - (Item*) new Item_ref((YYTHD->client_capabilities & - CLIENT_NO_SCHEMA ? NullS : $1.str), + (Item*) new Item_ref(0,0,(YYTHD->client_capabilities & + CLIENT_NO_SCHEMA ? NullS : $1.str), $3.str, $5.str); }; |