Changeset: 82e09b10b54c for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/82e09b10b54c
Modified Files:
sql/backends/monet5/rel_bin.c
sql/server/rel_optimize_proj.c
sql/server/rel_optimize_sel.c
sql/server/rel_optimizer_private.h
Branch: groupjoin
Log Message:
enabled outerjoin for non complex cases (ie no is nor any semantics).
diffs (148 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
@@ -2775,14 +2775,39 @@ split_join_exps(sql_rel *rel, list *join
static bool
-can_outerjoin_exp(sql_rel *rel, sql_exp *e, bool anti)
+gj_outerjoin_exp(sql_rel *rel, sql_exp *e)
+{
+ (void)rel;
+ if (e->type == e_cmp && e->flag == cmp_equal && !is_any(e) &&
!is_semantics(e))
+ return true;
+ return false;
+}
+
+#define is_equi_exp_(e) ((e)->flag == cmp_equal)
+static list *
+get_simple_equi_joins_first(mvc *sql, list *exps, bool *equality_only)
{
- if (can_join_exp(rel, e, anti)) {
- if (e->flag != cmp_equal && rel->op == op_left)
- return false;
- return true;
- }
- return false;
+ list *new_exps = sa_list(sql->sa);
+ *equality_only = true;
+
+ if (!exps)
+ return new_exps;
+
+ for (node *n = exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+
+ if (is_equi_exp_(e) /*&& !is_any(e)*/)
+ list_append(new_exps, e);
+ else /*if (!is_equi_exp_(e))*/
+ *equality_only = false;
+ }
+ for (node *n = exps->h; n; n = n->next) {
+ sql_exp *e = n->data;
+
+ if (!is_equi_exp_(e) /*|| is_any(e)*/)
+ list_append(new_exps, e);
+ }
+ return new_exps;
}
static stmt *
@@ -2815,20 +2840,22 @@ rel2bin_groupjoin(backend *be, sql_rel *
left = row2cols(be, left);
right = row2cols(be, right);
- list *jexps = rel->exps;
+ bool equality_only = true;
+ list *jexps = get_simple_equi_joins_first(sql, rel->exps,
&equality_only);
en = jexps?jexps->h:NULL;
- if (1 || list_empty(jexps) || !can_outerjoin_exp(rel, en->data, true)) {
+ if (/*list_empty(jexps)*/ list_length(jexps) <= 1 ||
!gj_outerjoin_exp(rel, en->data)) {
printf("# outer cross\n");
stmt *l = bin_find_smallest_column(be, left);
stmt *r = bin_find_smallest_column(be, right);
- if (list_empty(jexps) && list_empty(rel->exps)) {
+ if (list_empty(jexps)) {
stmt *limit = stmt_limit(be, r, NULL, NULL,
stmt_atom_lng(be, 0), stmt_atom_lng(be, 1), 0, 0, 0, 0, 0);
r = stmt_project(be, limit, r);
}
join = stmt_join_cand(be, column(be, l), column(be, r),
left->cand, NULL/*right->cand*/, 0, cmp_all, 0, 0, false, rel->op ==
op_left?false:true);
need_project = true;
} else if (!list_empty(jexps)) {
+ printf("# outer join\n");
sql_exp *e = en->data;
en = en->next;
stmt *l = exp_bin(be, e->l, left, NULL, NULL, NULL, NULL, NULL,
0, 1, 0), *r = NULL;
@@ -2854,7 +2881,7 @@ rel2bin_groupjoin(backend *be, sql_rel *
}
ls = l;
if (en) {
- join = stmt_join_cand(be, column(be, l), column(be, r),
left->cand, NULL/*right->cand*/, is_anti(e), (comp_type) cmp_equal/*e->flag*/,
0, is_semantics(e), false, rel->op == op_left?false:true);
+ join = stmt_join_cand(be, column(be, l), column(be, r),
left->cand, NULL/*right->cand*/, is_anti(e), (comp_type) cmp_equal/*e->flag*/,
0, is_any(e)|is_semantics(e), false, rel->op == op_left?false:true);
} else {
/* todo mark as mark/outerjoin */
join = stmt_join(be, l, r, 0, /*cmp*/cmp_equal, 0, 0,
false);
@@ -2901,8 +2928,8 @@ rel2bin_groupjoin(backend *be, sql_rel *
*/
if (ls) {
stmt *nls = stmt_project(be, jl, ls);
- jr = sql_Nop_(be, "ifthenelse", sql_unop_(be, "isnull",
nls), stmt_bool(be, bit_nil),
- sql_Nop_(be, "ifthenelse",
sql_unop_(be, "isnull", jr), stmt_bool(be, 0), stmt_bool(be, 1), NULL),
+ jr = sql_Nop_(be, "ifthenelse", sql_unop_(be, "isnull",
nls), stmt_bool(be, 0),
+ sql_Nop_(be, "ifthenelse",
sql_unop_(be, "isnull", jr), stmt_bool(be, bit_nil), stmt_bool(be, 1), NULL),
NULL);
} else {
/* nil == empty, 0 - no match (ie nil), 1 match */
diff --git a/sql/server/rel_optimize_proj.c b/sql/server/rel_optimize_proj.c
--- a/sql/server/rel_optimize_proj.c
+++ b/sql/server/rel_optimize_proj.c
@@ -453,7 +453,7 @@ rel_push_project_up_(visitor *v, sql_rel
/* Don't rewrite refs, non projections or constant or
order by projections */
if (!l || rel_is_ref(l) || is_topn(l->op) || is_sample(l->op) ||
- (is_join(rel->op) && /*exps_has_setjoin(rel->exps)*/
!list_empty(rel->attr)) ||
+ (is_join(rel->op) && !list_empty(rel->attr)) ||
(is_join(rel->op) && (!r || rel_is_ref(r))) ||
(is_left(rel->op) && (rel->flag&MERGE_LEFT) /* can't push
projections above merge statments left joins */) ||
(is_select(rel->op) && l->op != op_project) ||
diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -3636,7 +3636,7 @@ can_push_func(sql_exp *e, sql_rel *rel,
sql_exp *l = e->l, *r = e->r, *f = e->f;
/* don't push down functions inside attribute joins */
- if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter)
+ if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter || (is_join(rel->op) && is_any(e)))
return 0;
if (depth > 0) { /* for comparisons under the top ones, they
become functions */
int lmust = 0;
@@ -3700,7 +3700,7 @@ exp_needs_push_down(sql_rel *rel, sql_ex
switch(e->type) {
case e_cmp:
/* don't push down functions inside attribute joins */
- if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter)
+ if (e->flag == cmp_or || e->flag == cmp_in || e->flag ==
cmp_notin || e->flag == cmp_filter || (is_join(rel->op) && is_any(e)))
return 0;
return exp_needs_push_down(rel, e->l) ||
exp_needs_push_down(rel, e->r) || (e->f && exp_needs_push_down(rel, e->f));
case e_convert:
diff --git a/sql/server/rel_optimizer_private.h
b/sql/server/rel_optimizer_private.h
--- a/sql/server/rel_optimizer_private.h
+++ b/sql/server/rel_optimizer_private.h
@@ -21,7 +21,6 @@ typedef struct global_props {
needs_mergetable_rewrite:1,
needs_remote_replica_rewrite:1,
needs_distinct:1,
- needs_setjoin_rewrite:1,
has_special_modify:1, /* Don't prune updates as pruning will
possibly result in removing the joins which therefor cannot be used for
constraint checking */
opt_level:1; /* 0 run necessary rewriters, 1 run all optimizers
*/
uint8_t opt_cycle; /* the optimization cycle number */
@@ -99,7 +98,6 @@ extern run_optimizer bind_push_func_and_
extern run_optimizer bind_push_topn_and_sample_down(visitor *v, global_props
*gp) __attribute__((__visibility__("hidden")));
extern run_optimizer bind_distinct_project2groupby(visitor *v, global_props
*gp) __attribute__((__visibility__("hidden")));
extern run_optimizer bind_merge_table_rewrite(visitor *v, global_props *gp)
__attribute__((__visibility__("hidden")));
-extern run_optimizer bind_setjoins_2_joingroupby(visitor *v, global_props *gp)
__attribute__((__visibility__("hidden")));
extern run_optimizer bind_get_statistics(visitor *v, global_props *gp)
__attribute__((__visibility__("hidden")));
extern run_optimizer bind_join_order2(visitor *v, global_props *gp)
__attribute__((__visibility__("hidden")));
extern run_optimizer bind_final_optimization_loop(visitor *v, global_props
*gp) __attribute__((__visibility__("hidden")));
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]