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

Reply via email to