Changeset: 6725be6c839e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6725be6c839e
Modified Files:
        sql/server/sql_parser.y
        sql/server/sql_scan.c
Branch: literal_features
Log Message:

first version of octal literal implementation


diffs (117 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
@@ -63,9 +63,11 @@ makeAtomNode(mvc *m, const char* type, c
 #ifdef HAVE_HGE
 #define MAX_DEC_DIGITS 38
 #define MAX_HEX_DIGITS 32
+#define MAX_OCT_DIGITS 64 /* TODO */
 #else
 #define MAX_DEC_DIGITS 18
 #define MAX_HEX_DIGITS 16
+#define MAX_OCT_DIGITS 32 /* TODO */
 #endif
 
 static inline int
@@ -635,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 INTNUM APPROXNUM
+       IDENT UIDENT aTYPE ALIAS RANK sqlINT OIDNUM HEXADECIMAL OCTAL INTNUM 
APPROXNUM
        USING
        GLOBAL CAST CONVERT
        CHARACTER VARYING LARGE OBJECT VARCHAR CLOB sqlTEXT BINARY sqlBLOB
@@ -4838,6 +4840,60 @@ literal:
                  sql_find_subtype(&t, "char", len, 0 );
                  $$ = _newAtomNode( _atom_string(&t, s)); }
 
+ |  OCTAL { int len = _strlen($1), i = 2, err = 0;
+                 char * octal = $1;
+                 sql_subtype t;
+#ifdef HAVE_HGE
+                 hge res = 0;
+#else
+                 lng res = 0;
+#endif
+                 /* skip leading '0' */
+                 while (i < len && octal[i] == '0')
+                       i++;
+
+                 if (len - i < MAX_OCT_DIGITS || (len - i == MAX_OCT_DIGITS && 
octal[i] < '8'))
+                       while (err == 0 && i < len)
+                       {
+                               res <<= 3;
+                               if ('0' <= octal[i] && octal[i] < '8')
+                                       res = res + (octal[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 octal number 
or octal too large (%s)", $1);
+                       $$ = NULL;
+                       YYABORT;
+                 } else {
+                       $$ = _newAtomNode( atom_int(SA, &t, res));
+                 }
+
+ }
  |  HEXADECIMAL { int len = _strlen($1), i = 2, err = 0;
                  char * hexa = $1;
                  sql_subtype t;
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,10 +976,27 @@ number(mvc * c, int cur)
         * [0-9]+                           -- (decimal) INTEGER
         */
        lc->started = 1;
+       if (cur == '0' && (cur = scanner_getc(lc)) == 'o') {
+               cur = scanner_getc(lc);
+               while (cur != EOF && isdigit(cur) && cur < '8') {
+                       token = OCTAL;
+                       cur = scanner_getc(lc);
+               }
+
+               if (cur == EOF)
+                       return cur;
+
+               if (token != OCTAL) {
+                       /* 0o not followed by a octal digit: show 'o' as 
erroneous */
+                       utf8_putchar(lc, cur);
+                       cur = 'o';
+                       token = 0;
+               }
+       }
        /* 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 */
-       if (cur == '0' && (cur = scanner_getc(lc)) == 'x') {
+       else if (cur == '0' && (cur = scanner_getc(lc)) == 'x') {
                cur = scanner_getc(lc);
                while (cur != EOF && iswxdigit(cur)) {
                        token = HEXADECIMAL;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]

Reply via email to