Changeset: fc49679e99e2 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/fc49679e99e2 Modified Files: sql/server/sql_parser.y sql/server/sql_scan.c Branch: literal_features Log Message:
introduce literal binary integer diffs (162 lines): 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 @@ -637,7 +637,7 @@ int yydebug=1; /* sql prefixes to avoid name clashes on various architectures */ %token <sval> - IDENT UIDENT aTYPE ALIAS RANK sqlINT OIDNUM HEXADECIMAL OCTAL INTNUM APPROXNUM + IDENT UIDENT aTYPE ALIAS RANK sqlINT OIDNUM HEXADECIMALNUM OCTALNUM BINARYNUM INTNUM APPROXNUM USING GLOBAL CAST CONVERT CHARACTER VARYING LARGE OBJECT VARCHAR CLOB sqlTEXT BINARY sqlBLOB @@ -4840,7 +4840,61 @@ literal: sql_find_subtype(&t, "char", len, 0 ); $$ = _newAtomNode( _atom_string(&t, s)); } - | OCTAL { int len = _strlen($1), i = 2, err = 0; + | BINARYNUM { int len = _strlen($1), i = 2, err = 0; + char * binary = $1; + sql_subtype t; +#ifdef HAVE_HGE + hge res = 0; +#else + lng res = 0; +#endif + /* skip leading '0' */ + while (i < len && binary[i] == '0') + i++; + + if (len - i < MAX_OCT_DIGITS || (len - i == MAX_OCT_DIGITS && binary[i] < '2')) + while (err == 0 && i < len) + { + res <<= 1; + if (binary[i] == '0' || binary[i] == '1') // TODO: an be asserted + res = res + (binary[i] - '0'); + else + err = 1; + i++; + } + else + err = 1; + + if (err == 0) { + assert(res >= 0); + + /* use smallest type that can accommodate the given value */ + if (res <= GDK_bte_max) + sql_find_subtype(&t, "tinyint", 8, 0 ); + else if (res <= GDK_sht_max) + sql_find_subtype(&t, "smallint", 16, 0 ); + else if (res <= GDK_int_max) + sql_find_subtype(&t, "int", 32, 0 ); + else if (res <= GDK_lng_max) + sql_find_subtype(&t, "bigint", 64, 0 ); +#ifdef HAVE_HGE + else if (res <= GDK_hge_max) + sql_find_subtype(&t, "hugeint", 128, 0 ); +#endif + else + err = 1; + } + + if (err != 0) { + sqlformaterror(m, SQLSTATE(22003) "Invalid binary number or binary too large (%s)", $1); + $$ = NULL; + YYABORT; + } else { + $$ = _newAtomNode( atom_int(SA, &t, res)); + } + + } + | OCTALNUM { int len = _strlen($1), i = 2, err = 0; char * octal = $1; sql_subtype t; #ifdef HAVE_HGE @@ -4894,7 +4948,7 @@ literal: } } - | HEXADECIMAL { int len = _strlen($1), i = 2, err = 0; + | HEXADECIMALNUM { int len = _strlen($1), i = 2, err = 0; char * hexa = $1; sql_subtype t; #ifdef HAVE_HGE diff --git a/sql/server/sql_scan.c b/sql/server/sql_scan.c --- a/sql/server/sql_scan.c +++ b/sql/server/sql_scan.c @@ -976,17 +976,49 @@ number(mvc * c, int cur) * [0-9]+ -- (decimal) INTEGER */ lc->started = 1; - if (cur == '0' && (cur = scanner_getc(lc)) == 'o') { + int is_literal_integer = 0; + if (cur == '0') { + switch ((cur = scanner_getc(lc))) { + case 'b': + is_literal_integer = BINARYNUM; + break; + case 'o': + is_literal_integer = OCTALNUM; + break; + case 'x': + is_literal_integer = HEXADECIMALNUM; + break; + } + } + + if (is_literal_integer == BINARYNUM) { cur = scanner_getc(lc); - while (cur != EOF && isdigit(cur) && cur < '8') { - token = OCTAL; + while (cur != EOF && isdigit(cur) && cur < '2') { + token = BINARYNUM; cur = scanner_getc(lc); } if (cur == EOF) return cur; - if (token != OCTAL) { + if (token != BINARYNUM) { + /* 0b not followed by a binary digit: show 'b' as erroneous */ + utf8_putchar(lc, cur); + cur = 'b'; + token = 0; + } + } + else if (is_literal_integer == OCTALNUM) { + cur = scanner_getc(lc); + while (cur != EOF && isdigit(cur) && cur < '8') { + token = OCTALNUM; + cur = scanner_getc(lc); + } + + if (cur == EOF) + return cur; + + if (token != OCTALNUM) { /* 0o not followed by a octal digit: show 'o' as erroneous */ utf8_putchar(lc, cur); cur = 'o'; @@ -996,17 +1028,17 @@ number(mvc * c, int cur) /* after this block, cur contains the first character after the * parsed number (which may be the first causing it not to be a number); * it token == 0 after this block, a parse error was detected */ - else if (cur == '0' && (cur = scanner_getc(lc)) == 'x') { + else if (is_literal_integer == HEXADECIMALNUM) { cur = scanner_getc(lc); while (cur != EOF && iswxdigit(cur)) { - token = HEXADECIMAL; + token = HEXADECIMALNUM; cur = scanner_getc(lc); } if (cur == EOF) return cur; - if (token != HEXADECIMAL) { + if (token != HEXADECIMALNUM) { /* 0x not followed by a hex digit: show 'x' as erroneous */ utf8_putchar(lc, cur); cur = 'x'; _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org