Commit d3269f88 authored by unknown's avatar unknown
Browse files

Merge bk-internal.mysql.com:/home/bk/mysql-5.0-maint

into  polly.local:/home/kaa/src/maint/m50-maint--07OGt

parents a008b072 09e8459a
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -262,6 +262,13 @@ desc t3;
Field	Type	Null	Key	Default	Extra
a	decimal(21,2)	NO		0.00	
drop table t1,t2,t3;
select 1e-308, 1.00000001e-300, 100000000e-300;
1e-308	1.00000001e-300	100000000e-300
0	1.00000001e-300	1e-292
select 10e307;
10e307
1e+308
End of 4.1 tests
create table t1 (s1 float(0,2));
ERROR 42000: For float(M,D), double(M,D) or decimal(M,D), M must be >= D (column 's1').
create table t1 (s1 float(1,2));
+10 −1
Original line number Diff line number Diff line
@@ -178,7 +178,16 @@ show warnings;
desc t3;
drop table t1,t2,t3;

# End of 4.1 tests
#
# Bug #22129: A small double precision number becomes zero
#
# check if underflows are detected correctly
select 1e-308, 1.00000001e-300, 100000000e-300;

# check if overflows are detected correctly
select 10e307;

--echo End of 4.1 tests

#
# bug #12694 (float(m,d) specifications)
+43 −24
Original line number Diff line number Diff line
@@ -30,7 +30,8 @@
#include "m_ctype.h"

#define MAX_DBL_EXP	308
#define MAX_RESULT_FOR_MAX_EXP 1.79769313486232
#define MAX_RESULT_FOR_MAX_EXP 1.7976931348623157
#define MIN_RESULT_FOR_MIN_EXP 2.225073858507202
static double scaler10[] = {
  1.0, 1e10, 1e20, 1e30, 1e40, 1e50, 1e60, 1e70, 1e80, 1e90
};
@@ -57,10 +58,11 @@ double my_strtod(const char *str, char **end_ptr, int *error)
{
  double result= 0.0;
  uint negative= 0, ndigits, dec_digits= 0, neg_exp= 0;
  int exp= 0, digits_after_dec_point= 0;
  int exp= 0, digits_after_dec_point= 0, tmp_exp;
  const char *old_str, *end= *end_ptr, *start_of_number;
  char next_char;
  my_bool overflow=0;
  double scaler= 1.0;

  *error= 0;
  if (str >= end)
@@ -91,6 +93,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
  while ((next_char= *str) >= '0' && next_char <= '9')
  {
    result= result*10.0 + (next_char - '0');
    scaler= scaler*10.0;
    if (++str == end)
    {
      next_char= 0;                             /* Found end of string */
@@ -114,6 +117,7 @@ double my_strtod(const char *str, char **end_ptr, int *error)
    {
      result= result*10.0 + (next_char - '0');
      digits_after_dec_point++;
      scaler= scaler*10.0;
      if (++str == end)
      {
        next_char= 0;
@@ -144,39 +148,54 @@ double my_strtod(const char *str, char **end_ptr, int *error)
      } while (str < end && my_isdigit(&my_charset_latin1, *str));
    }
  }
  if ((exp= (neg_exp ? exp + digits_after_dec_point :
             exp - digits_after_dec_point)))
  {
    double scaler;
    if (exp < 0)
    {
      exp= -exp;
      neg_exp= 1;                               /* neg_exp was 0 before */
    }
    if (exp + ndigits >= MAX_DBL_EXP + 1 && result)
  tmp_exp= neg_exp ? exp + digits_after_dec_point : exp - digits_after_dec_point;
  if (tmp_exp)
  {
    int order;
    /*
        This is not 100 % as we actually will give an owerflow for
        17E307 but not for 1.7E308 but lets cut some corners to make life
        simpler
      Check for underflow/overflow.
      order is such an integer number that f = C * 10 ^ order,
      where f is the resulting floating point number and 1 <= C < 10.
      Here we compute the modulus
    */
      if (exp + ndigits > MAX_DBL_EXP + 1 ||
          result >= MAX_RESULT_FOR_MAX_EXP)
      {
    order= exp + (neg_exp ? -1 : 1) * (ndigits - 1);
    if (order < 0)
      order= -order;
    if (order >= MAX_DBL_EXP && result)
    {
      double c;
      /* Compute modulus of C (see comment above) */
      c= result / scaler * 10.0;
      if (neg_exp)
      {
        if (order > MAX_DBL_EXP || c < MIN_RESULT_FOR_MIN_EXP)
        {
          result= 0.0;
          goto done;
        }
      }
      else
      {
        if (order > MAX_DBL_EXP || c > MAX_RESULT_FOR_MAX_EXP)
        {
          overflow= 1;
          goto done;
        }
      }
    scaler= 1.0;
    }

    exp= tmp_exp;
    if (exp < 0)
    {
      exp= -exp;
      neg_exp= 1;                               /* neg_exp was 0 before */
    }
    while (exp >= 100)
    {
      scaler*= 1.0e100;
      result= neg_exp ? result/1.0e100 : result*1.0e100;
      exp-= 100;
    }
    scaler*= scaler10[exp/10]*scaler1[exp%10];
    scaler= scaler10[exp/10]*scaler1[exp%10];
    if (neg_exp)
      result/= scaler;
    else