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