Changeset: c497a8bb067e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/c497a8bb067e
Modified Files:
gdk/gdk_atoms.c
sql/server/sql_decimal.c
sql/server/sql_parser.y
Branch: Mar2025
Log Message:
Remove arbitrary limit of 50 characters in a number.
diffs (164 lines):
diff --git a/gdk/gdk_atoms.c b/gdk/gdk_atoms.c
--- a/gdk/gdk_atoms.c
+++ b/gdk/gdk_atoms.c
@@ -649,11 +649,12 @@ numFromStr(const char *src, size_t *len,
int sign = 1;
/* a valid number has the following syntax:
- * [-+]?[0-9]+([eE][0-9]+)?(LL)? -- PCRE syntax, or in other words
+ * [-+]?[0-9]+(_[0-9]+)*([eE][0-9]+(_[0-9]+)*)?(LL)? -- PCRE syntax, or
in other words
* optional sign, one or more digits, optional exponent, optional LL
* the exponent has the following syntax:
* lower or upper case letter E, one or more digits
- * embedded spaces are not allowed
+ * embedded spaces are not allowed but embedded underscores are
+ * (but not more than one consecutively)
* the optional LL at the end are only allowed for lng and hge
* values */
atommem(sz);
@@ -699,6 +700,8 @@ numFromStr(const char *src, size_t *len,
}
base = 10 * base + dig;
p++;
+ if (*p == '_' && GDKisdigit(p[1]))
+ p++;
} while (GDKisdigit(*p));
if ((*p == 'e' || *p == 'E') && GDKisdigit(p[1])) {
p++;
@@ -717,6 +720,8 @@ numFromStr(const char *src, size_t *len,
goto overflow;
}
p++;
+ if (*p == '_' && GDKisdigit(p[1]))
+ p++;
} while (GDKisdigit(*p));
if (base > maxdiv[exp].maxval) {
/* overflow */
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
@@ -60,7 +60,7 @@ fractional_sep_first_opp:
*has_errors = 1;
goto end_state;
}
- while (*dec == '0'){
+ while (*dec == '0' || *dec == '_'){
// skip leading zeros in preceding digits, e.g. '0004563.1234'
=> '4563.1234'
dec++;
if (*dec == '.') {
@@ -68,7 +68,9 @@ fractional_sep_first_opp:
goto fractional_sep_first_opp;
}
}
- for (; *dec && (isdigit((unsigned char) *dec)); dec++) {
+ for (; *dec && (*dec == '_' || isdigit((unsigned char) *dec)); dec++) {
+ if (*dec == '_')
+ continue;
if (res > max0 || (res == max0 && *dec - '0' > max1)) {
*has_errors = 1;
return 0;
@@ -87,7 +89,9 @@ fractional_sep_first_opp:
trailing_digits:
if (!isdigit((unsigned char) *dec))
goto trailing_whitespace;
- for (; *dec && (isdigit((unsigned char) *dec)); dec++) {
+ for (; *dec && (*dec == '_' || isdigit((unsigned char) *dec)); dec++) {
+ if (*dec == '_')
+ continue;
if (res > max0 || (res == max0 && *dec - '0' > max1)) {
*has_errors = 1;
return 0;
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
@@ -5480,18 +5480,7 @@ literal:
}
| sqlINT
{
- char filtered[50] = {0};
- int j = 0;
- for (int i = 0; i < 50; i++) {
- char d = $1[i];
- if (!d)
- break;
- else if (d == '_')
- continue;
- filtered[j] = d;
- ++j;
- }
- int err = 0;
+ int err = 0;
#ifdef HAVE_HGE
hge value, *p = &value;
size_t len = sizeof(hge);
@@ -5502,10 +5491,10 @@ literal:
sql_subtype t;
#ifdef HAVE_HGE
- if (hgeFromStr(filtered, &len, &p, false) < 0 ||
is_hge_nil(value))
+ if (hgeFromStr($1, &len, &p, false) < 0 || is_hge_nil(value))
err = 2;
#else
- if (lngFromStr(filtered, &len, &p, false) < 0 ||
is_lng_nil(value))
+ if (lngFromStr($1, &len, &p, false) < 0 || is_lng_nil(value))
err = 2;
#endif
@@ -5539,19 +5528,7 @@ literal:
}
| INTNUM
{
- char filtered[51] = {0};
- int j = 0;
- for (int i = 0; i < 50; i++) {
- char d = $1[i];
- if (!d)
- break;
- else if (d == '_')
- continue;
- filtered[j] = d;
- ++j;
- }
- filtered[j] = 0;
- char *s = filtered;
+ char *s = $1;
int digits;
int scale;
@@ -5587,23 +5564,27 @@ literal:
}
| APPROXNUM
{
- char filtered[50] = {0};
+ char *filtered = strdup($1);
+ if (filtered == NULL) {
+ sqlformaterror(m, SQLSTATE(HY013) "Malloc failed");
+ $$ = NULL;
+ YYABORT;
+ }
int j = 0;
- for (int i = 0; i < 50; i++) {
- char d = $1[i];
- if (!d)
- break;
- else if (d == '_')
- continue;
- filtered[j] = d;
- ++j;
+ for (int i = 0; $1[i]; i++) {
+ char d = $1[i];
+ if (d == '_')
+ continue;
+ filtered[j++] = d;
}
+ filtered[j] = 0;
sql_subtype t;
char *p = filtered;
double val;
errno = 0;
val = strtod(filtered,&p);
+ free(filtered);
if (p == filtered || is_dbl_nil(val) || (errno == ERANGE &&
(val < -1 || val > 1))) {
sqlformaterror(m, SQLSTATE(22003) "Double value too
large or not a number (%s)", $1);
$$ = NULL;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]