List:Internals« Previous MessageNext Message »
From:Jim Winstead Date:March 12 2005 1:53am
Subject:bk commit into 4.1 tree (jimw:1.2110) BUG#7036
View as plain text  
Below is the list of changes that have just been committed into a local
4.1 repository of jimw. When jimw 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
  1.2110 05/03/11 17:53:38 jimw@stripped +8 -0
  Fix CAST(<value> AS UNSIGNED) to handle large integer values
  passed within strings. (Bug #7036)

  sql/procedure.h
    1.17 05/03/11 17:53:36 jimw@stripped +5 -2
    Use unsigned_flag to decide whether to call my_strntoll()
    or my_strntoull() in val_int() method.

  sql/item_sum.h
    1.79 05/03/11 17:53:36 jimw@stripped +10 -2
    Use unsigned_flag to decide whether to call my_strntoll()
    or my_strntoull() in val_int() method.

  sql/item_strfunc.cc
    1.220 05/03/11 17:53:36 jimw@stripped +8 -4
    Use unsigned_flag to decide whether to call my_strntoll()
    or my_strntoull() in val_int() method.

  sql/item_func.h
    1.120 05/03/11 17:53:36 jimw@stripped +23 -2
    Add Item_func_unsigned::val_int() that fiddles with unsigned_flag of its
    argument to get an unsigned result out of Item objects that
    use my_strntoll().

  sql/item.h
    1.173 05/03/11 17:53:36 jimw@stripped +15 -4
    Use unsigned_flag to decide whether to call my_strntoll()
    or my_strntoull() in various val_int() methods.

  sql/item.cc
    1.194 05/03/11 17:53:36 jimw@stripped +12 -4
    Use unsigned_flag to decide whether to call my_strntoll()
    or my_strntoull() in various val_int() methods.

  mysql-test/t/cast.test
    1.16 05/03/11 17:53:36 jimw@stripped +13 -0
    Add new regression test

  mysql-test/r/cast.result
    1.22 05/03/11 17:53:36 jimw@stripped +24 -0
    Add new results

# 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:	jimw
# Host:	rama.(none)
# Root:	/home/jimw/my/mysql-4.1-7036v2

--- 1.193/sql/item.cc	2005-03-09 06:50:57 -08:00
+++ 1.194/sql/item.cc	2005-03-11 17:53:36 -08:00
@@ -1164,8 +1164,12 @@
   case LONG_DATA_VALUE:
     {
       int dummy_err;
-      return my_strntoll(str_value.charset(), str_value.ptr(),
-                         str_value.length(), 10, (char**) 0, &dummy_err);
+      if (unsigned_flag)
+        return my_strntoull(str_value.charset(), str_value.ptr(),
+                            str_value.length(), 10, (char**) 0, &dummy_err);
+      else
+        return my_strntoll(str_value.charset(), str_value.ptr(),
+                           str_value.length(), 10, (char**) 0, &dummy_err);
     }
   case TIME_VALUE:
     return (longlong) TIME_to_ulonglong(&value.time);
@@ -2595,8 +2599,12 @@
   DBUG_ASSERT(fixed == 1);
   int err;
   if (value)
-    return my_strntoll(value->charset(), value->ptr(),
-		       value->length(), 10, (char**) 0, &err);
+    if (unsigned_flag)
+      return my_strntoull(value->charset(), value->ptr(),
+                          value->length(), 10, (char**) 0, &err);
+    else
+      return my_strntoll(value->charset(), value->ptr(),
+                         value->length(), 10, (char**) 0, &err);
   else
     return (longlong)0;
 }

--- 1.172/sql/item.h	2005-03-04 02:16:24 -08:00
+++ 1.173/sql/item.h	2005-03-11 17:53:36 -08:00
@@ -723,8 +723,12 @@
   {
     DBUG_ASSERT(fixed == 1);
     int err;
-    return my_strntoll(str_value.charset(), str_value.ptr(),
-		       str_value.length(), 10, (char**) 0, &err);
+    if (unsigned_flag)
+      return my_strntoull(str_value.charset(), str_value.ptr(),
+                          str_value.length(), 10, (char**) 0, &err);
+    else
+      return my_strntoll(str_value.charset(), str_value.ptr(),
+                         str_value.length(), 10, (char**) 0, &err);
   }
   String *val_str(String*)
   {
@@ -1054,9 +1058,16 @@
 		       str_value.length(), &end_not_used, &err));
   }
   longlong val_int()
-  { 
+  {
     int err;
-    return null_value ? LL(0) : my_strntoll(str_value.charset(),str_value.ptr(),str_value.length(),10, (char**) 0,&err); 
+    if (null_value)
+      return LL(0);
+    if (unsigned_flag)
+      return my_strntoull(str_value.charset(),str_value.ptr(),
+                          str_value.length(), 10, (char**) 0,&err);
+    else
+      return my_strntoll(str_value.charset(),str_value.ptr(),
+                         str_value.length(), 10, (char**) 0,&err);
   }
   String *val_str(String*);
   void make_field(Send_field *field) { item->make_field(field); }

--- 1.119/sql/item_func.h	2005-02-22 02:51:19 -08:00
+++ 1.120/sql/item_func.h	2005-03-11 17:53:36 -08:00
@@ -245,6 +245,19 @@
   const char *func_name() const { return "cast_as_unsigned"; }
   void fix_length_and_dec()
   { max_length=args[0]->max_length; unsigned_flag=1; }
+  longlong val_int()
+  {
+    /*
+      Set unsigned_flag on args[0] so that we will get an unsigned
+      result from val_int(), but reset it after we've done so.
+     */
+    my_bool old_uf= args[0]->unsigned_flag;
+    args[0]->unsigned_flag= TRUE;
+    longlong tmp= args[0]->val_int();
+    args[0]->unsigned_flag= old_uf;
+    null_value= args[0]->null_value;
+    return tmp;
+  }
   void print(String *str);
 };
 
@@ -837,8 +850,16 @@
   longlong val_int()
   {
     int err;
-    String *res;  res=val_str(&str_value);
-    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,(char**) 0,&err) : (longlong) 0;
+    String *res;
+    res= val_str(&str_value);
+    if (!res)
+      return (longlong) 0;
+    if (unsigned_flag)
+      return my_strntoull(res->charset(),res->ptr(),res->length(),
+                          10,(char**) 0,&err);
+    else
+      return my_strntoll(res->charset(),res->ptr(),res->length(),
+                         10,(char**) 0,&err);
   }
   enum Item_result result_type () const { return STRING_RESULT; }
   void fix_length_and_dec();

--- 1.219/sql/item_strfunc.cc	2005-03-09 10:37:24 -08:00
+++ 1.220/sql/item_strfunc.cc	2005-03-11 17:53:36 -08:00
@@ -77,10 +77,14 @@
   char buff[22];
   String *res, tmp(buff,sizeof(buff), &my_charset_bin);
   res= val_str(&tmp);
-  return (res ?
-	  my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
-		      &err) :
-	  (longlong) 0);
+  if (!res)
+    return (longlong) 0;
+  if (unsigned_flag)
+    return my_strntoull(res->charset(), res->ptr(), res->length(),
+                        10, NULL, &err);
+  else
+    return my_strntoll(res->charset(), res->ptr(), res->length(),
+                       10, NULL, &err);
 }
 
 

--- 1.78/sql/item_sum.h	2005-02-22 02:51:20 -08:00
+++ 1.79/sql/item_sum.h	2005-03-11 17:53:36 -08:00
@@ -609,8 +609,16 @@
   longlong val_int()
   {
     int err;
-    String *res;  res=val_str(&str_value);
-    return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10, (char**) 0, &err) : (longlong) 0;
+    String *res;
+    res= val_str(&str_value);
+    if (!res)
+      return (longlong) 0;
+    if (unsigned_flag)
+      return my_strntoull(res->charset(),res->ptr(),res->length(),
+                          10, (char**) 0, &err);
+    else
+      return my_strntoll(res->charset(),res->ptr(),res->length(),
+                         10, (char**) 0, &err);
   }
   enum Item_result result_type () const { return STRING_RESULT; }
   void fix_length_and_dec();

--- 1.16/sql/procedure.h	2005-02-22 02:51:20 -08:00
+++ 1.17/sql/procedure.h	2005-03-11 17:53:36 -08:00
@@ -109,10 +109,13 @@
 		      &end_not_used, &err);
   }
   longlong val_int()
-  { 
+  {
     int err;
     CHARSET_INFO *cs=str_value.charset();
-    return my_strntoll(cs,str_value.ptr(),str_value.length(),10,NULL,&err);
+    if (unsigned_flag)
+      return my_strntoull(cs,str_value.ptr(),str_value.length(),10,NULL,&err);
+    else
+      return my_strntoll(cs,str_value.ptr(),str_value.length(),10,NULL,&err);
   }
   String *val_str(String*)
   {

--- 1.21/mysql-test/r/cast.result	2004-12-30 02:38:29 -08:00
+++ 1.22/mysql-test/r/cast.result	2005-03-11 17:53:36 -08:00
@@ -187,3 +187,27 @@
 select timediff(cast('1 12:00:00' as time), '12:00:00');
 timediff(cast('1 12:00:00' as time), '12:00:00')
 24:00:00
+select cast(18446744073709551615 as unsigned);
+cast(18446744073709551615 as unsigned)
+18446744073709551615
+select cast(18446744073709551615 as signed);
+cast(18446744073709551615 as signed)
+-1
+select cast('18446744073709551615' as unsigned);
+cast('18446744073709551615' as unsigned)
+18446744073709551615
+select cast('18446744073709551615' as signed);
+cast('18446744073709551615' as signed)
+9223372036854775807
+select cast(concat('184467440','73709551615') as unsigned);
+cast(concat('184467440','73709551615') as unsigned)
+18446744073709551615
+select cast(concat('184467440','73709551615') as signed);
+cast(concat('184467440','73709551615') as signed)
+9223372036854775807
+select cast(repeat('1',20) as unsigned);
+cast(repeat('1',20) as unsigned)
+11111111111111111111
+select cast(repeat('1',20) as signed);
+cast(repeat('1',20) as signed)
+9223372036854775807

--- 1.15/mysql-test/t/cast.test	2004-12-30 02:38:29 -08:00
+++ 1.16/mysql-test/t/cast.test	2005-03-11 17:53:36 -08:00
@@ -118,3 +118,16 @@
 select timediff(cast('2004-12-30 12:00:00' as time), '12:00:00');
 # Still we should not throw away "days" part of time value
 select timediff(cast('1 12:00:00' as time), '12:00:00');
+
+# Bug #7036: Casting from string to unsigned would cap value of result at
+# maximum signed value instead of maximum unsigned value
+select cast(18446744073709551615 as unsigned);
+select cast(18446744073709551615 as signed);
+select cast('18446744073709551615' as unsigned);
+select cast('18446744073709551615' as signed);
+
+select cast(concat('184467440','73709551615') as unsigned);
+select cast(concat('184467440','73709551615') as signed);
+
+select cast(repeat('1',20) as unsigned);
+select cast(repeat('1',20) as signed);
Thread
bk commit into 4.1 tree (jimw:1.2110) BUG#7036Jim Winstead12 Mar