Changeset: 1c4f0555e35c for MonetDB URL: https://dev.monetdb.org/hg/MonetDB/rev/1c4f0555e35c Modified Files: sql/server/rel_basetable.c sql/server/rel_exp.c sql/server/rel_exp.h sql/server/rel_select.c sql/server/rel_statistics.c Branch: cleanup_types Log Message:
try to use smallest output possible for sum diffs (141 lines): diff --git a/sql/server/rel_basetable.c b/sql/server/rel_basetable.c --- a/sql/server/rel_basetable.c +++ b/sql/server/rel_basetable.c @@ -17,6 +17,7 @@ #include "rel_basetable.h" #include "rel_remote.h" #include "rel_statistics.h" +#include "rel_rewriter.h" #include "sql_privileges.h" #define USED_LEN(nr) ((nr+31)/32) @@ -106,10 +107,13 @@ rel_basetable(mvc *sql, sql_table *t, co sql_rel *rel = rel_create(sa); int nrcols = ol_length(t->columns), end = nrcols + 1 + ol_length(t->idxs); rel_base_t *ba = (rel_base_t*)sa_zalloc(sa, sizeof(rel_base_t) + sizeof(int)*USED_LEN(end)); + sqlstore *store = sql->session->tr->store; if(!rel || !ba) return NULL; + if (isTable(t) && t->s && !isDeclaredTable(t)) /* count active rows only */ + set_count_prop(sql->sa, rel, (BUN)store->storage_api.count_col(sql->session->tr, ol_first_node(t->columns)->data, 10)); assert(atname); if (strcmp(atname, t->base.name) != 0) ba->name = sa_strdup(sa, atname); 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 @@ -13,6 +13,7 @@ #include "monetdb_config.h" #include "sql_relation.h" #include "sql_semantic.h" +#include "sql_decimal.h" #include "rel_exp.h" #include "rel_rel.h" #include "rel_basetable.h" @@ -3113,6 +3114,43 @@ exps_inout(sql_subfunc *f, list *exps) res->digits = digits; } +/* for aggregates we can reduce the result types size based on real digits/bits used number of known input rows */ +void +exps_largest_int(sql_subfunc *f, list *exps, lng cnt) +{ + if (!f->func->res || cnt == 0) + return; + sql_subtype *res = f->res->h->data; + if (res->type->eclass != EC_DEC && res->type->eclass != EC_NUM) + return; + bool is_decimal = (res->type->eclass == EC_DEC); + unsigned int digits = 0, scale = 0, mdigits = is_decimal ? decimal_digits(cnt) : number_bits(cnt); + sql_type *largesttype = NULL; + for(node *n = exps->h; n; n = n->next) { + sql_subtype *t = exp_subtype(n->data); + + if (!t) + continue; + + largesttype = t->type; + if (is_decimal && t->type->eclass == EC_NUM) { + unsigned int d = bits2digits(t->digits); + digits = d>digits?d:digits; + } else if (digits < t->digits) + digits = t->digits; + if (scale < t->scale) + scale = t->scale; + break; + } + digits += mdigits; + if (largesttype && digits <= largesttype->digits) + sql_init_subtype(res, largesttype, digits, scale); + else if (is_decimal) + sql_find_subtype(res, res->type->base.name, digits, scale); + else + sql_find_numeric(res, 1, digits); +} + #define is_addition(fname) (strcmp(fname, "sql_add") == 0) #define is_subtraction(fname) (strcmp(fname, "sql_sub") == 0) void diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h --- a/sql/server/rel_exp.h +++ b/sql/server/rel_exp.h @@ -210,6 +210,7 @@ extern void exps_sum_scales(sql_subfunc extern sql_exp *exps_scale_algebra(mvc *sql, sql_subfunc *f, sql_rel *rel, list *exps); extern void exps_digits_add(sql_subfunc *f, list *exps); extern void exps_inout(sql_subfunc *f, list *exps); +extern void exps_largest_int(sql_subfunc *f, list *exps, lng cnt); extern int exp_aggr_is_count(sql_exp *e); extern list *check_distinct_exp_names(mvc *sql, list *exps); 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 @@ -416,6 +416,23 @@ exp_fix_scale(mvc *sql, sql_subtype *ct, return e; } +static lng +rel_get_count(sql_rel *rel) +{ + if (!rel) + return 0; + prop *p = NULL; + if (rel->p && (p = find_prop(rel->p, PROP_COUNT)) != NULL) + return p->value.lval; + else if(rel->l) { + if (is_select(rel->op) || is_project(rel->op)) + return rel_get_count(rel->l); + } + return 0; +} + +#define is_sum_aggr(f) (f->type == F_AGGR && strcmp(f->base.name, "sum") == 0) + list * check_arguments_and_find_largest_any_type(mvc *sql, sql_rel *rel, list *exps, sql_subfunc *sf, int maybe_zero_or_one, bool internal) { @@ -507,7 +524,9 @@ check_arguments_and_find_largest_any_typ exps_digits_add(sf, nexps); } else if (sf->func->fix_scale == INOUT) { exps_inout(sf, nexps); - } + } else if (is_sum_aggr(sf->func)) + exps_largest_int(sf, nexps, rel_get_count(rel)); + /* dirty hack */ if (sf->func->type != F_PROC && sf->func->type != F_UNION && sf->func->type != F_LOADER && res) { if (res->type->eclass == EC_ANY && atp) 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 @@ -270,6 +270,8 @@ sql_column_get_statistics(mvc *sql, sql_ } if (digits) et->digits = digits; + if (et->type->eclass == EC_DEC && et->digits <= et->scale) + et->digits = et->scale + 1; } static void _______________________________________________ checkin-list mailing list -- checkin-list@monetdb.org To unsubscribe send an email to checkin-list-le...@monetdb.org