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)}. ...@@ -46921,6 +46921,13 @@ Fixed the @code{FLOAT(X+1,X)} is not converted to @code{FLOAT(X+2,X)}.
@item @item
Fixed the result from @code{IF()} is case in-sensitive if the 2 and Fixed the result from @code{IF()} is case in-sensitive if the 2 and
third arguments are case sensitive. 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 @end itemize
@node News-3.23.50, News-3.23.49, News-3.23.51, News-3.23.x @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. ...@@ -4,7 +4,7 @@ dnl Process this file with autoconf to produce a configure script.
AC_INIT(sql/mysqld.cc) AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM AC_CANONICAL_SYSTEM
# The Docs Makefile.am parses this line! # 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) AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10 PROTOCOL_VERSION=10
...@@ -921,6 +921,10 @@ dnl Is this the right match for DEC OSF on alpha? ...@@ -921,6 +921,10 @@ dnl Is this the right match for DEC OSF on alpha?
CFLAGS="$CFLAGS -mieee" CFLAGS="$CFLAGS -mieee"
CXXFLAGS="$CXXFLAGS -mieee" CXXFLAGS="$CXXFLAGS -mieee"
fi 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 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_HASHCHK 1000
#define ER_NISAMCHK 1001 #define ER_NISAMCHK 1001
......
/* Copyright (C) 1979-1999 TcX AB & Monty Program KB & Detron HB /* Copyright (C) 1979-2002 MySQL AB
This software is distributed with NO WARRANTY OF ANY KIND. No author or This program is free software; you can redistribute it and/or modify
distributor accepts any responsibility for the consequences of using it, or it under the terms of the GNU General Public License as published by
for whether it serves any particular purpose or works at all, unless he or the Free Software Foundation; either version 2 of the License, or
she says so in writing. Refer to the Free Public License (the "License") (at your option) any later version.
for full details.
Every copy of this file must include a copy of the License, normally in a This program is distributed in the hope that it will be useful,
plain ASCII text file named PUBLIC. The License grants you the right to but WITHOUT ANY WARRANTY; without even the implied warranty of
copy, modify and redistribute this file, but only under certain conditions MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
described in the License. Among other things, the License requires that GNU General Public License for more details.
the copyright notice and this notice be preserved on all copies. */
You should have received a copy of the GNU General Public License
/* Pack isam file*/ 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 #ifndef USE_MY_FUNC
#define USE_MY_FUNC /* We nead at least my_malloc */ #define USE_MY_FUNC /* We nead at least my_malloc */
......
...@@ -3,3 +3,111 @@ id datatype_id minvalue maxvalue valuename forecolor backcolor ...@@ -3,3 +3,111 @@ id datatype_id minvalue maxvalue valuename forecolor backcolor
146 16 0.0000000000 1.9000000000 0 16769024 146 16 0.0000000000 1.9000000000 0 16769024
id datatype_id minvalue maxvalue valuename forecolor backcolor id datatype_id minvalue maxvalue valuename forecolor backcolor
143 16 -4.9000000000 -0.1000000000 NULL 15774720 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 ...@@ -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;
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; 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=','; ...@@ -63,8 +63,8 @@ const char field_separator=',';
*****************************************************************************/ *****************************************************************************/
/* /*
** Calculate length of number and it's parts Calculate length of number and it's parts
** Increment cuted_fields if wrong number Increment cuted_fields if wrong number
*/ */
static bool static bool
...@@ -380,13 +380,34 @@ Field_decimal::reset(void) ...@@ -380,13 +380,34 @@ Field_decimal::reset(void)
void Field_decimal::overflow(bool negative) void Field_decimal::overflow(bool negative)
{ {
uint len=field_length; uint len=field_length;
char *to=ptr; char *to=ptr, filler= '9';
if (negative && !unsigned_flag) if (negative)
{
if (!unsigned_flag)
{ {
/* Put - sign as a first digit so we'll have -999..999 or 999..999 */
*to++ = '-'; *to++ = '-';
len--; len--;
} }
bfill(to,len,negative && unsigned_flag ? '0' : '9'); 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, filler);
if (dec) if (dec)
ptr[field_length-dec-1]='.'; ptr[field_length-dec-1]='.';
return; return;
...@@ -420,6 +441,10 @@ void Field_decimal::store(const char *from,uint len) ...@@ -420,6 +441,10 @@ void Field_decimal::store(const char *from,uint len)
{ {
from++; from++;
if (unsigned_flag) // No sign with zerofill if (unsigned_flag) // No sign with zerofill
{
if (decstr.sign_char == '+') // just remove "+"
decstr.sign= 0;
else
{ {
if (!error) if (!error)
current_thd->cuted_fields++; current_thd->cuted_fields++;
...@@ -427,6 +452,7 @@ void Field_decimal::store(const char *from,uint len) ...@@ -427,6 +452,7 @@ void Field_decimal::store(const char *from,uint len)
return; return;
} }
} }
}
/* /*
** Remove pre-zeros if too big number ** Remove pre-zeros if too big number
*/ */
......
...@@ -45,7 +45,8 @@ EXTRA_DIST = ctype-big5.c ctype-czech.c ctype-euc_kr.c \ ...@@ -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-gb2312.c ctype-gbk.c ctype-sjis.c \
ctype-tis620.c ctype-ujis.c \ ctype-tis620.c ctype-ujis.c \
ctype_autoconf.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 \ strxmov.c bmove_upp.c strappend.c strcont.c strend.c \
strfill.c strcend.c is_prefix.c strstr.c strinstr.c \ strfill.c strcend.c is_prefix.c strstr.c strinstr.c \
strmake.c strnmov.c strmov.c strnlen.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