summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <kaa@polly.local>2006-09-12 19:35:44 +0400
committerunknown <kaa@polly.local>2006-09-12 19:35:44 +0400
commit76f18d7ff0b76fd19495fae3b34c98ce33371a1c (patch)
tree87937eb913a46a5ab21071c8d4e2bd3cdf9bbe7f
parentb597aaf906b4bdda7fb7ccf34943fff4a077df58 (diff)
parentd31a3434650a9991bcc16478e65efd7d2ea23c76 (diff)
downloadmariadb-git-76f18d7ff0b76fd19495fae3b34c98ce33371a1c.tar.gz
Merge polly.local:/tmp/20924/bug20294/my50-bug20294
into polly.local:/home/kaa/src/maint/m50-maint--07OGt sql/item_cmpfunc.cc: Auto merged sql/item_cmpfunc.h: Auto merged sql/sql_class.h: Auto merged mysql-test/r/user_var.result: Manual merge mysql-test/t/user_var.test: Manual merge sql/item_func.cc: Manual merge sql/item_func.h: Manual merge
-rw-r--r--mysql-test/r/case.result7
-rw-r--r--mysql-test/r/func_if.result7
-rw-r--r--mysql-test/r/func_test.result7
-rw-r--r--mysql-test/r/user_var.result1
-rw-r--r--mysql-test/t/case.test11
-rw-r--r--mysql-test/t/func_if.test15
-rw-r--r--mysql-test/t/func_test.test12
-rw-r--r--mysql-test/t/user_var.test4
-rw-r--r--sql/item_cmpfunc.cc21
-rw-r--r--sql/item_cmpfunc.h14
-rw-r--r--sql/item_func.cc37
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/log_event.cc2
13 files changed, 109 insertions, 31 deletions
diff --git a/mysql-test/r/case.result b/mysql-test/r/case.result
index cf358e6a404..7154c689783 100644
--- a/mysql-test/r/case.result
+++ b/mysql-test/r/case.result
@@ -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
diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result
index eef380c8f52..59f8db93084 100644
--- a/mysql-test/r/func_if.result
+++ b/mysql-test/r/func_if.result
@@ -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
diff --git a/mysql-test/r/func_test.result b/mysql-test/r/func_test.result
index d9437f6c515..4543988a845 100644
--- a/mysql-test/r/func_test.result
+++ b/mysql-test/r/func_test.result
@@ -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
diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result
index 1664a907c99..2b9ec8e2164 100644
--- a/mysql-test/r/user_var.result
+++ b/mysql-test/r/user_var.result
@@ -301,3 +301,4 @@ select @var;
@var
3
drop table t1;
+End of 4.1 tests
diff --git a/mysql-test/t/case.test b/mysql-test/t/case.test
index fbe1ee2b8c8..a22b9cc39f1 100644
--- a/mysql-test/t/case.test
+++ b/mysql-test/t/case.test
@@ -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
diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test
index beaa371f847..553387b9d42 100644
--- a/mysql-test/t/func_if.test
+++ b/mysql-test/t/func_if.test
@@ -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
diff --git a/mysql-test/t/func_test.test b/mysql-test/t/func_test.test
index f2ff47704c9..83432dcc7fc 100644
--- a/mysql-test/t/func_test.test
+++ b/mysql-test/t/func_test.test
@@ -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
diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test
index b2a9728de00..192a92fc660 100644
--- a/mysql-test/t/user_var.test
+++ b/mysql-test/t/user_var.test
@@ -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);
#
@@ -212,3 +210,5 @@ 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;
+
+--echo End of 4.1 tests
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 919a23ed65d..756754dde3c 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -730,11 +730,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;
@@ -755,13 +751,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;
@@ -1402,11 +1392,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;
}
@@ -1557,6 +1549,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;
}
@@ -1805,6 +1798,7 @@ longlong Item_func_case::val_int()
}
res=item->val_int();
null_value=item->null_value;
+ unsigned_flag= item->unsigned_flag;
return res;
}
@@ -1991,7 +1985,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;
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 47f9f2aa98f..544f1470d9a 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1396,3 +1396,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);
+}
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 579e7f88ee6..4d9893e1bbd 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -2152,18 +2152,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++)
{
+ 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=args[i]->val_int();
+ {
+ value= tmp;
+ unsigned_flag= arg_unsigned_flag;
+ }
else
{
- longlong tmp=args[i]->val_int();
- if (!args[i]->null_value && (tmp < value ? cmp_sign : -cmp_sign) > 0)
- value=tmp;
+ 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;
+ }
}
- if ((null_value= args[i]->null_value))
- break;
}
return value;
}
@@ -3799,7 +3814,7 @@ 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:
@@ -3813,23 +3828,23 @@ Item_func_set_user_var::update()
{
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:
{
if (!save_result.vdec) // Null value
res= update_hash((void*) 0, 0, DECIMAL_RESULT, &my_charset_bin,
- DERIVATION_IMPLICIT);
+ DERIVATION_IMPLICIT, 0);
else
res= update_hash((void*) save_result.vdec,
sizeof(my_decimal), DECIMAL_RESULT,
- &my_charset_bin, DERIVATION_IMPLICIT);
+ &my_charset_bin, DERIVATION_IMPLICIT, 0);
break;
}
case ROW_RESULT:
diff --git a/sql/item_func.h b/sql/item_func.h
index c15b0b854b0..8abf5d91cd5 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -1173,7 +1173,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, bool unsigned_arg= 0);
+ CHARSET_INFO *cs, Derivation dv, bool unsigned_arg);
bool send(Protocol *protocol, String *str_arg);
void make_field(Send_field *tmp_field);
bool check(bool use_result_field);
diff --git a/sql/log_event.cc b/sql/log_event.cc
index cf5dbb1e77c..219434ab218 100644
--- a/sql/log_event.cc
+++ b/sql/log_event.cc
@@ -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();