Changeset: 822e5a590a29 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/822e5a590a29
Branch: default
Log Message:

Merge branch literal_features into default


diffs (truncated from 1772 to 300 lines):

diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -937,6 +937,7 @@ sqltypeinit( sql_allocator *sa)
        /* needed for indices/clusters oid(schema.table,val) returns 
max(head(schema.table))+1 */
        sql_create_func(sa, "rowid", "calc", "rowid", TRUE, TRUE, SCALE_NONE, 
0, OID, 3, ANY, STR, STR);
        sql_create_aggr(sa, "min", "aggr", "min", FALSE, FALSE, ANY, 1, ANY);
+       sql_create_aggr(sa, "any_value", "aggr", "min", FALSE, FALSE, ANY, 1, 
ANY);
        sql_create_aggr(sa, "max", "aggr", "max", FALSE, FALSE, ANY, 1, ANY);
        sql_create_func(sa, "sql_min", "calc", "min", FALSE, FALSE, SCALE_FIX, 
0, ANY, 2, ANY, ANY);
        sql_create_func(sa, "sql_max", "calc", "max", FALSE, FALSE, SCALE_FIX, 
0, ANY, 2, ANY, ANY);
@@ -1095,6 +1096,7 @@ sqltypeinit( sql_allocator *sa)
 
        sql_create_analytic(sa, "count", "sql", "count", FALSE, SCALE_NONE, 
LNG, 2, ANY, BIT);
        sql_create_analytic(sa, "min", "sql", "min", FALSE, SCALE_NONE, ANY, 1, 
ANY);
+       sql_create_analytic(sa, "any_value", "sql", "min", FALSE, SCALE_NONE, 
ANY, 1, ANY);
        sql_create_analytic(sa, "max", "sql", "max", FALSE, SCALE_NONE, ANY, 1, 
ANY);
 
        /* analytical sum for numerical and decimals */
@@ -1511,8 +1513,8 @@ sqltypeinit( sql_allocator *sa)
                sql_create_func(sa, "ucase", "str", "toUpper", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
                sql_create_func(sa, "lower", "str", "toLower", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
                sql_create_func(sa, "lcase", "str", "toLower", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
-               sql_create_func(sa, "trim", "str", "trim", FALSE, FALSE, INOUT, 
0, *t, 1, *t);
-               sql_create_func(sa, "trim", "str", "trim2", FALSE, FALSE, 
INOUT, 0, *t, 2, *t, *t);
+               sql_create_func(sa, "btrim", "str", "trim", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
+               sql_create_func(sa, "btrim", "str", "trim2", FALSE, FALSE, 
INOUT, 0, *t, 2, *t, *t);
                sql_create_func(sa, "ltrim", "str", "ltrim", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
                sql_create_func(sa, "ltrim", "str", "ltrim2", FALSE, FALSE, 
INOUT, 0, *t, 2, *t, *t);
                sql_create_func(sa, "rtrim", "str", "rtrim", FALSE, FALSE, 
INOUT, 0, *t, 1, *t);
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
@@ -421,6 +423,8 @@ int yydebug=1;
        opt_null_string
        opt_to_savepoint
        opt_uescape
+       opt_trim_type
+       opt_trim_characters
        opt_using
        opt_XML_attribute_name
        restricted_ident
@@ -636,7 +640,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 HEXADECIMALNUM OCTALNUM 
BINARYNUM INTNUM APPROXNUM
        USING
        GLOBAL CAST CONVERT
        CHARACTER VARYING LARGE OBJECT VARCHAR CLOB sqlTEXT BINARY sqlBLOB
@@ -694,7 +698,7 @@ int yydebug=1;
 %left <operation> ALL ANY NOT_BETWEEN BETWEEN NOT_IN sqlIN NOT_EXISTS EXISTS 
NOT_LIKE LIKE NOT_ILIKE ILIKE OR SOME
 %left <operation> AND
 %left <sval> COMPARISON /* <> < > <= >= */
-%left <operation> '+' '-' '&' '|' '^' LEFT_SHIFT RIGHT_SHIFT LEFT_SHIFT_ASSIGN 
RIGHT_SHIFT_ASSIGN CONCATSTRING SUBSTRING POSITION SPLIT_PART
+%left <operation> '+' '-' '&' '|' '^' LEFT_SHIFT RIGHT_SHIFT LEFT_SHIFT_ASSIGN 
RIGHT_SHIFT_ASSIGN CONCATSTRING SUBSTRING TRIM POSITION SPLIT_PART
 %left <operation> '*' '/' '%'
 %left UMINUS
 %left <operation> '~'
@@ -721,6 +725,7 @@ SQLCODE SQLERROR UNDER WHENEVER
 %token PATH PRIMARY PRIVILEGES
 %token<sval> PUBLIC REFERENCES SCHEMA SET AUTO_COMMIT
 %token RETURN
+%token LEADING TRAILING BOTH
 
 %token ALTER ADD TABLE COLUMN TO UNIQUE VALUES VIEW WHERE WITH WITHOUT
 %token<sval> sqlDATE TIME TIMESTAMP INTERVAL
@@ -4501,6 +4506,18 @@ opt_brackets:
  | '(' ')'     { $$ = 1; }
  ;
 
+opt_trim_type:
+   /* empty */ { $$ = NULL; }
+  | LEADING {$$ = "ltrim"; }
+  | TRAILING {$$ = "rtrim"; }
+  | BOTH {$$ = "btrim"; }
+  ;
+
+opt_trim_characters:
+   /* empty */ { $$ = NULL; }
+  | string {$$ = $1; }
+  ;
+
 string_funcs:
     SUBSTRING '(' scalar_exp FROM scalar_exp FOR scalar_exp ')'
                        { dlist *l = L();
@@ -4567,6 +4584,38 @@ string_funcs:
                          append_symbol(ops, $7);
                          append_list(l, ops);
                          $$ = _symbol_create_list( SQL_NOP, l ); }
+| TRIM '(' opt_trim_type opt_trim_characters FROM scalar_exp  ')'
+                       { dlist *l = L();
+                         if ( $3 == NULL && $4 == NULL ) {
+                               sqlformaterror(m, SQLSTATE(2000) "%s", "trim 
specification or trim characters need to be specified preceding FROM in TRIM");
+                               YYABORT;
+                         }
+                         append_list(l,
+                               append_string(L(), sa_strdup(SA, 
$3?$3:"btrim")));
+                               append_int(l, FALSE); /* ignore distinct */
+                         append_symbol(l, $6);
+
+                         char* s = $4?$4:" ";
+                         int len = UTF8_strlen(s);
+                         sql_subtype t;
+                         sql_find_subtype(&t, "char", len, 0 );
+                         append_symbol(l, _newAtomNode( _atom_string(&t, s)));
+                         $$ = _symbol_create_list( SQL_BINOP, l ); }
+| TRIM '(' scalar_exp ',' scalar_exp  ')'
+                       { dlist *l = L();
+                         append_list(l,
+                               append_string(L(), sa_strdup(SA, "btrim")));
+                               append_int(l, FALSE); /* ignore distinct */
+                         append_symbol(l, $3);
+                         append_symbol(l, $5);
+                         $$ = _symbol_create_list( SQL_BINOP, l ); }
+| TRIM '(' scalar_exp ')'
+                       { dlist *l = L();
+                         append_list(l,
+                               append_string(L(), sa_strdup(SA, "btrim")));
+                               append_int(l, FALSE); /* ignore distinct */
+                         append_symbol(l, $3);
+                         $$ = _symbol_create_list( SQL_UNOP, l ); }
  ;
 
 column_exp_commalist:
@@ -4857,7 +4906,123 @@ literal:
                  sql_find_subtype(&t, "char", len, 0 );
                  $$ = _newAtomNode( _atom_string(&t, s)); }
 
- |  HEXADECIMAL { 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)
+                       {
+                               if (binary[i] == '_') {
+                                       i++;
+                                       continue;
+                               }
+                               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
+                 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)
+                       {
+                               if (octal[i] == '_') {
+                                       i++;
+                                       continue;
+                               }
+                               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));
+                 }
+
+ }
+ |  HEXADECIMALNUM { int len = _strlen($1), i = 2, err = 0; 
                  char * hexa = $1;
                  sql_subtype t;
 #ifdef HAVE_HGE
@@ -4876,6 +5041,10 @@ literal:
                  if (len - i < MAX_HEX_DIGITS || (len - i == MAX_HEX_DIGITS && 
hexa[i] < '8'))
                        while (err == 0 && i < len)
                        {
+                               if (hexa[i] == '_') {
+                                       i++;
+                                       continue;
+                               }
                                res <<= 4;
                                if (isdigit((unsigned char) hexa[i]))
                                        res = res + (hexa[i] - '0');
@@ -4947,7 +5116,19 @@ literal:
                  }
                }
  |  sqlINT
-               { int digits = _strlen($1), err = 0;
+               { 
+                       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 digits = j, err = 0;
 #ifdef HAVE_HGE
                  hge value, *p = &value;
                  size_t len = sizeof(hge);
@@ -4960,10 +5141,10 @@ literal:
                  sql_subtype t;
 
 #ifdef HAVE_HGE
-                 if (hgeFromStr($1, &len, &p, false) < 0 || is_hge_nil(value))
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to