Changeset: 366d41abe2a4 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=366d41abe2a4
Modified Files:
        sql/server/rel_statistics.c
        sql/server/sql_atom.c
Branch: properties
Log Message:

Don't swap parameters for division. Improved prunning for equality and 
inequality comparisons with semantics. Also make sure min property will always 
be less or equal to the max


diffs (187 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
@@ -203,7 +203,6 @@ atom_from_valptr( sql_allocator *sa, sql
        } else {
                VALcopy(&a->data, pt);
        }
-       a->isnull = VALisnil(&a->data);
        return a;
 }
 
@@ -221,11 +220,11 @@ rel_basetable_get_statistics(visitor *v,
                        set_has_no_nil(e);
  
                if (EC_NUMBER(c->type.type->eclass) || 
EC_VARCHAR(c->type.type->eclass) || EC_TEMP_NOFRAC(c->type.type->eclass) || 
c->type.type->eclass == EC_DATE) {
-                       if ((max = mvc_has_max_value(sql, c))) {
+                       if ((max = mvc_has_max_value(sql, c)) && 
!VALisnil(max)) {
                                prop *p = e->p = prop_create(sql->sa, PROP_MAX, 
e->p);
                                p->value = atom_from_valptr(sql->sa, &c->type, 
max);
                        }
-                       if ((min = mvc_has_min_value(sql, c))) {
+                       if ((min = mvc_has_min_value(sql, c)) && 
!VALisnil(min)) {
                                prop *p = e->p = prop_create(sql->sa, PROP_MIN, 
e->p);
                                p->value = atom_from_valptr(sql->sa, &c->type, 
min);
                        }
@@ -243,8 +242,7 @@ rel_setop_get_statistics(mvc *sql, sql_r
 
        /* for the intersection, if both expresssions don't overlap, it can be 
pruned */
        if (is_inter(rel->op) && exp_is_not_null(le) && exp_is_not_null(re) &&
-               lval_min && rval_min && lval_max && rval_max && 
!lval_min->isnull && !rval_min->isnull && !lval_max->isnull && 
!rval_max->isnull &&
-               (atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, 
lval_max) > 0))
+               lval_min && rval_min && lval_max && rval_max && 
(atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, lval_max) > 0))
                return true;
 
        if (lval_min && rval_min) {
@@ -375,14 +373,12 @@ rel_propagate_statistics(visitor *v, sql
                        for (node *n = vals->h ? vals->h->next : NULL ; n ; n = 
n->next) {
                                sql_exp *ee = n->data;
 
-                               if (max) {
+                               if (min && max) {
                                        if ((lval = find_prop_and_get(ee->p, 
PROP_MAX))) {
                                                max = atom_cmp(lval, max) > 0 ? 
lval : max;
                                        } else {
                                                max = NULL;
                                        }
-                               }
-                               if (min) {
                                        if ((lval = find_prop_and_get(ee->p, 
PROP_MIN))) {
                                                min = atom_cmp(min, lval) > 0 ? 
lval : min;
                                        } else {
@@ -391,10 +387,10 @@ rel_propagate_statistics(visitor *v, sql
                                }
                        }
 
-                       if (max)
+                       if (min && max) {
                                set_property(sql, e, PROP_MAX, max);
-                       if (min)
                                set_property(sql, e, PROP_MIN, min);
+                       }
                }
        } break;
        case e_cmp:
@@ -415,6 +411,19 @@ rel_propagate_statistics(visitor *v, sql
        case e_psm:
                break;
        }
+
+#ifndef NDEBUG
+       {
+               /* min and max cannot be NULL and min must be <= than max */
+               atom *min = find_prop_and_get(e->p, PROP_MIN), *max = 
find_prop_and_get(e->p, PROP_MAX);
+
+               (void) min;
+               (void) max;
+               assert(!min || !min->isnull);
+               assert(!max || !max->isnull);
+               assert(!min || !max || atom_cmp(min, max) <= 0);
+       }
+#endif
        return e;
 }
 
@@ -433,51 +442,59 @@ rel_prune_predicates(visitor *v, sql_rel
                        if (fe && !(e->flag & CMP_SYMMETRIC)) {
                                atom *fval_min = find_prop_and_get(fe->p, 
PROP_MIN), *fval_max = find_prop_and_get(fe->p, PROP_MAX);
                                comp_type lower = range2lcompare(e->flag), 
higher = range2rcompare(e->flag);
-                               int not_int1 = rval_min && lval_max && 
!rval_min->isnull && !lval_max->isnull && /* the middle and left intervals 
don't overlap */
+                               int not_int1 = rval_min && lval_max && /* the 
middle and left intervals don't overlap */
                                        (!e->anti && (lower == cmp_gte ? 
atom_cmp(rval_min, lval_max) > 0 : atom_cmp(rval_min, lval_max) >= 0)),
-                                       not_int2 = lval_min && fval_max && 
!lval_min->isnull && !fval_max->isnull && /* the middle and right intervals 
don't overlap */
+                                       not_int2 = lval_min && fval_max && /* 
the middle and right intervals don't overlap */
                                        (!e->anti && (higher == cmp_lte ? 
atom_cmp(lval_min, fval_max) > 0 : atom_cmp(lval_min, fval_max) >= 0)),
-                                       not_int3 = rval_min && fval_max && 
!rval_min->isnull && !fval_max->isnull && /* the left interval is after the 
right one */
+                                       not_int3 = rval_min && fval_max && /* 
the left interval is after the right one */
                                        (!e->anti && (atom_cmp(rval_min, 
fval_max) > 0));
 
                                always_false |= not_int1 || not_int2 || 
not_int3;
                                /* for anti the middle must be before the left 
or after the right or the right after the left, for the other the middle must 
be always between the left and right intervals */
                                always_true |= exp_is_not_null(le) && 
exp_is_not_null(re) && exp_is_not_null(fe) &&
-                                       lval_min && lval_max && rval_min && 
rval_max && fval_min && fval_max && !lval_min->isnull && !lval_max->isnull && 
!rval_min->isnull && !rval_max->isnull && !fval_min->isnull && 
!fval_max->isnull &&
+                                       lval_min && lval_max && rval_min && 
rval_max && fval_min && fval_max &&
                                        (e->anti ? ((lower == cmp_gte ? 
atom_cmp(rval_min, lval_max) > 0 : atom_cmp(rval_min, lval_max) >= 0) || 
(higher == cmp_lte ? atom_cmp(lval_min, fval_max) > 0 : atom_cmp(lval_min, 
fval_max) >= 0) || atom_cmp(rval_min, fval_max) > 0) :
                                        ((lower == cmp_gte ? atom_cmp(lval_min, 
rval_max) >= 0 : atom_cmp(lval_min, rval_max) > 0) && (higher == cmp_lte ? 
atom_cmp(fval_min, lval_max) >= 0 : atom_cmp(fval_min, lval_max) > 0)));
                        } 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));
+                                       if (lval_min && lval_max && rval_min && 
rval_max)
+                                               always_false |= e->anti ? 
(atom_cmp(lval_min, rval_min) == 0 && atom_cmp(lval_max, rval_max) <= 0) : 
(atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, lval_max) > 0);
+                                       if (is_semantics(e)) { /* prune *= NULL 
cases */
+                                               always_false |= e->anti ? 
(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)));
+                                               always_true |= e->anti ? 
((exp_is_not_null(le) && exp_is_null(re)) || (exp_is_null(le) && 
exp_is_not_null(re))) : (exp_is_null(le) && exp_is_null(re));
+                                       }
+                                       break;
+                               case cmp_notequal:
+                                       if (lval_min && lval_max && rval_min && 
rval_max)
+                                               always_true |= e->anti ? 
(atom_cmp(lval_min, rval_min) == 0 && atom_cmp(lval_max, rval_max) <= 0) : 
(atom_cmp(rval_max, lval_min) < 0 || atom_cmp(rval_min, lval_max) > 0);
+                                       if (is_semantics(e)) {
+                                               always_true |= e->anti ? 
(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)));
+                                               always_false |= e->anti ? 
((exp_is_not_null(le) && exp_is_null(re)) || (exp_is_null(le) && 
exp_is_not_null(re))) : (exp_is_null(le) && exp_is_null(re));
+                                       }
                                        break;
                                case cmp_gt:
-                                       if (lval_max && rval_min && 
!lval_max->isnull && !rval_min->isnull)
+                                       if (lval_max && rval_min)
                                                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)
+                                       if (lval_min && rval_max)
                                                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)
+                                       if (lval_max && rval_min)
                                                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)
+                                       if (lval_min && rval_max)
                                                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)
+                                       if (lval_min && rval_max)
                                                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)
+                                       if (lval_max && rval_min)
                                                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)
+                                       if (lval_min && rval_max)
                                                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)
+                                       if (lval_max && rval_min)
                                                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 */
@@ -486,7 +503,7 @@ rel_prune_predicates(visitor *v, sql_rel
                        }
                        assert(!always_false || !always_true);
                        if (always_false || always_true) {
-                               sql_exp *ne = exp_atom_bool(v->sql->sa, 
always_true);
+                               sql_exp *ne = exp_atom_bool(v->sql->sa, 
always_true /* if always_true set then true else false */);
                                if (exp_name(e))
                                        exp_prop_alias(v->sql->sa, ne, e);
                                n->data = ne;
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
@@ -1452,12 +1452,6 @@ atom_div(atom *a1, atom *a2)
 
        if (!EC_NUMBER(a1->tpe.type->eclass))
                return NULL;
-       if (!EC_INTERVAL(a1->tpe.type->eclass) && (a1->tpe.type->localtype < 
a2->tpe.type->localtype ||
-               (a1->tpe.type->localtype == a2->tpe.type->localtype && 
a1->tpe.digits < a2->tpe.digits))) {
-               atom *t = a1;
-               a1 = a2;
-               a2 = t;
-       }
        if (a1->isnull || a2->isnull) {
                a1->isnull = 1;
                return a1;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to