diff --git a/configure.in b/configure.in index 7148c26187a..cb48710f5c6 100644 --- a/configure.in +++ b/configure.in @@ -838,8 +838,8 @@ AC_TYPE_SIZE_T AC_HEADER_DIRENT AC_HEADER_STDC AC_HEADER_SYS_WAIT -AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h ieeefp.h limits.h \ - memory.h pwd.h select.h \ +AC_CHECK_HEADERS(fcntl.h fenv.h float.h floatingpoint.h fpu_control.h \ + ieeefp.h limits.h memory.h pwd.h select.h \ stdlib.h stddef.h \ strings.h string.h synch.h sys/mman.h sys/socket.h netinet/in.h arpa/inet.h \ sys/timeb.h sys/types.h sys/un.h sys/vadvise.h sys/wait.h term.h \ diff --git a/mysql-test/r/explain.result b/mysql-test/r/explain.result index 8f2d704b312..f46fe8daaad 100644 --- a/mysql-test/r/explain.result +++ b/mysql-test/r/explain.result @@ -238,4 +238,17 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables DROP TABLE t1, t2; +# +# Bug #48573: difference of index selection between rpm binary and +# .tar.gz, windows vs linux.. +# +CREATE TABLE t1(c1 INT, c2 INT, c4 INT, c5 INT, KEY(c2, c5), KEY(c2, c4, c5)); +INSERT INTO t1 VALUES(4, 1, 1, 1); +INSERT INTO t1 VALUES(3, 1, 1, 1); +INSERT INTO t1 VALUES(2, 1, 1, 1); +INSERT INTO t1 VALUES(1, 1, 1, 1); +EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ref c2,c2_2 c2 10 const,const 3 Using where +DROP TABLE t1; End of 5.1 tests. diff --git a/mysql-test/t/explain.test b/mysql-test/t/explain.test index ba6be72dbdc..b635a1b2968 100644 --- a/mysql-test/t/explain.test +++ b/mysql-test/t/explain.test @@ -213,4 +213,19 @@ EXPLAIN SELECT 1 FROM t1 WHERE a = (SELECT 1 FROM t1 t JOIN t2 WHERE b <= 1 AND DROP TABLE t1, t2; +--echo # +--echo # Bug #48573: difference of index selection between rpm binary and +--echo # .tar.gz, windows vs linux.. +--echo # + +CREATE TABLE t1(c1 INT, c2 INT, c4 INT, c5 INT, KEY(c2, c5), KEY(c2, c4, c5)); +INSERT INTO t1 VALUES(4, 1, 1, 1); +INSERT INTO t1 VALUES(3, 1, 1, 1); +INSERT INTO t1 VALUES(2, 1, 1, 1); +INSERT INTO t1 VALUES(1, 1, 1, 1); + +EXPLAIN SELECT c1 FROM t1 WHERE c2 = 1 AND c4 = 1 AND c5 = 1; + +DROP TABLE t1; + --echo End of 5.1 tests. diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 3664f46995f..3ffc1a21e9c 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -183,6 +183,21 @@ typedef fp_except fp_except_t; /* for IRIX to use set_fpc_csr() */ #include #endif +#ifdef HAVE_FPU_CONTROL_H +#include +#endif +#if defined(__i386__) && !defined(HAVE_FPU_CONTROL_H) +# define fpu_control_t unsigned int +# define _FPU_EXTENDED 0x300 +# define _FPU_DOUBLE 0x200 +# ifdef __GNUC__ +# define _FPU_GETCW(cw) __asm__ __volatile__("fnstcw %0" : "=m" (*&cw)) +# define _FPU_SETCW(cw) __asm__ __volatile__("fldcw %0" : : "m" (*&cw)) +# else +# define _FPU_GETCW(cw) (cw= 0) +# define _FPU_SETCW(cw) +# endif +#endif inline void setup_fpu() { @@ -204,7 +219,26 @@ inline void setup_fpu() /* Set FPU rounding mode to "round-to-nearest" */ fesetround(FE_TONEAREST); #endif /* HAVE_FESETROUND */ - + + /* + x86 (32-bit) requires FPU precision to be explicitly set to 64 bit + (double precision) for portable results of floating point operations. + However, there is no need to do so if compiler is using SSE2 for floating + point, double values will be stored and processed in 64 bits anyway. + */ +#if defined(__i386__) && !defined(__SSE2_MATH__) +#if defined(_WIN32) +#if !defined(_WIN64) + _control87(_PC_53, MCW_PC); +#endif /* !_WIN64 */ +#else /* !_WIN32 */ + fpu_control_t cw; + _FPU_GETCW(cw); + cw= (cw & ~_FPU_EXTENDED) | _FPU_DOUBLE; + _FPU_SETCW(cw); +#endif /* _WIN32 && */ +#endif /* __i386__ */ + #if defined(__sgi) && defined(HAVE_SYS_FPU_H) /* Enable denormalized DOUBLE values support for IRIX */ union fpc_csr n;