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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list