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 -- [email protected]
To unsubscribe send an email to [email protected]