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