Commit 367ded9f authored by unknown's avatar unknown

Fix for prepared statements

Here i added Item_*::cleanup() functions,
removed a lot of ~Item_*'s,
added code to restore order_list and group_list


sql/item.cc:
  cleanups methods implemented
  Item_ref constructors changed
sql/item.h:
  cleanups declared
  Item_ref constructors changed
  some ~Item_* deleted
sql/item_cmpfunc.cc:
  new Item_ref format
sql/item_cmpfunc.h:
  saving/restoring of the original arguments added to
  eq and equal functions
sql/item_func.cc:
  New Item_ref format
sql/item_func.h:
  destructors removed/changed to 'cleanup()'
sql/item_row.cc:
  New Item_ref format
sql/item_row.h:
  ~Item_row -> cleanup()
sql/item_strfunc.cc:
  new Item_ref format
sql/item_strfunc.h:
  destructors removed
sql/item_subselect.cc:
  Item_subselect implementation,
  new Item_ref() format
sql/item_subselect.h:
  cleanups for subselects declared
sql/item_sum.cc:
  cleanups implementations
sql/item_sum.h:
  cleanups declarations
  destructors removed
sql/mysql_priv.h:
  free_items, cleanup_items exported
sql/sql_prepare.cc:
  cleanup_items, free_items calls added
  stmt->query_id= thd->query_id restored
  cleanup procedures for group_list and order_list added
sql/sql_yacc.yy:
  New Item_ref() format
parent d5538236
...@@ -920,6 +920,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -920,6 +920,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
Item_ref *rf; Item_ref *rf;
*ref= rf= new Item_ref(last->ref_pointer_array + counter, *ref= rf= new Item_ref(last->ref_pointer_array + counter,
ref,
(char *)table_name, (char *)table_name,
(char *)field_name); (char *)field_name);
if (!rf) if (!rf)
...@@ -936,7 +937,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -936,7 +937,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
if (last->having_fix_field) if (last->having_fix_field)
{ {
Item_ref *rf; 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 *)where->alias,
(char *)field_name); (char *)field_name);
if (!rf) if (!rf)
...@@ -962,6 +964,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) ...@@ -962,6 +964,12 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
return 0; return 0;
} }
void Item_field::cleanup()
{
Item_ident::cleanup();
field= 0;
result_field= 0;
}
void Item::init_make_field(Send_field *tmp_field, void Item::init_make_field(Send_field *tmp_field,
enum enum_field_types field_type) enum enum_field_types field_type)
...@@ -1601,6 +1609,14 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -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) void Item_ref::print(String *str)
{ {
if (ref && *ref) if (ref && *ref)
......
...@@ -290,6 +290,7 @@ class Item_field :public Item_ident ...@@ -290,6 +290,7 @@ class Item_field :public Item_ident
bool get_time(TIME *ltime); bool get_time(TIME *ltime);
bool is_null() { return field->is_null(); } bool is_null() { return field->is_null(); }
Item *get_tmp_table_item(THD *thd); Item *get_tmp_table_item(THD *thd);
void cleanup();
friend class Item_default_value; friend class Item_default_value;
friend class Item_insert_value; friend class Item_insert_value;
}; };
...@@ -498,7 +499,6 @@ class Item_string :public Item ...@@ -498,7 +499,6 @@ class Item_string :public Item
set_name(name_par,0,cs); set_name(name_par,0,cs);
decimals=NOT_FIXED_DEC; decimals=NOT_FIXED_DEC;
} }
~Item_string() {}
enum Type type() const { return STRING_ITEM; } enum Type type() const { return STRING_ITEM; }
double val() double val()
{ {
...@@ -565,7 +565,6 @@ class Item_varbinary :public Item ...@@ -565,7 +565,6 @@ class Item_varbinary :public Item
{ {
public: public:
Item_varbinary(const char *str,uint str_length); Item_varbinary(const char *str,uint str_length);
~Item_varbinary() {}
enum Type type() const { return VARBIN_ITEM; } enum Type type() const { return VARBIN_ITEM; }
double val() { return (double) Item_varbinary::val_int(); } double val() { return (double) Item_varbinary::val_int(); }
longlong val_int(); longlong val_int();
...@@ -602,20 +601,25 @@ class Item_result_field :public Item /* Item with result field */ ...@@ -602,20 +601,25 @@ class Item_result_field :public Item /* Item with result field */
class Item_ref :public Item_ident class Item_ref :public Item_ident
{ {
public: public:
Field *result_field; /* Save result here */ Field *result_field; /* Save result here */
Item **ref; Item **ref;
Item_ref(const char *db_par, const char *table_name_par, Item **hook_ptr; /* These two to restore */
const char *field_name_par) Item *orig_item; /* things in 'cleanup()' */
:Item_ident(db_par,table_name_par,field_name_par),ref(0) {} Item_ref(Item **hook, Item *original,const char *db_par,
Item_ref(Item **item, const char *table_name_par, const char *field_name_par) const char *table_name_par, const char *field_name_par)
:Item_ident(NullS,table_name_par,field_name_par),ref(item) {} :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) // Constructor need to process subselect with temporary tables (see Item)
Item_ref(THD *thd, Item_ref &item) Item_ref(THD *thd, Item_ref &item, Item **hook)
:Item_ident(thd, item), ref(item.ref) {} :Item_ident(thd, item), ref(item.ref),
hook_ptr(hook), orig_item(hook ? *hook : 0) {}
enum Type type() const { return REF_ITEM; } enum Type type() const { return REF_ITEM; }
bool eq(const Item *item, bool binary_cmp) const bool eq(const Item *item, bool binary_cmp) const
{ return ref && (*ref)->eq(item, binary_cmp); } { return ref && (*ref)->eq(item, binary_cmp); }
~Item_ref() { if (ref && (*ref) && (*ref) != this) delete *ref; }
double val() double val()
{ {
double tmp=(*ref)->val_result(); double tmp=(*ref)->val_result();
...@@ -660,6 +664,7 @@ class Item_ref :public Item_ident ...@@ -660,6 +664,7 @@ class Item_ref :public Item_ident
} }
Item *real_item() { return *ref; } Item *real_item() { return *ref; }
void print(String *str); void print(String *str);
void cleanup();
}; };
class Item_in_subselect; class Item_in_subselect;
...@@ -670,7 +675,7 @@ class Item_ref_null_helper: public Item_ref ...@@ -670,7 +675,7 @@ class Item_ref_null_helper: public Item_ref
public: public:
Item_ref_null_helper(Item_in_subselect* master, Item **item, Item_ref_null_helper(Item_in_subselect* master, Item **item,
const char *table_name_par, const char *field_name_par): 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(); double val();
longlong val_int(); longlong val_int();
String* val_str(String* s); String* val_str(String* s);
...@@ -734,7 +739,6 @@ class Item_copy_string :public Item ...@@ -734,7 +739,6 @@ class Item_copy_string :public Item
name=item->name; name=item->name;
cached_field_type= item->field_type(); cached_field_type= item->field_type();
} }
~Item_copy_string() { delete item; }
enum Type type() const { return COPY_STR_ITEM; } enum Type type() const { return COPY_STR_ITEM; }
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return cached_field_type; } enum_field_types field_type() const { return cached_field_type; }
...@@ -982,6 +986,11 @@ class Item_cache_row: public Item_cache ...@@ -982,6 +986,11 @@ class Item_cache_row: public Item_cache
bool check_cols(uint c); bool check_cols(uint c);
bool null_inside(); bool null_inside();
void bring_value(); void bring_value();
void cleanup()
{
Item_cache::cleanup();
values= 0;
}
}; };
......
...@@ -496,7 +496,6 @@ longlong Item_func_eq::val_int() ...@@ -496,7 +496,6 @@ longlong Item_func_eq::val_int()
return value == 0 ? 1 : 0; return value == 0 ? 1 : 0;
} }
/* Same as Item_func_eq, but NULL = NULL */ /* Same as Item_func_eq, but NULL = NULL */
void Item_func_equal::fix_length_and_dec() 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) ...@@ -1754,7 +1753,7 @@ void Item_cond::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
uint el= fields.elements; uint el= fields.elements;
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= 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(); item->update_used_tables();
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
......
...@@ -197,11 +197,19 @@ class Item_bool_func2 :public Item_int_func ...@@ -197,11 +197,19 @@ class Item_bool_func2 :public Item_int_func
class Item_bool_rowready_func2 :public Item_bool_func2 class Item_bool_rowready_func2 :public Item_bool_func2
{ {
Item *orig_a, *orig_b; /* propagate_const can change parameters */
public: 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(); 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 class Item_func_not :public Item_bool_func
...@@ -705,10 +713,6 @@ class Item_func_in :public Item_int_func ...@@ -705,10 +713,6 @@ class Item_func_in :public Item_int_func
} }
longlong val_int(); longlong val_int();
void fix_length_and_dec(); void fix_length_and_dec();
~Item_func_in()
{
cleanup(); /* This is not called by Item::~Item() */
}
void cleanup() void cleanup()
{ {
delete array; delete array;
...@@ -888,7 +892,6 @@ class Item_cond :public Item_bool_func ...@@ -888,7 +892,6 @@ class Item_cond :public Item_bool_func
Item_cond(THD *thd, Item_cond &item); Item_cond(THD *thd, Item_cond &item);
Item_cond(List<Item> &nlist) Item_cond(List<Item> &nlist)
:Item_bool_func(), list(nlist), abort_on_null(0) {} :Item_bool_func(), list(nlist), abort_on_null(0) {}
~Item_cond() { list.delete_elements(); }
bool add(Item *item) { return list.push_back(item); } bool add(Item *item) { return list.push_back(item); }
bool fix_fields(THD *, struct st_table_list *, Item **ref); bool fix_fields(THD *, struct st_table_list *, Item **ref);
......
...@@ -252,7 +252,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields) ...@@ -252,7 +252,7 @@ void Item_func::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
uint el= fields.elements; uint el= fields.elements;
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= 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);
} }
} }
} }
......
...@@ -107,7 +107,6 @@ class Item_func :public Item_result_field ...@@ -107,7 +107,6 @@ class Item_func :public Item_result_field
Item_func(List<Item> &list); Item_func(List<Item> &list);
// Constructor used for Item_cond_and/or (see Item comment) // Constructor used for Item_cond_and/or (see Item comment)
Item_func(THD *thd, Item_func &item); 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); bool fix_fields(THD *,struct st_table_list *, Item **ref);
table_map used_tables() const; table_map used_tables() const;
table_map not_null_tables() const; table_map not_null_tables() const;
...@@ -755,7 +754,6 @@ class Item_udf_func :public Item_func ...@@ -755,7 +754,6 @@ class Item_udf_func :public Item_func
Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {} Item_udf_func(udf_func *udf_arg) :Item_func(), udf(udf_arg) {}
Item_udf_func(udf_func *udf_arg, List<Item> &list) Item_udf_func(udf_func *udf_arg, List<Item> &list)
:Item_func(list), udf(udf_arg) {} :Item_func(list), udf(udf_arg) {}
~Item_udf_func() {}
const char *func_name() const { return udf.name(); } const char *func_name() const { return udf.name(); }
bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref) 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 ...@@ -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) :Item_udf_func(udf_arg) {}
Item_func_udf_float(udf_func *udf_arg, List<Item> &list) Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
:Item_udf_func(udf_arg,list) {} :Item_udf_func(udf_arg,list) {}
~Item_func_udf_float() {}
longlong val_int() { return (longlong) Item_func_udf_float::val(); } longlong val_int() { return (longlong) Item_func_udf_float::val(); }
double val(); double val();
String *val_str(String *str); String *val_str(String *str);
...@@ -790,7 +787,6 @@ class Item_func_udf_int :public Item_udf_func ...@@ -790,7 +787,6 @@ class Item_func_udf_int :public Item_udf_func
Item_func_udf_int(udf_func *udf_arg) :Item_udf_func(udf_arg) {} 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_func_udf_int(udf_func *udf_arg, List<Item> &list)
:Item_udf_func(udf_arg,list) {} :Item_udf_func(udf_arg,list) {}
~Item_func_udf_int() {}
longlong val_int(); longlong val_int();
double val() { return (double) Item_func_udf_int::val_int(); } double val() { return (double) Item_func_udf_int::val_int(); }
String *val_str(String *str); String *val_str(String *str);
...@@ -805,7 +801,6 @@ class Item_func_udf_str :public Item_udf_func ...@@ -805,7 +801,6 @@ class Item_func_udf_str :public Item_udf_func
Item_func_udf_str(udf_func *udf_arg) :Item_udf_func(udf_arg) {} 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_func_udf_str(udf_func *udf_arg, List<Item> &list)
:Item_udf_func(udf_arg,list) {} :Item_udf_func(udf_arg,list) {}
~Item_func_udf_str() {}
String *val_str(String *); String *val_str(String *);
double val() double val()
{ {
...@@ -830,7 +825,6 @@ class Item_func_udf_float :public Item_real_func ...@@ -830,7 +825,6 @@ class Item_func_udf_float :public Item_real_func
public: public:
Item_func_udf_float(udf_func *udf_arg) :Item_real_func() {} 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(udf_func *udf_arg, List<Item> &list) :Item_real_func(list) {}
~Item_func_udf_float() {}
double val() { return 0.0; } double val() { return 0.0; }
}; };
...@@ -840,7 +834,6 @@ class Item_func_udf_int :public Item_int_func ...@@ -840,7 +834,6 @@ class Item_func_udf_int :public Item_int_func
public: public:
Item_func_udf_int(udf_func *udf_arg) :Item_int_func() {} 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(udf_func *udf_arg, List<Item> &list) :Item_int_func(list) {}
~Item_func_udf_int() {}
longlong val_int() { return 0; } longlong val_int() { return 0; }
}; };
...@@ -850,7 +843,6 @@ class Item_func_udf_str :public Item_func ...@@ -850,7 +843,6 @@ class Item_func_udf_str :public Item_func
public: public:
Item_func_udf_str(udf_func *udf_arg) :Item_func() {} 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(udf_func *udf_arg, List<Item> &list) :Item_func(list) {}
~Item_func_udf_str() {}
String *val_str(String *) { null_value=1; return 0; } String *val_str(String *) { null_value=1; return 0; }
double val() { null_value=1; return 0.0; } double val() { null_value=1; return 0.0; }
longlong val_int() { null_value=1; return 0; } longlong val_int() { null_value=1; return 0; }
...@@ -997,7 +989,7 @@ class Item_func_match :public Item_real_func ...@@ -997,7 +989,7 @@ class Item_func_match :public Item_real_func
Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b), 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) { } join_key(0), ft_handler(0), table(0), master(0), concat(0) { }
~Item_func_match() void cleanup()
{ {
if (!master && ft_handler) if (!master && ft_handler)
{ {
......
...@@ -91,7 +91,7 @@ void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields) ...@@ -91,7 +91,7 @@ void Item_row::split_sum_func(Item **ref_pointer_array, List<Item> &fields)
uint el= fields.elements; uint el= fields.elements;
fields.push_front(*arg); fields.push_front(*arg);
ref_pointer_array[el]= *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);
} }
} }
} }
......
...@@ -34,10 +34,14 @@ class Item_row: public Item ...@@ -34,10 +34,14 @@ class Item_row: public Item
with_null(0) with_null(0)
{} {}
~Item_row() void cleanup()
{ {
if (array_holder && items) if (array_holder && items)
{
sql_element_free(items); sql_element_free(items);
items= 0;
array_holder= 0;
}
} }
enum Type type() const { return ROW_ITEM; }; enum Type type() const { return ROW_ITEM; };
......
...@@ -616,7 +616,8 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array, ...@@ -616,7 +616,8 @@ void Item_func_concat_ws::split_sum_func(Item **ref_pointer_array,
uint el= fields.elements; uint el= fields.elements;
fields.push_front(separator); fields.push_front(separator);
ref_pointer_array[el]= 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); 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, ...@@ -1709,7 +1710,7 @@ void Item_func_make_set::split_sum_func(Item **ref_pointer_array,
uint el= fields.elements; uint el= fields.elements;
fields.push_front(item); fields.push_front(item);
ref_pointer_array[el]= 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); Item_str_func::split_sum_func(ref_pointer_array, fields);
} }
......
...@@ -95,7 +95,6 @@ class Item_func_concat_ws :public Item_str_func ...@@ -95,7 +95,6 @@ class Item_func_concat_ws :public Item_str_func
public: public:
Item_func_concat_ws(Item *a,List<Item> &list) Item_func_concat_ws(Item *a,List<Item> &list)
:Item_str_func(list),separator(a) {} :Item_str_func(list),separator(a) {}
~Item_func_concat_ws() { delete separator; }
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
...@@ -409,7 +408,6 @@ class Item_func_make_set :public Item_str_func ...@@ -409,7 +408,6 @@ class Item_func_make_set :public Item_str_func
public: public:
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} 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); String *val_str(String *str);
bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
......
...@@ -63,6 +63,11 @@ void Item_subselect::init(st_select_lex *select_lex, ...@@ -63,6 +63,11 @@ void Item_subselect::init(st_select_lex *select_lex,
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
void Item_subselect::cleanup()
{
Item_result_field::cleanup();
engine->cleanup();
}
Item_subselect::~Item_subselect() Item_subselect::~Item_subselect()
{ {
...@@ -641,7 +646,8 @@ Item_in_subselect::single_value_transformer(JOIN *join, ...@@ -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 As far as Item_ref_in_optimizer do not substitude itself on fix_fields
we can use same item for all selects. 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 *)"<no matter>",
(char *)in_left_expr_name); (char *)in_left_expr_name);
...@@ -791,7 +797,8 @@ Item_in_subselect::row_value_transformer(JOIN *join) ...@@ -791,7 +797,8 @@ Item_in_subselect::row_value_transformer(JOIN *join)
(char *) "<list ref>"); (char *) "<list ref>");
func= func=
eq_creator.create(new Item_ref((*optimizer->get_cache())-> eq_creator.create(new Item_ref((*optimizer->get_cache())->
addr(i), addr(i),
NULL,
(char *)"<no matter>", (char *)"<no matter>",
(char *)in_left_expr_name), (char *)in_left_expr_name),
func); func);
...@@ -889,6 +896,12 @@ subselect_single_select_engine(st_select_lex *select, ...@@ -889,6 +896,12 @@ subselect_single_select_engine(st_select_lex *select,
this->select_lex= select_lex; 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, subselect_union_engine::subselect_union_engine(st_select_lex_unit *u,
select_subselect *result_arg, select_subselect *result_arg,
......
...@@ -69,6 +69,7 @@ class Item_subselect :public Item_result_field ...@@ -69,6 +69,7 @@ class Item_subselect :public Item_result_field
select_subselect *result); select_subselect *result);
~Item_subselect(); ~Item_subselect();
void cleanup();
virtual void reset() virtual void reset()
{ {
null_value= 1; null_value= 1;
...@@ -199,6 +200,13 @@ class Item_in_subselect :public Item_exists_subselect ...@@ -199,6 +200,13 @@ class Item_in_subselect :public Item_exists_subselect
{} {}
void cleanup()
{
Item_exists_subselect::cleanup();
abort_on_null= 0;
transformed= 0;
upper_not= 0;
}
subs_type substype() { return IN_SUBS; } subs_type substype() { return IN_SUBS; }
void reset() void reset()
{ {
...@@ -261,6 +269,7 @@ class subselect_engine: public Sql_alloc ...@@ -261,6 +269,7 @@ class subselect_engine: public Sql_alloc
maybe_null= 0; maybe_null= 0;
} }
virtual ~subselect_engine() {}; // to satisfy compiler virtual ~subselect_engine() {}; // to satisfy compiler
virtual void cleanup() {}
// set_thd should be called before prepare() // set_thd should be called before prepare()
void set_thd(THD *thd_arg) { thd= thd_arg; } void set_thd(THD *thd_arg) { thd= thd_arg; }
...@@ -290,6 +299,7 @@ class subselect_single_select_engine: public subselect_engine ...@@ -290,6 +299,7 @@ class subselect_single_select_engine: public subselect_engine
subselect_single_select_engine(st_select_lex *select, subselect_single_select_engine(st_select_lex *select,
select_subselect *result, select_subselect *result,
Item_subselect *item); Item_subselect *item);
void cleanup();
int prepare(); int prepare();
void fix_length_and_dec(Item_cache** row); void fix_length_and_dec(Item_cache** row);
int exec(); int exec();
......
...@@ -1082,8 +1082,9 @@ int dump_leaf(byte* key, uint32 count __attribute__((unused)), ...@@ -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 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 ) to original item from which was made copy => it own its objects )
...@@ -1095,6 +1096,7 @@ Item_sum_count_distinct::~Item_sum_count_distinct() ...@@ -1095,6 +1096,7 @@ Item_sum_count_distinct::~Item_sum_count_distinct()
delete tmp_table_param; delete tmp_table_param;
if (use_tree) if (use_tree)
delete_tree(tree); delete_tree(tree);
table= 0;
} }
} }
...@@ -1661,6 +1663,23 @@ Item_func_group_concat::Item_func_group_concat(bool is_distinct, ...@@ -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() Item_func_group_concat::~Item_func_group_concat()
{ {
/* /*
...@@ -1676,11 +1695,6 @@ 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); sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
warning->set_msg(thd, warn_buff); warning->set_msg(thd, warn_buff);
} }
if (table)
free_tmp_table(thd, table);
delete tmp_table_param;
if (tree_mode)
delete_tree(tree);
} }
} }
......
...@@ -58,7 +58,11 @@ class Item_sum :public Item_result_field ...@@ -58,7 +58,11 @@ class Item_sum :public Item_result_field
Item_sum(List<Item> &list); Item_sum(List<Item> &list);
//Copy constructor, need to perform subselects with temporary tables //Copy constructor, need to perform subselects with temporary tables
Item_sum(THD *thd, Item_sum &item); 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; } enum Type type() const { return SUM_FUNC_ITEM; }
virtual enum Sumfunctype sum_func () const=0; virtual enum Sumfunctype sum_func () const=0;
...@@ -235,7 +239,7 @@ class Item_sum_count_distinct :public Item_sum_int ...@@ -235,7 +239,7 @@ class Item_sum_count_distinct :public Item_sum_int
rec_offset(item.rec_offset), use_tree(item.use_tree), rec_offset(item.rec_offset), use_tree(item.use_tree),
always_null(item.always_null) always_null(item.always_null)
{} {}
~Item_sum_count_distinct(); void cleanup();
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; } enum Sumfunctype sum_func () const { return COUNT_DISTINCT_FUNC; }
...@@ -523,7 +527,6 @@ class Item_udf_sum : public Item_sum ...@@ -523,7 +527,6 @@ class Item_udf_sum : public Item_sum
{ quick_group=0;} { quick_group=0;}
Item_udf_sum(THD *thd, Item_udf_sum &item) Item_udf_sum(THD *thd, Item_udf_sum &item)
:Item_sum(thd, item), udf(item.udf) {} :Item_sum(thd, item), udf(item.udf) {}
~Item_udf_sum() {}
const char *func_name() const { return udf.name(); } const char *func_name() const { return udf.name(); }
bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
...@@ -548,7 +551,6 @@ class Item_sum_udf_float :public Item_udf_sum ...@@ -548,7 +551,6 @@ class Item_sum_udf_float :public Item_udf_sum
:Item_udf_sum(udf_arg,list) {} :Item_udf_sum(udf_arg,list) {}
Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
:Item_udf_sum(thd, item) {} :Item_udf_sum(thd, item) {}
~Item_sum_udf_float() {}
longlong val_int() { return (longlong) Item_sum_udf_float::val(); } longlong val_int() { return (longlong) Item_sum_udf_float::val(); }
double val(); double val();
String *val_str(String*str); String *val_str(String*str);
...@@ -565,7 +567,6 @@ class Item_sum_udf_int :public Item_udf_sum ...@@ -565,7 +567,6 @@ class Item_sum_udf_int :public Item_udf_sum
:Item_udf_sum(udf_arg,list) {} :Item_udf_sum(udf_arg,list) {}
Item_sum_udf_int(THD *thd, Item_sum_udf_int &item) Item_sum_udf_int(THD *thd, Item_sum_udf_int &item)
:Item_udf_sum(thd, item) {} :Item_udf_sum(thd, item) {}
~Item_sum_udf_int() {}
longlong val_int(); longlong val_int();
double val() { return (double) Item_sum_udf_int::val_int(); } double val() { return (double) Item_sum_udf_int::val_int(); }
String *val_str(String*str); String *val_str(String*str);
...@@ -583,7 +584,6 @@ class Item_sum_udf_str :public Item_udf_sum ...@@ -583,7 +584,6 @@ class Item_sum_udf_str :public Item_udf_sum
:Item_udf_sum(udf_arg,list) {} :Item_udf_sum(udf_arg,list) {}
Item_sum_udf_str(THD *thd, Item_sum_udf_str &item) Item_sum_udf_str(THD *thd, Item_sum_udf_str &item)
:Item_udf_sum(thd, item) {} :Item_udf_sum(thd, item) {}
~Item_sum_udf_str() {}
String *val_str(String *); String *val_str(String *);
double val() double val()
{ {
...@@ -612,7 +612,6 @@ class Item_sum_udf_float :public Item_sum_num ...@@ -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(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {}
Item_sum_udf_float(THD *thd, Item_sum_udf_float &item) Item_sum_udf_float(THD *thd, Item_sum_udf_float &item)
:Item_sum_num(thd, item) {} :Item_sum_num(thd, item) {}
~Item_sum_udf_float() {}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
double val() { return 0.0; } double val() { return 0.0; }
void clear() {} void clear() {}
...@@ -628,7 +627,6 @@ class Item_sum_udf_int :public Item_sum_num ...@@ -628,7 +627,6 @@ class Item_sum_udf_int :public Item_sum_num
Item_sum_udf_int(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} 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_udf_int(THD *thd, Item_sum_udf_int &item)
:Item_sum_num(thd, item) {} :Item_sum_num(thd, item) {}
~Item_sum_udf_int() {}
enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; } enum Sumfunctype sum_func () const { return UDF_SUM_FUNC; }
longlong val_int() { return 0; } longlong val_int() { return 0; }
double val() { return 0; } double val() { return 0; }
...@@ -645,7 +643,6 @@ class Item_sum_udf_str :public Item_sum_num ...@@ -645,7 +643,6 @@ class Item_sum_udf_str :public Item_sum_num
Item_sum_udf_str(udf_func *udf_arg, List<Item> &list) :Item_sum_num() {} 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_udf_str(THD *thd, Item_sum_udf_str &item)
:Item_sum_num(thd, item) {} :Item_sum_num(thd, item) {}
~Item_sum_udf_str() {}
String *val_str(String *) { null_value=1; return 0; } String *val_str(String *) { null_value=1; return 0; }
double val() { null_value=1; return 0.0; } double val() { null_value=1; return 0.0; }
longlong val_int() { null_value=1; return 0; } longlong val_int() { null_value=1; return 0; }
...@@ -734,6 +731,8 @@ class Item_func_group_concat : public Item_sum ...@@ -734,6 +731,8 @@ class Item_func_group_concat : public Item_sum
quick_group= item.quick_group; quick_group= item.quick_group;
}; };
~Item_func_group_concat(); ~Item_func_group_concat();
void cleanup();
enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;} enum Sumfunctype sum_func () const {return GROUP_CONCAT_FUNC;}
const char *func_name() const { return "group_concat"; } const char *func_name() const { return "group_concat"; }
enum Type type() const { return SUM_FUNC_ITEM; } enum Type type() const { return SUM_FUNC_ITEM; }
......
...@@ -759,6 +759,11 @@ uint find_type(TYPELIB *lib, const char *find, uint length, bool part_match); ...@@ -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, uint check_word(TYPELIB *lib, const char *val, const char *end,
const char **end_of_word); const char **end_of_word);
/* sql_parse.cc */
void free_items(Item *item);
void cleanup_items(Item *item);
/* /*
External variables External variables
*/ */
......
...@@ -756,7 +756,9 @@ static bool mysql_test_select_fields(Prepared_statement *stmt, ...@@ -756,7 +756,9 @@ static bool mysql_test_select_fields(Prepared_statement *stmt,
JOIN *join= new JOIN(thd, fields, select_options, result); JOIN *join= new JOIN(thd, fields, select_options, result);
thd->used_tables= 0; // Updated by setup_fields 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, wild_num, conds, og_num, order, group, having, proc,
select_lex, unit)) select_lex, unit))
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -925,6 +927,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length) ...@@ -925,6 +927,7 @@ bool mysql_stmt_prepare(THD *thd, char *packet, uint packet_length)
sl->prep_where= sl->where; sl->prep_where= sl->where;
} }
cleanup_items(thd->free_list);
stmt->set_statement(thd); stmt->set_statement(thd);
thd->set_statement(&thd->stmt_backup); thd->set_statement(&thd->stmt_backup);
...@@ -975,14 +978,10 @@ void mysql_stmt_execute(THD *thd, char *packet) ...@@ -975,14 +978,10 @@ void mysql_stmt_execute(THD *thd, char *packet)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
/* stmt->query_id= thd->query_id;
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; */
thd->stmt_backup.set_statement(thd); thd->stmt_backup.set_statement(thd);
thd->set_statement(stmt); thd->set_statement(stmt);
thd->free_list= 0;
/* /*
To make sure that all runtime data is stored in its own memory root and 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) ...@@ -1006,6 +1005,11 @@ void mysql_stmt_execute(THD *thd, char *packet)
if (sl->prep_where) if (sl->prep_where)
sl->where= sl->prep_where->copy_andor_structure(thd); sl->where= sl->prep_where->copy_andor_structure(thd);
DBUG_ASSERT(sl->join == 0); 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) ...@@ -1042,6 +1046,8 @@ void mysql_stmt_execute(THD *thd, char *packet)
if (!(specialflag & SPECIAL_NO_PRIOR)) if (!(specialflag & SPECIAL_NO_PRIOR))
my_pthread_setprio(pthread_self(), WAIT_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)); free_root(&thd->mem_root, MYF(0));
thd->set_statement(&thd->stmt_backup); thd->set_statement(&thd->stmt_backup);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
......
...@@ -4486,7 +4486,7 @@ simple_ident: ...@@ -4486,7 +4486,7 @@ simple_ident:
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ? sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,NullS,$1.str) : (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 | ident '.' ident
{ {
...@@ -4502,7 +4502,7 @@ simple_ident: ...@@ -4502,7 +4502,7 @@ simple_ident:
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ? sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,$1.str,$3.str) : (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 | '.' ident '.' ident
{ {
...@@ -4518,7 +4518,7 @@ simple_ident: ...@@ -4518,7 +4518,7 @@ simple_ident:
$$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING || $$= (sel->parsing_place != SELECT_LEX_NODE::IN_HAVING ||
sel->get_in_sum_expr() > 0) ? sel->get_in_sum_expr() > 0) ?
(Item*) new Item_field(NullS,$2.str,$4.str) : (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 | ident '.' ident '.' ident
{ {
...@@ -4536,8 +4536,8 @@ simple_ident: ...@@ -4536,8 +4536,8 @@ simple_ident:
(Item*) new Item_field((YYTHD->client_capabilities & (Item*) new Item_field((YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str), CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str) : $3.str, $5.str) :
(Item*) new Item_ref((YYTHD->client_capabilities & (Item*) new Item_ref(0,0,(YYTHD->client_capabilities &
CLIENT_NO_SCHEMA ? NullS : $1.str), CLIENT_NO_SCHEMA ? NullS : $1.str),
$3.str, $5.str); $3.str, $5.str);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment