Update of /cvsroot/monetdb/sql/src/server
In directory 23jxhf1.ch3.sourceforge.com:/tmp/cvs-serv808/src/server
Modified Files:
rel_optimizer.mx
Log Message:
propagated changes of Wednesday Nov 11 2009
from the Nov2009 branch to the development trunk
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2009/11/11 - nielsnes: src/server/rel_optimizer.mx,1.71.2.1
add optimizer step to fix div by zero problems
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Index: rel_optimizer.mx
===================================================================
RCS file: /cvsroot/monetdb/sql/src/server/rel_optimizer.mx,v
retrieving revision 1.73
retrieving revision 1.74
diff -u -d -r1.73 -r1.74
--- rel_optimizer.mx 9 Nov 2009 22:06:36 -0000 1.73
+++ rel_optimizer.mx 11 Nov 2009 15:37:05 -0000 1.74
@@ -1348,6 +1348,126 @@
return rel;
}
+static sql_subfunc *
+find_func( mvc *sql, char *name, list *exps )
+{
+ list * l = list_create(NULL);
+ node *n;
+
+ for(n = exps->h; n; n = n->next)
+ append(l, exp_subtype(n->data));
+ return sql_bind_func_(sql->session->schema, name, l);
+}
+
+static sql_exp *
+exp_case_fixup( mvc *sql, sql_exp *e )
+{
+ /* only functions need fix up */
+ if (e->type == e_func && e->l && !is_rank_op(e) ) {
+ list *l = new_exp_list(), *args = e->l;
+ node *n;
+ sql_exp *ne;
+ sql_subfunc *f = sql_dup_func(e->f);
+
+ /* first fixup arguments */
+ for (n=args->h; n; n=n->next) {
+ sql_exp *a = exp_case_fixup(sql, n->data);
+ list_append(l, a);
+ }
+ ne = exp_op(l, f);
+ exp_setname( ne, e->rname, e->name );
+
+ /* ifthenelse with one of the sides an 'sql_div' */
+ args = ne->l;
+ if (!f->func->s && !strcmp(f->func->base.name,"ifthenelse")) {
+ sql_exp *cond = exp_dup(args->h->data), *nne;
+ sql_exp *a1 = args->h->next->data;
+ sql_exp *a2 = args->h->next->next->data;
+ sql_subfunc *a1f = a1->f;
+ sql_subfunc *a2f = a2->f;
+ sql_subfunc *ifthen;
+
+ /* TODO we should find the div recursively ! */
+
+ /* rewrite right hands of div */
+ if (a1->type == e_func && !a1f->func->s &&
+ !strcmp(a1f->func->base.name, "sql_div")) {
+ list *args = a1->l;
+ sql_exp *le = exp_dup(args->h->next->data), *o;
+ sql_exp *re = exp_dup(args->h->next->data);
+
+ /* if (cond) then val else const */
+ args = new_exp_list();
+ append(args, exp_dup(cond));
+ append(args, re);
+ o = exp_atom_wrd(1);
+ append(args, exp_convert(o, exp_subtype(o),
exp_subtype(re)));
+ ifthen = find_func(sql, "ifthenelse", args);
+ assert(ifthen);
+ re = exp_op(args, ifthen);
+
+ a1 = exp_binop(le, re, sql_dup_func(a1->f));
+ } else {
+ a1 = exp_dup(a1);
+ }
+ if (a2->type == e_func && !a2f->func->s &&
+ !strcmp(a2f->func->base.name, "sql_div")) {
+ list *args = a2->l;
+ sql_exp *le = exp_dup(args->h->next->data), *o;
+ sql_exp *re = exp_dup(args->h->next->data);
+
+ /* if (cond) then const else val */
+ args = new_exp_list();
+ append(args, exp_dup(cond));
+ o = exp_atom_wrd(1);
+ append(args, exp_convert(o, exp_subtype(o),
exp_subtype(re)));
+ append(args, re);
+ ifthen = find_func(sql, "ifthenelse", args);
+ assert(ifthen);
+ re = exp_op(args, ifthen);
+
+ a2 = exp_binop(le, re, sql_dup_func(a2->f));
+ } else {
+ a2 = exp_dup(a2);
+ }
+ nne = exp_op3(cond, a1, a2, sql_dup_func(ne->f));
+ exp_setname( nne, ne->rname, ne->name );
+ exp_destroy(ne);
+ ne = nne;
+ }
+ return ne;
+ }
+ if (e->type == e_convert) {
+ sql_exp *e1 = exp_case_fixup(sql, e->l);
+ sql_exp *ne = exp_convert(e1, exp_fromtype(e), exp_totype(e));
+ exp_setname(ne, e->rname, e->name);
+ return ne;
+ }
+ return exp_dup(e);
+}
+
+static sql_rel *
+rel_case_fixup(int *changes, mvc *sql, sql_rel *rel)
+{
+
+ (void)sql;
+ (void)changes; /* only go through it once, ie don't mark for changes */
+ if (rel->op == op_project && rel->exps) {
+ list *exps = rel->exps;
+ node *n;
+
+ rel->exps = new_exp_list();
+ for (n = exps->h; n; n = n->next) {
+ sql_exp *e = exp_case_fixup( sql, n->data );
+
+ if (!e)
+ return NULL;
+ list_append(rel->exps, e);
+ }
+ }
+ return rel;
+}
+
static sql_rel *
rel_find_ref( sql_rel *r)
{
@@ -2085,17 +2205,6 @@
return NULL;
}
-static sql_subfunc *
-find_func( mvc *sql, char *name, list *exps )
-{
- list * l = list_create(NULL);
- node *n;
-
- for(n = exps->h; n; n = n->next)
- append(l, exp_subtype(n->data));
- return sql_bind_func_(sql->session->schema, name, l);
-}
-
/* rewrite avg into sum/count */
static sql_rel *
rel_avg2sum_count(int *changes, mvc *sql, sql_rel *rel)
@@ -3182,8 +3291,10 @@
/* make parts conditional (via debug flag) */
/* simple merging of projects */
- if (gp.cnt[op_project])
- rel = rewrite(sql, rel, &rel_merge_projects);
+ if (gp.cnt[op_project]) {
+ rel = rewrite(sql, rel, &rel_merge_projects);
+ rel = rewrite(sql, rel, &rel_case_fixup);
+ }
if (gp.cnt[op_join] ||
gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full] ||
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Monetdb-sql-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/monetdb-sql-checkins