Changeset: 980f527b6742 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/980f527b6742
Modified Files:
        sql/server/rel_optimizer.c
        sql/server/rel_rewriter.c
        sql/server/rel_select.c
Branch: default
Log Message:

Value based optimization fixes


diffs (106 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
@@ -3719,10 +3719,10 @@ try_rewrite_equal_or_is_null(mvc *sql, s
 
                if (is_compare(cmp->type) && !is_anti(cmp) && !cmp->f && 
cmp->flag == cmp_equal) {
                        for(node *n = l2->h ; n && valid; n = n->next) {
-                               sql_exp *e = n->data;
+                               sql_exp *e = n->data, *r = e->r;
 
                                if (is_compare(e->type) && e->flag == cmp_equal 
&& !e->f &&
-                                       !is_anti(e) && is_semantics(e) && 
exp_is_null(e->r)) {
+                                       !is_anti(e) && is_semantics(e) && 
r->type == e_atom && r->l && atom_null(r->l)) {
                                        if (exp_match_exp(first, e->l))
                                                first_is_null_found = true;
                                        else if (exp_match_exp(second, e->l))
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -178,29 +178,29 @@ rewrite_simplify(visitor *v, sql_rel *re
                return rel;
 
        if ((is_select(rel->op) || is_join(rel->op) || is_semi(rel->op)) && 
!list_empty(rel->exps)) {
+               int changes = v->changes, level = *(int*)v->data;
                rel->exps = exps_simplify_exp(v, rel->exps);
                /* At a select or inner join relation if the single expression 
is false, eliminate the inner relations with a dummy projection */
-               if (v->value_based_opt && list_length(rel->exps) == 1 && 
(exp_is_false(rel->exps->h->data) || exp_is_null(rel->exps->h->data))) {
-                       if ((is_select(rel->op) || (is_innerjoin(rel->op) && 
!rel_is_ref(rel->r))) && rel->card > CARD_ATOM && !rel_is_ref(rel->l)) {
-                               list *nexps = sa_list(v->sql->sa), *toconvert = 
rel_projections(v->sql, rel->l, NULL, 1, 1);
-                               if (is_innerjoin(rel->op))
-                                       toconvert = list_merge(toconvert, 
rel_projections(v->sql, rel->r, NULL, 1, 1), NULL);
+               if (v->value_based_opt && (v->changes > changes || level == 0) 
&& list_length(rel->exps) == 1 &&
+                       (is_select(rel->op) || is_innerjoin(rel->op)) && 
(exp_is_false(rel->exps->h->data) || exp_is_null(rel->exps->h->data))) {
+                       list *nexps = sa_list(v->sql->sa), *toconvert = 
rel_projections(v->sql, rel->l, NULL, 1, 1);
+                       if (is_innerjoin(rel->op))
+                               toconvert = list_merge(toconvert, 
rel_projections(v->sql, rel->r, NULL, 1, 1), NULL);
 
-                               for (node *n = toconvert->h ; n ; n = n->next) {
-                                       sql_exp *e = n->data, *a = 
exp_atom(v->sql->sa, atom_general(v->sql->sa, exp_subtype(e), NULL));
-                                       exp_prop_alias(v->sql->sa, a, e);
-                                       list_append(nexps, a);
-                               }
-                               rel_destroy(rel->l);
-                               if (is_innerjoin(rel->op)) {
-                                       rel_destroy(rel->r);
-                                       rel->r = NULL;
-                                       rel->op = op_select;
-                               }
-                               rel->l = rel_project(v->sql->sa, NULL, nexps);
-                               rel->card = CARD_ATOM;
-                               v->changes++;
+                       for (node *n = toconvert->h ; n ; n = n->next) {
+                               sql_exp *e = n->data, *a = exp_atom(v->sql->sa, 
atom_general(v->sql->sa, exp_subtype(e), NULL));
+                               exp_prop_alias(v->sql->sa, a, e);
+                               list_append(nexps, a);
                        }
+                       rel_destroy(rel->l);
+                       if (is_innerjoin(rel->op)) {
+                               rel_destroy(rel->r);
+                               rel->r = NULL;
+                               rel->op = op_select;
+                       }
+                       rel->l = rel_project(v->sql->sa, NULL, nexps);
+                       rel->card = CARD_ATOM;
+                       v->changes++;
                }
        }
        if (is_join(rel->op) && list_empty(rel->exps))
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -2172,6 +2172,16 @@ exp_between_check_types(sql_subtype *res
        return 0;
 }
 
+static bool
+exp_is_null_no_value_opt(sql_exp *e) 
+{
+       if (!e)
+               return false;
+       while (is_convert(e->type))
+               e = e->l;
+       return e->type == e_atom && e->l && atom_null(e->l);
+}
+
 sql_exp *
 rel_logical_value_exp(sql_query *query, sql_rel **rel, symbol *sc, int f, 
exp_kind ek)
 {
@@ -2294,7 +2304,7 @@ rel_logical_value_exp(sql_query *query, 
 
                if (rel_convert_types(sql, rel ? *rel : NULL, rel ? *rel : 
NULL, &ls, &rs, 1, type_equal_no_any) < 0)
                        return NULL;
-               if (exp_is_null(ls) && exp_is_null(rs))
+               if (exp_is_null_no_value_opt(ls) && 
exp_is_null_no_value_opt(rs))
                        return exp_atom(sql->sa, atom_general(sql->sa, 
sql_bind_localtype("bit"), NULL));
 
                return exp_compare_func(sql, ls, rs, compare_func(cmp_type, 
need_not), quantifier);
@@ -4608,7 +4618,7 @@ calculate_window_bound(sql_query *query,
                                return NULL;
                        bt = exp_subtype(res);
                }
-               if (exp_is_null(res))
+               if (exp_is_null_no_value_opt(res))
                        return sql_error(sql, 02, SQLSTATE(42000) "%s offset 
must not be NULL", bound_desc);
                if ((frame_type == FRAME_ROWS || frame_type == FRAME_GROUPS) && 
bt->type->eclass != EC_NUM && !(res = exp_check_type(sql, bound_tp, p, res, 
type_equal)))
                        return NULL;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to