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]

Reply via email to