Changeset: 6a21368cdcc0 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/6a21368cdcc0
Modified Files:
sql/backends/monet5/rel_bin.c
sql/include/sql_catalog.h
sql/rel.txt
sql/server/rel_dump.c
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimize_others.c
sql/server/rel_optimize_proj.c
sql/server/rel_optimize_sel.c
sql/server/rel_rel.c
sql/server/rel_rewriter.c
sql/server/rel_select.c
sql/server/rel_statistics.c
sql/server/rel_unnest.c
sql/server/sql_parser.y
Branch: reducedstack
Log Message:
try using a smaller stack by simplified expression tree
diffs (truncated from 1144 to 300 lines):
diff --git a/sql/backends/monet5/rel_bin.c b/sql/backends/monet5/rel_bin.c
--- a/sql/backends/monet5/rel_bin.c
+++ b/sql/backends/monet5/rel_bin.c
@@ -799,6 +799,104 @@ exp_bin_or(backend *be, sql_exp *e, stmt
}
static stmt *
+exp_bin_conjunctive(backend *be, sql_exp *e, stmt *left, stmt *right, stmt
*grp, stmt *ext, stmt *cnt, stmt *sel, int depth, bool reduce, int push)
+{
+ sql_subtype *bt = sql_bind_localtype("bit");
+ list *l = e->l;
+ node *n;
+ stmt *sel1 = NULL, *s = NULL;
+ int anti = is_anti(e);
+
+ sel1 = sel;
+ for (n = l->h; n; n = n->next) {
+ sql_exp *c = n->data;
+ stmt *sin = (sel1 && sel1->nrcols)?sel1:NULL;
+
+ /* propagate the anti flag */
+ if (anti)
+ set_anti(c);
+ s = exp_bin(be, c, left, right, grp, ext, cnt, reduce?sin:NULL,
depth, reduce, push);
+ if (!s)
+ return s;
+
+ if (!reduce && sin && sin != sel) {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true, true);
+ assert(f);
+ s = stmt_binop(be, sin, s, NULL, f);
+ } else if (!reduce && !sin && sel1 && sel1->nrcols == 0 &&
s->nrcols == 0) {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"or":"and", bt, bt, F_FUNC, true, true);
+ assert(f);
+ s = stmt_binop(be, sel1, s, sin, f);
+ } else if (reduce && ((sel1 && (sel1->nrcols == 0 || s->nrcols
== 0)) || c->type != e_cmp)) {
+ if (s->nrcols) {
+ s = stmt_uselect(be, s, stmt_bool(be, 1),
cmp_equal, sel1, anti, is_semantics(c));
+ } else {
+ stmt *predicate = bin_find_smallest_column(be,
left);
+
+ predicate = stmt_const(be, predicate,
stmt_bool(be, 1));
+ s = stmt_uselect(be, predicate, s, cmp_equal,
sel1, anti, is_semantics(c));
+ }
+ }
+ sel1 = s;
+ }
+ if (sel1->nrcols == 0 && left) {
+ stmt *predicate = bin_find_smallest_column(be, left);
+
+ if (!reduce) {
+ predicate = stmt_const(be, predicate, sel1);
+ } else {
+ predicate = stmt_const(be, predicate, stmt_bool(be, 1));
+ sel1 = stmt_uselect(be, predicate, sel1, cmp_equal,
NULL, 0/*anti*/, 0);
+ }
+ }
+ return sel1;
+}
+
+static stmt *
+exp_bin_disjunctive(backend *be, sql_exp *e, stmt *left, stmt *right, stmt
*grp, stmt *ext, stmt *cnt, stmt *sel, int depth, bool reduce, int push)
+{
+ sql_subtype *bt = sql_bind_localtype("bit");
+ list *l = e->l;
+ node *n;
+ stmt *s = NULL, *cur = NULL;
+ int anti = is_anti(e);
+
+ assert(!anti);
+ for (n = l->h; n; n = n->next) {
+ sql_exp *c = n->data;
+
+ /* propagate the anti flag */
+ if (anti)
+ set_anti(c);
+ s = exp_bin(be, c, left, right, grp, ext, cnt, reduce?sel:NULL,
depth, reduce, push);
+ if (!s)
+ return s;
+
+ if (reduce && s->nrcols == 0 && left) {
+ stmt *predicate = bin_find_smallest_column(be, left);
+ predicate = stmt_const(be, predicate, stmt_bool(be, 1));
+ s = stmt_uselect(be, predicate, s, cmp_equal, sel,
anti, is_semantics(c));
+ } else if (reduce && c->type != e_cmp) {
+ s = stmt_uselect(be, s, stmt_bool(be, 1), cmp_equal,
sel, 0, 0);
+ }
+ if (cur) {
+ if (reduce) {
+ s = stmt_tunion(be, s, cur);
+ } else {
+ sql_subfunc *f = sql_bind_func(be->mvc, "sys",
anti?"and":"or", bt, bt, F_FUNC, true, true);
+ assert(f);
+ s = stmt_binop(be, cur, s, NULL, f);
+ }
+ }
+ cur = s;
+ }
+ //if (reduce)
+ // return stmt_uselect(be, cur, stmt_bool(be, 1), cmp_equal, sel,
0/*anti*/, 0);
+ return cur;
+}
+
+
+static stmt *
exp2bin_case(backend *be, sql_exp *fe, stmt *left, stmt *right, stmt *isel,
int depth)
{
stmt *res = NULL, *ires = NULL, *rsel = NULL, *osel = NULL, *ncond =
NULL, *ocond = NULL, *cond = NULL;
@@ -1945,6 +2043,10 @@ exp_bin(backend *be, sql_exp *e, stmt *l
}
if (e->flag == cmp_in || e->flag == cmp_notin)
return handle_in_exps(be, e->l, e->r, left, right, grp,
ext, cnt, sel, (e->flag == cmp_in), depth, reduce, push);
+ if (e->flag == cmp_con)
+ return exp_bin_conjunctive(be, e, left, right, grp,
ext, cnt, sel, depth, reduce, push);
+ if (e->flag == cmp_dis)
+ return exp_bin_disjunctive(be, e, left, right, grp,
ext, cnt, sel, depth, reduce, push);
if (e->flag == cmp_or && (!right || right->nrcols == 1))
return exp_bin_or(be, e, left, right, grp, ext, cnt,
sel, depth, reduce, push);
if (e->flag == cmp_or && right) { /* join */
@@ -2028,7 +2130,10 @@ exp_bin(backend *be, sql_exp *e, stmt *l
list_append(args, l);
list_append(args, r);
list_append(args,
stmt_bool(be, 1));
- s = stmt_Nop(be,
stmt_list(be, args), sel, f, NULL);
+ s = stmt_Nop(be,
stmt_list(be, args), NULL, f, NULL);
+ /* TODO cleanup once
candidates api has been stabalized */
+ if (sel)
+
list_append(args, sel);
}
} else {
s = stmt_binop(be, l, r, sel,
f);
diff --git a/sql/include/sql_catalog.h b/sql/include/sql_catalog.h
--- a/sql/include/sql_catalog.h
+++ b/sql/include/sql_catalog.h
@@ -167,6 +167,8 @@ typedef enum comp_type {
cmp_or = 7,
cmp_in = 8, /* in value list */
cmp_notin = 9, /* not in value list */
+ cmp_con = 10, /* conjunctive (and) list */
+ cmp_dis = 11, /* disjunctive (or) list */
/* The following cmp_* are only used within stmt (not sql_exp) */
cmp_all = 12, /* special case for crossproducts */
@@ -178,7 +180,7 @@ typedef enum comp_type {
#define is_theta_exp(e) ((e) == cmp_gt || (e) == cmp_gte || (e) == cmp_lte ||\
(e) == cmp_lt || (e) ==
cmp_equal || (e) == cmp_notequal)
-#define is_complex_exp(et) ((et) == cmp_or || (et) == cmp_in || (et) ==
cmp_notin || (et) == cmp_filter)
+#define is_complex_exp(et) ((et) == cmp_or || (et) == cmp_in || (et) ==
cmp_notin || (et) == cmp_filter || (et) == cmp_con || (et) == cmp_dis)
#define is_equality_or_inequality_exp(et) ((et) == cmp_equal || (et) ==
cmp_notequal || (et) == cmp_in || (et) == cmp_notin)
diff --git a/sql/rel.txt b/sql/rel.txt
--- a/sql/rel.txt
+++ b/sql/rel.txt
@@ -143,7 +143,10 @@ e_cmp
cmp_filter = 6, filters ->l/r
are both lists
cmp_or = 7, or handling
->l/r are both lists
cmp_in = 8, in list handling
->r is a list of values
- cmp_notin = 9 not in list handling ->r is
a list of values
+ cmp_notin = 9, not in list handling ->r is
a list of values
+
+ cmp_conjunctive = 10, and handling
-> l is a list
+ cmp_disjuncive = 11, or handling
-> l is a list
/* The following cmp_* are only used within stmt (not
sql_exp) */
cmp_all = 12, /* special case for
crossproducts */
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -279,6 +279,14 @@ exp_print(mvc *sql, stream *fout, sql_ex
mnstr_printf(fout, " !");
cmp_print(sql, fout, e->flag);
exps_print(sql, fout, e->r, depth, refs, 0, 1,
decorate, 0);
+ } else if (e->flag == cmp_con || e->flag == cmp_dis) {
+ if (is_anti(e))
+ mnstr_printf(fout, " !");
+ if (e->flag == cmp_con)
+ mnstr_printf(fout, ".AND");
+ else
+ mnstr_printf(fout, ".OR");
+ exps_print(sql, fout, e->l, depth, refs, 0, 1,
decorate, 0);
} else if (e->flag == cmp_or) {
exps_print(sql, fout, e->l, depth, refs, 0, 1,
decorate, 0);
if (is_anti(e))
@@ -1535,9 +1543,15 @@ exp_read(mvc *sql, sql_rel *lrel, sql_re
tname = b;
*e = 0;
convertIdent(tname);
- if (tname && !mvc_bind_schema(sql, tname))
+ if (!tname[0]) {
+ if (strcmp(cname, "AND") == 0) {
+ exp = exp_conjunctive(sql->sa, exps);
+ } else if (strcmp(cname, "OR") == 0) {
+ exp = exp_disjunctive(sql->sa, exps);
+ }
+ } else if (tname && !mvc_bind_schema(sql, tname)) {
return sql_error(sql, ERR_NOTFOUND, SQLSTATE(3F000) "No
such schema '%s'\n", tname);
- if (grp) {
+ } else if (grp) {
if (exps && exps->h) {
list *ops = sa_list(sql->sa);
for( node *n = exps->h; n; n = n->next)
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
@@ -348,6 +348,34 @@ exp_compare_func(mvc *sql, sql_exp *le,
return e;
}
+sql_exp *
+exp_conjunctive(allocator *sa, list *exps)
+{
+ sql_exp *e = exp_create(sa, e_cmp);
+
+ if (e == NULL)
+ return NULL;
+
+ e->card = exps_card(exps);
+ e->l = exps;
+ e->flag = cmp_con;
+ return e;
+}
+
+sql_exp *
+exp_disjunctive(allocator *sa, list *exps)
+{
+ sql_exp *e = exp_create(sa, e_cmp);
+
+ if (e == NULL)
+ return NULL;
+
+ e->card = exps_card(exps);
+ e->l = exps;
+ e->flag = cmp_dis;
+ return e;
+}
+
static sql_subtype*
dup_subtype(allocator *sa, sql_subtype *st)
{
@@ -1454,6 +1482,10 @@ exp_match_exp_semantics( sql_exp *e1, sq
exp_match_list(e1->l, e2->l) &&
exp_match_list(e1->r, e2->r))
return 1;
else if (e1->flag == e2->flag &&
+ (e1->flag == cmp_con || e1->flag == cmp_dis) &&
+ exp_match_list(e1->l, e2->l))
+ return 1;
+ else if (e1->flag == e2->flag &&
(e1->flag == cmp_in || e1->flag == cmp_notin) &&
exp_match_exp(e1->l, e2->l) &&
exp_match_list(e1->r, e2->r))
return 1;
@@ -1819,6 +1851,9 @@ rel_find_exp_and_corresponding_rel_(sql_
if (rel_find_exps_and_corresponding_rel_(rel, e->l,
subexp, res) ||
rel_find_exps_and_corresponding_rel_(rel, e->r,
subexp, res))
return e;
+ } else if (e->flag == cmp_con || e->flag == cmp_dis) {
+ if (rel_find_exps_and_corresponding_rel_(rel, e->l,
subexp, res))
+ return e;
} else if (e->flag == cmp_in || e->flag == cmp_notin) {
if (rel_find_exp_and_corresponding_rel_(rel, e->l,
subexp, res) ||
rel_find_exps_and_corresponding_rel_(rel, e->r,
subexp, res))
@@ -2149,6 +2184,8 @@ exp_is_null(sql_exp *e )
if (!is_semantics(e)) {
if (e->flag == cmp_or || e->flag == cmp_filter) {
return (exps_have_null(e->l) &&
exps_have_null(e->r));
+ } else if (e->flag == cmp_con || e->flag == cmp_dis) {
+ return false;
} else if (e->flag == cmp_in || e->flag == cmp_notin) {
return ((e->flag == cmp_in &&
exp_is_null(e->l)) ||
(e->flag == cmp_notin &&
(exp_is_null(e->l) || exps_have_null(e->r))));
@@ -2212,6 +2249,8 @@ exp_is_atom( sql_exp *e )
return 0;
if (e->flag == cmp_or || e->flag == cmp_filter)
return exps_are_atoms(e->l) && exps_are_atoms(e->r);
+ if (e->flag == cmp_con || e->flag == cmp_dis)
+ return exps_are_atoms(e->l);
if (e->flag == cmp_in || e->flag == cmp_notin)
return exp_is_atom(e->l) && exps_are_atoms(e->r);
return exp_is_atom(e->l) && exp_is_atom(e->r) && (!e->f ||
exp_is_atom(e->f));
@@ -2252,6 +2291,8 @@ exp_is_aggr(sql_rel *r, sql_exp *e)
return false;
if (e->flag == cmp_or || e->flag == cmp_filter)
return exps_are_aggr(r, e->l) && exps_are_aggr(r, e->r);
+ if (e->flag == cmp_con || e->flag == cmp_dis)
+ return exps_are_aggr(r, e->l);
if (e->flag == cmp_in || e->flag == cmp_notin)
return exp_is_aggr(r, e->l) && exps_are_aggr(r, e->r);
return exp_is_aggr(r, e->l) && exp_is_aggr(r, e->r) && (!e->f
|| exp_is_aggr(r, e->f));
@@ -2298,6 +2339,8 @@ exp_has_aggr(sql_rel *r, sql_exp *e )
return false;
if (e->flag == cmp_or || e->flag == cmp_filter)
return exps_have_aggr(r, e->l) && exps_have_aggr(r,
e->r);
+ if (e->flag == cmp_con || e->flag == cmp_dis)
+ return exps_have_aggr(r, e->l);
if (e->flag == cmp_in || e->flag == cmp_notin)
return exp_has_aggr(r, e->l) && exps_have_aggr(r, e->r);
return exp_has_aggr(r, e->l) && exp_has_aggr(r, e->r) && (!e->f
|| exp_has_aggr(r, e->f));
@@ -2327,6 +2370,8 @@ exp_has_rel( sql_exp *e )
case e_cmp:
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]