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

SEMA/CODEGEN: compute a BFS in case a constant weight has been specified


diffs (130 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
@@ -4817,9 +4817,13 @@ rel2bin_graph(backend *be, sql_rel* rel,
        lst1 = sa_list(sql->sa);
        for(node *n = graph_ptr->spfw->h; n; n = n->next){
                sql_exp* e = n->data;
-               stmt* 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(!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;
+               }
 
                list_append(lst1, s);
        }
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
@@ -3690,7 +3690,7 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        }
 
        // I can use macros too..
-#define EVIL_PUSH(S) if (((stmt*) (S))->type == st_none ) { q = 
pushNil(be->mb, q, TYPE_bat); } \
+#define EVIL_PUSH(S) if ( (S) == NULL || ((stmt*) (S))->type == st_none ) { q 
= pushNil(be->mb, q, TYPE_bat); } \
                else if(((stmt*)S)->nr < 0) { return NULL; } else { q = 
pushArgument(be->mb, q, ((stmt*) S)->nr); }
 
        // generate the MAL instruction
@@ -3735,7 +3735,6 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        mnstr_printf(stream, "\t\t<column name='dst' pos='%d' />\n", q->retc 
+6);
        mnstr_printf(stream, "\t</graph>\n");
 
-
        // spfw
        do {
                int ret_spfw = 2; // 0 = jl, 1 = jr
@@ -3746,7 +3745,9 @@ stmt_gr8_spfw(backend *be, stmt *query, 
                for(node *n = weights->op4.lval->h; n; 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++);
-                       mnstr_printf(stream, "\t\t\t<column name='weights' 
pos='%d' />\n", arg_spfw++);
+                       if(n->data) // weighted shortest path?
+                               mnstr_printf(stream, "\t\t\t<column 
name='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");
                }
 
diff --git a/sql/common/sql_types.c b/sql/common/sql_types.c
--- a/sql/common/sql_types.c
+++ b/sql/common/sql_types.c
@@ -905,8 +905,11 @@ sql_bind_func_(sql_allocator *sa, sql_sc
                if (f->type != type && f->type != filt) 
                        continue;
                if (strcmp(f->base.name, sqlfname) == 0) {
-                       if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 
0) 
+                       printf("match %s\n", f->base.name);
+                       if (list_cmp(f->ops, ops, (fcmp) &arg_subtype_cmp) == 
0) {
+                               printf("found\n");
                                return sql_dup_subfunc(sa, f, ops, NULL);
+                       }
                }
        }
        if (s) {
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
@@ -184,7 +184,7 @@ static sql_exp* bind_cheapest_sum_graph(
        const char* table_ref = NULL; // the table referred (optional)
        symbol* expr_weight = NULL; // the expression inside CHEAPEST SUM ( ... 
);
        sql_rel* edges = NULL; // the table expression representing the edges
-       sql_exp* e = NULL; // the final result
+       sql_exp* e = NULL; // the expression being bound
        exp_kind exp_kind_value = {type_value, card_column, TRUE}; // 
rel_value_exp parameters
 
        // init
@@ -205,6 +205,14 @@ static sql_exp* bind_cheapest_sum_graph(
 
        if(e){ // success
                node* duplicate = NULL;
+               sql_exp* bound_exp = e; // the resulting expression
+               bool is_bfs = false; // is this a BFS?
+
+               // if this is an atom, then perform a simple BFS and multiply 
the final result by the original atom
+               if(exp_is_atom(e)){
+                       e = exp_atom_lng(sql->sa, 1); // whatever value or 
type, the important part for the codegen is that this is an atom
+                       is_bfs = true;
+               }
 
                // before creating a new spfw, search for duplicates in the 
list of expressions
                // already registered
@@ -219,7 +227,34 @@ static sql_exp* bind_cheapest_sum_graph(
                        e = duplicate->data;
                }
 
-               return exp_column(sql->sa, exp_relname(e), exp_name(e), 
exp_subtype(e), graph->relation.card, /* has_nil = */ FALSE, /* is_intern = */ 
FALSE);
+               e = exp_column(sql->sa, exp_relname(e), exp_name(e), 
exp_subtype(e), graph->relation.card, /* has_nil = */ FALSE, /* is_intern = */ 
FALSE);
+
+               // if this is a bfs, we need to multiply the result by the 
actual value
+               if(is_bfs){
+                       sql_subfunc* f_mult = NULL;
+
+                       // cast the result to the expected type
+                       if(type_cmp(exp_subtype(e)->type, 
exp_subtype(bound_exp)->type) != 0 /* 0 = same type */){
+                               sql_type* e_t = exp_subtype(e)->type;
+                               sql_type* bound_exp_t = 
exp_subtype(bound_exp)->type;
+                               // currently a bfs returns a lng, so cast to 
lng unless it is even bigger
+                               if(bound_exp_t->eclass == EC_NUM && 
bound_exp_t->digits < e_t->digits) {
+                                       bound_exp = exp_convert(sql->sa, 
bound_exp, exp_subtype(bound_exp), exp_subtype(e));
+                               } else {
+                                       e = exp_convert(sql->sa, e, 
exp_subtype(e), exp_subtype(bound_exp));
+                               }
+                       }
+
+                       f_mult = sql_bind_func(sql->sa, /*mvc_bind_schema(sql, 
"sys")*/ NULL, "sql_mul", exp_subtype(bound_exp), exp_subtype(e), F_FUNC);
+                       assert(f_mult != NULL && "Cannot bind the multiply 
function");
+                       bound_exp = exp_binop(sql->sa, bound_exp, e, f_mult);
+               } else {
+                       // the result is the actual column computed by the spfw 
operator => weighted shortest path
+                       bound_exp = e;
+               }
+
+               return bound_exp;
+
        } else { // nope
                return NULL; // == e
        }
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to