Changeset: de4f281c8d0a for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=de4f281c8d0a
Modified Files:
        sql/include/sql_relation.h
        sql/server/rel_optimizer.c
Branch: graph0
Log Message:

QRW: adapt the `rel_push_func_down' rule for the graph op~


diffs (217 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
@@ -235,6 +235,8 @@ typedef enum operator_type {
        (is_select(op) || op == op_graph_select)
 #define is_extended_join(op) \
        (is_join(op) || op == op_graph_join)
+#define is_extended_joinop(op) \
+       (is_joinop(op) || op == op_graph_join)
 
 /* NO NIL semantics of aggr operations */
 #define need_no_nil(e) \
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
@@ -1764,8 +1764,28 @@ can_push_func(sql_exp *e, sql_rel *rel, 
                (*must) |= lmust;
                return res;
        }
+       case e_graph: {
+               list* ll = e->l;
+               list* lr = e->r;
+               int mustg = 0;
+               int result = 0;
+
+               // lhs
+               for(node* n = ll->h; n; n = n->next){
+                       result |= can_push_func(n->data, rel, &mustg);
+                       *must |= mustg;
+               }
+
+               // rhs
+               for(node* n = lr->h; n; n = n->next){
+                       result |= can_push_func(n->data, rel, &mustg);
+                       *must |= mustg;
+               }
+
+               return result;
+       } break;
        case e_column:
-               if (rel && !rel_find_exp(rel, e)) 
+               if (rel && !rel_find_exp(rel, e))
                        return 0;
                (*must) = 1;
        case e_atom:
@@ -1783,15 +1803,18 @@ exps_can_push_func(list *exps, sql_rel *
                sql_exp *e = n->data;
                int must = 0, mustl = 0, mustr = 0;
 
-               if (is_joinop(rel->op) && ((can_push_func(e, rel->l, &mustl) && 
mustl) || (can_push_func(e, rel->r, &mustr) && mustr)))
+               if (is_extended_joinop(rel->op) && ((can_push_func(e, rel->l, 
&mustl) && mustl) || (can_push_func(e, rel->r, &mustr) && mustr)))
                        return 1;
-               else if (is_select(rel->op) && can_push_func(e, NULL, &must) && 
must)
+               else if (is_extended_select(rel->op) && can_push_func(e, NULL, 
&must) && must)
                        return 1;
        }
        return 0;
 }
 
 static int
+exps_need_push_down( list *exps );
+
+static int
 exp_needs_push_down(sql_exp *e)
 {
        if (!e)
@@ -1806,6 +1829,8 @@ exp_needs_push_down(sql_exp *e)
        case e_aggr: 
        case e_func: 
                return 1;
+       case e_graph:
+               return exps_need_push_down(e->l) || exps_need_push_down(e->r);
        case e_column:
        case e_atom:
        default:
@@ -1823,13 +1848,39 @@ exps_need_push_down( list *exps )
        return 0;
 }
 
+static sql_exp*
+rel_push_func_down_graph_exp(int *changes, mvc *sql, sql_rel* subrel, sql_exp* 
e){
+       sql_exp* ne = e;
+       int must = 0;
+
+       assert(e->type != e_graph);
+       assert(subrel && is_project(subrel->op));
+
+       if (exp_needs_push_down(e) && can_push_func(e, subrel, &must) && must){
+               exp_label(sql->sa, e, ++sql->label);
+               list_append(subrel->exps, e);
+               ne = exp_column(sql->sa, exp_relname(e), exp_name(e), 
exp_subtype(e), e->card, has_nil(e), is_intern(e));
+               (*changes)++;
+       }
+
+       return ne;
+}
+
+static void
+rel_push_func_down_graph_list(int *changes, mvc *sql, sql_rel* subrel, list* 
l){
+       if(subrel == NULL || l == NULL) return;
+       for(node *n = l->h; n; n = n->next){
+               n->data = rel_push_func_down_graph_exp(changes, sql, subrel, 
n->data);
+       }
+}
+
 static sql_rel *
 rel_push_func_down(int *changes, mvc *sql, sql_rel *rel) 
 {
-       if ((is_select(rel->op) || is_joinop(rel->op)) && rel->l && rel->exps 
&& !(rel_is_ref(rel))) {
+       if ((is_select(rel->op) || is_joinop(rel->op) || is_graph(rel->op)) && 
rel->l && rel->exps && !(rel_is_ref(rel))) {
                list *exps = rel->exps;
 
-               if (is_select(rel->op) &&  list_length(rel->exps) <= 1)  /* 
only push down when thats useful */
+               if (is_select(rel->op) && list_length(rel->exps) <= 1)  /* only 
push down when thats useful */
                        return rel;
                if (exps_can_push_func(exps, rel) && exps_need_push_down(exps)) 
{
                        sql_rel *nrel;
@@ -1845,7 +1896,7 @@ rel_push_func_down(int *changes, mvc *sq
                                rel->l = l = rel_project(sql->sa, l, 
                                        rel_projections(sql, l, NULL, 1, 1));
                        }
-                       if (is_joinop(rel->op) && r->op != op_project) {
+                       if (is_extended_joinop(rel->op) && r->op != op_project) 
{
                                if (is_subquery(r))
                                        return rel;
                                rel->r = r = rel_project(sql->sa, r, 
@@ -1858,10 +1909,24 @@ rel_push_func_down(int *changes, mvc *sq
 
                                if (e->type == e_column)
                                        continue;
-                               if ((is_joinop(rel->op) && ((can_push_func(e, 
l, &mustl) && mustl) || (can_push_func(e, r, &mustr) && mustr))) ||
-                                   (is_select(rel->op) && can_push_func(e, 
NULL, &must) && must)) {
+                               if ((is_extended_joinop(rel->op) && 
((can_push_func(e, l, &mustl) && mustl) || (can_push_func(e, r, &mustr) && 
mustr))) ||
+                                   (is_extended_select(rel->op) && 
can_push_func(e, NULL, &must) && must)) {
                                        must = 0; mustl = 0; mustr = 0;
-                                       if (e->type != e_cmp) { /* predicate */
+                                       if(is_graph(rel->op)){
+                                               sql_exp *e = NULL;
+
+                                               // init
+                                               assert(list_length(rel->exps) 
== 1);
+                                               e = rel->exps->h->data;
+                                               assert(e->type == e_graph && 
"Unexpected expression type for the graph op.");
+
+                                               // lhs
+                                               
rel_push_func_down_graph_list(changes, sql, l, e->l);
+                                               
rel_push_func_down_graph_list(changes, sql, l, e->r);
+                                               // rhs
+                                               
rel_push_func_down_graph_list(changes, sql, r, e->l);
+                                               
rel_push_func_down_graph_list(changes, sql, r, e->r);
+                                       } else if (e->type != e_cmp) { /* 
predicate */
                                                if ((is_joinop(rel->op) && 
((can_push_func(e, l, &mustl) && mustl) || (can_push_func(e, r, &mustr) && 
mustr))) ||
                                                    (is_select(rel->op) && 
can_push_func(e, NULL, &must) && must)) {
                                                        exp_label(sql->sa, e, 
++sql->label);
@@ -1932,7 +1997,7 @@ rel_push_func_down(int *changes, mvc *sq
        if (rel->op == op_project && rel->l && rel->exps) {
                sql_rel *pl = rel->l;
 
-               if (is_joinop(pl->op) && exps_can_push_func(rel->exps, rel)) {
+               if (is_extended_joinop(pl->op) && exps_can_push_func(rel->exps, 
rel)) {
                        node *n;
                        sql_rel *l = pl->l, *r = pl->r;
                        list *nexps;
@@ -1943,7 +2008,7 @@ rel_push_func_down(int *changes, mvc *sq
                                pl->l = l = rel_project(sql->sa, l, 
                                        rel_projections(sql, l, NULL, 1, 1));
                        }
-                       if (is_joinop(rel->op) && r->op != op_project) {
+                       if (is_extended_joinop(rel->op) && r->op != op_project) 
{
                                if (is_subquery(r))
                                        return rel;
                                pl->r = r = rel_project(sql->sa, r, 
@@ -6343,8 +6408,6 @@ rel_remove_unused(mvc *sql, sql_rel *rel
                sql_graph* graph_ptr = (sql_graph*) rel;
                bool needed = false;
 
-               printf("remove unused\n");
-
                // do we need to remove any of the attributes?
                for(node* n = graph_ptr->spfw->h; n && !needed; n = n->next){
                        sql_exp* e = n->data;
@@ -9063,8 +9126,8 @@ rel_graph_pda(int *changes, mvc *sql, sq
                bool pda_lhs = true; // otherwise go to the right
 
                // can we push down to the lhs or rhs of the join?
-               bool left = r->op == op_join || r->op == op_left || r->op == 
op_graph_join || r->op == op_graph_select;
-               bool right = r->op == op_join || r->op == op_right || r->op == 
op_graph_join;
+               bool left = target->op == op_join || target->op == op_left || 
target->op == op_graph_join || target->op == op_graph_select;
+               bool right = target->op == op_join || target->op == op_right || 
target->op == op_graph_join;
 
                // push down to the lhs
                if (left){
@@ -9316,6 +9379,8 @@ static sql_rel *
        bool graph_operators = false;
        global_props gp; 
 
+       printf("[Optimizer] (%d) Input: %s\n", level, dump_rel(sql, rel));
+
        memset(&gp, 0, sizeof(global_props));
        rel_properties(sql, &gp, rel);
 
@@ -9468,7 +9533,7 @@ static sql_rel *
                rel = rel_dce(sql, rel);
 
        if (gp.cnt[op_join] || gp.cnt[op_left] || gp.cnt[op_right] || 
gp.cnt[op_full] || 
-           gp.cnt[op_semi] || gp.cnt[op_anti] || gp.cnt[op_select]) {
+           gp.cnt[op_semi] || gp.cnt[op_anti] || gp.cnt[op_select] || 
graph_operators) {
                rel = rewrite(sql, rel, &rel_push_func_down, &changes);
                rel = rewrite_topdown(sql, rel, &rel_push_select_down, 
&changes); 
                rel = rewrite(sql, rel, &rel_remove_empty_select, &e_changes); 
@@ -9497,6 +9562,5 @@ static sql_rel *
 sql_rel *
 rel_optimizer(mvc *sql, sql_rel *rel) 
 {
-       printf("[Optimizer] Input: %s\n", dump_rel(sql, rel));
        return _rel_optimizer(sql, rel, 0);
 }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to