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 -- [email protected]
To unsubscribe send an email to [email protected]