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