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 checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list