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