Below is the list of changes that have just been committed into a local
5.0 repository of greenman. When greenman does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-01-24 08:53:35-08:00, igreenhoe@stripped +4 -0
Fix for bug #24912 (misc functions having trouble with unsigned)
This patch is for 5.0/5.1 version of the server. This is *not* cumulative with the 4.1
patch.
Problem: Needed to check/set unsigned_flag in a number of places. Also need to
have the variable being assigned to from "val_int" be a longlong type or casted
to ulonglong.
mysql-test/r/func_math.result@stripped, 2007-01-24 08:53:32-08:00,
igreenhoe@stripped +39 -0
Added new test cases
mysql-test/t/func_math.test@stripped, 2007-01-24 08:53:32-08:00,
igreenhoe@stripped +16 -0
Added new test cases
sql/item_func.cc@stripped, 2007-01-24 08:53:32-08:00, igreenhoe@stripped +38
-8
Various changes to remove problem with longlong/ulonglong ambiguity.
sql/item_func.h@stripped, 2007-01-24 08:53:33-08:00, igreenhoe@stripped +7
-1
Misc Fixes
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: igreenhoe
# Host: ra.greendragongames.com
# Root: /home/greenman/workspace/mysql/bug-24912/my50-changes
--- 1.322/sql/item_func.cc 2007-01-24 08:53:40 -08:00
+++ 1.323/sql/item_func.cc 2007-01-24 08:53:40 -08:00
@@ -609,6 +609,14 @@ Item *Item_func::get_tmp_table_item(THD
return copy_or_same(thd);
}
+double Item_int_func::val_real()
+{
+ DBUG_ASSERT(fixed == 1);
+
+ return unsigned_flag ? (double) ((ulonglong) val_int()) : (double) val_int();
+}
+
+
String *Item_int_func::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -797,7 +805,10 @@ double Item_func_numhybrid::val_real()
return result;
}
case INT_RESULT:
- return (double)int_op();
+ {
+ longlong result = int_op();
+ return unsigned_flag ? (double) ((ulonglong) result) : (double) result;
+ }
case REAL_RESULT:
return real_op();
case STRING_RESULT:
@@ -970,6 +981,7 @@ void Item_func_unsigned::print(String *s
longlong Item_func_unsigned::val_int()
{
longlong value;
+ unsigned_flag = true;
int error;
if (args[0]->cast_to_int_type() == DECIMAL_RESULT)
@@ -1334,6 +1346,8 @@ longlong Item_func_mod::int_op()
DBUG_ASSERT(fixed == 1);
longlong value= args[0]->val_int();
longlong val2= args[1]->val_int();
+ longlong result;
+
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0; /* purecov: inspected */
if (val2 == 0)
@@ -1342,10 +1356,24 @@ longlong Item_func_mod::int_op()
return 0;
}
+ unsigned_flag = args[0]->unsigned_flag;
+
if (args[0]->unsigned_flag)
- return ((ulonglong) value) % val2;
+ {
+ if (args[1]->unsigned_flag)
+ result= ((ulonglong) value) % ((ulonglong) val2);
+ else
+ result= ((ulonglong) value) % val2;
+ }
+ else
+ {
+ if (args[1]->unsigned_flag)
+ result= value % ((ulonglong) val2);
+ else
+ result= value % val2;
+ }
- return value % val2;
+ return result;
}
double Item_func_mod::real_op()
@@ -1478,8 +1506,9 @@ double Item_func_abs::real_op()
longlong Item_func_abs::int_op()
{
longlong value= args[0]->val_int();
+ unsigned_flag= args[0]->unsigned_flag;
null_value= args[0]->null_value;
- return value >= 0 ? value : -value;
+ return (value >= 0) || unsigned_flag ? value : -value;
}
@@ -1903,7 +1932,8 @@ void Item_func_round::fix_length_and_dec
if (!decimals_to_set &&
(truncate || (args[0]->decimal_precision() < DECIMAL_LONGLONG_DIGITS)))
{
- int length_can_increase= test(!truncate && (args[1]->val_int() < 0));
+ int length_can_increase= test(!truncate && (args[1]->val_int() < 0)
&&
+ !args[1]->unsigned_flag);
max_length= args[0]->max_length + length_can_increase;
/* Here we can keep INT_RESULT */
hybrid_type= INT_RESULT;
@@ -1970,12 +2000,12 @@ double Item_func_round::real_op()
longlong Item_func_round::int_op()
{
longlong value= args[0]->val_int();
- int dec=(int) args[1]->val_int();
+ longlong dec= args[1]->val_int();
decimals= 0;
- uint abs_dec;
+ ulonglong abs_dec;
if ((null_value= args[0]->null_value || args[1]->null_value))
return 0;
- if (dec >= 0)
+ if ((dec >= 0) || args[1]->unsigned_flag)
return value; // integer have not digits after point
abs_dec= -dec;
--- 1.160/sql/item_func.h 2007-01-24 08:53:40 -08:00
+++ 1.161/sql/item_func.h 2007-01-24 08:53:40 -08:00
@@ -278,7 +278,7 @@ public:
{ max_length= 21; }
Item_int_func(List<Item> &list) :Item_func(list) { max_length= 21; }
Item_int_func(THD *thd, Item_int_func *item) :Item_func(thd, item) {}
- double val_real() { DBUG_ASSERT(fixed == 1); return (double) val_int(); }
+ double val_real();
String *val_str(String*str);
enum Item_result result_type () const { return INT_RESULT; }
void fix_length_and_dec() {}
@@ -324,6 +324,12 @@ class Item_func_unsigned :public Item_fu
public:
Item_func_unsigned(Item *a) :Item_func_signed(a) {}
const char *func_name() const { return "cast_as_unsigned"; }
+ double val_real()
+ {
+ double tmp= (ulonglong) val_int();
+ null_value= args[0]->null_value;
+ return tmp;
+ }
void fix_length_and_dec()
{ max_length=args[0]->max_length; unsigned_flag=1; }
longlong val_int();
--- 1.35/mysql-test/r/func_math.result 2007-01-24 08:53:40 -08:00
+++ 1.36/mysql-test/r/func_math.result 2007-01-24 08:53:40 -08:00
@@ -176,6 +176,45 @@ select a from t1 where a='http://www.foo
a
http://www.foo.com/
drop table t1;
+select cast(-2 as unsigned), 18446744073709551614, -2;
+cast(-2 as unsigned) 18446744073709551614 -2
+18446744073709551614 18446744073709551614 -2
+select abs(cast(-2 as unsigned)), abs(18446744073709551614), abs(-2);
+abs(cast(-2 as unsigned)) abs(18446744073709551614) abs(-2)
+18446744073709551614 18446744073709551614 2
+select ceiling(cast(-2 as unsigned)), ceiling(18446744073709551614), ceiling(-2);
+ceiling(cast(-2 as unsigned)) ceiling(18446744073709551614) ceiling(-2)
+18446744073709551614 18446744073709551614 -2
+select floor(cast(-2 as unsigned)), floor(18446744073709551614), floor(-2);
+floor(cast(-2 as unsigned)) floor(18446744073709551614) floor(-2)
+18446744073709551614 18446744073709551614 -2
+select format(cast(-2 as unsigned), 2), format(18446744073709551614, 2), format(-2, 2);
+format(cast(-2 as unsigned), 2) format(18446744073709551614, 2) format(-2, 2)
+18,446,744,073,709,551,614.00 18,446,744,073,709,551,614.00 -2.00
+select sqrt(cast(-2 as unsigned)), sqrt(18446744073709551614), sqrt(-2);
+sqrt(cast(-2 as unsigned)) sqrt(18446744073709551614) sqrt(-2)
+4294967296 4294967296 NULL
+select round(cast(-2 as unsigned), 1), round(18446744073709551614, 1), round(-2, 1);
+round(cast(-2 as unsigned), 1) round(18446744073709551614, 1) round(-2, 1)
+18446744073709551614.0 18446744073709551614.0 -2.0
+select round(4, cast(-2 as unsigned)), round(4, 18446744073709551614), round(4, -2);
+round(4, cast(-2 as unsigned)) round(4, 18446744073709551614) round(4, -2)
+4 4 0
+select mod(cast(-2 as unsigned), 3), mod(18446744073709551614, 3), mod(-2, 3);
+mod(cast(-2 as unsigned), 3) mod(18446744073709551614, 3) mod(-2, 3)
+2 2 -2
+select mod(5, cast(-2 as unsigned)), mod(5, 18446744073709551614), mod(5, -2);
+mod(5, cast(-2 as unsigned)) mod(5, 18446744073709551614) mod(5, -2)
+5 5 1
+select truncate(cast(-2 as unsigned), 1), truncate(18446744073709551614, 1), truncate(-2,
1);
+truncate(cast(-2 as unsigned), 1) truncate(18446744073709551614, 1) truncate(-2, 1)
+18446744073709551614.0 18446744073709551614.0 -2.0
+select truncate(4, cast(-2 as unsigned)), truncate(4, 18446744073709551614), truncate(4,
-2);
+truncate(4, cast(-2 as unsigned)) truncate(4, 18446744073709551614) truncate(4, -2)
+4 4 0
+select pow(cast(-2 as unsigned), 5), pow(18446744073709551614, 5), pow(-2, 5);
+pow(cast(-2 as unsigned), 5) pow(18446744073709551614, 5) pow(-2, 5)
+2.1359870359209e+96 2.1359870359209e+96 -32
set sql_mode='traditional';
select ln(-1);
ln(-1)
--- 1.27/mysql-test/t/func_math.test 2007-01-24 08:53:40 -08:00
+++ 1.28/mysql-test/t/func_math.test 2007-01-24 08:53:40 -08:00
@@ -128,6 +128,22 @@ insert into t1 values ('http://www.foo.c
select a from t1 where a='http://www.foo.com/' order by abs(timediff(ts, 0));
drop table t1;
+# Bug 24912 -- misc functions have trouble with unsigned
+
+select cast(-2 as unsigned), 18446744073709551614, -2;
+select abs(cast(-2 as unsigned)), abs(18446744073709551614), abs(-2);
+select ceiling(cast(-2 as unsigned)), ceiling(18446744073709551614), ceiling(-2);
+select floor(cast(-2 as unsigned)), floor(18446744073709551614), floor(-2);
+select format(cast(-2 as unsigned), 2), format(18446744073709551614, 2), format(-2, 2);
+select sqrt(cast(-2 as unsigned)), sqrt(18446744073709551614), sqrt(-2);
+select round(cast(-2 as unsigned), 1), round(18446744073709551614, 1), round(-2, 1);
+select round(4, cast(-2 as unsigned)), round(4, 18446744073709551614), round(4, -2);
+select mod(cast(-2 as unsigned), 3), mod(18446744073709551614, 3), mod(-2, 3);
+select mod(5, cast(-2 as unsigned)), mod(5, 18446744073709551614), mod(5, -2);
+select truncate(cast(-2 as unsigned), 1), truncate(18446744073709551614, 1), truncate(-2,
1);
+select truncate(4, cast(-2 as unsigned)), truncate(4, 18446744073709551614), truncate(4,
-2);
+select pow(cast(-2 as unsigned), 5), pow(18446744073709551614, 5), pow(-2, 5);
+
# End of 4.1 tests
#
| Thread |
|---|
| • bk commit into 5.0 tree (igreenhoe:1.2391) BUG#24912 | Ian Greenhoe | 24 Jan |