Changeset: 81b3ccc3f7ce for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=81b3ccc3f7ce
Modified Files:
sql/include/sql_relation.h
sql/server/rel_dump.c
sql/server/rel_graph.c
sql/server/rel_optimizer.c
sql/server/rel_rel.c
Branch: graph0
Log Message:
QRW: handle push down for selects
diffs (218 lines):
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -230,7 +230,7 @@ typedef enum operator_type {
#define is_sample(op) \
(op == op_sample)
#define is_graph(op) \
- (op == op_graph_join || op_graph_select)
+ (op == op_graph_join || op == op_graph_select)
/* NO NIL semantics of aggr operations */
#define need_no_nil(e) \
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
@@ -514,7 +514,8 @@ rel_print_(mvc *sql, stream *fout, sql_
if (rel->exps)
exps_print(sql, fout, rel->exps, depth, 1, 0);
} break;
- case op_graph_join: {
+ case op_graph_join:
+ case op_graph_select: {
sql_graph *graph_ptr = (sql_graph*) rel;
print_indent(sql, fout, depth, decorate);
mnstr_printf(fout, "%s", op2string(rel->op));
@@ -525,6 +526,7 @@ rel_print_(mvc *sql, stream *fout, sql_
} else
rel_print_(sql, fout, rel->l, depth+1, refs, decorate);
if (rel->r) {
+ assert(rel->op == op_graph_join && "Expected join
semantics when a rhs is present");
if (rel_is_ref(rel->r)) {
int nr = find_ref(refs, rel->r);
print_indent(sql, fout, depth+1, decorate);
diff --git a/sql/server/rel_graph.c b/sql/server/rel_graph.c
--- a/sql/server/rel_graph.c
+++ b/sql/server/rel_graph.c
@@ -78,7 +78,7 @@ sql_rel* rel_graph_reaches(mvc *sql, sql
if(!qto) return NULL; // cannot refer to qto
// TODO: to be handled with graph_select
if(qfrom->card != CARD_MULTI || qto->card != CARD_MULTI){
- return sql_error(sql, 42, "["__FILE__ ":%d] select/filter syntax not
implemented yet", __LINE__);
+ return sql_error(sql, 42, "["__FILE__ ":%d] select/filter semantic not
allowed for the time being", __LINE__);
}
// edges table
@@ -141,7 +141,7 @@ sql_rel* rel_graph_reaches(mvc *sql, sql
// let us see if what we are creating makes sense
printf("[Semantic analysis] Output relation: %s\n", rel2str1(sql, result));
- return rel;
+ return result;
}
/*****************************************************************************
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
@@ -3912,13 +3912,13 @@ rel_push_select_down(int *changes, mvc *
r && r->op == op_project && !(rel_is_ref(r)))
return rel_merge_projects(changes, sql, rel);
- /* push select through join */
- if (is_select(rel->op) && r && (is_join(r->op) || is_apply(r->op)) &&
!(rel_is_ref(r))) {
+ /* push select through graph/join */
+ if (is_select(rel->op) && r && (is_join(r->op) || is_graph(r->op) ||
is_apply(r->op)) && !(rel_is_ref(r))) {
sql_rel *jl = r->l;
sql_rel *jr = r->r;
// booleans, can we push down in the lhs and rhs?
- int left = r->op == op_join || r->op == op_left;
- int right = r->op == op_join || r->op == op_right;
+ int left = r->op == op_join || r->op == op_left ||
is_graph(r->op);
+ int right = r->op == op_join || r->op == op_right || r->op ==
op_graph_join;
if (is_apply(r->op)) {
left = right = 1;
@@ -3930,10 +3930,10 @@ rel_push_select_down(int *changes, mvc *
/* introduce selects under the join (if needed) */
set_processed(jl);
- set_processed(jr);
+ if(jr) set_processed(jr);
if (!is_select(jl->op))
r->l = jl = rel_select(sql->sa, jl, NULL);
- if (!is_select(jr->op))
+ if (jr && !is_select(jr->op))
r->r = jr = rel_select(sql->sa, jr, NULL);
rel->exps = new_exp_list(sql->sa);
@@ -4074,7 +4074,7 @@ rel_remove_empty_select(int *changes, mv
{
(void)sql;
- if ((is_join(rel->op) || is_semi(rel->op) || is_select(rel->op) ||
is_project(rel->op) || is_topn(rel->op) || is_sample(rel->op)) && rel->l) {
+ if ((is_join(rel->op) || is_semi(rel->op) || is_select(rel->op) ||
is_project(rel->op) || is_topn(rel->op) || is_sample(rel->op) ||
is_graph(rel->op)) && rel->l) {
sql_rel *l = rel->l;
if (is_select(l->op) && !(rel_is_ref(l)) &&
(!l->exps || list_length(l->exps) == 0)) {
@@ -4084,7 +4084,7 @@ rel_remove_empty_select(int *changes, mv
(*changes)++;
}
}
- if ((is_join(rel->op) || is_semi(rel->op) || is_set(rel->op)) &&
rel->r) {
+ if ((is_join(rel->op) || is_semi(rel->op) || is_set(rel->op) ||
is_graph(rel->op)) && rel->r) {
sql_rel *r = rel->r;
if (is_select(r->op) && !(rel_is_ref(r)) &&
(!r->exps || list_length(r->exps) == 0)) {
@@ -8825,16 +8825,16 @@ static sql_rel *
if (gp.cnt[op_left] || gp.cnt[op_right] || gp.cnt[op_full])
rel = rewrite_topdown(sql, rel, &rel_split_outerjoin, &changes);
+ printf("Optimizer rel_push_select_down [before]: %s", rel2str1(sql,
rel));
if (gp.cnt[op_select] || gp.cnt[op_semi]) {
/* only once */
if (level <= 0)
rel = rewrite(sql, rel, &rel_merge_rse, &changes);
- printf("Optimizer rel_push_select_down [before]: %s",
rel2str1(sql, rel));
rel = rewrite_topdown(sql, rel, &rel_push_select_down,
&changes);
- printf("Optimizer rel_push_select_down [after]: %s",
rel2str1(sql, rel));
rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes);
}
+ printf("Optimizer rel_push_select_down [after]: %s", rel2str1(sql,
rel));
if (gp.cnt[op_select] && gp.cnt[op_join]) {
rel = rewrite_topdown(sql, rel, &rel_push_select_down_join,
&changes);
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -182,7 +182,8 @@ rel_bind_column_(mvc *sql, sql_rel **p,
case op_join:
case op_left:
case op_right:
- case op_full: {
+ case op_full:
+ case op_graph_join: {
sql_rel *right = rel->r;
*p = rel;
@@ -228,6 +229,7 @@ rel_bind_column_(mvc *sql, sql_rel **p,
case op_select:
case op_topn:
case op_sample:
+ case op_graph_select:
*p = rel;
if (rel->l)
return rel_bind_column_(sql, p, rel->l, cname);
@@ -272,7 +274,7 @@ rel_bind_column2( mvc *sql, sql_rel *rel
if (is_project(rel->op) && rel->l) {
if (!is_processed(rel))
return rel_bind_column2(sql, rel->l, tname, cname, f);
- } else if (is_join(rel->op)) {
+ } else if (is_join(rel->op) || rel->op == op_graph_join) {
sql_exp *e = rel_bind_column2(sql, rel->l, tname, cname, f);
if (!e)
e = rel_bind_column2(sql, rel->r, tname, cname, f);
@@ -281,7 +283,8 @@ rel_bind_column2( mvc *sql, sql_rel *rel
is_sort(rel) ||
is_semi(rel->op) ||
is_apply(rel->op) ||
- is_select(rel->op)) {
+ is_select(rel->op) ||
+ rel->op == op_graph_select) {
if (rel->l)
return rel_bind_column2(sql, rel->l, tname, cname, f);
}
@@ -913,9 +916,10 @@ rel_bind_path_(sql_rel *rel, sql_exp *e,
case op_graph_select:
// this code path is only looking for column names, do not
iterate on the cheapest paths
found = rel_bind_path_(rel->l, e, path);
- if(!found && rel->op == op_graph_join)
+ if(!found && rel->op == op_graph_join) {
assert(rel->r != NULL);
found = rel_bind_path_(rel->r, e, path);
+ }
break;
}
if (found)
@@ -970,7 +974,8 @@ rel_push_select(mvc *sql, sql_rel *rel,
if (!is_select(lrel->op) &&
!(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
lrel->op != op_join &&
- lrel->op != op_left)
+ lrel->op != op_left &&
+ !is_graph(lrel->op))
break;
/* pushing through left head of a left join is allowed */
if (lrel->op == op_left && (!n->next || lrel->l !=
n->next->data))
@@ -985,10 +990,11 @@ rel_push_select(mvc *sql, sql_rel *rel,
sql_rel *n = rel_select(sql->sa, lrel, e);
if (p && p != lrel) {
- assert(p->op == op_join || p->op == op_left ||
is_semi(p->op));
+ assert(p->op == op_join || p->op == op_left ||
is_semi(p->op) || is_graph(p->op));
if (p->l == lrel) {
p->l = n;
} else {
+ assert(p->op != op_graph_select);
p->r = n;
}
} else {
@@ -1013,6 +1019,7 @@ rel_push_join(mvc *sql, sql_rel *rel, sq
node *ln, *rn;
sql_rel *lrel = NULL, *rrel = NULL, *rrel2 = NULL, *p = NULL;
+ // TODO: Dean what is rs2 for?
if (rs2)
r2 = rel_bind_path(sql->sa, rel, rs2);
if (!l || !r || (rs2 && !r2))
@@ -1062,7 +1069,8 @@ rel_push_join(mvc *sql, sql_rel *rel, sq
(!is_select(lrel->op) &&
!(is_semi(lrel->op) && !rel_is_ref(lrel->l)) &&
lrel->op != op_join &&
- lrel->op != op_left))
+ lrel->op != op_left &&
+ !is_graph(lrel->op)))
break;
/* pushing through left head of a left join is allowed
*/
if (lrel->op == op_left && (!ln->next || lrel->l !=
ln->next->data))
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list