Changeset: 998f526f60c1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/998f526f60c1
Modified Files:
        sql/include/sql_relation.h
        sql/server/rel_optimize_sel.c
Branch: groupjoin
Log Message:

rewrite left outer group joins into semi/anti joins when possible, ie when the 
result of an exists/in/not in/any/all is used in the projection on which later 
a where/having expression is done.


diffs (67 lines):

diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -242,6 +242,7 @@ typedef enum operator_type {
 #define set_semantics(e)       (e)->semantics = 1
 #define is_any(e)                      ((e)->any)
 #define set_any(e)                     (e)->any = 1
+#define reset_any(e)           (e)->any = 0
 #define is_symmetric(e)        ((e)->symmetric)
 #define set_symmetric(e)       (e)->symmetric = 1
 #define is_intern(e)           ((e)->intern)
diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -3592,6 +3592,44 @@ rel_use_index(visitor *v, sql_rel *rel)
        return rel;
 }
 
+static sql_rel *
+rel_select_leftgroup_2_semi(visitor *v, sql_rel *rel)
+{
+       (void)v;
+       if (rel_is_ref(rel) || !is_select(rel->op) || list_empty(rel->exps))
+               return rel;
+       sql_rel *l = rel->l;
+
+       if (!l || rel_is_ref(l) || !is_left(l->op) || list_empty(l->attr))
+               return rel;
+
+       for(node *n = rel->exps->h; n; n = n->next) {
+               sql_exp *e = n->data;
+
+               if (e->type == e_cmp && !is_semantics(e) && !e->f) {
+                       list *attrs = l->attr;
+                       sql_exp *a = attrs->h->data;
+
+                       if (exps_find_exp(l->attr, e->l) && exp_is_true(e->r) 
&& e->flag == cmp_equal /*&& exp_is_true(a)*/) {
+                               printf("# optimize select leftgroup -> semi\n");
+                               if (!list_empty(l->exps)) {
+                                       for(node *m = l->exps->h; m; m = 
m->next) {
+                                               sql_exp *j = m->data;
+                                               reset_any(j);
+                                       }
+                               }
+                               l->attr = NULL;
+                               l->op = exp_is_true(a)?op_semi:op_anti;
+                               list_remove_node(rel->exps, NULL, n);
+                               rel = rel_project(v->sql->sa, rel, 
rel_projections(v->sql, rel, NULL, 1, 1));
+                               list_append(rel->exps, attrs->h->data);
+                               v->changes++;
+                               return rel;
+                       }
+               }
+       }
+       return rel;
+}
 
 static sql_rel *
 rel_optimize_select_and_joins_topdown_(visitor *v, sql_rel *rel)
@@ -3605,6 +3643,7 @@ rel_optimize_select_and_joins_topdown_(v
 
        rel = rel_simplify_fk_joins(v, rel);
        rel = rel_push_select_down(v, rel);
+       rel = rel_select_leftgroup_2_semi(v, rel);
        if (rel && rel->l && (is_select(rel->op) || is_join(rel->op)))
                rel = rel_use_index(v, rel);
        return rel;
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to