Changeset: 93aeda8eb00e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=93aeda8eb00e
Modified Files:
sql/server/rel_statistics.c
Branch: properties
Log Message:
More prunning and cleanup
diffs (190 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
@@ -1,4 +1,3 @@
-
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
@@ -28,8 +27,6 @@ comparison_find_column(sql_exp *input, s
static sql_exp *
rel_propagate_column_ref_statistics(mvc *sql, sql_rel *rel, sql_exp *e)
{
- sql_exp *found = NULL;
-
assert(e->type == e_column);
if (rel) {
switch(rel->op) {
@@ -61,7 +58,6 @@ rel_propagate_column_ref_statistics(mvc
atom *lval_min =
find_prop_and_get(le->p, PROP_MIN), *lval_max = find_prop_and_get(le->p,
PROP_MAX), *rval_min = find_prop_and_get(re->p, PROP_MIN),
*rval_max =
find_prop_and_get(re->p, PROP_MAX), *fval_min = fe ? find_prop_and_get(re->p,
PROP_MIN) : NULL, *fval_max = fe ? find_prop_and_get(re->p, PROP_MAX) : NULL;
- found = found ? found :
lne ? lne : rne ? rne : fne;
found_without_semantics
|= !comp->semantics;
if
(is_outerjoin(rel->op)) /* on outer joins, min and max cannot be propagated */
continue;
@@ -144,13 +140,10 @@ rel_propagate_column_ref_statistics(mvc
}
}
}
- if (found) {
- /* if semantics flag was found, null values
will pass */
- if (is_full(rel->op) || (is_left(rel->op) &&
found_right) || (is_right(rel->op) && found_left) || !found_without_semantics)
- set_has_nil(e);
- else if (found_without_semantics ||
!is_outerjoin(rel->op)) /* at an outer join, null values pass */
- set_has_no_nil(e);
- }
+ if (is_full(rel->op) || (is_left(rel->op) &&
found_right) || (is_right(rel->op) && found_left))
+ set_has_nil(e);
+ if (!is_outerjoin(rel->op) && found_without_semantics)
/* at an outer join, null values pass */
+ set_has_no_nil(e);
return e;
}
case op_table:
@@ -160,6 +153,7 @@ rel_propagate_column_ref_statistics(mvc
case op_inter:
case op_project:
case op_groupby: {
+ sql_exp *found;
atom *fval;
if ((found = rel_find_exp(rel, e)) && rel->op !=
op_table) {
if ((fval = find_prop_and_get(found->p,
PROP_MAX)))
@@ -505,61 +499,76 @@ rel_simplify_count(visitor *v, sql_rel *
return rel;
}
-static sql_rel *
-rel_prune_predicates(visitor *v, sql_rel *rel)
+static sql_exp * /* Remove predicates always false from min/max values */
+rel_prune_predicates(visitor *v, sql_rel *rel, sql_exp *e, int depth)
{
mvc *sql = v->sql;
+ bool always_false = false, always_true = false;
- if ((is_joinop(rel->op) || is_select(rel->op)) &&
!list_empty(rel->exps)) {
- /* Remove predicates always false from min/max values */
- for (node *n = rel->exps->h; n ; n = n->next) {
- sql_exp *e = n->data;
- bool always_false = false;
-
- if (e->type == e_cmp && (is_theta_exp(e->flag) ||
e->f)) {
- sql_exp *le = e->l, *re = e->r, *fe = e->f;
- atom *lval_min = find_prop_and_get(le->p,
PROP_MIN), *lval_max = find_prop_and_get(le->p, PROP_MAX), *rval_min =
find_prop_and_get(re->p, PROP_MIN),
- *rval_max = find_prop_and_get(re->p,
PROP_MAX), *fval_min = fe ? find_prop_and_get(re->p, PROP_MIN) : NULL,
*fval_max = fe ? find_prop_and_get(re->p, PROP_MAX) : NULL;
+ (void) rel;
+ (void) depth;
+ if (e->type == e_cmp && (is_theta_exp(e->flag) || e->f)) {
+ sql_exp *le = e->l, *re = e->r, *fe = e->f;
+ atom *lval_min = find_prop_and_get(le->p, PROP_MIN), *lval_max
= find_prop_and_get(le->p, PROP_MAX), *rval_min = find_prop_and_get(re->p,
PROP_MIN),
+ *rval_max = find_prop_and_get(re->p, PROP_MAX),
*fval_min = fe ? find_prop_and_get(re->p, PROP_MIN) : NULL, *fval_max = fe ?
find_prop_and_get(re->p, PROP_MAX) : NULL;
- if (fe) {
- (void) fval_min;
- (void) fval_max;
- } else {
- switch (e->flag) {
- case cmp_equal:
- if (lval_min && lval_max &&
rval_min && rval_max && !lval_min->isnull && !lval_max->isnull &&
!rval_min->isnull && !rval_max->isnull)
- always_false |=
(!e->anti && (atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, lval_max)
> 0)) || (e->anti && atom_cmp(lval_min, rval_min) == 0 && atom_cmp(lval_max,
rval_max) <= 0);
- if (is_semantics(e))
- always_false |=
is_semantics(e) ?
-
e->anti ? (exp_is_null(le) && exp_is_null(re)) || (exp_is_not_null(le) &&
exp_is_not_null(re)) : (exp_is_not_null(le) && exp_is_null(re)) ||
(exp_is_null(le) && exp_is_not_null(re)) :
-
e->anti ? exp_is_not_null(le) && exp_is_not_null(re) : (exp_is_null(le) &&
exp_is_null(re)) || (exp_is_not_null(le) && exp_is_null(re)) ||
(exp_is_null(le) && exp_is_not_null(re));
- break;
- case cmp_notequal:
- break;
- case cmp_gt:
- case cmp_gte:
- case cmp_lt:
- case cmp_lte:
- default: /* Maybe later I can do cmp_in
and cmp_notin */
- break;
- }
- }
- }
-
- if (always_false) {
- n->data = exp_atom_bool(sql->sa, 0);
- v->changes++;
+ if (fe) {
+ (void) fval_min;
+ (void) fval_max;
+ } else {
+ switch (e->flag) {
+ case cmp_equal:
+ if (lval_min && lval_max && rval_min &&
rval_max && !lval_min->isnull && !lval_max->isnull && !rval_min->isnull &&
!rval_max->isnull)
+ always_false |= (!e->anti &&
(atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, lval_max) > 0)) ||
(e->anti && atom_cmp(lval_min, rval_min) == 0 && atom_cmp(lval_max, rval_max)
<= 0);
+ if (is_semantics(e))
+ always_false |= is_semantics(e) ?
+ e->anti ? (exp_is_null(le) &&
exp_is_null(re)) || (exp_is_not_null(le) && exp_is_not_null(re)) :
(exp_is_not_null(le) && exp_is_null(re)) || (exp_is_null(le) &&
exp_is_not_null(re)) :
+ e->anti ? exp_is_not_null(le)
&& exp_is_not_null(re) : (exp_is_null(le) && exp_is_null(re)) ||
(exp_is_not_null(le) && exp_is_null(re)) || (exp_is_null(le) &&
exp_is_not_null(re));
+ break;
+ case cmp_gt:
+ if (lval_max && rval_min && !lval_max->isnull
&& !rval_min->isnull)
+ always_false |= e->anti ?
atom_cmp(lval_max, rval_min) > 0 : atom_cmp(lval_max, rval_min) <= 0;
+ if (lval_min && rval_max && !lval_min->isnull
&& !rval_max->isnull)
+ always_true |= exp_is_not_null(le) &&
exp_is_not_null(re) && (e->anti ? atom_cmp(lval_min, rval_max) <= 0 :
atom_cmp(lval_min, rval_max) > 0);
+ break;
+ case cmp_gte:
+ if (lval_max && rval_min && !lval_max->isnull
&& !rval_min->isnull)
+ always_false |= e->anti ?
atom_cmp(lval_max, rval_min) >= 0 : atom_cmp(lval_max, rval_min) < 0;
+ if (lval_min && rval_max && !lval_min->isnull
&& !rval_max->isnull)
+ always_true |= exp_is_not_null(le) &&
exp_is_not_null(re) && (e->anti ? atom_cmp(lval_min, rval_max) < 0 :
atom_cmp(lval_min, rval_max) >= 0);
+ break;
+ case cmp_lt:
+ if (lval_min && rval_max && !lval_min->isnull
&& !rval_max->isnull)
+ always_false |= e->anti ?
atom_cmp(lval_min, rval_max) < 0 : atom_cmp(lval_min, rval_max) >= 0;
+ if (lval_max && rval_min && !lval_max->isnull
&& !rval_min->isnull)
+ always_true |= exp_is_not_null(le) &&
exp_is_not_null(re) && (e->anti ? atom_cmp(lval_max, rval_min) >= 0 :
atom_cmp(lval_max, rval_min) < 0);
+ break;
+ case cmp_lte:
+ if (lval_min && rval_max && !lval_min->isnull
&& !rval_max->isnull)
+ always_false |= e->anti ?
atom_cmp(lval_min, rval_max) <= 0 : atom_cmp(lval_min, rval_max) > 0;
+ if (lval_max && rval_min && !lval_max->isnull
&& !rval_min->isnull)
+ always_true |= exp_is_not_null(le) &&
exp_is_not_null(re) && (e->anti ? atom_cmp(lval_max, rval_min) > 0 :
atom_cmp(lval_max, rval_min) <= 0);
+ break;
+ default: /* Maybe later I can do cmp_in and cmp_notin */
+ break;
}
}
}
- return rel;
+ assert(!always_false || !always_true);
+ if (always_false || always_true) {
+ sql_exp *ne = exp_atom_bool(sql->sa, always_true);
+ if (exp_name(e))
+ exp_prop_alias(v->sql->sa, ne, e);
+ e = ne;
+ v->changes++;
+ }
+ return e;
}
-
sql_rel *
rel_statistics(mvc *sql, sql_rel *rel)
{
- visitor v = { .sql = sql };
+ visitor v = { .sql = sql, .value_based_opt = 1, .storage_based_opt = 1
}, ev = { .sql = sql, .value_based_opt = 1, .storage_based_opt = 1 };
global_props gp = (global_props) {.cnt = {0},};
rel_properties(sql, &gp, rel);
@@ -568,11 +577,13 @@ rel_statistics(mvc *sql, sql_rel *rel)
rel = rel_visitor_bottomup(&v, rel, &rel_simplify_count);
if (gp.cnt[op_select] || gp.cnt[op_left] || gp.cnt[op_right] ||
gp.cnt[op_full] || gp.cnt[op_anti] || gp.cnt[op_join] || gp.cnt[op_semi]) {
int cur_changes = v.changes;
- v.changes = 0; /* reset changes counter */
- rel = rel_visitor_bottomup(&v, rel, &rel_prune_predicates);
- if (v.changes > 0) /* there were changes by
rel_prune_predicates, run rewrite_simplify */
- rel = rel_visitor_bottomup(&v, rel, &rewrite_simplify);
- v.changes += cur_changes;
+ rel = rel_exp_visitor_bottomup(&v, rel, &rel_prune_predicates,
false);
+ if (v.changes > cur_changes) { /* there were changes by
rel_prune_predicates, run rewrite_simplify */
+ rel = rel_visitor_bottomup(&ev, rel, &rewrite_simplify);
+ if (gp.cnt[op_select])
+ rel = rel_visitor_bottomup(&ev, rel,
&rel_remove_empty_select);
+ rel = rel_dce(sql, rel);
+ }
}
return rel;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list