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