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
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list