Changeset: 923aadde0a46 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/923aadde0a46
Modified Files:
sql/server/rel_optimizer.c
Branch: default
Log Message:
Packing and cleaning some SQL optimizers (It will help on the upcoming projects)
diffs (206 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
@@ -3059,7 +3059,7 @@ exp_simplify_math( mvc *sql, sql_exp *e,
static inline sql_rel *
rel_simplify_math(visitor *v, sql_rel *rel)
{
- if ((is_simple_project(rel->op) || is_groupby(rel->op) || (rel->op ==
op_ddl && rel->flag == ddl_psm)) && rel->exps) {
+ if ((is_simple_project(rel->op) || (rel->op == op_ddl && rel->flag ==
ddl_psm)) && rel->exps) {
int needed = 0, ochanges = 0;
for (node *n = rel->exps->h; n && !needed; n = n->next) {
@@ -7477,75 +7477,6 @@ rel_select_order(visitor *v, sql_rel *re
return rel;
}
-static inline sql_rel *
-rel_simplify_like_select(visitor *v, sql_rel *rel)
-{
- if (is_select(rel->op) && !list_empty(rel->exps)) {
- 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) == 3) {
- list *r = e->r;
- sql_exp *fmt = r->h->data;
- sql_exp *esc = r->h->next->data;
- sql_exp *isen = r->h->next->next->data;
- int rewrite = 0, isnull = 0;
-
- if (fmt->type == e_convert)
- fmt = fmt->l;
- /* check for simple like expression */
- if (exp_is_null(fmt)) {
- isnull = 1;
- } else if (is_atom(fmt->type)) {
- atom *fa = NULL;
-
- if (fmt->l)
- fa = fmt->l;
- if (fa && fa->data.vtype == TYPE_str &&
!strchr(fa->data.val.sval, '%') && !strchr(fa->data.val.sval, '_'))
- rewrite = 1;
- }
- if (rewrite && !isnull) { /* check escape flag
*/
- if (exp_is_null(esc)) {
- isnull = 1;
- } else {
- atom *ea = esc->l;
-
- if (!is_atom(esc->type) || !ea)
- rewrite = 0;
- else if (ea->data.vtype !=
TYPE_str || strlen(ea->data.val.sval) != 0)
- rewrite = 0;
- }
- }
- if (rewrite && !isnull) { /* check insensitive
flag */
- if (exp_is_null(isen)) {
- isnull = 1;
- } else {
- atom *ia = isen->l;
-
- if (!is_atom(isen->type) || !ia)
- rewrite = 0;
- else if (ia->data.vtype !=
TYPE_bit || ia->data.val.btval == 1)
- rewrite = 0;
- }
- }
- if (isnull) {
- rel->exps =
list_append(sa_list(v->sql->sa), exp_null(v->sql->sa,
sql_bind_localtype("bit")));
- v->changes++;
- return rel;
- } else if (rewrite) { /* rewrite to cmp_equal
! */
- list *l = e->l;
- list *r = e->r;
- n->data = exp_compare(v->sql->sa,
l->h->data, r->h->data, is_anti(e) ? cmp_notequal : cmp_equal);
- v->changes++;
- }
- }
- }
- }
- return rel;
-}
-
static sql_exp *
rel_simplify_predicates(visitor *v, sql_rel *rel, sql_exp *e, int depth)
{
@@ -7569,6 +7500,65 @@ rel_simplify_predicates(visitor *v, sql_
}
}
if (is_select(rel->op) || is_join(rel->op) || is_semi(rel->op)) {
+ /* simplify like expressions */
+ if (is_compare(e->type) && e->flag == cmp_filter &&
!((sql_subfunc*)e->f)->func->s && strcmp(((sql_subfunc*)e->f)->func->base.name,
"like") == 0 &&
+ list_length((list *)e->l) == 1 && list_length((list
*)e->r) == 3) {
+ list *r = e->r;
+ sql_exp *fmt = r->h->data;
+ sql_exp *esc = r->h->next->data;
+ sql_exp *isen = r->h->next->next->data;
+ int rewrite = 0, isnull = 0;
+
+ if (fmt->type == e_convert)
+ fmt = fmt->l;
+ /* check for simple like expression */
+ if (exp_is_null(fmt)) {
+ isnull = 1;
+ } else if (is_atom(fmt->type)) {
+ atom *fa = NULL;
+
+ if (fmt->l)
+ fa = fmt->l;
+ if (fa && fa->data.vtype == TYPE_str &&
!strchr(fa->data.val.sval, '%') && !strchr(fa->data.val.sval, '_'))
+ rewrite = 1;
+ }
+ if (rewrite && !isnull) { /* check escape flag */
+ if (exp_is_null(esc)) {
+ isnull = 1;
+ } else {
+ atom *ea = esc->l;
+
+ if (!is_atom(esc->type) || !ea)
+ rewrite = 0;
+ else if (ea->data.vtype != TYPE_str ||
strlen(ea->data.val.sval) != 0)
+ rewrite = 0;
+ }
+ }
+ if (rewrite && !isnull) { /* check insensitive flag */
+ if (exp_is_null(isen)) {
+ isnull = 1;
+ } else {
+ atom *ia = isen->l;
+
+ if (!is_atom(isen->type) || !ia)
+ rewrite = 0;
+ else if (ia->data.vtype != TYPE_bit ||
ia->data.val.btval == 1)
+ rewrite = 0;
+ }
+ }
+ if (isnull) {
+ e = exp_null(v->sql->sa,
sql_bind_localtype("bit"));
+ v->changes++;
+ return e;
+ } else if (rewrite) { /* rewrite to cmp_equal ! */
+ list *l = e->l;
+ 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;
+ }
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 */
if (exp_is_null(e->l)) {
@@ -8230,7 +8220,7 @@ rel_project_reduce_casts(visitor *v, sql
{
if (!rel)
return NULL;
- if (is_project(rel->op) && list_length(rel->exps)) {
+ if (is_simple_project(rel->op) && list_length(rel->exps)) {
list *exps = rel->exps;
node *n;
@@ -9385,15 +9375,6 @@ rel_remove_union_partitions(visitor *v,
return rel;
}
-static sql_rel *
-rel_first_level_optimizations(visitor *v, sql_rel *rel)
-{
- /* rel_simplify_math optimizer requires to clear the hash, so make sure
it runs last in this batch */
- if (v->value_based_opt)
- rel = rel_simplify_math(v, rel);
- return rel;
-}
-
/* pack optimizers into a single function call to avoid iterations in the AST
*/
static sql_rel *
rel_optimize_select_and_joins_bottomup(visitor *v, sql_rel *rel)
@@ -9402,15 +9383,12 @@ rel_optimize_select_and_joins_bottomup(v
return rel;
int level = *(int*) v->data;
- if (rel)
- rel->exps = exp_merge_range(v, rel, rel->exps);
+ 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);
- if (v->value_based_opt && level <= 1)
- rel = rel_simplify_like_select(v, rel);
rel = rewrite_simplify(v, rel);
return rel;
}
@@ -9614,7 +9592,8 @@ optimize_rel(visitor *v, sql_rel *rel, g
if (level <= 0) {
if (gp->cnt[op_left] || gp->cnt[op_right] ||
gp->cnt[op_full] || gp->cnt[op_join] || gp->cnt[op_semi] || gp->cnt[op_anti])
rel = rel_visitor_bottomup(v, rel,
&rel_remove_redundant_join); /* this optimizer has to run before
rel_first_level_optimizations */
- rel = rel_visitor_bottomup(v, rel,
&rel_first_level_optimizations);
+ if (v->value_based_opt)
+ rel = rel_visitor_bottomup(v, rel,
&rel_simplify_math);
}
}
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list