Commit 58240614 authored by kaa@kaamos.(none)'s avatar kaa@kaamos.(none)

Merge kaamos.(none):/data/src/opt/bug31236/my51-bug31236

into  kaamos.(none):/data/src/opt/mysql-5.1-opt
parents ee33f136 8d222210
...@@ -1031,8 +1031,8 @@ case $SYSTEM_TYPE in ...@@ -1031,8 +1031,8 @@ case $SYSTEM_TYPE in
;; ;;
*hpux11.*) *hpux11.*)
AC_MSG_WARN([Enabling workarounds for hpux 11]) 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" 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 -DDONT_USE_FINITE -D_INCLUDE_LONGLONG -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" if test "$with_named_thread" = "no"
then then
AC_MSG_WARN([Using --with-named-thread=-lpthread]) AC_MSG_WARN([Using --with-named-thread=-lpthread])
......
...@@ -486,9 +486,6 @@ C_MODE_END ...@@ -486,9 +486,6 @@ C_MODE_END
#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */ #include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
#define HAVE_ULONG #define HAVE_ULONG
#endif #endif
#ifdef DONT_USE_FINITE /* HPUX 11.x has is_finite() */
#undef HAVE_FINITE
#endif
#if defined(HPUX10) && defined(_LARGEFILE64_SOURCE) && defined(THREAD) #if defined(HPUX10) && defined(_LARGEFILE64_SOURCE) && defined(THREAD)
/* Fix bug in setrlimit */ /* Fix bug in setrlimit */
#undef setrlimit #undef setrlimit
...@@ -858,9 +855,13 @@ typedef SOCKET_SIZE_TYPE size_socket; ...@@ -858,9 +855,13 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define SIZE_T_MAX ~((size_t) 0) #define SIZE_T_MAX ~((size_t) 0)
#endif #endif
#ifndef HAVE_FINITE #ifndef isfinite
#ifdef HAVE_FINITE
#define isfinite(x) finite(x)
#else
#define finite(x) (1.0 / fabs(x) > 0.0) #define finite(x) (1.0 / fabs(x) > 0.0)
#endif #endif /* HAVE_FINITE */
#endif /* isfinite */
#ifndef HAVE_ISNAN #ifndef HAVE_ISNAN
#define isnan(x) ((x) != (x)) #define isnan(x) ((x) != (x))
...@@ -870,7 +871,7 @@ typedef SOCKET_SIZE_TYPE size_socket; ...@@ -870,7 +871,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* isinf() can be used in both C and C++ code */ /* isinf() can be used in both C and C++ code */
#define my_isinf(X) isinf(X) #define my_isinf(X) isinf(X)
#else #else
#define my_isinf(X) (!finite(X) && !isnan(X)) #define my_isinf(X) (!isfinite(X) && !isnan(X))
#endif #endif
/* Define missing math constants. */ /* Define missing math constants. */
......
...@@ -408,3 +408,22 @@ a DIV 2 ...@@ -408,3 +408,22 @@ a DIV 2
0 0
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests 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
...@@ -895,7 +895,6 @@ ERROR 22003: Out of range value for column 'col1' at row 1 ...@@ -895,7 +895,6 @@ ERROR 22003: Out of range value for column 'col1' at row 1
INSERT INTO t1 (col2) VALUES ('-1.2E-3'); INSERT INTO t1 (col2) VALUES ('-1.2E-3');
ERROR 22003: Out of range value for column 'col2' at row 1 ERROR 22003: Out of range value for column 'col2' at row 1
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0; 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; UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
ERROR 22012: Division by 0 ERROR 22012: Division by 0
UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0; UPDATE t1 SET col2= MOD(col2,0) WHERE col2 > 0;
...@@ -923,10 +922,10 @@ SELECT * FROM t1; ...@@ -923,10 +922,10 @@ SELECT * FROM t1;
col1 col2 col1 col2
-2.2e-307 0 -2.2e-307 0
1e-303 0 1e-303 0
1.7e+308 1.7e+308 NULL 1.7e+308
-2.2e-307 0 -2.2e-307 0
-2e-307 0 -2e-307 0
1.7e+308 1.7e+308 NULL 1.7e+308
0 NULL 0 NULL
2 NULL 2 NULL
NULL NULL NULL NULL
......
...@@ -248,5 +248,17 @@ INSERT INTO t1 VALUES ('a'); ...@@ -248,5 +248,17 @@ INSERT INTO t1 VALUES ('a');
SELECT a DIV 2 FROM t1 UNION SELECT a DIV 2 FROM t1; SELECT a DIV 2 FROM t1 UNION SELECT a DIV 2 FROM t1;
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.0 tests --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
...@@ -822,7 +822,6 @@ INSERT INTO t1 (col2) VALUES (-1.1E-3); ...@@ -822,7 +822,6 @@ INSERT INTO t1 (col2) VALUES (-1.1E-3);
INSERT INTO t1 (col1) VALUES ('+1.8E+309'); INSERT INTO t1 (col1) VALUES ('+1.8E+309');
--error 1264 --error 1264
INSERT INTO t1 (col2) VALUES ('-1.2E-3'); INSERT INTO t1 (col2) VALUES ('-1.2E-3');
--error 1264
UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0; UPDATE t1 SET col1 =col1 * 5000 WHERE col1 > 0;
--error 1365 --error 1365
UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0; UPDATE t1 SET col2 =col2 / 0 WHERE col2 > 0;
......
...@@ -2261,13 +2261,11 @@ int Field_decimal::store(double nr) ...@@ -2261,13 +2261,11 @@ int Field_decimal::store(double nr)
return 1; return 1;
} }
#ifdef HAVE_FINITE if (!isfinite(nr)) // Handle infinity as special case
if (!finite(nr)) // Handle infinity as special case
{ {
overflow(nr < 0.0); overflow(nr < 0.0);
return 1; return 1;
} }
#endif
reg4 uint i; reg4 uint i;
size_t length; size_t length;
......
...@@ -1093,7 +1093,7 @@ double Item_func_plus::real_op() ...@@ -1093,7 +1093,7 @@ double Item_func_plus::real_op()
double value= args[0]->val_real() + args[1]->val_real(); double value= args[0]->val_real() + args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value)) if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0; return 0.0;
return value; return fix_result(value);
} }
...@@ -1171,7 +1171,7 @@ double Item_func_minus::real_op() ...@@ -1171,7 +1171,7 @@ double Item_func_minus::real_op()
double value= args[0]->val_real() - args[1]->val_real(); double value= args[0]->val_real() - args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value)) if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0; return 0.0;
return value; return fix_result(value);
} }
...@@ -1211,7 +1211,7 @@ double Item_func_mul::real_op() ...@@ -1211,7 +1211,7 @@ double Item_func_mul::real_op()
double value= args[0]->val_real() * args[1]->val_real(); double value= args[0]->val_real() * args[1]->val_real();
if ((null_value=args[0]->null_value || args[1]->null_value)) if ((null_value=args[0]->null_value || args[1]->null_value))
return 0.0; return 0.0;
return value; return fix_result(value);
} }
...@@ -1269,7 +1269,7 @@ double Item_func_div::real_op() ...@@ -1269,7 +1269,7 @@ double Item_func_div::real_op()
signal_divide_by_null(); signal_divide_by_null();
return 0.0; return 0.0;
} }
return value/val2; return fix_result(value/val2);
} }
...@@ -1643,7 +1643,7 @@ double Item_func_exp::val_real() ...@@ -1643,7 +1643,7 @@ double Item_func_exp::val_real()
double value= args[0]->val_real(); double value= args[0]->val_real();
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0.0; /* purecov: inspected */ return 0.0; /* purecov: inspected */
return exp(value); return fix_result(exp(value));
} }
double Item_func_sqrt::val_real() double Item_func_sqrt::val_real()
...@@ -1662,7 +1662,7 @@ double Item_func_pow::val_real() ...@@ -1662,7 +1662,7 @@ double Item_func_pow::val_real()
double val2= args[1]->val_real(); double val2= args[1]->val_real();
if ((null_value=(args[0]->null_value || args[1]->null_value))) if ((null_value=(args[0]->null_value || args[1]->null_value)))
return 0.0; /* purecov: inspected */ return 0.0; /* purecov: inspected */
return pow(value,val2); return fix_result(pow(value,val2));
} }
// Trigonometric functions // Trigonometric functions
...@@ -1674,7 +1674,7 @@ double Item_func_acos::val_real() ...@@ -1674,7 +1674,7 @@ double Item_func_acos::val_real()
volatile double value= args[0]->val_real(); volatile double value= args[0]->val_real();
if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
return 0.0; return 0.0;
return fix_result(acos(value)); return acos(value);
} }
double Item_func_asin::val_real() double Item_func_asin::val_real()
...@@ -1684,7 +1684,7 @@ double Item_func_asin::val_real() ...@@ -1684,7 +1684,7 @@ double Item_func_asin::val_real()
volatile double value= args[0]->val_real(); volatile double value= args[0]->val_real();
if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0)))) if ((null_value=(args[0]->null_value || (value < -1.0 || value > 1.0))))
return 0.0; return 0.0;
return fix_result(asin(value)); return asin(value);
} }
double Item_func_atan::val_real() double Item_func_atan::val_real()
...@@ -1700,7 +1700,7 @@ double Item_func_atan::val_real() ...@@ -1700,7 +1700,7 @@ double Item_func_atan::val_real()
return 0.0; return 0.0;
return fix_result(atan2(value,val2)); return fix_result(atan2(value,val2));
} }
return fix_result(atan(value)); return atan(value);
} }
double Item_func_cos::val_real() double Item_func_cos::val_real()
...@@ -1709,7 +1709,7 @@ double Item_func_cos::val_real() ...@@ -1709,7 +1709,7 @@ double Item_func_cos::val_real()
double value= args[0]->val_real(); double value= args[0]->val_real();
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0.0; return 0.0;
return fix_result(cos(value)); return cos(value);
} }
double Item_func_sin::val_real() double Item_func_sin::val_real()
...@@ -1718,7 +1718,7 @@ double Item_func_sin::val_real() ...@@ -1718,7 +1718,7 @@ double Item_func_sin::val_real()
double value= args[0]->val_real(); double value= args[0]->val_real();
if ((null_value=args[0]->null_value)) if ((null_value=args[0]->null_value))
return 0.0; return 0.0;
return fix_result(sin(value)); return sin(value);
} }
double Item_func_tan::val_real() double Item_func_tan::val_real()
......
...@@ -192,6 +192,13 @@ public: ...@@ -192,6 +192,13 @@ public:
void * arg, traverse_order order); void * arg, traverse_order order);
bool is_expensive_processor(uchar *arg); bool is_expensive_processor(uchar *arg);
virtual bool is_expensive() { return 0; } 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 ...@@ -499,18 +506,6 @@ class Item_dec_func :public Item_real_func
decimals=NOT_FIXED_DEC; max_length=float_length(decimals); decimals=NOT_FIXED_DEC; max_length=float_length(decimals);
maybe_null=1; 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 class Item_func_exp :public Item_dec_func
......
/* 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
...@@ -108,7 +108,6 @@ ...@@ -108,7 +108,6 @@
#define READ_RECORD_BUFFER (uint) (IO_SIZE*8) /* Pointer_buffer_size */ #define READ_RECORD_BUFFER (uint) (IO_SIZE*8) /* Pointer_buffer_size */
#define DISK_BUFFER_SIZE (uint) (IO_SIZE*16) /* Size of diskbuffer */ #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_INFO (ME_HOLDTANG+ME_OLDWIN+ME_NOREFRESH)
#define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH) #define ME_ERROR (ME_BELL+ME_OLDWIN+ME_NOREFRESH)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment