Changeset: 9518f0f0b844 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=9518f0f0b844
Modified Files:
        sql/server/rel_optimizer.c
Branch: default
Log Message:

Packing SQL optimizers into a single AST iteration


diffs (truncated from 494 to 300 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
@@ -4079,7 +4079,7 @@ exps_uses_any(list *exps, list *l)
  * into
  *     groupby ( [ union all( groupby( a, [gbe], [ count, sum] ), [ groupby( 
b, [gbe], [ count, sum] )) , [gbe], [sum, sum] )
  */
-static sql_rel *
+static inline sql_rel *
 rel_push_aggr_down(visitor *v, sql_rel *rel)
 {
        if (rel->op == op_groupby && rel->l) {
@@ -4373,7 +4373,7 @@ gen_push_groupby_down(mvc *sql, sql_rel 
  *     project(join(groupby (A)[a.i],[a.i]), Dict)[a.i==dict.i])[dict.n]
  *
  */
-static sql_rel *
+static inline sql_rel *
 rel_push_groupby_down(visitor *v, sql_rel *rel)
 {
        sql_rel *p = rel->l;
@@ -5737,7 +5737,7 @@ score_gbe(visitor *v, sql_rel *rel, sql_
 }
 
 /* reorder group by expressions */
-static sql_rel *
+static inline sql_rel *
 rel_groupby_order(visitor *v, sql_rel *rel)
 {
        int *scores = NULL;
@@ -5782,7 +5782,7 @@ rel_groupby_order(visitor *v, sql_rel *r
  * The reduced group by and (derived) aggr expressions are restored via
  * extra (new) aggregate columns.
  */
-static sql_rel *
+static inline sql_rel *
 rel_reduce_groupby_exps(visitor *v, sql_rel *rel)
 {
        list *gbe = rel->r;
@@ -6060,7 +6060,7 @@ rel_groupby_distinct2(visitor *v, sql_re
  *     groupby(R) [e,f,a,b] [ a, b, aggr3 c, aggr4 d]
  * ) [e,f]( aggr1 a distinct, aggr2 b distinct, aggr3_phase2 c, aggr4_phase2 d)
  */
-static sql_rel *
+static inline sql_rel *
 rel_groupby_distinct(visitor *v, sql_rel *rel)
 {
        node *n;
@@ -6158,16 +6158,29 @@ rel_groupby_distinct(visitor *v, sql_rel
        return rel;
 }
 
+/* pack grouby optimizers into a single function to void iterations in the AST 
*/
+static sql_rel *
+rel_optimize_group_by(visitor *v, sql_rel *rel)
+{
+       if (!is_groupby(rel->op))
+               return rel;
+
+       rel = rel_push_aggr_down(v, rel);
+       rel = rel_push_groupby_down(v, rel);
+       rel = rel_groupby_order(v, rel);
+       rel = rel_reduce_groupby_exps(v, rel);
+       rel = rel_groupby_distinct(v, rel);
+       return rel;
+}
+
 static sql_exp *split_aggr_and_project(mvc *sql, list *aexps, sql_exp *e);
 
 static void
 list_split_aggr_and_project(mvc *sql, list *aexps, list *exps)
 {
-       node *n;
-
-       if (!exps)
+       if (list_empty(exps))
                return ;
-       for(n = exps->h; n; n = n->next)
+       for(node *n = exps->h; n; n = n->next)
                n->data = split_aggr_and_project(sql, aexps, n->data);
 }
 
@@ -7533,13 +7546,14 @@ score_se(visitor *v, sql_rel *rel, sql_e
        return score;
 }
 
-static sql_rel *
+static inline sql_rel *
 rel_select_order(visitor *v, sql_rel *rel)
 {
        int *scores = NULL;
        sql_exp **exps = NULL;
 
-       if (is_select(rel->op) && list_length(rel->exps) > 1) {
+       assert(is_select(rel->op));
+       if (list_length(rel->exps) > 1) {
                node *n;
                int i, nexps = list_length(rel->exps);
                scores = SA_NEW_ARRAY(v->sql->ta, int, nexps);
@@ -7558,87 +7572,95 @@ rel_select_order(visitor *v, sql_rel *re
        return rel;
 }
 
-static sql_rel *
+static inline sql_rel *
 rel_simplify_like_select(visitor *v, sql_rel *rel)
 {
-       if (is_select(rel->op) && rel->exps) {
-               node *n;
-               list *exps;
-               int needed = 0;
-
-               for (n = rel->exps->h; n && !needed; n = n->next) {
-                       sql_exp *e = n->data;
-                       list *l = e->l;
+       list *exps;
+       int needed = 0;
+
+       assert(is_select(rel->op) && !list_empty(rel->exps));
+       for (node *n = rel->exps->h; n && !needed; n = n->next) {
+               sql_exp *e = n->data;
+               list *l = e->l;
+               list *r = e->r;
+
+               if (e->type == e_cmp && e->flag == cmp_filter && 
strcmp(((sql_subfunc*)e->f)->func->base.name, "like") == 0 && list_length(l) == 
1 && list_length(r) <= 2 && !is_anti(e))
+                       needed = 1;
+       }
+
+       if (!needed)
+               return rel;
+
+       exps = sa_list(v->sql->sa);
+       if (exps == NULL)
+               return NULL;
+       for (node *n = rel->exps->h; n; n = n->next) {
+               sql_exp *e = n->data;
+               list *l = e->l;
+               list *r = e->r;
+
+               if (e->type == e_cmp && e->flag == cmp_filter && 
strcmp(((sql_subfunc*)e->f)->func->base.name, "like") == 0 && list_length(l) == 
1 && list_length(r) <= 2 && !is_anti(e)) {
                        list *r = e->r;
-
-                       if (e->type == e_cmp && e->flag == cmp_filter && 
strcmp(((sql_subfunc*)e->f)->func->base.name, "like") == 0 && list_length(l) == 
1 && list_length(r) <= 2 && !is_anti(e))
-                               needed = 1;
-               }
-
-               if (!needed)
-                       return rel;
-
-               exps = sa_list(v->sql->sa);
-               if (exps == NULL)
-                       return NULL;
-               for (n = rel->exps->h; n; n = n->next) {
-                       sql_exp *e = n->data;
-                       list *l = e->l;
-                       list *r = e->r;
-
-                       if (e->type == e_cmp && e->flag == cmp_filter && 
strcmp(((sql_subfunc*)e->f)->func->base.name, "like") == 0 && list_length(l) == 
1 && list_length(r) <= 2 && !is_anti(e)) {
+                       sql_exp *fmt = r->h->data;
+                       sql_exp *esc = (r->h->next)?r->h->next->data:NULL;
+                       int rewrite = 0, isnull = 0;
+
+                       if (fmt->type == e_convert)
+                               fmt = fmt->l;
+                       /* check for simple like expression */
+                       if (is_atom(fmt->type)) {
+                               atom *fa = NULL;
+
+                               if (fmt->l)
+                                       fa = fmt->l;
+                               if (fa && fa->isnull)
+                                       isnull = 1;
+                               else if (fa && fa->data.vtype == TYPE_str && 
!strchr(fa->data.val.sval, '%') && !strchr(fa->data.val.sval, '_'))
+                                       rewrite = 1;
+                       }
+                       if (rewrite && !isnull && esc && is_atom(esc->type)) {
+                               atom *ea = NULL;
+
+                               if (esc->l)
+                                       ea = esc->l;
+                               if (ea && ea->isnull)
+                                       isnull = 1;
+                               else if (ea && (ea->data.vtype != TYPE_str || 
strlen(ea->data.val.sval) != 0))
+                                       rewrite = 0;
+                       }
+                       if (isnull) {
+                               list_append(exps, exp_null(v->sql->sa, 
sql_bind_localtype("bit")));
+                               v->changes++;
+                       } else if (rewrite) {   /* rewrite to cmp_equal ! */
+                               list *l = e->l;
                                list *r = e->r;
-                               sql_exp *fmt = r->h->data;
-                               sql_exp *esc = 
(r->h->next)?r->h->next->data:NULL;
-                               int rewrite = 0, isnull = 0;
-
-                               if (fmt->type == e_convert)
-                                       fmt = fmt->l;
-                               /* check for simple like expression */
-                               if (is_atom(fmt->type)) {
-                                       atom *fa = NULL;
-
-                                       if (fmt->l)
-                                               fa = fmt->l;
-                                       if (fa && fa->isnull)
-                                               isnull = 1;
-                                       else if (fa && fa->data.vtype == 
TYPE_str &&
-                                           !strchr(fa->data.val.sval, '%') &&
-                                           !strchr(fa->data.val.sval, '_'))
-                                               rewrite = 1;
-                               }
-                               if (rewrite && !isnull && esc && 
is_atom(esc->type)) {
-                                       atom *ea = NULL;
-
-                                       if (esc->l)
-                                               ea = esc->l;
-                                       if (ea && ea->isnull)
-                                               isnull = 1;
-                                       else if (ea && (ea->data.vtype != 
TYPE_str ||
-                                           strlen(ea->data.val.sval) != 0))
-                                               rewrite = 0;
-                               }
-                               if (isnull) {
-                                       list_append(exps, exp_null(v->sql->sa, 
sql_bind_localtype("bit")));
-                                       v->changes++;
-                               } else if (rewrite) {   /* rewrite to cmp_equal 
! */
-                                       list *l = e->l;
-                                       list *r = e->r;
-                                       sql_exp *ne = exp_compare(v->sql->sa, 
l->h->data, r->h->data, cmp_equal);
-
-                                       if (is_anti(e)) set_anti(ne);
-                                       if (is_semantics(e)) set_semantics(ne);
-                                       list_append(exps, ne);
-                                       v->changes++;
-                               } else {
-                                       list_append(exps, e);
-                               }
+                               sql_exp *ne = exp_compare(v->sql->sa, 
l->h->data, r->h->data, cmp_equal);
+
+                               if (is_anti(e)) set_anti(ne);
+                               if (is_semantics(e)) set_semantics(ne);
+                               list_append(exps, ne);
+                               v->changes++;
                        } else {
                                list_append(exps, e);
                        }
-               }
-               rel->exps = exps;
-       }
+               } else {
+                       list_append(exps, e);
+               }
+       }
+       rel->exps = exps;
+       return rel;
+}
+
+/* pack select optimizers into a single function to void iterations in the AST 
*/
+static sql_rel *
+rel_optimize_select(visitor *v, sql_rel *rel)
+{
+       if (!is_select(rel->op) || list_empty(rel->exps))
+               return rel;
+
+       if (v->value_based_opt)
+               rel = rel_simplify_like_select(v, rel);
+       rel = rel_select_order(v, rel);
        return rel;
 }
 
@@ -8243,14 +8265,6 @@ exp_merge_range(visitor *v, list *exps)
        return exps;
 }
 
-static sql_rel *
-rel_find_range(visitor *v, sql_rel *rel)
-{
-       if ((is_join(rel->op) || is_semi(rel->op) || is_select(rel->op)) && 
rel->exps && !list_empty(rel->exps))
-               rel->exps = exp_merge_range(v, rel->exps);
-       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
@@ -8350,83 +8364,94 @@ rel_project_reduce_casts(visitor *v, sql
        return rel;
 }
 
-static sql_rel *
+static inline sql_rel *
 rel_reduce_casts(visitor *v, sql_rel *rel)
 {
-       if ((is_join(rel->op) || is_semi(rel->op) || is_select(rel->op)) &&
-                       rel->exps && list_length(rel->exps)) {
-               list *exps = rel->exps;
-               node *n;
-
-               for (n=exps->h; n; n = n->next) {
-                       sql_exp *e = n->data;
-                       sql_exp *le = e->l;
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to