Changeset: 25f6c008500b for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/25f6c008500b
Modified Files:
        sql/common/sql_types.c
        sql/server/rel_dump.c
        sql/server/rel_schema.c
        sql/server/rel_select.c
        sql/server/sql_parser.y
        sql/test/SQLancer/Tests/sqlancer08.test
Branch: Aug2024
Log Message:

Kind of reapply changeset a32c685fa62b, but now do it mostly in the parser.


diffs (214 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
@@ -244,6 +244,8 @@ sql_init_subtype(sql_subtype *res, sql_t
        if (t->digits && res->digits > t->digits)
                res->digits = t->digits;
        res->scale = scale;
+       if (!digits && !scale && t->eclass == EC_DEC)
+               res->scale = res->digits = 0;
 }
 
 sql_subtype *
@@ -765,7 +767,7 @@ sql_create_type(allocator *sa, const cha
                (void) keywords_insert(t->base.name, KW_TYPE);
        list_append(types, t);
 
-       list_append(localtypes, sql_create_subtype(sa, t, 0, 0));
+       list_append(localtypes, sql_create_subtype(sa, t, digits, 0));
 
        return t;
 }
@@ -799,10 +801,10 @@ sql_create_func_(allocator *sa, const ch
 
        for (int i = 0; i < nargs; i++) {
                sql_type *tpe = va_arg(valist, sql_type*);
-               list_append(ops, create_arg(sa, NULL, sql_create_subtype(sa, 
tpe, 0, 0), ARG_IN));
+               list_append(ops, create_arg(sa, NULL, sql_create_subtype(sa, 
tpe, tpe->digits, 0), ARG_IN));
        }
        if (res)
-               fres = create_arg(sa, NULL, sql_create_subtype(sa, res, 0, 0), 
ARG_OUT);
+               fres = create_arg(sa, NULL, sql_create_subtype(sa, res, 
res->digits, 0), ARG_OUT);
        base_init(sa, &t->base, local_id++, false, name);
 
        t->imp = sa_strdup(sa, imp);
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -1473,7 +1473,7 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                        if (!sql_find_subtype(&tpe, tname, 0, 0)) {
                                if (!(t = mvc_bind_type(sql, tname))) /* try an 
external type */
                                        return sql_error(sql, ERR_NOTFOUND, 
SQLSTATE(42000) "SQL type %s not found\n", tname);
-                               sql_init_subtype(&tpe, t, 0, 0);
+                               sql_init_subtype(&tpe, t, t->digits, 0);
                        }
                        if (!(exp = parse_atom(sql, r, pos, &tpe)))
                                return NULL;
diff --git a/sql/server/rel_schema.c b/sql/server/rel_schema.c
--- a/sql/server/rel_schema.c
+++ b/sql/server/rel_schema.c
@@ -1094,6 +1094,9 @@ create_column(sql_query *query, symbol *
        if (l->h->next->next)
                opt_list = l->h->next->next->data.lval;
 
+       if (ctype && ctype->type->eclass == EC_DEC && !ctype->digits && 
!ctype->scale) /* default 18,3 */
+               ctype = sql_bind_subtype(query->sql->sa, "decimal", 18, 3);
+
        if (cname && ctype) {
                sql_column *cs = NULL;
 
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -4073,10 +4073,12 @@ rel_cast(sql_query *query, sql_rel **rel
                sql_subtype *et = exp_subtype(e);
                if (et->type->eclass == EC_NUM) {
                        unsigned int min_precision = atom_num_digits(e->l);
+                       if (!tpe->digits && !tpe->scale)
+                               tpe->digits = min_precision;
                        if (min_precision > tpe->digits)
                                return sql_error(sql, 02, SQLSTATE(42000) 
"Precision (%d) should be at least (%d)", tpe->digits, min_precision);
-                       tpe = sql_bind_subtype(sql->sa, "decimal", 
min_precision, et->scale);
-               } else if (EC_VARCHAR(et->type->eclass)) {
+                       tpe = sql_bind_subtype(sql->sa, "decimal", tpe->digits, 
et->scale);
+               } else if (EC_VARCHAR(et->type->eclass) && !tpe->digits && 
!tpe->scale) {
                        char *s = E_ATOM_STRING(e);
                        unsigned int min_precision = 0, min_scale = 0;
                        bool dot_seen = false;
@@ -4091,6 +4093,12 @@ rel_cast(sql_query *query, sql_rel **rel
                        }
                        tpe = sql_bind_subtype(sql->sa, "decimal", 
min_precision, min_scale);
                }
+       } else if (tpe->type->eclass == EC_DEC && !tpe->digits && !tpe->scale) {
+               sql_subtype *et = exp_subtype(e);
+               if (et->type->eclass == EC_NUM)
+                       tpe = sql_bind_subtype(sql->sa, "decimal", et->digits, 
0);
+               else /* fallback */
+                       tpe = sql_bind_subtype(sql->sa, "decimal", 18, 3);
        }
 
        if (e)
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
@@ -2632,11 +2632,17 @@ opt_end_label:
 table_function_column_list:
        column data_type        { $$ = L();
                                  append_string($$, $1);
+                                 if (strcmp($2.type->base.name, "decimal") == 
0 &&
+                                     $2.digits == 0 && $2.scale == 0)
+                                         sql_find_subtype(&$2, "decimal", 18, 
3);
                                  append_type($$, &$2);
                                }
   |     table_function_column_list ',' column data_type
                                {
                                  append_string($$, $3);
+                                 if (strcmp($4.type->base.name, "decimal") == 
0 &&
+                                     $4.digits == 0 && $4.scale == 0)
+                                         sql_find_subtype(&$4, "decimal", 18, 
3);
                                  append_type($$, &$4);
                                }
   ;
@@ -2645,7 +2651,12 @@ func_data_type:
     TABLE '(' table_function_column_list ')'
                { $$ = _symbol_create_list(SQL_TABLE, $3); }
  |  data_type
-               { $$ = _symbol_create_list(SQL_TYPE, append_type(L(),&$1)); }
+               {
+                       if (strcmp($1.type->base.name, "decimal") == 0 &&
+                           $1.digits == 0 && $1.scale == 0)
+                               sql_find_subtype(&$1, "decimal", 18, 3);
+                       $$ = _symbol_create_list(SQL_TYPE, 
append_type(L(),&$1));
+               }
  ;
 
 opt_paramlist:
@@ -2661,12 +2672,18 @@ paramlist:
     paramlist ',' ident data_type
                        { dlist *p = L();
                          append_string(p, $3);
+                         if (strcmp($4.type->base.name, "decimal") == 0 &&
+                             $4.digits == 0 && $4.scale == 0)
+                                 sql_find_subtype(&$4, "decimal", 18, 3);
                          append_type(p, &$4);
                          $$ = append_list($1, p); }
  |  ident data_type
                        { dlist *l = L();
                          dlist *p = L();
                          append_string(p, $1);
+                         if (strcmp($2.type->base.name, "decimal") == 0 &&
+                             $2.digits == 0 && $2.scale == 0)
+                                 sql_find_subtype(&$2, "decimal", 18, 3);
                          append_type(p, &$2);
                          $$ = append_list(l, p); }
  ;
@@ -2869,11 +2886,21 @@ opt_typelist:
  ;
 
 typelist:
-    data_type                  { dlist *l = L();
-                                 append_type(l, &$1 );
-                                 $$= l; }
- |  data_type ',' typelist     { append_type($3, &$1);
-                                 $$ = $3; }
+    data_type                  {
+           dlist *l = L();
+           if (strcmp($1.type->base.name, "decimal") == 0 &&
+               $1.digits == 0 && $1.scale == 0)
+                   sql_find_subtype(&$1, "decimal", 18, 3);
+           append_type(l, &$1 );
+           $$= l;
+    }
+ |  data_type ',' typelist     {
+           if (strcmp($1.type->base.name, "decimal") == 0 &&
+               $1.digits == 0 && $1.scale == 0)
+                   sql_find_subtype(&$1, "decimal", 18, 1);
+           append_type($3, &$1);
+           $$ = $3;
+    }
  ;
 
 drop_action:
@@ -5752,7 +5779,7 @@ data_type:
  |  BIGINT             { sql_find_subtype(&$$, "bigint", 0, 0); }
  |  HUGEINT            { sql_find_subtype(&$$, "hugeint", 0, 0); }
 
- |  sqlDECIMAL         { sql_find_subtype(&$$, "decimal", 18, 3); }
+ |  sqlDECIMAL         { sql_find_subtype(&$$, "decimal", 0, 0); }
  |  sqlDECIMAL '(' nonzero ')'
                        {
                          int d = $3;
@@ -7019,7 +7046,7 @@ odbc_data_type:
     | SQL_DATE
        { sql_find_subtype(&$$, "date", 0, 0); }
     | SQL_DECIMAL
-       { sql_find_subtype(&$$, "decimal", 18, 3); }
+       { sql_find_subtype(&$$, "decimal", 0, 0); }
     | SQL_DOUBLE
        { sql_find_subtype(&$$, "double", 0, 0); }
     | SQL_FLOAT
@@ -7068,7 +7095,7 @@ odbc_data_type:
     | SQL_LONGVARCHAR
        { sql_find_subtype(&$$, "varchar", 0, 0); }
     | SQL_NUMERIC
-       { sql_find_subtype(&$$, "decimal", 18, 3); }
+       { sql_find_subtype(&$$, "decimal", 0, 0); }
     | SQL_REAL
        { sql_find_subtype(&$$, "real", 0, 0); }
     | SQL_SMALLINT
diff --git a/sql/test/SQLancer/Tests/sqlancer08.test 
b/sql/test/SQLancer/Tests/sqlancer08.test
--- a/sql/test/SQLancer/Tests/sqlancer08.test
+++ b/sql/test/SQLancer/Tests/sqlancer08.test
@@ -170,10 +170,10 @@ 0
 statement ok
 ROLLBACK
 
-statement error 42000!Decimal (0.2.3) doesn't have format (3.2)
+statement error 42000!Decimal (0.2.3) doesn't have format (10.2)
 select cast('0.2.3' as decimal(10,2))
 
-statement error 42000!Decimal (+0..2) doesn't have format (2.1)
+statement error 42000!Decimal (+0..2) doesn't have format (10.2)
 select cast('+0..2' as decimal(10,2))
 
 statement ok
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to