Commit e90c6b48 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Fixed problems with DECIMAL() type on overflow.

parent 0b6a7865
......@@ -46921,6 +46921,13 @@ Fixed the @code{FLOAT(X+1,X)} is not converted to @code{FLOAT(X+2,X)}.
@item
Fixed the result from @code{IF()} is case in-sensitive if the 2 and
third arguments are case sensitive.
@item
Fixed core dump problem on OSF in @code{gethostbyname_r}.
@item
Fixed that underflowed decimal fields is not zero filled.
@item
@code{'+11111'} in overflow for @code{decimal(5,0) unsigned} columns,
Just sign will be dropped.
@end itemize
@node News-3.23.50, News-3.23.49, News-3.23.51, News-3.23.x
......@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line!
AM_INIT_AUTOMAKE(mysql, 3.23.50)
AM_INIT_AUTOMAKE(mysql, 3.23.51)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
......@@ -921,6 +921,10 @@ dnl Is this the right match for DEC OSF on alpha?
CFLAGS="$CFLAGS -mieee"
CXXFLAGS="$CXXFLAGS -mieee"
fi
echo "Adding defines for OSF1"
# gethostbyname_r is deprecated and doesn't work ok on OSF1
CFLAGS="$CFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
CXXFLAGS="$CXXFLAGS -DUNDEF_HAVE_GETHOSTBYNAME_R"
;;
esac
......
/* Definefile for errormessagenumbers */
/* Copyright (C) 2000 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; either version 2 of the License, or
(at your option) any later version.
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 */
/* Definefile for error messagenumbers */
#define ER_HASHCHK 1000
#define ER_NISAMCHK 1001
......
/* Copyright (C) 1979-1999 TcX AB & Monty Program KB & Detron HB
This software is distributed with NO WARRANTY OF ANY KIND. No author or
distributor accepts any responsibility for the consequences of using it, or
for whether it serves any particular purpose or works at all, unless he or
she says so in writing. Refer to the Free Public License (the "License")
for full details.
Every copy of this file must include a copy of the License, normally in a
plain ASCII text file named PUBLIC. The License grants you the right to
copy, modify and redistribute this file, but only under certain conditions
described in the License. Among other things, the License requires that
the copyright notice and this notice be preserved on all copies. */
/* Pack isam file*/
/* Copyright (C) 1979-2002 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; either version 2 of the License, or
(at your option) any later version.
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 */
/* Pack isam file */
#ifndef USE_MY_FUNC
#define USE_MY_FUNC /* We nead at least my_malloc */
......
......@@ -3,3 +3,111 @@ id datatype_id minvalue maxvalue valuename forecolor backcolor
146 16 0.0000000000 1.9000000000 0 16769024
id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720
a
0.00
-0.00
+0.00
01.00
+01.00
-01.00
-0.10
+0.10
0.10
000000001.00
+00000001.00
-00000001.00
111111111.11
111111111.11
-11111111.11
-99999999.99
999999999.99
999999999.99
a
0.00
0.00
0.00
01.00
01.00
0.00
0.00
0.10
0.10
00000001.00
00000001.00
0.00
99999999.99
99999999.99
0.00
0.00
99999999.99
99999999.99
a
00000000.00
00000000.00
00000000.00
00000001.00
00000001.00
00000000.00
00000000.00
00000000.10
00000000.10
00000001.00
00000001.00
00000000.00
99999999.99
99999999.99
00000000.00
00000000.00
99999999.99
99999999.99
a
0.00
-0.00
0.00
1.00
1.00
-1.00
-0.10
0.10
0.10
1.00
1.00
-1.00
111111111.11
111111111.11
-11111111.11
-99999999.99
999999999.99
999999999.99
a
-9999999999
-1
+1
01
+0000000001
12345678901
99999999999
a
0
0
1
01
0000000001
1234567890
9999999999
a
0000000000
0000000000
0000000001
0000000001
0000000001
1234567890
9999999999
a
0000000000
0000000000
0000000001
0000000001
0000000001
1234567890
9999999999
......@@ -147,3 +147,67 @@ INSERT INTO t1 VALUES ( '146', '16', '0.0000000000', '1.9000000000', '', '0', '1
select * from t1 where minvalue<=1 and maxvalue>=-1 and datatype_id=16;
select * from t1 where minvalue<=-1 and maxvalue>=-1 and datatype_id=16;
drop table t1;
#
# Test of correct handling leading zero and +/- signs
# then values are passed as strings
# Also test overflow handling in this case
#
create table t1 (a decimal(10,2));
insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
select * from t1;
drop table t1;
create table t1 (a decimal(10,2) unsigned);
insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
select * from t1;
drop table t1;
create table t1 (a decimal(10,2) zerofill);
insert into t1 values ("0.0"),("-0.0"),("+0.0"),("01.0"),("+01.0"),("-01.0");
insert into t1 values ("-.1"),("+.1"),(".1");
insert into t1 values ("00000000000001"),("+0000000000001"),("-0000000000001");
insert into t1 values ("+111111111.11"),("111111111.11"),("-11111111.11");
insert into t1 values ("-111111111.11"),("+1111111111.11"),("1111111111.11");
select * from t1;
drop table t1;
create table t1 (a decimal(10,2));
insert into t1 values (0.0),(-0.0),(+0.0),(01.0),(+01.0),(-01.0);
insert into t1 values (-.1),(+.1),(.1);
insert into t1 values (00000000000001),(+0000000000001),(-0000000000001);
insert into t1 values (+111111111.11),(111111111.11),(-11111111.11);
insert into t1 values (-111111111.11),(+1111111111.11),(1111111111.11);
select * from t1;
drop table t1;
#
# Test correct handling of overflowed decimal values
#
create table t1 (a decimal);
insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+12345678901'),(99999999999999);
select * from t1;
drop table t1;
create table t1 (a decimal unsigned);
insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
select * from t1;
drop table t1;
create table t1 (a decimal zerofill);
insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
select * from t1;
drop table t1;
create table t1 (a decimal unsigned zerofill);
insert into t1 values (-99999999999999),(-1),('+1'),('01'),('+00000000000001'),('+1234567890'),(99999999999999);
select * from t1;
drop table t1;
......@@ -63,8 +63,8 @@ const char field_separator=',';
*****************************************************************************/
/*
** Calculate length of number and it's parts
** Increment cuted_fields if wrong number
Calculate length of number and it's parts
Increment cuted_fields if wrong number
*/
static bool
......@@ -380,13 +380,34 @@ Field_decimal::reset(void)
void Field_decimal::overflow(bool negative)
{
uint len=field_length;
char *to=ptr;
if (negative && !unsigned_flag)
char *to=ptr, filler= '9';
if (negative)
{
*to++ = '-';
len--;
if (!unsigned_flag)
{
/* Put - sign as a first digit so we'll have -999..999 or 999..999 */
*to++ = '-';
len--;
}
else
{
filler= '0'; // Fill up with 0
if (!zerofill)
{
/*
Handle unsigned integer without zerofill, in which case
the number should be of format ' 0' or ' 0.000'
*/
uint whole_part=field_length- (dec ? dec+2 : 1);
// Fill with spaces up to the first digit
bfill(to, whole_part, ' ');
to+= whole_part;
len-= whole_part;
// The main code will also handle the 0 before the decimal point
}
}
}
bfill(to,len,negative && unsigned_flag ? '0' : '9');
bfill(to, len, filler);
if (dec)
ptr[field_length-dec-1]='.';
return;
......@@ -421,10 +442,15 @@ void Field_decimal::store(const char *from,uint len)
from++;
if (unsigned_flag) // No sign with zerofill
{
if (!error)
current_thd->cuted_fields++;
Field_decimal::overflow(1);
return;
if (decstr.sign_char == '+') // just remove "+"
decstr.sign= 0;
else
{
if (!error)
current_thd->cuted_fields++;
Field_decimal::overflow(1);
return;
}
}
}
/*
......
......@@ -45,7 +45,8 @@ EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \
ctype-gb2312.c ctype-gbk.c ctype-sjis.c \
ctype-tis620.c ctype-ujis.c \
ctype_autoconf.c \
strto.c strings-x86.s longlong2str-x86.s \
strto.c strings-x86.s \
longlong2str.c longlong2str-x86.s \
strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
strfill.c strcend.c is_prefix.c strstr.c strinstr.c \
strmake.c strnmov.c strmov.c strnlen.c \
......
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