Changeset: 61a635da41cf for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/61a635da41cf
Modified Files:
        sql/backends/monet5/sql_execute.c
        sql/common/sql_types.c
        sql/server/rel_dump.c
        sql/server/rel_exp.c
        sql/server/rel_propagate.c
        sql/server/rel_statistics.c
        sql/server/sql_atom.c
        sql/server/sql_decimal.c
        sql/server/sql_decimal.h
        sql/server/sql_parser.y
        sql/storage/store.c
        sql/test/BugTracker-2015/Tests/large_join.Bug-3809.test
        sql/test/BugTracker-2015/Tests/schemadiff.Bug-3778.SQL.py
        sql/test/BugTracker-2019/Tests/outer-join-varchar.Bug-6776.test
        
sql/test/BugTracker-2019/Tests/remote-table-non-existent-column.Bug-6750.py
        sql/test/BugTracker-2021/Tests/plan-not-optimal-view.Bug-7140.test
        sql/test/emptydb/Tests/check.stable.out.int128
        sql/test/merge-partitions/Tests/mergepart31.test
        sql/test/miscellaneous/Tests/groupby_expressions.test
        sql/test/miscellaneous/Tests/groupby_prepare.stable.out
        sql/test/miscellaneous/Tests/simple_plans.test
        sql/test/miscellaneous/Tests/unique_keys.test
        sql/test/miscellaneous/Tests/view-mul-digits.test
        sql/test/out2in/Tests/out2in.test
        sql/test/prepare/Tests/prepare_unop_crash.Bug-3653.stable.out
        sql/test/prepare/Tests/prepared-merge-statement.Bug-6706.stable.out
        sql/test/rel-optimizers/Tests/split-select.test
Branch: cleanup_types
Log Message:

handle more cases of digits/bits reduction because of statistics.
on remote sides we now upcast if the functions return lower number of 
bits/digits.


diffs (truncated from 2539 to 300 lines):

diff --git a/sql/backends/monet5/sql_execute.c 
b/sql/backends/monet5/sql_execute.c
--- a/sql/backends/monet5/sql_execute.c
+++ b/sql/backends/monet5/sql_execute.c
@@ -743,6 +743,25 @@ RAstatement2_return(backend *be, mvc *m,
        return RAcommit_statement(be, msg);
 }
 
+static void
+subtype_from_string(mvc *sql, sql_subtype *st, char *type)
+{
+       unsigned digits = 0, scale = 0;
+
+       char *end = strchr(type, '(');
+       if (end) {
+               end[0] = 0;
+               digits = strtol(end+1, &end, 10);
+               if (end && end[0] == ',')
+                       scale = strtol(end+1, NULL, 10);
+       }
+       if (!sql_find_subtype(st, type, digits, scale)) {
+               sql_type *t = mvc_bind_type(sql, type);
+               if (t)
+                       sql_init_subtype(st, t, 0, 0);
+       }
+}
+
 str
 RAstatement2(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
 {
@@ -892,14 +911,20 @@ RAstatement2(Client cntxt, MalBlkPtr mb,
                else {
                        int i = 1;
                        for (node *n = rel->exps->h, *m = types_list->h ; n && 
m && !msg ; n = n->next, m = m->next) {
-                               sql_exp *e = (sql_exp *) n->data;
-                               sql_subtype *t = exp_subtype(e);
-                               str got = sql_subtype_string(be->mvc->ta, t), 
expected = (str) m->data;
+                               sql_exp *e = n->data, *ne = NULL;
+                               sql_subtype *t = exp_subtype(e), et;
 
-                               if (!got)
-                                       msg = createException(SQL, 
"RAstatement2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
-                               else if (strcmp(expected, got) != 0)
+                               subtype_from_string(be->mvc, &et, m->data);
+                               if (!is_subtype(t, &et) && (ne = 
exp_check_type(be->mvc, &et, rel, e, type_equal)) == NULL) {
+                                       str got = 
sql_subtype_string(be->mvc->ta, t), expected = (str) m->data;
+                                       if (!got)
+                                               msg = createException(SQL, 
"RAstatement2", SQLSTATE(HY013) MAL_MALLOC_FAIL);
                                        msg = createException(SQL, 
"RAstatement2", SQLSTATE(42000) "Parameter %d has wrong SQL type, expected %s, 
but got %s instead", i, expected, got);
+                               }
+                               if (ne) {
+                                       exp_setname(be->mvc->sa, ne, 
exp_relname(e), exp_name(e));
+                                       n->data = ne;
+                               }
                                i++;
                        }
                }
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
@@ -35,9 +35,9 @@ static list *localtypes = NULL;
 unsigned int digits2bits(unsigned int digits)
 {
        if (digits < 3)
-               return 8;
+               return 7;
        else if (digits < 5)
-               return 16;
+               return 15;
        else if (digits <= 5)
                return 17;
        else if (digits <= 6)
@@ -47,15 +47,15 @@ unsigned int digits2bits(unsigned int di
        else if (digits <= 8)
                return 27;
        else if (digits < 10)
-               return 32;
+               return 31;
        else if (digits < 17)
                return 51;
 #ifdef HAVE_HGE
        else if (digits < 19)
-               return 64;
-       return 128;
+               return 63;
+       return 127;
 #else
-       return 64;
+       return 63;
 #endif
 }
 
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
@@ -1421,8 +1421,38 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
                                        if (!execute_priv(sql, f->func))
                                                return 
function_error_string(sql, tname, cname, exps, true, F_FUNC);
                                        sql_exp *res = exps->t->data;
-                                       sql_subtype *restype = exp_subtype(res);
+                                       sql_subtype *restype = 
exp_subtype(res), *condtype = NULL;
                                        f->res->h->data = 
sql_create_subtype(sql->sa, restype->type, restype->digits, restype->scale);
+                                       /* As the inner functions may return 
smaller types (because of statistics and optimization),
+                                        * ie upcast here */
+                                       /* case exps are lists of (result, 
condition) ending with single value */
+                                       /* casewhen exps are lists of first 
(fe) a expression followed by (resultN, valueN) ending with single  last result 
 (fe == value1 -> result1 etc else last result */
+                                       /* nullif is list of values */
+                                       /* coalesce is list of values */
+                                       bool skip = false;
+                                       node *n = exps->h;
+                                       if (strcmp(cname, "case") == 0 && 
n->next) {
+                                               skip = true;
+                                               n = n->next;
+                                       }
+                                       if (strcmp(cname, "casewhen") == 0) {
+                                               sql_exp *e = n->data;
+                                               condtype = exp_subtype(e);
+                                               n = n->next;
+                                       }
+                                       for (; n; n = n->next) {
+                                               sql_exp *e = n->data;
+
+                                               if (condtype && n->next) {
+                                                       n->data = 
exp_check_type(sql, condtype, NULL, e, type_equal);
+                                                       n = n->next;
+                                                       e = n->data;
+                                               }
+                                               n->data = exp_check_type(sql, 
restype, NULL, e, type_equal);
+
+                                               if (skip && n->next && 
n->next->next)
+                                                       n = n->next;
+                                       }
                                }
                        } else {
                                list *ops = sa_list(sql->sa);
@@ -1474,13 +1504,13 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
 #ifdef HAVE_HGE
                                                                if 
(res->type->radix == 10 && digits > 38)
                                                                        digits 
= 38;
-                                                               if 
(res->type->radix == 2 && digits > 128)
-                                                                       digits 
= 128;
+                                                               if 
(res->type->radix == 2 && digits > 127)
+                                                                       digits 
= 127;
 #else
                                                                if 
(res->type->radix == 10 && digits > 18)
                                                                        digits 
= 18;
-                                                               if 
(res->type->radix == 2 && digits > 64)
-                                                                       digits 
= 64;
+                                                               if 
(res->type->radix == 2 && digits > 63)
+                                                                       digits 
= 63;
 #endif
 
                                                                
sql_find_subtype(res, lt->type->base.name, digits, scale);
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -2930,13 +2930,13 @@ exp_scale_algebra(mvc *sql, sql_subfunc 
 #ifdef HAVE_HGE
                if (res->type->radix == 10 && digits > 38)
                        digits = 38;
-               if (res->type->radix == 2 && digits > 128)
-                       digits = 128;
+               if (res->type->radix == 2 && digits > 127)
+                       digits = 127;
 #else
                if (res->type->radix == 10 && digits > 18)
                        digits = 18;
-               if (res->type->radix == 2 && digits > 64)
-                       digits = 64;
+               if (res->type->radix == 2 && digits > 63)
+                       digits = 63;
 #endif
 
                sql_find_subtype(&nlt, lt->type->base.name, digL, scaleL);
@@ -2945,6 +2945,10 @@ exp_scale_algebra(mvc *sql, sql_subfunc 
                l = exp_check_type(sql, &nlt, rel, l, type_equal);
 
                sql_find_subtype(res, lt->type->base.name, digits, scale);
+       } else if (lt->type->scale == SCALE_FIX) {
+               sql_subtype *res = f->res->h->data;
+               if (res->type->eclass == EC_NUM)
+                       res->digits = MAX(lt->digits, rt->digits);
        }
        return l;
 }
@@ -3010,8 +3014,8 @@ exps_sum_scales(sql_subfunc *f, list *ex
                        res->digits = 38;
                        res->scale = MIN(res->scale, res->digits - 1);
                }
-               if (ares->type.type->radix == 2 && res->digits > 128) {
-                       res->digits = 128;
+               if (ares->type.type->radix == 2 && res->digits > 127) {
+                       res->digits = 127;
                        res->scale = MIN(res->scale, res->digits - 1);
                }
 #else
@@ -3019,8 +3023,8 @@ exps_sum_scales(sql_subfunc *f, list *ex
                        res->digits = 18;
                        res->scale = MIN(res->scale, res->digits - 1);
                }
-               if (ares->type.type->radix == 2 && res->digits > 64) {
-                       res->digits = 64;
+               if (ares->type.type->radix == 2 && res->digits > 63) {
+                       res->digits = 63;
                        res->scale = MIN(res->scale, res->digits - 1);
                }
 #endif
@@ -3029,11 +3033,11 @@ exps_sum_scales(sql_subfunc *f, list *ex
                /* numeric types are fixed length */
                if (ares->type.type->eclass == EC_NUM) {
 #ifdef HAVE_HGE
-                       if (ares->type.type->localtype == TYPE_hge && 
res->digits == 128)
+                       if (ares->type.type->localtype == TYPE_hge && 
res->digits == 127)
                                t = *sql_bind_localtype("hge");
                        else
 #endif
-                       if (ares->type.type->localtype == TYPE_lng && 
res->digits == 64)
+                       if (ares->type.type->localtype == TYPE_lng && 
res->digits == 63)
                                t = *sql_bind_localtype("lng");
                        else if (res->type->digits >= res->digits)
                                t = *res; /* we cannot reduce types! */
@@ -3143,7 +3147,8 @@ exps_scale_fix(sql_subfunc *f, list *exp
                        sql_init_subtype(res, largesttype, digits, scale);
                else
                        sql_find_subtype(res, 
res->type->localtype?res->type->base.name:atp->type->base.name, digits, scale);
-       }
+       } else if (res->type->eclass == EC_DEC || res->type->eclass == EC_NUM)
+               res->digits = digits;
 }
 
 int
diff --git a/sql/server/rel_propagate.c b/sql/server/rel_propagate.c
--- a/sql/server/rel_propagate.c
+++ b/sql/server/rel_propagate.c
@@ -32,8 +32,6 @@ rel_generate_anti_expression(mvc *sql, s
 
                res = rel_base_bind_colnr(sql, *anti_rel, colr);
                return res;
-               //res = list_fetch((*anti_rel)->exps, colr);
-               //res = exp_ref(sql, res);
        } else if (isPartitionedByExpressionTable(mt)) {
                *anti_rel = rel_project(sql->sa, *anti_rel, NULL);
                if (!(res = rel_parse_val(sql, mt->s, mt->part.pexp->exp, NULL, 
sql->emode, (*anti_rel)->l)))
@@ -180,6 +178,9 @@ create_range_partition_anti_rel(sql_quer
        anti_nils = rel_unop_(sql, anti_rel, anti_le, "sys", "isnull", 
card_value);
        set_has_no_nil(anti_nils);
        if (pmin && pmax) {
+               /* type could have changed because of partition expression */
+               if (!(anti_le = exp_check_type(sql, &tpe, NULL, anti_le, 
type_equal)))
+                       return NULL;
                if (all_ranges) { /*if holds all values in range, don't 
generate the range comparison */
                        assert(!with_nills);
                } else {
@@ -247,6 +248,11 @@ create_list_partition_anti_rel(sql_query
 
        set_has_no_nil(anti_nils);
        if (list_length(anti_exps) > 0) {
+               sql_exp *ae = anti_exps->h->data;
+               sql_subtype *ntpe = exp_subtype(ae);
+               /* function may need conversion */
+               if (!(anti_le = exp_check_type(sql, ntpe, NULL, anti_le, 
type_equal)))
+                       return NULL;
                anti_exp = exp_in(sql->sa, anti_le, anti_exps, cmp_notin);
                if (!with_nills) {
                        anti_nils = exp_compare(sql->sa, anti_nils, 
exp_atom_bool(sql->sa, 1), cmp_equal);
diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c
--- a/sql/server/rel_statistics.c
+++ b/sql/server/rel_statistics.c
@@ -238,7 +238,7 @@ sql_column_get_statistics(mvc *sql, sql_
        }
        unsigned int digits = 0;
        sql_subtype *et = exp_subtype(e);
-       if (et->type->eclass == EC_DEC)
+       if (et->type->eclass == EC_DEC || et->type->eclass == EC_NUM)
                digits = et->digits;
        if ((ok & 2) == 2) {
                if (!VALisnil(&max)) {
diff --git a/sql/server/sql_atom.c b/sql/server/sql_atom.c
--- a/sql/server/sql_atom.c
+++ b/sql/server/sql_atom.c
@@ -1138,23 +1138,43 @@ atom_is_false(atom *a)
 unsigned int
 atom_digits(atom *a)
 {
-       if (a->isnull || !ATOMlinear(a->tpe.type->localtype) || 
a->tpe.type->eclass != EC_DEC /* TODO: other types */)
+       if (a->isnull || !ATOMlinear(a->tpe.type->localtype) ||
+                       (a->tpe.type->eclass != EC_DEC && a->tpe.type->eclass 
!= EC_NUM))
                return 0;
-       switch (ATOMstorage(a->tpe.type->localtype)) {
-       case TYPE_bte:
-               return decimal_digits(a->data.val.btval);
-       case TYPE_sht:
-               return decimal_digits(a->data.val.shval);
-       case TYPE_int:
-               return decimal_digits(a->data.val.ival);
-       case TYPE_lng:
-               return decimal_digits(a->data.val.lval);
+       if (a->tpe.type->eclass == EC_DEC) {
+               switch (ATOMstorage(a->tpe.type->localtype)) {
+                       case TYPE_bte:
+                               return decimal_digits(a->data.val.btval);
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to