Changeset: 3a609491dcdd for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=3a609491dcdd
Modified Files:
        sql/server/rel_optimizer.c
        sql/test/BugTracker-2014/Tests/case-sqrt.Bug-3627.stable.out
Branch: default
Log Message:

fix for sqrt (< 0)


diffs (196 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
@@ -1311,6 +1311,18 @@ project_unsafe(sql_rel *rel)
 }
 
 static int 
+math_unsafe(sql_subfunc *f)
+{
+       if (!f->func->s) {
+               if (strcmp(f->func->base.name, "sql_div") == 0 ||
+                   strcmp(f->func->base.name, "sqrt") == 0 ||
+                   strcmp(f->func->base.name, "atan") == 0 ) 
+                       return 1;
+       }
+       return 0;
+}
+
+static int 
 can_push_func(sql_exp *e, sql_rel *rel, int *must)
 {
        if (!e)
@@ -1337,7 +1349,7 @@ can_push_func(sql_exp *e, sql_rel *rel, 
                
                if (e->f){
                        sql_subfunc *f = e->f;
-                       if (!f->func->s && !strcmp(f->func->base.name, 
"sql_div")) 
+                       if (math_unsafe(f))
                                return 0;
                }
                if (l) for (n = l->h; n && res; n = n->next)
@@ -2215,16 +2227,37 @@ find_func( mvc *sql, char *name, list *e
        return sql_bind_func_(sql->sa, sql->session->schema, name, l, F_FUNC);
 }
 
+/* f (args) unsafe  (examples a/b iff b == 0 and sqrt(a iff a<0))
+ */
 static sql_exp *
-sql_div_fixup( mvc *sql, sql_exp *e, sql_exp *cond, int lr )
-{
-       list *args = e->l;
-       sql_exp *le = args->h->data, *o;
-       sql_exp *re = args->h->next->data;
+math_unsafe_fixup_unop( mvc *sql, sql_exp *e, sql_exp *le, sql_exp *cond, int 
lr)
+{
+       list *args = new_exp_list(sql->sa);
        sql_subfunc *ifthen;
+       sql_exp *o;
 
        /* if (cond) then val else const */
-       args = new_exp_list(sql->sa);
+       append(args, cond);
+       if (!lr)
+               append(args, le);
+       o = exp_atom_wrd(sql->sa, 1);
+       append(args, exp_convert(sql->sa, o, exp_subtype(o), exp_subtype(le)));
+       if (lr)
+               append(args, le);
+       ifthen = find_func(sql, "ifthenelse", args);
+       assert(ifthen);
+       le = exp_op(sql->sa, args, ifthen);
+       return exp_unop(sql->sa, le, e->f);
+}
+
+static sql_exp *
+math_unsafe_fixup_binop( mvc *sql, sql_exp *e, sql_exp *le, sql_exp *re, 
sql_exp *cond, int lr )
+{
+       list *args = new_exp_list(sql->sa);
+       sql_subfunc *ifthen;
+       sql_exp *o;
+
+       /* if (cond) then val else const */
        append(args, cond);
        if (!lr)
                append(args, re);
@@ -2239,8 +2272,18 @@ sql_div_fixup( mvc *sql, sql_exp *e, sql
        return exp_binop(sql->sa, le, re, e->f);
 }
 
+static sql_exp *
+math_unsafe_fixup( mvc *sql, sql_exp *e, sql_exp *cond, int lr )
+{
+       list *args = e->l;
+       if (args->h->next)
+               return math_unsafe_fixup_binop(sql, e, args->h->data, 
args->h->next->data, cond, lr);
+       else
+               return math_unsafe_fixup_unop(sql, e, args->h->data, cond, lr);
+}
+
 static int 
-exp_find_func( sql_exp *e, char *name)
+exp_find_math_unsafe( sql_exp *e)
 {
        if (!e)
                return 0;
@@ -2252,19 +2295,19 @@ exp_find_func( sql_exp *e, char *name)
                        node *n;
                        sql_subfunc *f = e->f;
 
-                       if (!f->func->s && !strcmp(f->func->base.name, name)) 
+                       if (math_unsafe(f))
                                return 1;
                        if (!l)
                                return 0;
                        for (n = l->h; n; n = n->next) {
                                sql_exp *ne = n->data;
 
-                               if (exp_find_func( ne, name))
+                               if (exp_find_math_unsafe(ne))
                                        return 1;
                        }
                }
        case e_convert:
-               return exp_find_func( e->l, name);
+               return exp_find_math_unsafe(e->l);
        case e_column: 
        case e_cmp:
        case e_psm:
@@ -2274,7 +2317,7 @@ exp_find_func( sql_exp *e, char *name)
        }
 }
 
-static sql_exp * exp_div_fixup( mvc *sql, sql_exp *e, sql_exp *cond, int lr );
+static sql_exp * exp_math_unsafe_fixup( mvc *sql, sql_exp *e, sql_exp *cond, 
int lr );
 
 static list *
 exps_case_fixup( mvc *sql, list *exps, sql_exp *cond, int lr )
@@ -2288,8 +2331,8 @@ exps_case_fixup( mvc *sql, list *exps, s
                        if (is_func(e->type) && e->l && !is_rank_op(e) ) {
                                sql_subfunc *f = e->f;
 
-                               if (!f->func->s && !strcmp(f->func->base.name, 
"sql_div")) {
-                                       e = sql_div_fixup(sql, e, cond, lr);
+                               if (math_unsafe(f)) {
+                                       e = math_unsafe_fixup(sql, e, cond, lr);
                                } else {
                                        list *l = exps_case_fixup(sql, e->l, 
cond, lr);
                                        sql_exp *ne = exp_op(sql->sa, l, f);
@@ -2297,7 +2340,7 @@ exps_case_fixup( mvc *sql, list *exps, s
                                        e = ne;
                                }
                        } else if (e->type == e_convert) {
-                               sql_exp *l = exp_div_fixup(sql, e->l, cond, lr);
+                               sql_exp *l = exp_math_unsafe_fixup(sql, e->l, 
cond, lr);
                                sql_exp *ne = exp_convert(sql->sa, l, 
exp_fromtype(e), exp_totype(e));
                                e = ne;
                        }
@@ -2309,13 +2352,13 @@ exps_case_fixup( mvc *sql, list *exps, s
 }
 
 static sql_exp *
-exp_div_fixup( mvc *sql, sql_exp *e, sql_exp *cond, int lr )
+exp_math_unsafe_fixup( mvc *sql, sql_exp *e, sql_exp *cond, int lr )
 {
        if (is_func(e->type) && e->l && !is_rank_op(e) ) {
                sql_subfunc *f = e->f;
 
-               if (!f->func->s && !strcmp(f->func->base.name, "sql_div")) {
-                       e = sql_div_fixup(sql, e, cond, lr);
+               if (math_unsafe(f)) {
+                       e = math_unsafe_fixup(sql, e, cond, lr);
                } else {
                        list *l = exps_case_fixup(sql, e->l, cond, lr);
                        sql_exp *ne = exp_op(sql->sa, l, f);
@@ -2371,13 +2414,13 @@ exp_case_fixup( mvc *sql, sql_exp *e )
                        sql_exp *a2 = args->h->next->next->data; 
 
                        /* rewrite right hands of div */
-                       if ((a1->type == e_func || a1->type == e_convert) && 
exp_find_func(a1, "sql_div")) {
-                               a1 = exp_div_fixup(sql, a1, cond, 0);
+                       if ((a1->type == e_func || a1->type == e_convert) && 
exp_find_math_unsafe(a1)) {
+                               a1 = exp_math_unsafe_fixup(sql, a1, cond, 0);
                        } else if (a1->type == e_func && a1->l) { 
                                a1->l = exps_case_fixup(sql, a1->l, cond, 0); 
                        }
-                       if  ((a2->type == e_func || a2->type == e_convert) && 
exp_find_func(a2, "sql_div")) {
-                               a2 = exp_div_fixup(sql, a2, cond, 1);
+                       if  ((a2->type == e_func || a2->type == e_convert) && 
exp_find_math_unsafe(a2)) {
+                               a2 = exp_math_unsafe_fixup(sql, a2, cond, 1);
                        } else if (a2->type == e_func && a2->l) { 
                                a2->l = exps_case_fixup(sql, a2->l, cond, 1); 
                        }
diff --git a/sql/test/BugTracker-2014/Tests/case-sqrt.Bug-3627.stable.out 
b/sql/test/BugTracker-2014/Tests/case-sqrt.Bug-3627.stable.out
--- a/sql/test/BugTracker-2014/Tests/case-sqrt.Bug-3627.stable.out
+++ b/sql/test/BugTracker-2014/Tests/case-sqrt.Bug-3627.stable.out
@@ -92,8 +92,8 @@ Ready.
 #          FROM t1
 #       ) t0
 #;
-% sys.t0,      sys.t0, sys.L # table_name
-% id,  colint, sqrt_colint_sq # name
+% sys.t0,      sys.t0, sys.t0 # table_name
+% id,  colint, sqrt_colint # name
 % int, int,    double # type
 % 1,   2,      24 # length
 [ 1,   -2,     1.414213562     ]
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to