Changeset: 702bf745b929 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=702bf745b929
Modified Files:
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
Branch: Jan2014
Log Message:

Merge with Feb2013 branch.


diffs (196 lines):

diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1073,6 +1073,8 @@ exp_is_atom( sql_exp *e )
 {
        switch (e->type) {
        case e_atom:
+               if (e->f) /* values list */
+                       return 0;
                return 1;
        case e_convert:
                return exp_is_atom(e->l);
@@ -1096,6 +1098,17 @@ exp_is_atom( sql_exp *e )
        return 0;
 }
 
+int
+exps_are_atoms( list *exps)
+{
+       node *n;
+       int atoms = 1;
+
+       for(n=exps->h; n && atoms; n=n->next) 
+               atoms &= exp_is_atom(n->data);
+       return atoms;
+}
+
 static int
 exps_has_func( list *exps)
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -110,6 +110,7 @@ extern int exp_is_eqjoin(sql_exp *e);
 extern int exp_is_correlation(sql_exp *e, sql_rel *r );
 extern int exp_is_join_exp(sql_exp *e);
 extern int exp_is_atom(sql_exp *e);
+extern int exps_are_atoms(list *exps);
 extern int exp_has_func(sql_exp *e);
 
 extern int rel_has_exp(sql_rel *rel, sql_exp *e);
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
@@ -3984,6 +3984,139 @@ split_aggr_and_project(mvc *sql, list *a
        return NULL;
 }
 
+static sql_exp *
+exp_use_consts(mvc *sql, sql_exp *e, list *consts);
+
+static list *
+exps_use_consts(mvc *sql, list *exps, list *consts)
+{
+       node *n;
+       list *nl = new_exp_list(sql->sa);
+
+       if (!exps)
+               return sa_list(sql->sa);
+       for(n = exps->h; n; n = n->next) {
+               sql_exp *arg = n->data, *narg = NULL;
+
+               narg = exp_use_consts(sql, arg, consts);
+               if (!narg) 
+                       return NULL;
+               if (arg->p)
+                       narg->p = prop_copy(sql->sa, arg->p);
+               append(nl, narg);
+       }
+       return nl;
+}
+
+static sql_exp *
+exp_use_consts(mvc *sql, sql_exp *e, list *consts) 
+{
+       sql_exp *ne = NULL, *l, *r, *r2;
+
+       switch(e->type) {
+       case e_column:
+               if (e->l) 
+                       ne = exps_bind_column2(consts, e->l, e->r);
+               if (!ne && !e->l)
+                       ne = exps_bind_column(consts, e->r, NULL);
+               if (!ne)
+                       return e;
+               return ne;
+       case e_cmp: 
+               if (e->flag == cmp_or) {
+                       list *l = exps_use_consts(sql, e->l, consts);
+                       list *r = exps_use_consts(sql, e->r, consts);
+
+                       if (!l || !r) 
+                               return NULL;
+                       return exp_or(sql->sa, l, r);
+               } else if (e->flag == cmp_in || e->flag == cmp_notin || 
get_cmp(e) == cmp_filter) {
+                       sql_exp *l = exp_use_consts(sql, e->l, consts);
+                       list *r = exps_use_consts(sql, e->r, consts);
+
+                       if (!l || !r) 
+                               return NULL;
+                       if (get_cmp(e) == cmp_filter) 
+                               return exp_filter(sql->sa, l, r, e->f, 
is_anti(e));
+                       return exp_in(sql->sa, l, r, e->flag);
+               } else {
+                       l = exp_use_consts(sql, e->l, consts);
+                       r = exp_use_consts(sql, e->r, consts);
+                       if (e->f) {
+                               r2 = exp_use_consts(sql, e->f, consts);
+                               if (l && r && r2)
+                                       return exp_compare2(sql->sa, l, r, r2, 
e->flag);
+                       } else if (l && r) {
+                               return exp_compare(sql->sa, l, r, e->flag);
+                       }
+               }
+               return NULL;
+       case e_convert:
+               l = exp_use_consts(sql, e->l, consts);
+               if (l)
+                       return exp_convert(sql->sa, l, exp_fromtype(e), 
exp_totype(e));
+               return NULL;
+       case e_aggr:
+       case e_func: {
+               list *l = e->l, *nl = NULL;
+
+               if (!l) {
+                       return e;
+               } else {
+                       nl = exps_use_consts(sql, l, consts);
+                       if (!nl)
+                               return NULL;
+               }
+               if (e->type == e_func)
+                       return exp_op(sql->sa, nl, e->f);
+               else 
+                       return exp_aggr(sql->sa, nl, e->f, need_distinct(e), 
need_no_nil(e), e->card, has_nil(e));
+       }       
+       case e_atom:
+       case e_psm:
+               return e;
+       }
+       return NULL;
+}
+
+static sql_rel *
+rel_remove_join(int *changes, mvc *sql, sql_rel *rel)
+{
+       if (is_join(rel->op)) {
+               sql_rel *l = rel->l;
+               sql_rel *r = rel->r;
+               int lconst = 0, rconst = 0;
+
+
+               if (!l || rel_is_ref(l) || !r || rel_is_ref(r) ||
+                  (l->op != op_project && r->op != op_project)) 
+                       return rel;
+               if (l->op == op_project && exps_are_atoms(l->exps))
+                       lconst = 1;
+               if (r->op == op_project && exps_are_atoms(r->exps))
+                       rconst = 1;
+               if (!lconst && !rconst)
+                       return rel;
+               (*changes)++;
+               /* use constant (instead of alias) in expressions */
+               if (lconst) {
+                       sql_rel *s = l;
+                       l = r;
+                       r = s;
+               }
+               rel->exps = exps_use_consts(sql, rel->exps, r->exps);
+               /* change into select */
+               rel->op = op_select;
+               rel->l = l;
+               rel->r = NULL;
+               /* wrap in a project including, the constant columns */
+               l->subquery = 0;
+               rel = rel_project(sql->sa, rel, rel_projections(sql, l, NULL, 
1, 1));
+               list_merge(rel->exps, r->exps, (fdup)NULL);
+       }
+       return rel;
+}
+
 /* Pushing projects up the tree. Done very early in the optimizer.
  * Makes later steps easier. 
  */
@@ -6195,6 +6328,11 @@ static sql_rel *
        if (gp.cnt[op_project])
                rel = rewrite(sql, rel, &rel_push_project_up, &changes); 
 
+       /* join's/crossproducts between a relation and a constant (row).
+        * could be rewritten */
+       if (gp.cnt[op_join] && gp.cnt[op_project])
+               rel = rewrite(sql, rel, &rel_remove_join, &changes); 
+
        if (gp.cnt[op_join] || 
            gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full] || 
            gp.cnt[op_semi] || gp.cnt[op_anti] ||
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to