Changeset: 7dbda0968c84 for MonetDB URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=7dbda0968c84 Added Files: sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.err sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.out Modified Files: MonetDB.spec debian/control sql/backends/monet5/sql_round_impl.h sql/server/sql_decimal.c Branch: Oct2014 Log Message:
fixed bug 3543 - properly handle + before decimals - handle rounding properly (ie if round up, check if we still fit inot the digits format) - handle negative rounding properly diffs (224 lines): diff --git a/MonetDB.spec b/MonetDB.spec --- a/MonetDB.spec +++ b/MonetDB.spec @@ -98,7 +98,6 @@ BuildRequires: bzip2-devel %if %{?with_fits:1}%{!?with_fits:0} BuildRequires: cfitsio-devel %endif -BuildRequires: flex %if %{?with_geos:1}%{!?with_geos:0} BuildRequires: geos-devel >= 3.0.0 %endif diff --git a/debian/control b/debian/control --- a/debian/control +++ b/debian/control @@ -7,7 +7,7 @@ Vcs-Browser: http://dev.monetdb.org/hg/M Vcs-Hg: http://dev.monetdb.org/hg/MonetDB/ # for Build-Depends and Depends syntax, see # http://www.debian.org/doc/debian-policy/ch-relationships.html -Build-Depends: debhelper (>= 5), autotools-dev, bison, flex, libbz2-dev, +Build-Depends: debhelper (>= 5), autotools-dev, bison, libbz2-dev, libcurl4-gnutls-dev, libgeos-dev (>= 3.0.0), libgsl0-dev, libpcre3-dev, libreadline-gplv2-dev | libreadline-dev, libssl-dev, libxml2-dev, perl, ruby, rubygems | libyaml-0-2, unixodbc-dev, uuid-dev, zlib1g-dev, diff --git a/sql/backends/monet5/sql_round_impl.h b/sql/backends/monet5/sql_round_impl.h --- a/sql/backends/monet5/sql_round_impl.h +++ b/sql/backends/monet5/sql_round_impl.h @@ -302,6 +302,8 @@ str_2dec(TYPE *res, str *val, int *d, in } else { scale = 0; } + } else { /* we have a dot in the string */ + digits--; } value = decimal_from_str(s); @@ -309,20 +311,27 @@ str_2dec(TYPE *res, str *val, int *d, in digits--; if (scale < *sc) { /* the current scale is too small, increase it by adding 0's */ - int d = *sc - scale; /* CANNOT be 0! */ + int dff = *sc - scale; /* CANNOT be 0! */ - value *= scales[d]; - scale += d; - digits += d; + value *= scales[dff]; + scale += dff; + digits += dff; } else if (scale > *sc) { /* the current scale is too big, decrease it by correctly rounding */ - int d = scale - *sc; /* CANNOT be 0 */ - lng rnd = scales[d] >> 1; + /* we should round properly, and check for overflow (res >= 10^digits+scale) */ + int dff = scale - *sc; /* CANNOT be 0 */ + lng rnd = scales[dff] >> 1; - value += rnd; - value /= scales[d]; - scale -= d; - digits -= d; + if (value > 0) + value += rnd; + else + value -= rnd; + value /= scales[dff]; + scale -= dff; + digits -= dff; + if (value >= scales[digits] || value <= -scales[digits]) { + throw(SQL, STRING(TYPE), "rounding of decimal (%s) doesn't fit format (%d.%d)", *val, *d, *sc); + } } if (digits > *d) { throw(SQL, STRING(TYPE), "decimal (%s) doesn't have format (%d.%d)", *val, *d, *sc); diff --git a/sql/server/sql_decimal.c b/sql/server/sql_decimal.c --- a/sql/server/sql_decimal.c +++ b/sql/server/sql_decimal.c @@ -31,6 +31,10 @@ decimal_from_str(char *dec) neg = 1; dec++; } + if (*dec == '+') { + neg = 0; + dec++; + } for (; *dec; dec++) { if (*dec != '.') { res *= 10; diff --git a/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.err b/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.err new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.err @@ -0,0 +1,55 @@ +stderr of test 'number_4_4.Bug-3543` in directory 'sql/test/BugTracker-2014` itself: + + +# 14:07:37 > +# 14:07:37 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=38282" "--set" "mapi_usock=/var/tmp/mtest-23224/.s.monetdb.38282" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2014" "--set" "mal_listing=0" "--set" "embedded_r=yes" +# 14:07:37 > + +# builtin opt gdk_dbpath = /home/niels/scratch/rc-monetdb/Linux-x86_64/var/monetdb5/dbfarm/demo +# builtin opt gdk_debug = 0 +# builtin opt gdk_vmtrim = no +# builtin opt monet_prompt = > +# builtin opt monet_daemon = no +# builtin opt mapi_port = 50000 +# builtin opt mapi_open = false +# builtin opt mapi_autosense = false +# builtin opt sql_optimizer = default_pipe +# builtin opt sql_debug = 0 +# cmdline opt gdk_nr_threads = 0 +# cmdline opt mapi_open = true +# cmdline opt mapi_port = 38282 +# cmdline opt mapi_usock = /var/tmp/mtest-23224/.s.monetdb.38282 +# cmdline opt monet_prompt = +# cmdline opt mal_listing = 2 +# cmdline opt gdk_dbpath = /home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2014 +# cmdline opt mal_listing = 0 +# cmdline opt embedded_r = yes +# cmdline opt gdk_debug = 536870922 + +# 14:07:38 > +# 14:07:38 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-23224" "--port=38282" +# 14:07:38 > + +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (4, '0.99995'); -- should fail but is invalidly accepted +ERROR = !rounding of decimal (0.99995) doesn't fit format (4.4) +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (5, '0.99999'); -- should fail but is invalidly accepted +ERROR = !rounding of decimal (0.99999) doesn't fit format (4.4) +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (6, '+0.99995'); -- correctly fails +ERROR = !rounding of decimal (+0.99995) doesn't fit format (4.4) +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (6, '+.99995'); -- should fail but is invalidly accepted +ERROR = !rounding of decimal (+.99995) doesn't fit format (4.4) +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (7, '-0.99995'); -- correctly fails +ERROR = !rounding of decimal (-0.99995) doesn't fit format (4.4) +MAPI = (monetdb) /var/tmp/mtest-23224/.s.monetdb.38282 +QUERY = INSERT INTO fract_only VALUES (7, '-.999998'); -- should fail but is invalidly accepted +ERROR = !rounding of decimal (-.999998) doesn't fit format (4.4) + +# 14:07:38 > +# 14:07:38 > "Done." +# 14:07:38 > + diff --git a/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.out b/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.out new file mode 100644 --- /dev/null +++ b/sql/test/BugTracker-2014/Tests/number_4_4.Bug-3543.stable.out @@ -0,0 +1,72 @@ +stdout of test 'number_4_4.Bug-3543` in directory 'sql/test/BugTracker-2014` itself: + + +# 14:07:37 > +# 14:07:37 > "mserver5" "--debug=10" "--set" "gdk_nr_threads=0" "--set" "mapi_open=true" "--set" "mapi_port=38282" "--set" "mapi_usock=/var/tmp/mtest-23224/.s.monetdb.38282" "--set" "monet_prompt=" "--forcemito" "--set" "mal_listing=2" "--dbpath=/home/niels/scratch/rc-monetdb/Linux-x86_64/var/MonetDB/mTests_sql_test_BugTracker-2014" "--set" "mal_listing=0" "--set" "embedded_r=yes" +# 14:07:37 > + +# MonetDB 5 server v11.19.0 +# This is an unreleased version +# Serving database 'mTests_sql_test_BugTracker-2014', using 4 threads +# Compiled for x86_64-unknown-linux-gnu/64bit with 64bit OIDs dynamically linked +# Found 7.334 GiB available main-memory. +# Copyright (c) 1993-July 2008 CWI. +# Copyright (c) August 2008-2014 MonetDB B.V., all rights reserved +# Visit http://www.monetdb.org/ for further information +# Listening for connection requests on mapi:monetdb://localhost.nes.nl:38282/ +# Listening for UNIX domain connection requests on mapi:monetdb:///var/tmp/mtest-23224/.s.monetdb.38282 +# MonetDB/GIS module loaded +# MonetDB/SQL module loaded +# MonetDB/R module loaded + +Ready. + +# 14:07:38 > +# 14:07:38 > "mclient" "-lsql" "-ftest" "-Eutf-8" "-i" "-e" "--host=/var/tmp/mtest-23224" "--port=38282" +# 14:07:38 > + +#CREATE TABLE fract_only (id int, val numeric(4,4)); +#INSERT INTO fract_only VALUES (1, '-0.9999'); +[ 1 ] +#INSERT INTO fract_only VALUES (2, '+0.9999'); +[ 1 ] +#INSERT INTO fract_only VALUES (3, '+.9999'); +[ 1 ] +#SELECT * FROM fract_only; +% sys.fract_only, sys.fract_only # table_name +% id, val # name +% int, decimal # type +% 1, 6 # length +[ 1, -0.9999 ] +[ 2, 0.9999 ] +[ 3, 0.9999 ] +#SELECT * FROM fract_only; +% sys.fract_only, sys.fract_only # table_name +% id, val # name +% int, decimal # type +% 1, 6 # length +[ 1, -0.9999 ] +[ 2, 0.9999 ] +[ 3, 0.9999 ] +#SELECT * FROM fract_only; +% sys.fract_only, sys.fract_only # table_name +% id, val # name +% int, decimal # type +% 1, 6 # length +[ 1, -0.9999 ] +[ 2, 0.9999 ] +[ 3, 0.9999 ] +#SELECT * FROM fract_only; +% sys.fract_only, sys.fract_only # table_name +% id, val # name +% int, decimal # type +% 1, 6 # length +[ 1, -0.9999 ] +[ 2, 0.9999 ] +[ 3, 0.9999 ] +#drop table fract_only; + +# 14:07:38 > +# 14:07:38 > "Done." +# 14:07:38 > + _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list