Changeset: 20183131a788 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=20183131a788
Modified Files:
        sql/backends/monet5/rel_bin.c
        sql/backends/monet5/sql_statement.c
        sql/backends/monet5/sql_statement.h
        sql/server/rel_graph.c
        sql/server/rel_optimizer.c
Branch: graph0
Log Message:

CODEGEN: generate the instructions to retrieve a shortest path


diffs (truncated from 411 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
@@ -4809,7 +4809,7 @@ rel2bin_graph(backend *be, sql_rel* rel,
        list *lst1 = NULL; // temporary list
        int spfw_flags = 0; // spfw flags
        stmt *query = NULL; // query parameters
-       stmt *weights = NULL; // input columns to generate the weights
+       stmt *shortest_paths = NULL; // input columns to generate the weights & 
the list of attributes for the paths
        stmt *spfw = NULL; // shortest path operator
 
        // avoid to deal with the virtual OIDs (VOID) type, they are just an
@@ -4817,8 +4817,7 @@ rel2bin_graph(backend *be, sql_rel* rel,
        // for more extreme cases
 #define void2oid(statement) stmt_gr8_void2oid(be, statement)
 
-       // debugging
-       printf("[rel2bin_graph] input: %s\n", dump_rel(sql, rel));
+//     printf("[rel2bin_graph] input: %s\n", dump_rel(sql, rel)); // DEBUG ONLY
 
        // first construct the depending relations
        left = subrel_bin(be, rel->l, refs);
@@ -4908,30 +4907,51 @@ rel2bin_graph(backend *be, sql_rel* rel,
                }
        } while(0);
 
-       // weights
+       // weights & paths
        lst1 = sa_list(sql->sa);
-       for(node *n = graph_ptr->spfw->h; n; n = n->next){
+       for(node* n = graph_ptr->spfw->h; n; n = n->next){
                sql_exp* e = n->data;
-               stmt *s = NULL;
-
-               if(!exp_is_atom(e)){ // no need to generate a weight for a bfs
-                       s = exp_bin(be, e, edges, NULL, NULL, NULL, NULL, NULL);
-                       assert(s != NULL && "Weight expression is NULL");
-                       if(!s) return NULL;
+               stmt* s = NULL;
+               if(e->flag & GRAPH_EXPR_COST){
+                       if(!exp_is_atom(e)){ // no need to generate a weight 
for a bfs
+                               s = exp_bin(be, e, edges, NULL, NULL, NULL, 
NULL, NULL);
+                               assert(s != NULL && "Weight expression is 
NULL");
+                               if(!s) return NULL;
+                       } else {
+                               s = stmt_none(be);
+                       }
+                       s->flag |= GRAPH_EXPR_COST;
+               } else if (e->flag & GRAPH_EXPR_SHORTEST_PATH){
+                       list* arguments = e->l;
+                       list* attributes = sa_list(sql->sa);
+
+                       assert(e->type == e_aggr && "Expecting SYS.NEST");
+                       for(node* m = arguments->h; m; m = m->next){
+                               sql_exp* me = m->data;
+                               stmt* ms = exp_bin(be, me, edges, NULL, NULL, 
NULL, NULL, NULL);
+                               if(!ms) return NULL; // error
+                               list_append(attributes, ms);
+                       }
+                       assert(list_length(attributes) > 0);
+                       s = stmt_list(be, attributes);
+                       s->flag |= GRAPH_EXPR_SHORTEST_PATH;
+               } else {
+                       assert(0 && "Invalid expression type");
+                       return NULL;
                }
-
+               assert(s != NULL);
                list_append(lst1, s);
        }
-       weights = stmt_list(be, lst1); lst1 = NULL;
+       shortest_paths = stmt_list(be, lst1); lst1 = NULL;
 
        // invoke the spfw operator
-       spfw = stmt_gr8_spfw(be, query, edge_src, edge_dst, weights, 
spfw_flags);
+       spfw = stmt_gr8_spfw(be, query, edge_src, edge_dst, shortest_paths, 
spfw_flags);
 
        // finally project back the result
        lst1 = sa_list(sql->sa);
        do { // restrict the scope
                stmt *jl = NULL, *jr = NULL;
-               int cost_index = 2;
+               int op_out_index = 2;
 
                // start with the lhs
                jl = stmt_result(be, spfw, 0);
@@ -4958,13 +4978,21 @@ rel2bin_graph(backend *be, sql_rel* rel,
                        }
                }
 
-               // append the computed costs
-               for(node* n = graph_ptr->spfw->h; n; n = n->next){
+               // append the computed costs & paths
+               assert(list_length(graph_ptr->spfw) == 
list_length(shortest_paths->op4.lval));
+               for(node *n = graph_ptr->spfw->h, *m = 
shortest_paths->op4.lval->h; n; n = n->next, m = m->next){
                        sql_exp* e = n->data;
-                       stmt* s = stmt_result(be, spfw, cost_index);
+                       stmt* s = stmt_result(be, spfw, op_out_index);
                        stmt* c = stmt_alias(be, s, exp_relname(e), 
exp_name(e));
+
+                       // in case of a path to compute, we need to record the 
associated attributes of the nested table
+                       if(e->flag & GRAPH_EXPR_SHORTEST_PATH){
+                               stmt* attributes = m->data;
+                               s->op4.lval = attributes->op4.lval; // 
stmt_result
+                       }
+
                        list_append(lst1, c);
-                       cost_index++;
+                       op_out_index++;
                }
        } while (0);
 
@@ -5102,7 +5130,7 @@ output_rel_bin(backend *be, sql_rel *rel
        int sqltype = sql->type;
        stmt *s = subrel_bin(be, rel, refs);
 
-       printf("[output_rel_bin] %s\n", mal2str(be->mb, 0, be->mb->stop));
+//     printf("[output_rel_bin] %s\n", mal2str(be->mb, 0, be->mb->stop));
 
        if (sqltype == Q_SCHEMA)
                sql->type = sqltype;  /* reset */
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
@@ -19,6 +19,8 @@
 #include "mal_debugger.h"
 #include "opt_prelude.h"
 
+#include "nested_table.h"
+
 #include <stdio.h>
 #include <string.h>
 
@@ -2875,8 +2877,8 @@ stmt *stmt_unnest(backend *be, stmt *nes
        stmt* s = NULL;
 
        q = newStmt(be->mb, "nestedtable", "unnest1");
-       getArg(q, 0) = newTmpVariable(be->mb, TYPE_bat);
-       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat));
+       getArg(q, 0) = newTmpVariable(be->mb, newBatType(TYPE_oid));
+       q = pushReturn(be->mb, q, newTmpVariable(be->mb, newBatType(TYPE_oid)));
        assert(nested_attribute != NULL && nested_attribute->nr > 0);
        q = pushArgument(be->mb, q, nested_attribute->nr);
 
@@ -3523,8 +3525,17 @@ list *list_nested_attributes(stmt* st){
                return list_nested_attributes(st->op2);
        case st_convert:
                return NULL;
+       case st_gr8_concat:
+               if(list_length(st->op4.lval)){
+                       // assume all concatenated columns refer to the same 
table expressions
+                       return list_nested_attributes(st->op4.lval->h->data);
+               } else {
+                       return NULL;
+               }
        case st_join: // projection
                return st->op4.lval;
+       case st_result: // rel2bin_graph records the attributes in the output 
column
+               return st->op4.lval;
        case st_temp:
                return NULL;
        case st_bat: // implies storage
@@ -3535,7 +3546,7 @@ list *list_nested_attributes(stmt* st){
        case st_var: // implies storage
                return NULL;
        default:
-//             assert(0 && "Statement type not handled");
+               assert(0 && "Statement type not handled");
                fprintf(stderr, "[list_nested_attributes] Statement type not 
handled: %d\n", st->type);
        }
 
@@ -3715,7 +3726,7 @@ stmt_gr8_intersect_join_lists(backend *b
 
 
 stmt *
-stmt_gr8_spfw(backend *be, stmt *query, stmt *edge_from, stmt *edge_to, stmt 
*weights, int global_flags) {
+stmt_gr8_spfw(backend *be, stmt *query, stmt *edge_from, stmt *edge_to, stmt 
*shortest_paths, int global_flags) {
        InstrPtr q = NULL;
        stmt *s = NULL;
        int num_output_cols = 2; // number of output columns from the operator
@@ -3724,10 +3735,10 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        // Validate the input parameters
        assert(query->type == st_list && "Invalid parameter type");
        assert(list_length(query->op4.lval) == 4 && "Expected 4 input 
parameters: left & right candidate ids, left & right vertex ids");
-       assert(weights->type == st_list && "Invalid parameter type");
+       assert(shortest_paths->type == st_list && "Invalid parameter type");
 
        // prepare the query
-       mnstr_printf(stream, "<spfw from='codegen'>\n");
+       mnstr_printf(stream, "<spfw author='codegen'>\n");
 
        // is this a join?
        if(global_flags & SPFW_JOIN){
@@ -3744,11 +3755,26 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        q = newStmt(be->mb, "graph", "spfw");
        if(q == NULL) return NULL; // error
        // output values
-       getArg(q, 0) = newTmpVariable(be->mb, TYPE_bat); // left candidate list
-       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat)); // right 
candidate list
+       getArg(q, 0) = newTmpVariable(be->mb, newBatType(TYPE_oid)); // left 
candidate list
+       q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(TYPE_oid))); // right candidate list
        // add the shortest paths
-       for(node *n = weights->op4.lval->h; n; n = n->next){
-               q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat));
+       for(node *n = shortest_paths->op4.lval->h; n; n = n->next){ // cost or 
path
+               // find the type of the returned bat
+               stmt* s0 = n->data;
+               int ret_type = -1;
+               if(s0->flag & GRAPH_EXPR_COST){
+                       if(s0->type == st_none){ // bfs
+                               ret_type = TYPE_lng;
+                       } else {
+                               ret_type = tail_type(s0)->type->localtype;
+                       }
+               } else if (s0->flag & GRAPH_EXPR_SHORTEST_PATH){
+                       ret_type = TYPE_nested_table;
+               } else {
+                       assert(0 && "Invalid expression");
+               }
+
+               q = pushReturn(be->mb, q, newTmpVariable(be->mb, 
newBatType(ret_type)));
                num_output_cols++;
        }
 
@@ -3760,8 +3786,10 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        }
        EVIL_PUSH(edge_from);
        EVIL_PUSH(edge_to);
-       for(node *n = weights->op4.lval->h; n; n = n->next){ // weights
-               EVIL_PUSH(n->data);
+       for(node *n = shortest_paths->op4.lval->h; n; n = n->next){ // weights
+               stmt* s = n->data;
+               if (!(s->flag & GRAPH_EXPR_COST)) continue;
+               EVIL_PUSH(s); // nil if we need a bfs
        }
 
 #undef EVIL_PUSH
@@ -3786,14 +3814,29 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        do {
                int ret_spfw = 2; // 0 = jl, 1 = jr
                int arg_spfw = q->retc + 7;
+               node* n = shortest_paths->op4.lval->h;
 
                mnstr_printf(stream, "\t<subexpr>\n");
 
-               for(node *n = weights->op4.lval->h; n; n = n->next){
+               while(n){
+                       stmt* stmt_weight = n->data;
+                       bool compute_path = false;
+
+                       assert(stmt_weight->flag & GRAPH_EXPR_COST);
+                       n = n->next;
+                       if(n && (((stmt*) n->data)->flag & 
GRAPH_EXPR_SHORTEST_PATH)){
+                               compute_path = true;
+                               n = n->next;
+                       }
+
                        mnstr_printf(stream, "\t\t<shortest_path>\n");
-                       mnstr_printf(stream, "\t\t\t<column name='output' 
pos='%d' />\n", ret_spfw++);
-                       if(n->data) // weighted shortest path?
-                               mnstr_printf(stream, "\t\t\t<column 
name='weights' pos='%d' />\n", arg_spfw);
+                       mnstr_printf(stream, "\t\t\t<column name='out_cost' 
pos='%d' />\n", ret_spfw++);
+                       if(compute_path){ // retrieve the paths?
+                               mnstr_printf(stream, "\t\t\t<column 
name='out_path' pos='%d' />\n", ret_spfw++);
+                       }
+                       if(stmt_weight && stmt_weight->type != st_none) { // 
weighted shortest path?
+                               mnstr_printf(stream, "\t\t\t<column 
name='in_weights' pos='%d' />\n", arg_spfw);
+                       }
                        arg_spfw++; // increment anyway as we are pushing a 
dummy argument as nil if this is BFS
                        mnstr_printf(stream, "\t\t</shortest_path>\n");
                }
@@ -3801,7 +3844,6 @@ stmt_gr8_spfw(backend *be, stmt *query, 
                mnstr_printf(stream, "\t</subexpr>\n");
        } while (0);
 
-
        // save the query description
        do {
                char *spfw_argument_buffer = NULL;
@@ -3819,7 +3861,6 @@ stmt_gr8_spfw(backend *be, stmt *query, 
                record_ptr = defConstant(be->mb, TYPE_str, &record);
                q->argv[q->retc] = record_ptr;
 
-
                free(spfw_argument_buffer);
                mnstr_destroy(stream); stream = NULL;
        } while(0);
@@ -3831,7 +3872,7 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        s->flag = global_flags;
        s->op1 = query;
        s->op2 = stmt_list(be, append(append(sa_list(be->mvc->sa), edge_from), 
edge_to));
-       s->op3 = weights;
+       s->op3 = shortest_paths;
        // just required >= 1 to avoid projecting a column out of a constant 
when looking
        // for the shortest paths
        s->nrcols = num_output_cols; /* = i*/
diff --git a/sql/backends/monet5/sql_statement.h 
b/sql/backends/monet5/sql_statement.h
--- a/sql/backends/monet5/sql_statement.h
+++ b/sql/backends/monet5/sql_statement.h
@@ -248,7 +248,7 @@ extern stmt *stmt_gr8_concat(backend *be
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to