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