summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in4
-rw-r--r--include/my_global.h13
-rw-r--r--mysql-test/r/func_math.result19
-rw-r--r--mysql-test/r/strict.result5
-rw-r--r--mysql-test/t/func_math.test14
-rw-r--r--mysql-test/t/strict.test1
-rw-r--r--sql/field.cc4
-rw-r--r--sql/item_func.cc22
-rw-r--r--sql/item_func.h19
-rw-r--r--sql/matherr.c42
-rw-r--r--sql/unireg.h1
11 files changed, 62 insertions, 82 deletions
diff --git a/configure.in b/configure.in
index 2e623aacaf7..58fdf6d4375 100644
--- a/configure.in
+++ b/configure.in
@@ -1031,8 +1031,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 --git a/include/my_global.h b/include/my_global.h
index 4b0786aa826..26412d4102e 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -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 --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result
index 6a476d12896..b4a07f18521 100644
--- a/mysql-test/r/func_math.result
+++ b/mysql-test/r/func_math.result
@@ -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 --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 243c6192cc6..ef58a760297 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -895,7 +895,6 @@ ERROR 22003: Out of range value for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES ('-1.2E-3');
ERROR 22003: Out of range value for column 'col2' at row 1
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
-ERROR 22003: Out of range value for column 'col1' at row 3
UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
ERROR 22012: Division by 0
UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0;
@@ -923,10 +922,10 @@ SELECT * FROM t1;
col1 col2
-2.2e-307 0
1e-303 0
-1.7e+308 1.7e+308
+NULL 1.7e+308
-2.2e-307 0
-2e-307 0
-1.7e+308 1.7e+308
+NULL 1.7e+308
0 NULL
2 NULL
NULL NULL
diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test
index 274a953a314..87b172a6436 100644
--- a/mysql-test/t/func_math.test
+++ b/mysql-test/t/func_math.test
@@ -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 --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 2b71bf1093c..486f7ce7897 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -822,7 +822,6 @@ INSERT INTO t1 (col2) VALUES (-1.1E-3);
INSERT INTO t1 (col1) VALUES ('+1.8E+309');
--error 1264
INSERT INTO t1 (col2) VALUES ('-1.2E-3');
---error 1264
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
--error 1365
UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
diff --git a/sql/field.cc b/sql/field.cc
index 4a1db17b154..4b07da2c1c1 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -2261,13 +2261,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 --git a/sql/item_func.cc b/sql/item_func.cc
index 399aba12707..d9a32b596ed 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1093,7 +1093,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);
}
@@ -1171,7 +1171,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);
}
@@ -1211,7 +1211,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);
}
@@ -1269,7 +1269,7 @@ double Item_func_div::real_op()
signal_divide_by_null();
return 0.0;
}
- return value/val2;
+ return fix_result(value/val2);
}
@@ -1643,7 +1643,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()
@@ -1662,7 +1662,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
@@ -1674,7 +1674,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()
@@ -1684,7 +1684,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()
@@ -1700,7 +1700,7 @@ double Item_func_atan::val_real()
return 0.0;
return fix_result(atan2(value,val2));
}
- return fix_result(atan(value));
+ return atan(value);
}
double Item_func_cos::val_real()
@@ -1709,7 +1709,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()
@@ -1718,7 +1718,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 --git a/sql/item_func.h b/sql/item_func.h
index e09b584de95..cdcbbdab150 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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;
+ }
};
@@ -499,18 +506,6 @@ class Item_dec_func :public Item_real_func
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
- }
};
class Item_func_exp :public Item_dec_func
diff --git a/sql/matherr.c b/sql/matherr.c
deleted file mode 100644
index 4998d8b4961..00000000000
--- a/sql/matherr.c
+++ /dev/null
@@ -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 --git a/sql/unireg.h b/sql/unireg.h
index 2e0172ce31d..8731a0ac98a 100644
--- a/sql/unireg.h
+++ b/sql/unireg.h
@@ -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)