Changeset: a14d4678c148 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a14d4678c148
Modified Files:
        sql/backends/monet5/sql_round_impl.h
        sql/server/sql_decimal.c
        sql/server/sql_decimal.h
        sql/server/sql_parser.y
Branch: Oct2014
Log Message:

more string 2 decimal fixes. fixes bug 3558


diffs (93 lines):

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
@@ -290,7 +290,7 @@ str
 str_2dec(TYPE *res, str *val, int *d, int *sc)
 {
        char *s = strip_extra_zeros(*val);
-       char *dot = strchr(s, '.');
+       char *dot = strchr(s, '.'), *end = NULL;
        int digits = _strlen(s) - 1;
        int scale = digits - (int) (dot - s);
        lng value = 0;
@@ -305,8 +305,10 @@ str_2dec(TYPE *res, str *val, int *d, in
        } else { /* we have a dot in the string */
                digits--;
        }
+       if (digits <= 0)
+               throw(SQL, STRING(TYPE), "decimal (%s) doesn't have format 
(%d.%d)", *val, *d, *sc);
 
-       value = decimal_from_str(s);
+       value = decimal_from_str(s, &end);
        if (*s == '+' || *s == '-')
                digits--;
        if (scale < *sc) {
@@ -333,7 +335,7 @@ str_2dec(TYPE *res, str *val, int *d, in
                        throw(SQL, STRING(TYPE), "rounding of decimal (%s) 
doesn't fit format (%d.%d)", *val, *d, *sc);
                }
        }
-       if (digits > *d) {
+       if (digits <= 0 || digits > *d || *end) {
                throw(SQL, STRING(TYPE), "decimal (%s) doesn't have format 
(%d.%d)", *val, *d, *sc);
        }
        *res = (TYPE) value;
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
@@ -22,11 +22,13 @@
 #include "sql_decimal.h"
 
 lng
-decimal_from_str(char *dec)
+decimal_from_str(char *dec, char **end)
 {
        lng res = 0;
        int neg = 0;
 
+       while(isspace(*dec))
+               dec++;
        if (*dec == '-') {
                neg = 1;
                dec++;
@@ -35,12 +37,16 @@ decimal_from_str(char *dec)
                neg = 0;
                dec++;
        }
-       for (; *dec; dec++) {
+       for (; *dec && ((*dec >= '0' && *dec <= '9') || *dec == '.'); dec++) {
                if (*dec != '.') {
                        res *= 10;
                        res += *dec - '0';
                }
        }
+       while(isspace(*dec))
+               dec++;
+       if (end)
+               *end = dec;
        if (neg)
                return -res;
        else
diff --git a/sql/server/sql_decimal.h b/sql/server/sql_decimal.h
--- a/sql/server/sql_decimal.h
+++ b/sql/server/sql_decimal.h
@@ -24,7 +24,7 @@
 #include "sql_types.h"
 #include <gdk.h>
 
-extern lng decimal_from_str(char *dec);
+extern lng decimal_from_str(char *dec, char **end);
 extern char * decimal_to_str(lng v, sql_subtype *t);
 
 #endif /* _SQL_DECIMAL_H */
diff --git a/sql/server/sql_parser.y b/sql/server/sql_parser.y
--- a/sql/server/sql_parser.y
+++ b/sql/server/sql_parser.y
@@ -4160,7 +4160,7 @@ literal:
                        digits = 1;
                  if (digits <= 18) {
                        double val = strtod($1,NULL);
-                       lng value = decimal_from_str(s);
+                       lng value = decimal_from_str(s, NULL);
 
                        if (*s == '+' || *s == '-')
                                digits --;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to