Changeset: a3f7099eea70 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=a3f7099eea70
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/benchmarks/tpcds/Tests/09.stable.out
        sql/server/rel_exp.c
        sql/server/rel_exp.h
        sql/server/rel_optimizer.c
        sql/server/rel_select.c
        sql/server/rel_unnest.c
        sql/storage/store.c
Branch: subquery
Log Message:

handle equal_nil in select statements
handle single mark_in/notin in semijoin's (crossproduct gets too big)
push expressions into semijoins when possible
handle more complex order by column expression cases


diffs (truncated from 394 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
@@ -2197,7 +2197,7 @@ rel2bin_semijoin(backend *be, sql_rel *r
                        stmt *s = NULL;
 
                        /* only handle simple joins here */             
-                       if (/*list_length(lje) &&*/ (idx || e->type != e_cmp || 
e->flag != cmp_equal))
+                       if (/*list_length(lje) &&*/ (idx || e->type != e_cmp || 
(e->flag != cmp_equal && e->flag != mark_in)))
                                break;
                        if ((exp_has_func(e) && get_cmp(e) != cmp_filter) ||
                            (get_cmp(e) == cmp_or)) { 
diff --git a/sql/backends/monet5/sql_statement.c 
b/sql/backends/monet5/sql_statement.c
--- a/sql/backends/monet5/sql_statement.c
+++ b/sql/backends/monet5/sql_statement.c
@@ -1445,6 +1445,8 @@ stmt_uselect(backend *be, stmt *op1, stm
 
                if ((q = multiplex2(mb, mod, convertOperator(op), l, r, 
TYPE_bit)) == NULL) 
                        return NULL;
+               if (cmptype == cmp_equal_nil)
+                       q = pushBit(mb, q, TRUE); 
                k = getDestVar(q);
 
                q = newStmt(mb, algebraRef, selectRef);
diff --git a/sql/benchmarks/tpcds/Tests/09.stable.out 
b/sql/benchmarks/tpcds/Tests/09.stable.out
--- a/sql/benchmarks/tpcds/Tests/09.stable.out
+++ b/sql/benchmarks/tpcds/Tests/09.stable.out
@@ -35,7 +35,12 @@ Ready.
 #           ELSE
 #                  (SELECT avg(ss_net_paid)
 #                   FROM store_sales
-% sys.L13,     sys.L26,        sys.L41,        sys.L54,        sys.L67 # 
table_name
+#                   WHERE ss_quantity BETWEEN 1 AND 20)
+#       END bucket1,
+#       CASE
+#           WHEN
+#                  (SELECT count(*)
+% .L13,        .L26,   .L41,   .L54,   .L67 # table_name
 % bucket1,     bucket2,        bucket3,        bucket4,        bucket5 # name
 % double,      double, double, double, double # type
 % 24,  24,     24,     24,     24 # length
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
@@ -2154,6 +2154,14 @@ create_table_part_atom_exp(mvc *sql, sql
        return res;
 }
 
+int 
+exp_aggr_is_count(sql_exp *e)
+{
+       if (e->type == e_aggr && strcmp(((sql_subaggr *)e->f)->aggr->base.name, 
"count") == 0)
+               return 1;
+       return 0;
+}
+
 void
 exps_reset_freevar(list *exps)
 {
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -160,6 +160,8 @@ extern void exp_sum_scales(sql_subfunc *
 
 extern sql_exp *create_table_part_atom_exp(mvc *sql, sql_subtype tpe, ptr 
value);
 
+extern int exp_aggr_is_count(sql_exp *e);
+
 extern void exps_reset_freevar(list *exps);
 
 #endif /* _REL_EXP_H_ */
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
@@ -431,6 +431,12 @@ exp_count(int *cnt, sql_exp *e)
                case cmp_or: /* prefer or over functions */
                        *cnt += 3;
                        return 3;
+               case mark_in:
+               case mark_notin:
+               case mark_exists:
+               case mark_notexists:
+                       *cnt += 0;
+                       return 0;
                default:
                        return 0;
                }
@@ -1760,8 +1766,7 @@ rel_push_count_down(int *changes, mvc *s
        if (is_groupby(rel->op) && !rel_is_ref(rel) &&
             r && !r->exps && r->op == op_join && !(rel_is_ref(r)) && 
            /* currently only single count aggregation is handled, no other 
projects or aggregation */
-           list_length(rel->exps) == 1 && ((sql_exp *) 
rel->exps->h->data)->type == e_aggr &&
-            strcmp(((sql_subaggr *) ((sql_exp *) 
rel->exps->h->data)->f)->aggr->base.name, "count") == 0) {
+           list_length(rel->exps) == 1 && 
exp_aggr_is_count(rel->exps->h->data)) {
                sql_exp *nce, *oce;
                sql_rel *gbl, *gbr;             /* Group By */
                sql_rel *cp;                    /* Cross Product */
@@ -1956,8 +1961,7 @@ rel_simplify_fk_joins(int *changes, mvc 
        while (is_groupby(rel->op) && !rel_is_ref(rel) &&
             r && r->exps && is_join(r->op) && list_length(r->exps) == 1 && 
!(rel_is_ref(r)) && 
            /* currently only single count aggregation is handled, no other 
projects or aggregation */
-           list_length(rel->exps) == 1 && ((sql_exp *) 
rel->exps->h->data)->type == e_aggr &&
-            strcmp(((sql_subaggr *) ((sql_exp *) 
rel->exps->h->data)->f)->aggr->base.name, "count") == 0) {
+           list_length(rel->exps) == 1 && 
exp_aggr_is_count(rel->exps->h->data)) {
                sql_rel *or = r;
 
                r = rel_simplify_count_fk_join(changes, sql, r, rel->exps);
@@ -2905,7 +2909,7 @@ rel_case_fixup(int *changes, mvc *sql, s
                }
 
                /* get proper output first, then rewrite lower project (such 
that it can split expressions) */
-               push_down = is_simple_project(rel->op) && !rel->r && 
!rel_is_ref(rel);
+               push_down = is_simple_project(rel->op) && !rel->r && 
!rel_is_ref(rel) && !need_distinct(rel);
                if (push_down)
                        res = rel_project(sql->sa, rel, rel_projections(sql, 
rel, NULL, 1, 2));
 
@@ -3944,7 +3948,7 @@ rel_push_aggr_down(int *changes, mvc *sq
 
                        if (oa->type == e_aggr) {
                                sql_subaggr *f = oa->f;
-                               int cnt = strcmp(f->aggr->base.name,"count")==0;
+                               int cnt = exp_aggr_is_count(oa);
                                sql_subaggr *a = sql_bind_aggr(sql->sa, 
sql->session->schema, (cnt)?"sum":f->aggr->base.name, exp_subtype(e));
 
                                assert(a);
@@ -4068,7 +4072,7 @@ gen_push_groupby_down(int *changes, mvc 
                                /* check args are part of left/right */
                                if (!list_empty(args) && rel_has_exps(cl, args) 
== 0)
                                        return rel;
-                               if (rel->op != op_join && 
strcmp(((sql_subaggr*)ce->f)->aggr->base.name, "count") == 0)
+                               if (rel->op != op_join && exp_aggr_is_count(ce))
                                        ce->p = prop_create(sql->sa, 
PROP_COUNT, ce->p);
                                list_append(aggrs, ce); 
                        }
@@ -5481,7 +5485,7 @@ rel_groupby_distinct2(int *changes, mvc 
                } else if (e->type == e_aggr && !need_distinct(e)) {
                        sql_exp *v;
                        sql_subaggr *f = e->f;
-                       int cnt = strcmp(f->aggr->base.name,"count")==0;
+                       int cnt = exp_aggr_is_count(e);
                        sql_subaggr *a = sql_bind_aggr(sql->sa, 
sql->session->schema, (cnt)?"sum":f->aggr->base.name, exp_subtype(e));
 
                        append(aggrs, e);
diff --git a/sql/server/rel_select.c b/sql/server/rel_select.c
--- a/sql/server/rel_select.c
+++ b/sql/server/rel_select.c
@@ -1487,12 +1487,16 @@ rel_filter(mvc *sql, sql_rel *rel, list 
                /* push select into the given relation */
                return rel_push_select(sql, rel, L, e);
        } else { /* join */
-               if (is_semi(rel->op) || (is_outerjoin(rel->op) && 
!is_processed(rel))) {
+               sql_rel *r;
+               if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && 
!is_processed((rel)))) {
                        rel_join_add_exp(sql->sa, rel, e);
                        return rel;
                }
                /* push join into the given relation */
-               return rel_push_join(sql, rel, L, R, NULL, e);
+               if ((r = rel_push_join(sql, rel, L, R, NULL, e)) != NULL)
+                       return r;
+               rel_join_add_exp(sql->sa, rel, e);
+               return rel;
        }
 }
 
@@ -1595,12 +1599,16 @@ rel_compare_exp_(sql_query *query, sql_r
                /* push select into the given relation */
                return rel_push_select(sql, rel, L, e);
        } else { /* join */
-               if (is_semi(rel->op) || (is_outerjoin(rel->op) && 
!is_processed((rel)))) {
+               sql_rel *r;
+               if (/*is_semi(rel->op) ||*/ (is_outerjoin(rel->op) && 
!is_processed((rel)))) {
                        rel_join_add_exp(sql->sa, rel, e);
                        return rel;
                }
                /* push join into the given relation */
-               return rel_push_join(sql, rel, L, R, rs2, e);
+               if ((r = rel_push_join(sql, rel, L, R, rs2, e)) != NULL)
+                       return r;
+               rel_join_add_exp(sql->sa, rel, e);
+               return rel;
        }
 }
 
@@ -2717,7 +2725,10 @@ rel_in_exp(sql_query *query, sql_rel *re
 
                                        if (rel_convert_types(sql, &l, &r, 1, 
type_equal_no_any) < 0) 
                                                return NULL;
-                                       e = exp_compare(sql->sa, l, r, 
cmp_equal );
+                                       exp_label(sql->sa, r, ++sql->label);
+                                       r = exp_ref(sql->sa, r);
+                                       //e = exp_compare(sql->sa, l, r, 
cmp_equal );
+                                       e = exp_compare(sql->sa, l, r, 
sc->token==SQL_IN?mark_in:mark_notin); 
                                        rel_join_add_exp(sql->sa, left, e);
                                }
                                if (is_sql_sel(f)) {
@@ -4557,72 +4568,6 @@ rel_projections_(mvc *sql, sql_rel *rel)
        }
 }
 
-/* exp_rewrite */
-static sql_exp * exp_rewrite(mvc *sql, sql_exp *e, sql_rel *t);
-
-static list *
-exps_rename(mvc *sql, list *l, sql_rel *r) 
-{
-       node *n;
-       list *nl = new_exp_list(sql->sa);
-
-       for(n=l->h; n; n=n->next) {
-               sql_exp *arg = n->data;
-
-               arg = exp_rewrite(sql, arg, r);
-               if (!arg) 
-                       return NULL;
-               append(nl, arg);
-       }
-       return nl;
-}
-
-static sql_exp *
-exp_rewrite(mvc *sql, sql_exp *e, sql_rel *r) 
-{
-       sql_exp *l, *ne = NULL;
-
-       switch(e->type) {
-       case e_column:
-               if (e->l) { 
-                       e = exps_bind_column2(r->exps, e->l, e->r);
-               } else {
-                       e = exps_bind_column(r->exps, e->r, NULL);
-               }
-               if (!e)
-                       return NULL;
-               return exp_column(sql->sa, e->l, e->r, exp_subtype(e), 
exp_card(e), has_nil(e), is_intern(e));
-       case e_cmp: 
-               return NULL;
-       case e_convert:
-               l = exp_rewrite(sql, e->l, r);
-               if (l)
-                       ne = exp_convert(sql->sa, l, exp_fromtype(e), 
exp_totype(e));
-               break;
-       case e_aggr:
-       case e_func: {
-               list *l = e->l, *nl = NULL;
-
-               if (!l) {
-                       return e;
-               } else {
-                       nl = exps_rename(sql, l, r);
-                       if (!nl)
-                               return NULL;
-               }
-               if (e->type == e_func)
-                       ne = exp_op(sql->sa, nl, e->f);
-               else 
-                       ne = exp_aggr(sql->sa, nl, e->f, need_distinct(e), 
need_no_nil(e), e->card, has_nil(e));
-               break;
-       }       
-       case e_atom:
-       case e_psm:
-               return e;
-       }
-       return ne;
-}
-
 /* second complex columns only */
 static sql_exp *
 rel_order_by_column_exp(sql_query *query, sql_rel **R, symbol *column_r, int f)
@@ -4631,20 +4576,22 @@ rel_order_by_column_exp(sql_query *query
        sql_rel *r = *R;
        sql_exp *e = NULL;
        exp_kind ek = {type_value, card_column, FALSE};
-
-       (void)f;
-       /*
+       int added_project = 0;
+
        if (is_sql_orderby(f)) {
+               sql_rel *rl = r->l;
+
                assert(is_project(r->op));
-               r = r->l;
-       }
-       */
+               if (!is_processed(rl)) 
+                       r = r->l;
+       }
        if (!r)
                return e;
 
        if (!is_project(r->op) || is_set(r->op)) {
                r = rel_project(sql->sa, r, rel_projections(sql, r, NULL, 1, 
1));
                (*R)->l = r;
+               added_project = 1;
        }
 
        if (!e) {
@@ -4652,7 +4599,12 @@ rel_order_by_column_exp(sql_query *query
                /* add to internal project */
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to