List:Commits« Previous MessageNext Message »
From:Alexey Kopytov Date:February 19 2008 5:48pm
Subject:bk commit into 5.1 tree (kaa:1.2659) BUG#31236
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of kaa.  When kaa 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, 2008-02-19 19:48:24+03:00, kaa@kaamos.(none) +9 -0
  Fix for bug #31236: Inconsistent division by zero behavior for 
                      floating point numbers
  
  Some math functions did not check if the result is a valid number
  (i.e. neither of +-inf or nan).
  
  Fixed by validating the result where necessary and returning NULL in
  case of invalid result.

  BitKeeper/deleted/.del-matherr.c@stripped, 2008-02-19 19:46:03+03:00, kaa@kaamos.(none) +0 -0
    Rename: sql/matherr.c -> BitKeeper/deleted/.del-matherr.c

  configure.in@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +2 -2
    Removed DONT_USE_FINITE, it is not used anywhere.

  include/my_global.h@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +7 -6
    isfinite() is a C99 macro which absoletes finite(). First try to use
    it, then fall back to finite() if the target platform has it,
    otherwise use our own implementation.

  mysql-test/r/func_math.result@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +19 -0
    Added a test case for bug #31236.

  mysql-test/t/func_math.test@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +13 -1
    Added a test case for bug #31236.

  sql/field.cc@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +1 -3
    No need to check if the finite() or its equivalent is available.

  sql/item_func.cc@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +12 -12
    Use fix_result() wherever the result can be one of +-inf or nan, 
    assuming the function arguments are valid numbers.
    Removed fix_result() from functions that are defined for all possible
    input numbers.

  sql/item_func.h@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +7 -12
    Moved fix_result() from Item_dec_func to Item_func which is a common
    ancestor for Item_dec_func and Item_num_op.

  sql/unireg.h@stripped, 2008-02-19 19:48:22+03:00, kaa@kaamos.(none) +0 -1
    Removed POSTFIX_ERROR because no code returns it.

diff -Nrup a/configure.in b/configure.in
--- a/configure.in	2007-12-14 20:03:30 +03:00
+++ b/configure.in	2008-02-19 19:48:22 +03:00
@@ -991,8 +991,8 @@ case $SYSTEM_TYPE in
     ;;
   *hpux11.*)
     AC_MSG_WARN([Enabling workarounds for hpux 11])
-    CFLAGS="$CFLAGS -DHPUX11  -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD
-DDONT_USE_FINITE -DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK
-DDO_NOT_REMOVE_THREAD_WRAPPERS -DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
-    CXXFLAGS="$CXXFLAGS -DHPUX11  -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD
-DDONT_USE_FINITE -D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS
-DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+    CFLAGS="$CFLAGS -DHPUX11  -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD
-DHAVE_BROKEN_GETPASS -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS
-DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
+    CXXFLAGS="$CXXFLAGS -DHPUX11  -DSNPRINTF_RETURN_TRUNC -DHAVE_BROKEN_PREAD
-D_INCLUDE_LONGLONG -DNO_FCNTL_NONBLOCK -DDO_NOT_REMOVE_THREAD_WRAPPERS
-DHAVE_BROKEN_PTHREAD_COND_TIMEDWAIT"
     if test "$with_named_thread" = "no"
     then 
       AC_MSG_WARN([Using --with-named-thread=-lpthread])
diff -Nrup a/include/my_global.h b/include/my_global.h
--- a/include/my_global.h	2007-11-30 03:38:25 +03:00
+++ b/include/my_global.h	2008-02-19 19:48:22 +03:00
@@ -486,9 +486,6 @@ C_MODE_END
 #include <sys/stream.h>		/* HPUX 10.20 defines ulong here. UGLY !!! */
 #define HAVE_ULONG
 #endif
-#ifdef DONT_USE_FINITE		/* HPUX 11.x has is_finite() */
-#undef HAVE_FINITE
-#endif
 #if defined(HPUX10) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
 /* Fix bug in setrlimit */
 #undef setrlimit
@@ -858,9 +855,13 @@ typedef SOCKET_SIZE_TYPE size_socket;
 #define SIZE_T_MAX ~((size_t) 0)
 #endif
 
-#ifndef HAVE_FINITE
+#ifndef isfinite
+#ifdef HAVE_FINITE
+#define isfinite(x) finite(x)
+#else
 #define finite(x) (1.0 / fabs(x) > 0.0)
-#endif
+#endif /* HAVE_FINITE */
+#endif /* isfinite */
 
 #ifndef HAVE_ISNAN
 #define isnan(x) ((x) != (x))
@@ -870,7 +871,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
 /* isinf() can be used in both C and C++ code */
 #define my_isinf(X) isinf(X)
 #else
-#define my_isinf(X) (!finite(X) && !isnan(X))
+#define my_isinf(X) (!isfinite(X) && !isnan(X))
 #endif
 
 /* Define missing math constants. */
diff -Nrup a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
--- a/mysql-test/r/func_math.result	2007-10-04 16:10:54 +04:00
+++ b/mysql-test/r/func_math.result	2008-02-19 19:48:22 +03:00
@@ -408,3 +408,22 @@ a DIV 2
 0
 DROP TABLE t1;
 End of 5.0 tests
+SELECT 1e308 + 1e308;
+1e308 + 1e308
+NULL
+SELECT -1e308 - 1e308;
+-1e308 - 1e308
+NULL
+SELECT 1e300 * 1e300;
+1e300 * 1e300
+NULL
+SELECT 1e300 / 1e-300;
+1e300 / 1e-300
+NULL
+SELECT EXP(750);
+EXP(750)
+NULL
+SELECT POW(10, 309);
+POW(10, 309)
+NULL
+End of 5.1 tests
diff -Nrup a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
--- a/mysql-test/t/func_math.test	2007-10-04 16:10:54 +04:00
+++ b/mysql-test/t/func_math.test	2008-02-19 19:48:22 +03:00
@@ -248,5 +248,17 @@ INSERT INTO t1 VALUES ('a');
 SELECT a DIV 2 FROM t1 UNION SELECT a DIV 2 FROM t1;
 DROP TABLE t1;
 
-
 --echo End of 5.0 tests
+
+#
+# Bug #31236: Inconsistent division by zero behavior for floating point numbers
+#
+
+SELECT 1e308 + 1e308;
+SELECT -1e308 - 1e308;
+SELECT 1e300 * 1e300;
+SELECT 1e300 / 1e-300;
+SELECT EXP(750);
+SELECT POW(10, 309);
+
+--echo End of 5.1 tests
diff -Nrup a/sql/field.cc b/sql/field.cc
--- a/sql/field.cc	2008-01-10 13:46:31 +03:00
+++ b/sql/field.cc	2008-02-19 19:48:22 +03:00
@@ -2263,13 +2263,11 @@ int Field_decimal::store(double nr)
     return 1;
   }
   
-#ifdef HAVE_FINITE
-  if (!finite(nr)) // Handle infinity as special case
+  if (!isfinite(nr)) // Handle infinity as special case
   {
     overflow(nr < 0.0);
     return 1;
   }
-#endif
 
   reg4 uint i;
   size_t length;
diff -Nrup a/sql/item_func.cc b/sql/item_func.cc
--- a/sql/item_func.cc	2008-01-19 20:59:07 +03:00
+++ b/sql/item_func.cc	2008-02-19 19:48:22 +03:00
@@ -1104,7 +1104,7 @@ double Item_func_plus::real_op()
   double value= args[0]->val_real() + args[1]->val_real();
   if ((null_value=args[0]->null_value || args[1]->null_value))
     return 0.0;
-  return value;
+  return fix_result(value);
 }
 
 
@@ -1186,7 +1186,7 @@ double Item_func_minus::real_op()
   double value= args[0]->val_real() - args[1]->val_real();
   if ((null_value=args[0]->null_value || args[1]->null_value))
     return 0.0;
-  return value;
+  return fix_result(value);
 }
 
 
@@ -1224,7 +1224,7 @@ double Item_func_mul::real_op()
   double value= args[0]->val_real() * args[1]->val_real();
   if ((null_value=args[0]->null_value || args[1]->null_value))
     return 0.0;
-  return value;
+  return fix_result(value);
 }
 
 
@@ -1282,7 +1282,7 @@ double Item_func_div::real_op()
     signal_divide_by_null();
     return 0.0;
   }
-  return value/val2;
+  return fix_result(value/val2);
 }
 
 
@@ -1655,7 +1655,7 @@ double Item_func_exp::val_real()
   double value= args[0]->val_real();
   if ((null_value=args[0]->null_value))
     return 0.0; /* purecov: inspected */
-  return exp(value);
+  return fix_result(exp(value));
 }
 
 double Item_func_sqrt::val_real()
@@ -1674,7 +1674,7 @@ double Item_func_pow::val_real()
   double val2= args[1]->val_real();
   if ((null_value=(args[0]->null_value || args[1]->null_value)))
     return 0.0; /* purecov: inspected */
-  return pow(value,val2);
+  return fix_result(pow(value,val2));
 }
 
 // Trigonometric functions
@@ -1686,7 +1686,7 @@ double Item_func_acos::val_real()
   volatile double value= args[0]->val_real();
   if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
     return 0.0;
-  return fix_result(acos(value));
+  return acos(value);
 }
 
 double Item_func_asin::val_real()
@@ -1696,7 +1696,7 @@ double Item_func_asin::val_real()
   volatile double value= args[0]->val_real();
   if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
     return 0.0;
-  return fix_result(asin(value));
+  return asin(value);
 }
 
 double Item_func_atan::val_real()
@@ -1710,9 +1710,9 @@ double Item_func_atan::val_real()
     double val2= args[1]->val_real();
     if ((null_value=args[1]->null_value))
       return 0.0;
-    return fix_result(atan2(value,val2));
+    return atan2(value,val2);
   }
-  return fix_result(atan(value));
+  return atan(value);
 }
 
 double Item_func_cos::val_real()
@@ -1721,7 +1721,7 @@ double Item_func_cos::val_real()
   double value= args[0]->val_real();
   if ((null_value=args[0]->null_value))
     return 0.0;
-  return fix_result(cos(value));
+  return cos(value);
 }
 
 double Item_func_sin::val_real()
@@ -1730,7 +1730,7 @@ double Item_func_sin::val_real()
   double value= args[0]->val_real();
   if ((null_value=args[0]->null_value))
     return 0.0;
-  return fix_result(sin(value));
+  return sin(value);
 }
 
 double Item_func_tan::val_real()
diff -Nrup a/sql/item_func.h b/sql/item_func.h
--- a/sql/item_func.h	2007-12-13 14:57:03 +03:00
+++ b/sql/item_func.h	2008-02-19 19:48:22 +03:00
@@ -192,6 +192,13 @@ public:
                      void * arg, traverse_order order);
   bool is_expensive_processor(uchar *arg);
   virtual bool is_expensive() { return 0; }
+  inline double fix_result(double value)
+  {
+    if (isfinite(value))
+      return value;
+    null_value=1;
+    return 0.0;
+  }
 };
 
 
@@ -498,18 +505,6 @@ class Item_dec_func :public Item_real_fu
   {
     decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
     maybe_null=1;
-  }
-  inline double fix_result(double value)
-  {
-#ifndef HAVE_FINITE
-    return value;
-#else
-    /* The following should be safe, even if we compare doubles */
-    if (finite(value) && value != POSTFIX_ERROR)
-      return value;
-    null_value=1;
-    return 0.0;
-#endif
   }
 };
 
diff -Nrup a/sql/matherr.c b/sql/matherr.c
--- a/sql/matherr.c	2006-12-30 23:02:07 +03:00
+++ /dev/null	Wed Dec 31 16:00:00 196900
@@ -1,42 +0,0 @@
-/* Copyright (C) 2000-2001 MySQL AB
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; version 2 of the License.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-   GNU General Public License for more details.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
-
-/* Fix that we got POSTFIX_ERROR when doing unreasonable math (not core) */
-
-#include <my_global.h>
-#include <errno.h>
-
-	/* Fix that we gets POSTFIX_ERROR when error in math */
-
-#if defined(HAVE_MATHERR)
-int matherr(struct exception *x)
-{
-  if (x->type != PLOSS)
-    x->retval=POSTFIX_ERROR;
-  switch (x->type) {
-  case DOMAIN:
-  case SING:
-    my_errno=EDOM;
-    break;
-  case OVERFLOW:
-  case UNDERFLOW:
-    my_errno=ERANGE;
-    break;
-  default:
-    break;
-  }
-  return(1);					/* Take no other action */
-}
-#endif
diff -Nrup a/sql/unireg.h b/sql/unireg.h
--- a/sql/unireg.h	2007-09-10 15:16:01 +04:00
+++ b/sql/unireg.h	2008-02-19 19:48:22 +03:00
@@ -108,7 +108,6 @@
 
 #define READ_RECORD_BUFFER	(uint) (IO_SIZE*8) /* Pointer_buffer_size */
 #define DISK_BUFFER_SIZE	(uint) (IO_SIZE*16) /* Size of diskbuffer */
-#define POSTFIX_ERROR		DBL_MAX
 
 #define ME_INFO (ME_HOLDTANG+ME_OLDWIN+ME_NOREFRESH)
 #define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH)
Thread
bk commit into 5.1 tree (kaa:1.2659) BUG#31236Alexey Kopytov19 Feb 2008