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