Changeset: b81b4e05197e for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/b81b4e05197e
Modified Files:
        sql/server/rel_optimizer.c
Branch: default
Log Message:

Packing value based optimizers (needed for the upcoming changes on properties 
branch)


diffs (288 lines):

diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -7472,6 +7472,57 @@ rel_select_order(visitor *v, sql_rel *re
        return rel;
 }
 
+/*
+ * Casting decimal values on both sides of a compare expression is expensive,
+ * both in preformance (cpu cost) and memory requirements (need for large
+ * types).
+ */
+
+#define reduce_scale_tpe(tpe, uval) \
+       do { \
+               tpe v = uval; \
+               if (v != 0) { \
+                       while( (v/10)*10 == v ) { \
+                               i++; \
+                               v /= 10; \
+                       } \
+                       nval = v; \
+               } \
+       } while (0)
+
+static atom *
+reduce_scale(mvc *sql, atom *a)
+{
+       int i = 0;
+       atom *na = a;
+#ifdef HAVE_HGE
+       hge nval = 0;
+#else
+       lng nval = 0;
+#endif
+
+#ifdef HAVE_HGE
+       if (a->data.vtype == TYPE_hge) {
+               reduce_scale_tpe(hge, a->data.val.hval);
+       } else
+#endif
+       if (a->data.vtype == TYPE_lng) {
+               reduce_scale_tpe(lng, a->data.val.lval);
+       } else if (a->data.vtype == TYPE_int) {
+               reduce_scale_tpe(int, a->data.val.ival);
+       } else if (a->data.vtype == TYPE_sht) {
+               reduce_scale_tpe(sht, a->data.val.shval);
+       } else if (a->data.vtype == TYPE_bte) {
+               reduce_scale_tpe(bte, a->data.val.btval);
+       }
+       if (i) {
+               na = atom_int(sql->sa, &a->tpe, nval);
+               if (na->tpe.scale)
+                       na->tpe.scale -= i;
+       }
+       return na;
+}
+
 static inline sql_exp *
 rel_simplify_predicates(visitor *v, sql_rel *rel, sql_exp *e)
 {
@@ -7549,9 +7600,67 @@ rel_simplify_predicates(visitor *v, sql_
                                list *r = e->r;
                                e = exp_compare(v->sql->sa, l->h->data, 
r->h->data, is_anti(e) ? cmp_notequal : cmp_equal);
                                v->changes++;
-                               return e;
-                       }
-                       return e;
+                       }
+               }
+               /* rewrite e if left or right is a cast */
+               if (is_compare(e->type) && !e->f && is_theta_exp(e->flag) && 
(((sql_exp*)e->l)->type == e_convert || ((sql_exp*)e->r)->type == e_convert)) {
+                       sql_rel *r = rel->r;
+                       sql_exp *le = e->l, *re = e->r;
+
+                       /* if convert on left then find mul or div on right 
which increased scale! */
+                       if (le->type == e_convert && re->type == e_column && 
(e->flag == cmp_lt || e->flag == cmp_gt) && r && is_project(r->op)) {
+                               sql_exp *nre = rel_find_exp(r, re);
+                               sql_subtype *tt = exp_totype(le), *ft = 
exp_fromtype(le);
+
+                               if (nre && nre->type == e_func) {
+                                       sql_subfunc *f = nre->f;
+
+                                       if (!f->func->s && 
!strcmp(f->func->base.name, "sql_mul")) {
+                                               list *args = nre->l;
+                                               sql_exp *ce = args->t->data;
+                                               sql_subtype *fst = 
exp_subtype(args->h->data);
+
+                                               if (fst->scale && fst->scale == 
ft->scale && is_atom(ce->type) && ce->l) {
+                                                       atom *a = ce->l;
+                                                       int anti = is_anti(e);
+                                                       sql_exp *arg1, *arg2;
+#ifdef HAVE_HGE
+                                                       hge val = 1;
+#else
+                                                       lng val = 1;
+#endif
+                                                       /* multiply with 
smallest value, then scale and (round) */
+                                                       int scale = (int) 
tt->scale - (int) ft->scale, rs = 0;
+                                                       atom *na = 
reduce_scale(v->sql, a);
+
+                                                       if (na != a) {
+                                                               rs = 
a->tpe.scale - na->tpe.scale;
+                                                               ce->l = na;
+                                                       }
+                                                       scale -= rs;
+
+                                                       while (scale > 0) {
+                                                               scale--;
+                                                               val *= 10;
+                                                       }
+                                                       arg1 = re;
+#ifdef HAVE_HGE
+                                                       arg2 = 
exp_atom_hge(v->sql->sa, val);
+#else
+                                                       arg2 = 
exp_atom_lng(v->sql->sa, val);
+#endif
+                                                       if ((nre = 
rel_binop_(v->sql, NULL, arg1, arg2, "sys", "scale_down", card_value))) {
+                                                               e = 
exp_compare(v->sql->sa, le->l, nre, e->flag);
+                                                               if (anti) 
set_anti(e);
+                                                               v->changes++;
+                                                       } else {
+                                                               
v->sql->session->status = 0;
+                                                               
v->sql->errstr[0] = '\0';
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
                }
                if (is_compare(e->type) && is_semantics(e) && (e->flag == 
cmp_equal || e->flag == cmp_notequal) && exp_is_null(e->r)) {
                        /* simplify 'is null' predicates on constants */
@@ -8168,57 +8277,6 @@ exp_merge_range(visitor *v, sql_rel *rel
        return exps;
 }
 
-/*
- * Casting decimal values on both sides of a compare expression is expensive,
- * both in preformance (cpu cost) and memory requirements (need for large
- * types).
- */
-
-#define reduce_scale_tpe(tpe, uval) \
-       do { \
-               tpe v = uval; \
-               if (v != 0) { \
-                       while( (v/10)*10 == v ) { \
-                               i++; \
-                               v /= 10; \
-                       } \
-                       nval = v; \
-               } \
-       } while (0)
-
-static atom *
-reduce_scale(mvc *sql, atom *a)
-{
-       int i = 0;
-       atom *na = a;
-#ifdef HAVE_HGE
-       hge nval = 0;
-#else
-       lng nval = 0;
-#endif
-
-#ifdef HAVE_HGE
-       if (a->data.vtype == TYPE_hge) {
-               reduce_scale_tpe(hge, a->data.val.hval);
-       } else
-#endif
-       if (a->data.vtype == TYPE_lng) {
-               reduce_scale_tpe(lng, a->data.val.lval);
-       } else if (a->data.vtype == TYPE_int) {
-               reduce_scale_tpe(int, a->data.val.ival);
-       } else if (a->data.vtype == TYPE_sht) {
-               reduce_scale_tpe(sht, a->data.val.shval);
-       } else if (a->data.vtype == TYPE_bte) {
-               reduce_scale_tpe(bte, a->data.val.btval);
-       }
-       if (i) {
-               na = atom_int(sql->sa, &a->tpe, nval);
-               if (na->tpe.scale)
-                       na->tpe.scale -= i;
-       }
-       return na;
-}
-
 static sql_rel *
 rel_project_reduce_casts(visitor *v, sql_rel *rel)
 {
@@ -8265,88 +8323,6 @@ rel_project_reduce_casts(visitor *v, sql
        return rel;
 }
 
-static inline sql_rel *
-rel_reduce_casts(visitor *v, sql_rel *rel)
-{
-       list *exps = rel->exps;
-       assert(!list_empty(rel->exps));
-
-       for (node *n=exps->h; n; n = n->next) {
-               sql_exp *e = n->data;
-               sql_exp *le = e->l;
-               sql_exp *re = e->r;
-
-               /* handle the and's in the or lists */
-               if (e->type != e_cmp || !is_theta_exp(e->flag) || e->f)
-                       continue;
-               /* rewrite e if left or right is a cast */
-               if (le->type == e_convert || re->type == e_convert) {
-                       sql_rel *r = rel->r;
-
-                       /* if convert on left then find
-                        * mul or div on right which increased
-                        * scale!
-                        */
-                       if (le->type == e_convert && re->type == e_column && 
(e->flag == cmp_lt || e->flag == cmp_gt) && r && is_project(r->op)) {
-                               sql_exp *nre = rel_find_exp(r, re);
-                               sql_subtype *tt = exp_totype(le);
-                               sql_subtype *ft = exp_fromtype(le);
-
-                               if (nre && nre->type == e_func) {
-                                       sql_subfunc *f = nre->f;
-
-                                       if (!f->func->s && 
!strcmp(f->func->base.name, "sql_mul")) {
-                                               list *args = nre->l;
-                                               sql_exp *ce = args->t->data;
-                                               sql_subtype *fst = 
exp_subtype(args->h->data);
-
-                                               if (fst->scale && fst->scale == 
ft->scale && is_atom(ce->type) && ce->l) {
-                                                       atom *a = ce->l;
-                                                       int anti = is_anti(e);
-                                                       sql_exp *arg1, *arg2;
-#ifdef HAVE_HGE
-                                                       hge val = 1;
-#else
-                                                       lng val = 1;
-#endif
-                                                       /* multiply with 
smallest value, then scale and (round) */
-                                                       int scale = (int) 
tt->scale - (int) ft->scale, rs = 0;
-                                                       atom *na = 
reduce_scale(v->sql, a);
-
-                                                       if (na != a) {
-                                                               rs = 
a->tpe.scale - na->tpe.scale;
-                                                               ce->l = na;
-                                                       }
-                                                       scale -= rs;
-
-                                                       while(scale > 0) {
-                                                               scale--;
-                                                               val *= 10;
-                                                       }
-                                                       arg1 = re;
-#ifdef HAVE_HGE
-                                                       arg2 = 
exp_atom_hge(v->sql->sa, val);
-#else
-                                                       arg2 = 
exp_atom_lng(v->sql->sa, val);
-#endif
-                                                       if (!(nre = 
rel_binop_(v->sql, NULL, arg1, arg2, "sys", "scale_down", card_value))) {
-                                                               
v->sql->session->status = 0;
-                                                               
v->sql->errstr[0] = '\0';
-                                                               continue;
-                                                       }
-                                                       e = 
exp_compare(v->sql->sa, le->l, nre, e->flag);
-                                                       if (anti) set_anti(e);
-                                                       v->changes++;
-                                               }
-                                       }
-                               }
-                       }
-               }
-               n->data = e;
-       }
-       return rel;
-}
-
 static int
 is_identity_of(sql_exp *e, sql_rel *l)
 {
@@ -9388,8 +9364,6 @@ rel_optimize_select_and_joins_bottomup(v
        int level = *(int*) v->data;
 
        rel->exps = exp_merge_range(v, rel, rel->exps);
-       if (v->value_based_opt)
-               rel = rel_reduce_casts(v, rel);
        rel = rel_select_cse(v, rel);
        if (level == 1)
                rel = rel_merge_select_rse(v, rel);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to