Changeset: 3da49a645bba for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3da49a645bba
Modified Files:
sql/server/rel_statistics.c
Branch: balanced_union
Log Message:
add statistics for munion
diffs (144 lines):
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
@@ -285,7 +285,7 @@ rel_setop_get_statistics(mvc *sql, sql_r
set_minmax_property(sql, e, PROP_MIN, lval_min);
}
- if (is_union(rel->op)) {
+ if (is_union(rel->op) || is_munion(rel->op)) {
if (!has_nil(le) && !has_nil(re))
set_has_no_nil(e);
if (need_distinct(rel) && list_length(rel->exps) == 1)
@@ -310,6 +310,42 @@ rel_setop_get_statistics(mvc *sql, sql_r
return false;
}
+
+static void
+rel_munion_get_statistics(mvc *sql, sql_rel *rel, list *rels, sql_exp *e, int
i)
+{
+ assert(is_munion(rel->op));
+
+ sql_rel *l = rels->h->data;
+ sql_exp *le = list_fetch(l->exps, i);
+ atom *lval_min = find_prop_and_get(le->p, PROP_MIN), *lval_max =
find_prop_and_get(le->p, PROP_MAX);
+ bool has_nonil = !has_nil(le);
+
+ for(node *n = rels->h->next; n; n = n->next) {
+ sql_rel *r = n->data;
+ sql_exp *re = list_fetch(r->exps, i);
+ atom *rval_min = find_prop_and_get(re->p, PROP_MIN), *rval_max
= find_prop_and_get(re->p, PROP_MAX);
+
+ if (lval_max && rval_max) {
+ set_minmax_property(sql, e, PROP_MAX,
statistics_atom_max(sql, lval_max, rval_max)); /* for union the new max will be
the max of the two */
+ lval_max = find_prop_and_get(e->p, PROP_MAX);
+ }
+ if (lval_min && rval_min) {
+ set_minmax_property(sql, e, PROP_MIN,
statistics_atom_min(sql, lval_min, rval_min)); /* for union the new min will be
the min of the two */
+ lval_min = find_prop_and_get(e->p, PROP_MIN);
+ }
+ has_nonil &= !has_nil(re);
+
+ }
+
+ if (has_nonil)
+ set_has_no_nil(e);
+
+ if (need_distinct(rel) && list_length(rel->exps) == 1)
+ set_unique(e);
+}
+
+
static sql_exp *
rel_propagate_statistics(visitor *v, sql_rel *rel, sql_exp *e, int depth)
{
@@ -789,9 +825,86 @@ rel_get_statistics_(visitor *v, sql_rel
}
break;
}
- case op_munion:
- // TODO: munion statistis
+ case op_munion: {
+ list *l = rel->l, *nrels = sa_list(v->sql->sa);
+ BUN cnt = 0;
+ bool needs_pruning = false;
+
+ for (node *n = l->h; n; n = n->next) {
+ sql_rel *r = n->data, *pl = r;
+
+ while (is_sample(pl->op) || is_topn(pl->op)) /* skip
topN and sample relations in the middle */
+ pl = pl->l;
+ /* if it's not a projection, then project and propagate
statistics */
+ if (!is_project(pl->op) && !is_base(pl->op)) {
+ pl = rel_project(v->sql->sa, pl,
rel_projections(v->sql, pl, NULL, 0, 1));
+ set_count_prop(v->sql->sa, pl,
get_rel_count(pl->l));
+ pl->exps = exps_exp_visitor_bottomup(v, pl,
pl->exps, 0, &rel_propagate_statistics, false);
+ }
+ nrels = append(nrels, pl);
+ /* we need new munion statistics */
+ /* propagate row count */
+ BUN rv = need_distinct(rel) ? rel_calc_nuniques(v->sql,
r, r->exps) : get_rel_count(r);
+ if (!rv && can_be_pruned)
+ needs_pruning = true;
+ if (rv > (BUN_MAX - cnt)) /* overflow check */
+ rv = BUN_MAX;
+ else
+ cnt += rv;
+ }
+ int i = 0;
+ for (node *n = rel->exps->h ; n ; n = n->next, i++)
+ rel_munion_get_statistics(v->sql, rel, nrels, n->data,
i);
+
+ if (needs_pruning) {
+ v->changes++;
+ list *nl = sa_list(l->sa);
+
+ for (node *n = nrels->h; n; n = n->next) {
+ sql_rel *r = n->data;
+ BUN rv = need_distinct(rel) ?
rel_calc_nuniques(v->sql, r, r->exps) : get_rel_count(r);
+
+ if (!rv) { /* keep last for now */
+ rel_destroy(r);
+ continue;
+ }
+ nl = append(nl, r);
+ }
+ rel->l = nl;
+ if (list_length(nl) == 1) {
+ sql_rel *l = rel->l = nl->h->data; /* ugh */
+ rel->op = op_project;
+
+ for (node *n = rel->exps->h, *m = l->exps->h ;
n && m ; n = n->next, m = m->next) {
+ sql_exp *pe = n->data, *ie = m->data;
+ sql_exp *ne = exp_ref(v->sql, ie);
+ exp_setname(v->sql->sa, ne,
exp_relname(pe), exp_name(pe));
+ n->data = ne;
+ }
+ list_hash_clear(rel->exps);
+ } else if (list_empty(nl)) {
+ /* empty select (project [ nils ] ) */
+ for (node *n = rel->exps->h ; n ; n = n->next) {
+ sql_exp *e = n->data, *a =
exp_atom(v->sql->sa, atom_general(v->sql->sa, exp_subtype(e), NULL));
+ exp_prop_alias(v->sql->sa, a, e);
+ n->data = a;
+ }
+ list_hash_clear(rel->exps);
+ sql_rel *l = rel_project(v->sql->sa, NULL,
rel->exps);
+ set_count_prop(v->sql->sa, l, 1);
+ l = rel_select(v->sql->sa, l,
exp_atom_bool(v->sql->sa, 0));
+ set_count_prop(v->sql->sa, l, 0);
+ rel->op = op_project;
+ rel->l = l;
+ rel->exps = rel_projections(v->sql, l, NULL, 1,
1);
+ set_count_prop(v->sql->sa, rel, 0);
+ set_nodistinct(rel); /* set relations may have
distinct flag set */
+ }
+ } else {
+ set_count_prop(v->sql->sa, rel, cnt);
+ }
break;
+ }
case op_join:
case op_left:
case op_right:
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]