Loading mysql-test/r/ps.result +10 −0 Original line number Diff line number Diff line Loading @@ -308,3 +308,13 @@ execute stmt using @a, @a; a drop table t1; deallocate prepare stmt; create table t1 (a int); prepare stmt from "select * from t1 where 1 > (1 in (SELECT * FROM t1))"; execute stmt; a execute stmt; a execute stmt; a drop table t1; deallocate prepare stmt; mysql-test/t/ps.test +14 −0 Original line number Diff line number Diff line Loading @@ -329,3 +329,17 @@ execute stmt using @a, @a; drop table t1; deallocate prepare stmt; # # Bug #5987 subselect in bool function crashes server (prepared statements): # don't overwrite transformed subselects with old arguments of a bool # function. # create table t1 (a int); prepare stmt from "select * from t1 where 1 > (1 in (SELECT * FROM t1))"; execute stmt; execute stmt; execute stmt; drop table t1; deallocate prepare stmt; sql/item.cc +21 −11 Original line number Diff line number Diff line Loading @@ -2209,10 +2209,12 @@ Item_result item_cmp_type(Item_result a,Item_result b) } Item *resolve_const_item(Item *item,Item *comp_item) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; Item *new_item; if (item->basic_const_item()) return item; // Can't be better return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), item->result_type()); char *name=item->name; // Alloced by sql_alloc Loading @@ -2223,17 +2225,20 @@ Item *resolve_const_item(Item *item,Item *comp_item) String tmp(buff,sizeof(buff),&my_charset_bin),*result; result=item->val_str(&tmp); if (item->null_value) return new Item_null(name); new_item= new Item_null(name); else { uint length= result->length(); char *tmp_str= sql_strmake(result->ptr(), length); return new Item_string(name,tmp_str,length,result->charset()); new_item= new Item_string(name, tmp_str, length, result->charset()); } if (res_type == INT_RESULT) } else if (res_type == INT_RESULT) { longlong result=item->val_int(); uint length=item->max_length; bool null_value=item->null_value; return (null_value ? (Item*) new Item_null(name) : new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } else Loading @@ -2241,8 +2246,13 @@ Item *resolve_const_item(Item *item,Item *comp_item) double result=item->val(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; return (null_value ? (Item*) new Item_null(name) : (Item*) new Item_real(name,result,decimals,length)); new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_real(name, result, decimals, length)); } if (new_item) { thd->register_item_tree_change(ref, item, &thd->mem_root); *ref= new_item; } } Loading sql/item.h +1 −1 Original line number Diff line number Diff line Loading @@ -1224,5 +1224,5 @@ class Item_type_holder: public Item extern Item_buff *new_Item_buff(Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item *resolve_const_item(Item *item,Item *cmp_item); extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item); extern bool field_is_equal_to_item(Field *field,Item *item); sql/item_cmpfunc.h +1 −11 Original line number Diff line number Diff line Loading @@ -210,21 +210,11 @@ class Item_bool_func2 :public Item_int_func 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), orig_a(a), orig_b(b) Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) { allowed_arg_cols= a->cols(); } void cleanup() { DBUG_ENTER("Item_bool_rowready_func2::cleanup"); Item_bool_func2::cleanup(); tmp_arg[0]= orig_a; tmp_arg[1]= orig_b; DBUG_VOID_RETURN; } Item *neg_transformer(THD *thd); virtual Item *negated_item(); }; Loading Loading
mysql-test/r/ps.result +10 −0 Original line number Diff line number Diff line Loading @@ -308,3 +308,13 @@ execute stmt using @a, @a; a drop table t1; deallocate prepare stmt; create table t1 (a int); prepare stmt from "select * from t1 where 1 > (1 in (SELECT * FROM t1))"; execute stmt; a execute stmt; a execute stmt; a drop table t1; deallocate prepare stmt;
mysql-test/t/ps.test +14 −0 Original line number Diff line number Diff line Loading @@ -329,3 +329,17 @@ execute stmt using @a, @a; drop table t1; deallocate prepare stmt; # # Bug #5987 subselect in bool function crashes server (prepared statements): # don't overwrite transformed subselects with old arguments of a bool # function. # create table t1 (a int); prepare stmt from "select * from t1 where 1 > (1 in (SELECT * FROM t1))"; execute stmt; execute stmt; execute stmt; drop table t1; deallocate prepare stmt;
sql/item.cc +21 −11 Original line number Diff line number Diff line Loading @@ -2209,10 +2209,12 @@ Item_result item_cmp_type(Item_result a,Item_result b) } Item *resolve_const_item(Item *item,Item *comp_item) void resolve_const_item(THD *thd, Item **ref, Item *comp_item) { Item *item= *ref; Item *new_item; if (item->basic_const_item()) return item; // Can't be better return; // Can't be better Item_result res_type=item_cmp_type(comp_item->result_type(), item->result_type()); char *name=item->name; // Alloced by sql_alloc Loading @@ -2223,17 +2225,20 @@ Item *resolve_const_item(Item *item,Item *comp_item) String tmp(buff,sizeof(buff),&my_charset_bin),*result; result=item->val_str(&tmp); if (item->null_value) return new Item_null(name); new_item= new Item_null(name); else { uint length= result->length(); char *tmp_str= sql_strmake(result->ptr(), length); return new Item_string(name,tmp_str,length,result->charset()); new_item= new Item_string(name, tmp_str, length, result->charset()); } if (res_type == INT_RESULT) } else if (res_type == INT_RESULT) { longlong result=item->val_int(); uint length=item->max_length; bool null_value=item->null_value; return (null_value ? (Item*) new Item_null(name) : new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_int(name, result, length)); } else Loading @@ -2241,8 +2246,13 @@ Item *resolve_const_item(Item *item,Item *comp_item) double result=item->val(); uint length=item->max_length,decimals=item->decimals; bool null_value=item->null_value; return (null_value ? (Item*) new Item_null(name) : (Item*) new Item_real(name,result,decimals,length)); new_item= (null_value ? (Item*) new Item_null(name) : (Item*) new Item_real(name, result, decimals, length)); } if (new_item) { thd->register_item_tree_change(ref, item, &thd->mem_root); *ref= new_item; } } Loading
sql/item.h +1 −1 Original line number Diff line number Diff line Loading @@ -1224,5 +1224,5 @@ class Item_type_holder: public Item extern Item_buff *new_Item_buff(Item *item); extern Item_result item_cmp_type(Item_result a,Item_result b); extern Item *resolve_const_item(Item *item,Item *cmp_item); extern void resolve_const_item(THD *thd, Item **ref, Item *cmp_item); extern bool field_is_equal_to_item(Field *field,Item *item);
sql/item_cmpfunc.h +1 −11 Original line number Diff line number Diff line Loading @@ -210,21 +210,11 @@ class Item_bool_func2 :public Item_int_func 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), orig_a(a), orig_b(b) Item_bool_rowready_func2(Item *a, Item *b) :Item_bool_func2(a, b) { allowed_arg_cols= a->cols(); } void cleanup() { DBUG_ENTER("Item_bool_rowready_func2::cleanup"); Item_bool_func2::cleanup(); tmp_arg[0]= orig_a; tmp_arg[1]= orig_b; DBUG_VOID_RETURN; } Item *neg_transformer(THD *thd); virtual Item *negated_item(); }; Loading