Merge polly.local:/tmp/20924/bug20294/my41-bug20294
into polly.local:/tmp/20924/bug20294/my50-bug20294
This commit is contained in:
commit
e03faff3e4
@ -200,3 +200,10 @@ CEMPNUM EMPMUM1 EMPNUM2
|
||||
0.00 0 0.00
|
||||
2.00 2 NULL
|
||||
DROP TABLE t1,t2;
|
||||
SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
|
||||
CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END
|
||||
18446744073709551615
|
||||
SELECT COALESCE(18446744073709551615);
|
||||
COALESCE(18446744073709551615)
|
||||
18446744073709551615
|
||||
End of 4.1 tests
|
||||
|
@ -128,3 +128,10 @@ f1 f2 if(f1, 40.0, 5.00)
|
||||
0 0 5.00
|
||||
1 1 40.00
|
||||
drop table t1;
|
||||
SELECT IF(1 != 0, 18446744073709551615, 1);
|
||||
IF(1 != 0, 18446744073709551615, 1)
|
||||
18446744073709551615
|
||||
SELECT IFNULL(NULL, 18446744073709551615);
|
||||
IFNULL(NULL, 18446744073709551615)
|
||||
18446744073709551615
|
||||
End of 4.1 tests
|
||||
|
@ -204,3 +204,10 @@ NULL
|
||||
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
|
||||
GREATEST(1.5E+2,1.3E+2,NULL)
|
||||
NULL
|
||||
SELECT GREATEST(1, 18446744073709551615);
|
||||
GREATEST(1, 18446744073709551615)
|
||||
18446744073709551615
|
||||
SELECT LEAST(1, 18446744073709551615);
|
||||
LEAST(1, 18446744073709551615)
|
||||
1
|
||||
End of 4.1 tests
|
||||
|
@ -256,3 +256,8 @@ t1 CREATE TABLE `t1` (
|
||||
`@first_var` longtext
|
||||
) ENGINE=MyISAM DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
set @a=18446744073709551615;
|
||||
select @a;
|
||||
@a
|
||||
18446744073709551615
|
||||
End of 4.1 tests
|
||||
|
@ -133,8 +133,6 @@ select min(a), min(case when 1=1 then a else NULL end),
|
||||
from t1 where b=3 group by b;
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
||||
#
|
||||
# Tests for bug #9939: conversion of the arguments for COALESCE and IFNULL
|
||||
@ -154,3 +152,12 @@ SELECT IFNULL(t2.EMPNUM,t1.EMPNUM) AS CEMPNUM,
|
||||
FROM t1 LEFT JOIN t2 ON t1.EMPNUM=t2.EMPNUM;
|
||||
|
||||
DROP TABLE t1,t2;
|
||||
#
|
||||
# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
|
||||
# functions
|
||||
# - UNSIGNED values in CASE and COALESCE are treated as SIGNED
|
||||
#
|
||||
SELECT CASE 1 WHEN 1 THEN 18446744073709551615 ELSE 1 END;
|
||||
SELECT COALESCE(18446744073709551615);
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
@ -97,3 +97,18 @@ create table t1 (f1 int, f2 int);
|
||||
insert into t1 values(1,1),(0,0);
|
||||
select f1, f2, if(f1, 40.0, 5.00) from t1 group by f1 order by f2;
|
||||
drop table t1;
|
||||
#
|
||||
# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
|
||||
# functions
|
||||
# - UNSIGNED values in IF() are treated as SIGNED
|
||||
#
|
||||
SELECT IF(1 != 0, 18446744073709551615, 1);
|
||||
|
||||
#
|
||||
# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
|
||||
# functions
|
||||
# - UNSIGNED values in IFNULL() are treated as SIGNED
|
||||
#
|
||||
SELECT IFNULL(NULL, 18446744073709551615);
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
@ -108,8 +108,6 @@ select 5.1 mod 3, 5.1 mod -3, -5.1 mod 3, -5.1 mod -3;
|
||||
|
||||
select 5 mod 3, 5 mod -3, -5 mod 3, -5 mod -3;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug#6726: NOT BETWEEN parse failure
|
||||
#
|
||||
@ -127,3 +125,13 @@ SELECT GREATEST(1,NULL) FROM DUAL;
|
||||
SELECT LEAST('xxx','aaa',NULL,'yyy') FROM DUAL;
|
||||
SELECT LEAST(1.1,1.2,NULL,1.0) FROM DUAL;
|
||||
SELECT GREATEST(1.5E+2,1.3E+2,NULL) FROM DUAL;
|
||||
|
||||
#
|
||||
# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
|
||||
# functions
|
||||
# - UNSIGNED values in GREATEST() and LEAST() are treated as SIGNED
|
||||
#
|
||||
SELECT GREATEST(1, 18446744073709551615);
|
||||
SELECT LEAST(1, 18446744073709551615);
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
@ -144,8 +144,6 @@ select @@version;
|
||||
--replace_column 1 #
|
||||
select @@global.version;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
#
|
||||
# Bug #6598: problem with cast(NULL as signed integer);
|
||||
#
|
||||
@ -171,3 +169,12 @@ set @first_var= cast(NULL as CHAR);
|
||||
create table t1 select @first_var;
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
#
|
||||
# Bug #20924: CAST(expr as UNSIGNED) returns SIGNED value when used in various
|
||||
# functions
|
||||
# - SET on a user variable saves UNSIGNED as SIGNED
|
||||
#
|
||||
set @a=18446744073709551615;
|
||||
select @a;
|
||||
|
||||
--echo End of 4.1 tests
|
||||
|
@ -719,11 +719,7 @@ int Arg_comparator::compare_int_signed_unsigned()
|
||||
if (!(*b)->null_value)
|
||||
{
|
||||
owner->null_value= 0;
|
||||
if (sval1 < 0 || (ulonglong)sval1 < uval2)
|
||||
return -1;
|
||||
if ((ulonglong)sval1 == uval2)
|
||||
return 0;
|
||||
return 1;
|
||||
return ::compare_int_signed_unsigned(sval1, uval2);
|
||||
}
|
||||
}
|
||||
owner->null_value= 1;
|
||||
@ -744,13 +740,7 @@ int Arg_comparator::compare_int_unsigned_signed()
|
||||
if (!(*b)->null_value)
|
||||
{
|
||||
owner->null_value= 0;
|
||||
if (sval2 < 0)
|
||||
return 1;
|
||||
if (uval1 < (ulonglong)sval2)
|
||||
return -1;
|
||||
if (uval1 == (ulonglong)sval2)
|
||||
return 0;
|
||||
return 1;
|
||||
return ::compare_int_unsigned_signed(uval1, sval2);
|
||||
}
|
||||
}
|
||||
owner->null_value= 1;
|
||||
@ -1390,11 +1380,13 @@ Item_func_ifnull::int_op()
|
||||
if (!args[0]->null_value)
|
||||
{
|
||||
null_value=0;
|
||||
unsigned_flag= args[0]->unsigned_flag;
|
||||
return value;
|
||||
}
|
||||
value=args[1]->val_int();
|
||||
if ((null_value=args[1]->null_value))
|
||||
return 0;
|
||||
unsigned_flag= args[1]->unsigned_flag;
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1545,6 +1537,7 @@ Item_func_if::val_int()
|
||||
Item *arg= args[0]->val_bool() ? args[1] : args[2];
|
||||
longlong value=arg->val_int();
|
||||
null_value=arg->null_value;
|
||||
unsigned_flag= arg->unsigned_flag;
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -1793,6 +1786,7 @@ longlong Item_func_case::val_int()
|
||||
}
|
||||
res=item->val_int();
|
||||
null_value=item->null_value;
|
||||
unsigned_flag= item->unsigned_flag;
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -1979,7 +1973,10 @@ longlong Item_func_coalesce::int_op()
|
||||
{
|
||||
longlong res=args[i]->val_int();
|
||||
if (!args[i]->null_value)
|
||||
{
|
||||
unsigned_flag= args[i]->unsigned_flag;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
null_value=1;
|
||||
return 0;
|
||||
|
@ -1394,3 +1394,17 @@ inline Item *and_conds(Item *a, Item *b)
|
||||
}
|
||||
|
||||
Item *and_expressions(Item *a, Item *b, Item **org_item);
|
||||
|
||||
inline int compare_int_signed_unsigned(longlong sval, ulonglong uval)
|
||||
{
|
||||
if (sval < 0 || (ulonglong)sval < uval)
|
||||
return -1;
|
||||
if ((ulonglong)sval == uval)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
inline int compare_int_unsigned_signed(ulonglong uval, longlong sval)
|
||||
{
|
||||
return -compare_int_signed_unsigned(sval, uval);
|
||||
}
|
||||
|
@ -2136,18 +2136,33 @@ longlong Item_func_min_max::val_int()
|
||||
{
|
||||
DBUG_ASSERT(fixed == 1);
|
||||
longlong value=0;
|
||||
my_bool arg_unsigned_flag;
|
||||
my_bool cmp;
|
||||
for (uint i=0; i < arg_count ; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
value=args[i]->val_int();
|
||||
else
|
||||
{
|
||||
longlong tmp=args[i]->val_int();
|
||||
if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
|
||||
value=tmp;
|
||||
}
|
||||
longlong tmp= args[i]->val_int();
|
||||
if ((null_value= args[i]->null_value))
|
||||
break;
|
||||
arg_unsigned_flag= args[i]->unsigned_flag;
|
||||
if (i == 0)
|
||||
{
|
||||
value= tmp;
|
||||
unsigned_flag= arg_unsigned_flag;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (unsigned_flag == arg_unsigned_flag)
|
||||
cmp= tmp < value;
|
||||
else if (unsigned_flag)
|
||||
cmp= compare_int_signed_unsigned(tmp, value) < 0;
|
||||
else
|
||||
cmp= compare_int_unsigned_signed(tmp, value) < 0;
|
||||
if ((cmp ? cmp_sign : -cmp_sign) > 0)
|
||||
{
|
||||
value= tmp;
|
||||
unsigned_flag= arg_unsigned_flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
@ -3406,6 +3421,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
|
||||
entry->length=0;
|
||||
entry->update_query_id=0;
|
||||
entry->collation.set(NULL, DERIVATION_IMPLICIT);
|
||||
entry->unsigned_flag= 0;
|
||||
/*
|
||||
If we are here, we were called from a SET or a query which sets a
|
||||
variable. Imagine it is this:
|
||||
@ -3492,6 +3508,7 @@ Item_func_set_user_var::fix_length_and_dec()
|
||||
type - type of new value
|
||||
cs - charset info for new value
|
||||
dv - derivation for new value
|
||||
unsigned_arg - indiates if a value of type INT_RESULT is unsigned
|
||||
|
||||
RETURN VALUE
|
||||
False - success, True - failure
|
||||
@ -3499,7 +3516,8 @@ Item_func_set_user_var::fix_length_and_dec()
|
||||
|
||||
static bool
|
||||
update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
||||
Item_result type, CHARSET_INFO *cs, Derivation dv)
|
||||
Item_result type, CHARSET_INFO *cs, Derivation dv,
|
||||
bool unsigned_arg)
|
||||
{
|
||||
if (set_null)
|
||||
{
|
||||
@ -3547,6 +3565,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
||||
((my_decimal*)entry->value)->fix_buffer_pointer();
|
||||
entry->length= length;
|
||||
entry->collation.set(cs, dv);
|
||||
entry->unsigned_flag= unsigned_arg;
|
||||
}
|
||||
entry->type=type;
|
||||
return 0;
|
||||
@ -3555,7 +3574,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length,
|
||||
|
||||
bool
|
||||
Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
|
||||
CHARSET_INFO *cs, Derivation dv)
|
||||
CHARSET_INFO *cs, Derivation dv
|
||||
bool unsigned_arg)
|
||||
{
|
||||
/*
|
||||
If we set a variable explicitely to NULL then keep the old
|
||||
@ -3564,7 +3584,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type,
|
||||
if ((null_value= args[0]->null_value) && null_item)
|
||||
type= entry->type; // Don't change type of item
|
||||
if (::update_hash(entry, (null_value= args[0]->null_value),
|
||||
ptr, length, type, cs, dv))
|
||||
ptr, length, type, cs, dv, unsigned_arg))
|
||||
{
|
||||
current_thd->fatal_error(); // Probably end of memory
|
||||
null_value= 1;
|
||||
@ -3646,7 +3666,10 @@ String *user_var_entry::val_str(my_bool *null_value, String *str,
|
||||
str->set(*(double*) value, decimals, &my_charset_bin);
|
||||
break;
|
||||
case INT_RESULT:
|
||||
str->set(*(longlong*) value, &my_charset_bin);
|
||||
if (!unsigned_flag)
|
||||
str->set(*(longlong*) value, &my_charset_bin);
|
||||
else
|
||||
str->set(*(ulonglong*) value, &my_charset_bin);
|
||||
break;
|
||||
case DECIMAL_RESULT:
|
||||
my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str);
|
||||
@ -3717,6 +3740,7 @@ Item_func_set_user_var::check()
|
||||
case INT_RESULT:
|
||||
{
|
||||
save_result.vint= args[0]->val_int();
|
||||
unsigned_flag= args[0]->unsigned_flag;
|
||||
break;
|
||||
}
|
||||
case STRING_RESULT:
|
||||
@ -3766,25 +3790,26 @@ Item_func_set_user_var::update()
|
||||
case REAL_RESULT:
|
||||
{
|
||||
res= update_hash((void*) &save_result.vreal,sizeof(save_result.vreal),
|
||||
REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
|
||||
REAL_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, 0);
|
||||
break;
|
||||
}
|
||||
case INT_RESULT:
|
||||
{
|
||||
res= update_hash((void*) &save_result.vint, sizeof(save_result.vint),
|
||||
INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT);
|
||||
INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT,
|
||||
unsigned_flag);
|
||||
break;
|
||||
}
|
||||
case STRING_RESULT:
|
||||
{
|
||||
if (!save_result.vstr) // Null value
|
||||
res= update_hash((void*) 0, 0, STRING_RESULT, &my_charset_bin,
|
||||
DERIVATION_IMPLICIT);
|
||||
DERIVATION_IMPLICIT, 0);
|
||||
else
|
||||
res= update_hash((void*) save_result.vstr->ptr(),
|
||||
save_result.vstr->length(), STRING_RESULT,
|
||||
save_result.vstr->charset(),
|
||||
DERIVATION_IMPLICIT);
|
||||
DERIVATION_IMPLICIT, 0);
|
||||
break;
|
||||
}
|
||||
case DECIMAL_RESULT:
|
||||
|
@ -1170,7 +1170,7 @@ public:
|
||||
String *val_str(String *str);
|
||||
my_decimal *val_decimal(my_decimal *);
|
||||
bool update_hash(void *ptr, uint length, enum Item_result type,
|
||||
CHARSET_INFO *cs, Derivation dv);
|
||||
CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
|
||||
bool check();
|
||||
bool update();
|
||||
enum Item_result result_type () const { return cached_result_type; }
|
||||
|
@ -3846,7 +3846,7 @@ int User_var_log_event::exec_event(struct st_relay_log_info* rli)
|
||||
a single record and with a single column. Thus, like
|
||||
a column value, it could always have IMPLICIT derivation.
|
||||
*/
|
||||
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT);
|
||||
e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, 0);
|
||||
free_root(thd->mem_root,0);
|
||||
|
||||
rli->inc_event_relay_log_pos();
|
||||
|
@ -2015,6 +2015,7 @@ class user_var_entry
|
||||
ulong length;
|
||||
query_id_t update_query_id, used_query_id;
|
||||
Item_result type;
|
||||
bool unsigned_flag;
|
||||
|
||||
double val_real(my_bool *null_value);
|
||||
longlong val_int(my_bool *null_value);
|
||||
|
Loading…
x
Reference in New Issue
Block a user