mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Merge epotemkin@bk-internal.mysql.com:/home/bk/mysql-5.0-opt
into sunlight.local:/local_work/16861-bug-5.0-mysql
This commit is contained in:
@ -292,3 +292,12 @@ SELECT @a;
|
|||||||
@a
|
@a
|
||||||
18446744071710965857
|
18446744071710965857
|
||||||
drop table bigfailure;
|
drop table bigfailure;
|
||||||
|
create table t1(f1 int, f2 int);
|
||||||
|
insert into t1 values (1,2),(2,3),(3,1);
|
||||||
|
select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
||||||
|
@var:=f2
|
||||||
|
3
|
||||||
|
select @var;
|
||||||
|
@var
|
||||||
|
3
|
||||||
|
drop table t1;
|
||||||
|
@ -202,3 +202,13 @@ SET @a := (select * from bigfailure where afield = (SELECT afield FROM bigfailur
|
|||||||
SELECT @a;
|
SELECT @a;
|
||||||
|
|
||||||
drop table bigfailure;
|
drop table bigfailure;
|
||||||
|
|
||||||
|
#
|
||||||
|
# Bug#16861: User defined variable can have a wrong value if a tmp table was
|
||||||
|
# used.
|
||||||
|
#
|
||||||
|
create table t1(f1 int, f2 int);
|
||||||
|
insert into t1 values (1,2),(2,3),(3,1);
|
||||||
|
select @var:=f2 from t1 group by f1 order by f2 desc limit 1;
|
||||||
|
select @var;
|
||||||
|
drop table t1;
|
||||||
|
@ -548,7 +548,7 @@ void Item_func::signal_divide_by_null()
|
|||||||
|
|
||||||
Item *Item_func::get_tmp_table_item(THD *thd)
|
Item *Item_func::get_tmp_table_item(THD *thd)
|
||||||
{
|
{
|
||||||
if (!with_sum_func && !const_item())
|
if (!with_sum_func && !const_item() && functype() != SUSERVAR_FUNC)
|
||||||
return new Item_field(result_field);
|
return new Item_field(result_field);
|
||||||
return copy_or_same(thd);
|
return copy_or_same(thd);
|
||||||
}
|
}
|
||||||
@ -3719,30 +3719,38 @@ my_decimal *user_var_entry::val_decimal(my_bool *null_value, my_decimal *val)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Item_func_set_user_var::check()
|
Item_func_set_user_var::check(bool use_result_field)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("Item_func_set_user_var::check");
|
DBUG_ENTER("Item_func_set_user_var::check");
|
||||||
|
if (use_result_field)
|
||||||
|
DBUG_ASSERT(result_field);
|
||||||
|
|
||||||
switch (cached_result_type) {
|
switch (cached_result_type) {
|
||||||
case REAL_RESULT:
|
case REAL_RESULT:
|
||||||
{
|
{
|
||||||
save_result.vreal= args[0]->val_real();
|
save_result.vreal= use_result_field ? result_field->val_real() :
|
||||||
|
args[0]->val_real();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INT_RESULT:
|
case INT_RESULT:
|
||||||
{
|
{
|
||||||
save_result.vint= args[0]->val_int();
|
save_result.vint= use_result_field ? result_field->val_int() :
|
||||||
unsigned_flag= args[0]->unsigned_flag;
|
args[0]->val_int();
|
||||||
|
unsigned_flag= use_result_field ? ((Field_num*)result_field)->unsigned_flag:
|
||||||
|
args[0]->unsigned_flag;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRING_RESULT:
|
case STRING_RESULT:
|
||||||
{
|
{
|
||||||
save_result.vstr= args[0]->val_str(&value);
|
save_result.vstr= use_result_field ? result_field->val_str(&value) :
|
||||||
|
args[0]->val_str(&value);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DECIMAL_RESULT:
|
case DECIMAL_RESULT:
|
||||||
{
|
{
|
||||||
save_result.vdec= args[0]->val_decimal(&decimal_buff);
|
save_result.vdec= use_result_field ?
|
||||||
|
result_field->val_decimal(&decimal_buff) :
|
||||||
|
args[0]->val_decimal(&decimal_buff);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ROW_RESULT:
|
case ROW_RESULT:
|
||||||
@ -3828,7 +3836,7 @@ Item_func_set_user_var::update()
|
|||||||
double Item_func_set_user_var::val_real()
|
double Item_func_set_user_var::val_real()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
check();
|
check(0);
|
||||||
update(); // Store expression
|
update(); // Store expression
|
||||||
return entry->val_real(&null_value);
|
return entry->val_real(&null_value);
|
||||||
}
|
}
|
||||||
@ -3836,7 +3844,7 @@ double Item_func_set_user_var::val_real()
|
|||||||
longlong Item_func_set_user_var::val_int()
|
longlong Item_func_set_user_var::val_int()
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
check();
|
check(0);
|
||||||
update(); // Store expression
|
update(); // Store expression
|
||||||
return entry->val_int(&null_value);
|
return entry->val_int(&null_value);
|
||||||
}
|
}
|
||||||
@ -3844,7 +3852,7 @@ longlong Item_func_set_user_var::val_int()
|
|||||||
String *Item_func_set_user_var::val_str(String *str)
|
String *Item_func_set_user_var::val_str(String *str)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
check();
|
check(0);
|
||||||
update(); // Store expression
|
update(); // Store expression
|
||||||
return entry->val_str(&null_value, str, decimals);
|
return entry->val_str(&null_value, str, decimals);
|
||||||
}
|
}
|
||||||
@ -3853,7 +3861,7 @@ String *Item_func_set_user_var::val_str(String *str)
|
|||||||
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
|
my_decimal *Item_func_set_user_var::val_decimal(my_decimal *val)
|
||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
check();
|
check(0);
|
||||||
update(); // Store expression
|
update(); // Store expression
|
||||||
return entry->val_decimal(&null_value, val);
|
return entry->val_decimal(&null_value, val);
|
||||||
}
|
}
|
||||||
@ -3878,6 +3886,16 @@ void Item_func_set_user_var::print_as_stmt(String *str)
|
|||||||
str->append(')');
|
str->append(')');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Item_func_set_user_var::send(Protocol *protocol, String *str_arg)
|
||||||
|
{
|
||||||
|
if (result_field)
|
||||||
|
{
|
||||||
|
check(1);
|
||||||
|
update();
|
||||||
|
return protocol->store(result_field);
|
||||||
|
}
|
||||||
|
return Item::send(protocol, str_arg);
|
||||||
|
}
|
||||||
|
|
||||||
String *
|
String *
|
||||||
Item_func_get_user_var::val_str(String *str)
|
Item_func_get_user_var::val_str(String *str)
|
||||||
@ -4143,7 +4161,7 @@ bool Item_func_get_user_var::set_value(THD *thd,
|
|||||||
Item_func_set_user_var is not fixed after construction, call
|
Item_func_set_user_var is not fixed after construction, call
|
||||||
fix_fields().
|
fix_fields().
|
||||||
*/
|
*/
|
||||||
return (!suv || suv->fix_fields(thd, it) || suv->check() || suv->update());
|
return (!suv || suv->fix_fields(thd, it) || suv->check(0) || suv->update());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ public:
|
|||||||
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
|
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
|
||||||
NOT_FUNC, NOT_ALL_FUNC,
|
NOT_FUNC, NOT_ALL_FUNC,
|
||||||
NOW_FUNC, TRIG_COND_FUNC,
|
NOW_FUNC, TRIG_COND_FUNC,
|
||||||
GUSERVAR_FUNC, COLLATE_FUNC,
|
SUSERVAR_FUNC, GUSERVAR_FUNC, COLLATE_FUNC,
|
||||||
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC };
|
EXTRACT_FUNC, CHAR_TYPECAST_FUNC, FUNC_SP, UDF_FUNC };
|
||||||
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
|
||||||
OPTIMIZE_EQUAL };
|
OPTIMIZE_EQUAL };
|
||||||
@ -1167,13 +1167,15 @@ public:
|
|||||||
Item_func_set_user_var(LEX_STRING a,Item *b)
|
Item_func_set_user_var(LEX_STRING a,Item *b)
|
||||||
:Item_func(b), cached_result_type(INT_RESULT), name(a)
|
:Item_func(b), cached_result_type(INT_RESULT), name(a)
|
||||||
{}
|
{}
|
||||||
|
enum Functype functype() const { return SUSERVAR_FUNC; }
|
||||||
double val_real();
|
double val_real();
|
||||||
longlong val_int();
|
longlong val_int();
|
||||||
String *val_str(String *str);
|
String *val_str(String *str);
|
||||||
my_decimal *val_decimal(my_decimal *);
|
my_decimal *val_decimal(my_decimal *);
|
||||||
bool update_hash(void *ptr, uint length, enum Item_result type,
|
bool update_hash(void *ptr, uint length, enum Item_result type,
|
||||||
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg= 0);
|
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg= 0);
|
||||||
bool check();
|
bool send(Protocol *protocol, String *str_arg);
|
||||||
|
bool check(bool use_result_field);
|
||||||
bool update();
|
bool update();
|
||||||
enum Item_result result_type () const { return cached_result_type; }
|
enum Item_result result_type () const { return cached_result_type; }
|
||||||
bool fix_fields(THD *thd, Item **ref);
|
bool fix_fields(THD *thd, Item **ref);
|
||||||
|
@ -3252,7 +3252,7 @@ int set_var_user::check(THD *thd)
|
|||||||
0 can be passed as last argument (reference on item)
|
0 can be passed as last argument (reference on item)
|
||||||
*/
|
*/
|
||||||
return (user_var_item->fix_fields(thd, (Item**) 0) ||
|
return (user_var_item->fix_fields(thd, (Item**) 0) ||
|
||||||
user_var_item->check()) ? -1 : 0;
|
user_var_item->check(0)) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1883,7 +1883,7 @@ bool select_dumpvar::send_data(List<Item> &items)
|
|||||||
{
|
{
|
||||||
if ((xx=li++))
|
if ((xx=li++))
|
||||||
{
|
{
|
||||||
xx->check();
|
xx->check(0);
|
||||||
xx->update();
|
xx->update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13388,7 +13388,9 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
|
|||||||
{
|
{
|
||||||
Field *field;
|
Field *field;
|
||||||
|
|
||||||
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
|
if ((item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) ||
|
||||||
|
(item->type() == Item::FUNC_ITEM &&
|
||||||
|
((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC))
|
||||||
item_field= item;
|
item_field= item;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user