Loading mysql-test/r/ps.result +11 −0 Original line number Diff line number Diff line Loading @@ -297,3 +297,14 @@ execute stmt; 'abc' like convert('abc' using utf8) 1 deallocate prepare stmt; create table t1 ( a bigint ); prepare stmt from 'select a from t1 where a between ? and ?'; set @a=1; execute stmt using @a, @a; a execute stmt using @a, @a; a execute stmt using @a, @a; a drop table t1; deallocate prepare stmt; mysql-test/t/ps.test +15 −0 Original line number Diff line number Diff line Loading @@ -314,3 +314,18 @@ prepare stmt from "select 'abc' like convert('abc' using utf8)"; execute stmt; execute stmt; deallocate prepare stmt; # # BUG#5748 "Prepared statement with BETWEEN and bigint values crashes # mysqld". Just another place where an item tree modification must be # rolled back. # create table t1 ( a bigint ); prepare stmt from 'select a from t1 where a between ? and ?'; set @a=1; execute stmt using @a, @a; execute stmt using @a, @a; execute stmt using @a, @a; drop table t1; deallocate prepare stmt; sql/item.cc +6 −11 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ void Item::print_item_w_name(String *str) Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) :orig_db_name(db_name_par), orig_table_name(table_name_par), orig_field_name(field_name_par), changed_during_fix_field(0), orig_field_name(field_name_par), db_name(db_name_par), table_name(table_name_par), field_name(field_name_par), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(0), depended_from(0) Loading @@ -120,7 +120,6 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) orig_db_name(item->orig_db_name), orig_table_name(item->orig_table_name), orig_field_name(item->orig_field_name), changed_during_fix_field(0), db_name(item->db_name), table_name(item->table_name), field_name(item->field_name), Loading @@ -137,11 +136,6 @@ void Item_ident::cleanup() table_name, orig_table_name, field_name, orig_field_name)); Item::cleanup(); if (changed_during_fix_field) { *changed_during_fix_field= this; changed_during_fix_field= 0; } db_name= orig_db_name; table_name= orig_table_name; field_name= orig_field_name; Loading Loading @@ -1340,10 +1334,10 @@ 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, 0, (char *)table_name, (char *)field_name); register_item_tree_changing(ref); thd->register_item_tree_change(ref, this, &thd->mem_root); if (!rf) return 1; /* Loading @@ -1362,7 +1356,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(ref, *ref, thd->register_item_tree_change(ref, *ref, &thd->mem_root); *ref= rf= new Item_ref(ref, 0, (where->db[0]?where->db:0), (char *)where->alias, (char *)field_name); Loading Loading @@ -2003,7 +1998,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) Item_field* fld; if (!((*reference)= fld= new Item_field(tmp))) return 1; register_item_tree_changing(reference); thd->register_item_tree_change(reference, this, &thd->mem_root); mark_as_dependent(thd, last, thd->lex->current_select, fld); return 0; } Loading sql/item.h +0 −3 Original line number Diff line number Diff line Loading @@ -317,7 +317,6 @@ class Item_ident :public Item const char *orig_db_name; const char *orig_table_name; const char *orig_field_name; Item **changed_during_fix_field; public: const char *db_name; const char *table_name; Loading @@ -340,8 +339,6 @@ class Item_ident :public Item Item_ident(THD *thd, Item_ident *item); const char *full_name() const; void cleanup(); void register_item_tree_changing(Item **ref) { changed_during_fix_field= ref; } bool remove_dependence_processor(byte * arg); }; Loading sql/item_cmpfunc.cc +10 −6 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ void Item_func_not_all::print(String *str) 1 Item was replaced with an integer version of the item */ static bool convert_constant_item(Field *field, Item **item) static bool convert_constant_item(THD *thd, Field *field, Item **item) { if ((*item)->const_item()) { Loading @@ -153,7 +153,10 @@ static bool convert_constant_item(Field *field, Item **item) { Item *tmp=new Item_int_with_ref(field->val_int(), *item); if (tmp) { thd->register_item_tree_change(item, *item, &thd->mem_root); *item=tmp; } return 1; // Item was replaced } } Loading @@ -164,6 +167,7 @@ static bool convert_constant_item(Field *field, Item **item) void Item_bool_func2::fix_length_and_dec() { max_length= 1; // Function returns 0 or 1 THD *thd= current_thd; /* As some compare functions are generated after sql_yacc, Loading Loading @@ -199,7 +203,6 @@ void Item_bool_func2::fix_length_and_dec() !coll.set(args[0]->collation, args[1]->collation, TRUE)) { Item* conv= 0; THD *thd= current_thd; Item_arena *arena= thd->current_arena, backup; strong= coll.strong; weak= strong ? 0 : 1; Loading Loading @@ -245,7 +248,7 @@ void Item_bool_func2::fix_length_and_dec() Field *field=((Item_field*) args[0])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) if (convert_constant_item(thd, field,&args[1])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. Loading @@ -258,7 +261,7 @@ void Item_bool_func2::fix_length_and_dec() Field *field=((Item_field*) args[1])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[0])) if (convert_constant_item(thd, field,&args[0])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. Loading Loading @@ -836,6 +839,7 @@ longlong Item_func_interval::val_int() void Item_func_between::fix_length_and_dec() { max_length= 1; THD *thd= current_thd; /* As some compare functions are generated after sql_yacc, Loading @@ -858,9 +862,9 @@ void Item_func_between::fix_length_and_dec() Field *field=((Item_field*) args[0])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) if (convert_constant_item(thd, field,&args[1])) cmp_type=INT_RESULT; // Works for all types. if (convert_constant_item(field,&args[2])) if (convert_constant_item(thd, field,&args[2])) cmp_type=INT_RESULT; // Works for all types. } } Loading Loading
mysql-test/r/ps.result +11 −0 Original line number Diff line number Diff line Loading @@ -297,3 +297,14 @@ execute stmt; 'abc' like convert('abc' using utf8) 1 deallocate prepare stmt; create table t1 ( a bigint ); prepare stmt from 'select a from t1 where a between ? and ?'; set @a=1; execute stmt using @a, @a; a execute stmt using @a, @a; a execute stmt using @a, @a; a drop table t1; deallocate prepare stmt;
mysql-test/t/ps.test +15 −0 Original line number Diff line number Diff line Loading @@ -314,3 +314,18 @@ prepare stmt from "select 'abc' like convert('abc' using utf8)"; execute stmt; execute stmt; deallocate prepare stmt; # # BUG#5748 "Prepared statement with BETWEEN and bigint values crashes # mysqld". Just another place where an item tree modification must be # rolled back. # create table t1 ( a bigint ); prepare stmt from 'select a from t1 where a between ? and ?'; set @a=1; execute stmt using @a, @a; execute stmt using @a, @a; execute stmt using @a, @a; drop table t1; deallocate prepare stmt;
sql/item.cc +6 −11 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ void Item::print_item_w_name(String *str) Item_ident::Item_ident(const char *db_name_par,const char *table_name_par, const char *field_name_par) :orig_db_name(db_name_par), orig_table_name(table_name_par), orig_field_name(field_name_par), changed_during_fix_field(0), orig_field_name(field_name_par), db_name(db_name_par), table_name(table_name_par), field_name(field_name_par), cached_field_index(NO_CACHED_FIELD_INDEX), cached_table(0), depended_from(0) Loading @@ -120,7 +120,6 @@ Item_ident::Item_ident(THD *thd, Item_ident *item) orig_db_name(item->orig_db_name), orig_table_name(item->orig_table_name), orig_field_name(item->orig_field_name), changed_during_fix_field(0), db_name(item->db_name), table_name(item->table_name), field_name(item->field_name), Loading @@ -137,11 +136,6 @@ void Item_ident::cleanup() table_name, orig_table_name, field_name, orig_field_name)); Item::cleanup(); if (changed_during_fix_field) { *changed_during_fix_field= this; changed_during_fix_field= 0; } db_name= orig_db_name; table_name= orig_table_name; field_name= orig_field_name; Loading Loading @@ -1340,10 +1334,10 @@ 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, 0, (char *)table_name, (char *)field_name); register_item_tree_changing(ref); thd->register_item_tree_change(ref, this, &thd->mem_root); if (!rf) return 1; /* Loading @@ -1362,7 +1356,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(ref, *ref, thd->register_item_tree_change(ref, *ref, &thd->mem_root); *ref= rf= new Item_ref(ref, 0, (where->db[0]?where->db:0), (char *)where->alias, (char *)field_name); Loading Loading @@ -2003,7 +1998,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) Item_field* fld; if (!((*reference)= fld= new Item_field(tmp))) return 1; register_item_tree_changing(reference); thd->register_item_tree_change(reference, this, &thd->mem_root); mark_as_dependent(thd, last, thd->lex->current_select, fld); return 0; } Loading
sql/item.h +0 −3 Original line number Diff line number Diff line Loading @@ -317,7 +317,6 @@ class Item_ident :public Item const char *orig_db_name; const char *orig_table_name; const char *orig_field_name; Item **changed_during_fix_field; public: const char *db_name; const char *table_name; Loading @@ -340,8 +339,6 @@ class Item_ident :public Item Item_ident(THD *thd, Item_ident *item); const char *full_name() const; void cleanup(); void register_item_tree_changing(Item **ref) { changed_during_fix_field= ref; } bool remove_dependence_processor(byte * arg); }; Loading
sql/item_cmpfunc.cc +10 −6 Original line number Diff line number Diff line Loading @@ -145,7 +145,7 @@ void Item_func_not_all::print(String *str) 1 Item was replaced with an integer version of the item */ static bool convert_constant_item(Field *field, Item **item) static bool convert_constant_item(THD *thd, Field *field, Item **item) { if ((*item)->const_item()) { Loading @@ -153,7 +153,10 @@ static bool convert_constant_item(Field *field, Item **item) { Item *tmp=new Item_int_with_ref(field->val_int(), *item); if (tmp) { thd->register_item_tree_change(item, *item, &thd->mem_root); *item=tmp; } return 1; // Item was replaced } } Loading @@ -164,6 +167,7 @@ static bool convert_constant_item(Field *field, Item **item) void Item_bool_func2::fix_length_and_dec() { max_length= 1; // Function returns 0 or 1 THD *thd= current_thd; /* As some compare functions are generated after sql_yacc, Loading Loading @@ -199,7 +203,6 @@ void Item_bool_func2::fix_length_and_dec() !coll.set(args[0]->collation, args[1]->collation, TRUE)) { Item* conv= 0; THD *thd= current_thd; Item_arena *arena= thd->current_arena, backup; strong= coll.strong; weak= strong ? 0 : 1; Loading Loading @@ -245,7 +248,7 @@ void Item_bool_func2::fix_length_and_dec() Field *field=((Item_field*) args[0])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) if (convert_constant_item(thd, field,&args[1])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. Loading @@ -258,7 +261,7 @@ void Item_bool_func2::fix_length_and_dec() Field *field=((Item_field*) args[1])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[0])) if (convert_constant_item(thd, field,&args[0])) { cmp.set_cmp_func(this, tmp_arg, tmp_arg+1, INT_RESULT); // Works for all types. Loading Loading @@ -836,6 +839,7 @@ longlong Item_func_interval::val_int() void Item_func_between::fix_length_and_dec() { max_length= 1; THD *thd= current_thd; /* As some compare functions are generated after sql_yacc, Loading @@ -858,9 +862,9 @@ void Item_func_between::fix_length_and_dec() Field *field=((Item_field*) args[0])->field; if (field->can_be_compared_as_longlong()) { if (convert_constant_item(field,&args[1])) if (convert_constant_item(thd, field,&args[1])) cmp_type=INT_RESULT; // Works for all types. if (convert_constant_item(field,&args[2])) if (convert_constant_item(thd, field,&args[2])) cmp_type=INT_RESULT; // Works for all types. } } Loading