Commit 173efef4 authored by unknown's avatar unknown

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

into  kaamos.(none):/data/src/opt/mysql-5.1-opt


configure.in:
  Auto merged
mysql-test/r/strict.result:
  Auto merged
sql/field.cc:
  Auto merged
sql/item_func.cc:
  Auto merged
sql/unireg.h:
  Auto merged
parents a09384cb 61c31af4
......@@ -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])
......
......@@ -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. */
......
......@@ -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
......@@ -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
......
......@@ -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
......@@ -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;
......
......@@ -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;
......
......@@ -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()
......
......@@ -192,6 +192,13 @@ class Item_func :public Item_result_field
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
......
/* 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 @@
#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)
......
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