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

CODEGEN: adapted (more or less) the previous implementation for the
graph predicates


diffs (truncated from 544 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
@@ -24,6 +24,7 @@ static stmt * exp_bin(backend *be, sql_e
 static stmt * rel_bin(backend *be, sql_rel *rel);
 static stmt * subrel_bin(backend *be, sql_rel *rel, list *refs);
 
+
 static stmt *
 refs_find_rel(list *refs, sql_rel *rel)
 {
@@ -1584,11 +1585,10 @@ join_hash_key( backend *be, list *l )
        return h;
 }
 
+
+// do not project the result back
 static stmt *
-releqjoin( backend *be, list *l1, list *l2, int used_hash, comp_type cmp_op, 
int need_left )
-{
-       mvc *sql = be->mvc;
-       node *n1 = l1->h, *n2 = l2->h;
+releqjoin_( backend *be, list *l1, list *l2, int used_hash, comp_type cmp_op, 
int need_left ){
        stmt *l, *r, *res;
 
        if (list_length(l1) <= 1) {
@@ -1600,18 +1600,32 @@ releqjoin( backend *be, list *l1, list *
                return r;
        }
        if (used_hash) {
-               l = n1->data;
-               r = n2->data;
-               n1 = n1->next;
-               n2 = n2->next;
+               l = l1->h->data;
+               r = l2->h->data;
                res = stmt_join(be, l, r, 0, cmp_op);
        } else { /* need hash */
                l = join_hash_key(be, l1);
                r = join_hash_key(be, l2);
                res = stmt_join(be, l, r, 0, cmp_op);
        }
-       if (need_left) 
+       if (need_left)
                res->flag = cmp_left;
+
+       return res;
+}
+
+static stmt *
+releqjoin( backend *be, list *l1, list *l2, int used_hash, comp_type cmp_op, 
int need_left )
+{
+       mvc *sql = be->mvc;
+       node *n1 = l1->h, *n2 = l2->h;
+       stmt *l, *r, *res;
+
+       if (used_hash) {
+               n1 = n1->next;
+               n2 = n2->next;
+       }
+       res = releqjoin_(be, l1, l2, used_hash, cmp_op, need_left);
        l = stmt_result(be, res, 0);
        r = stmt_result(be, res, 1);
        for (; n1 && n2; n1 = n1->next, n2 = n2->next) {
@@ -4701,8 +4715,24 @@ rel2bin_ddl(backend *be, sql_rel *rel, l
 static stmt *
 rel2bin_graph(backend *be, sql_rel* rel, list *refs)
 {
+       mvc* sql = be->mvc; // query control block
        sql_graph* graph_ptr = (sql_graph*) rel;
        stmt *left = NULL, *right = NULL, *edges = NULL; // depending relations
+       stmt *codomain = NULL; // oids for the graph (vertices ids)
+       stmt *candidate_ids = NULL;
+       list *domain_list = sa_list(sql->sa); // the list of attributes that 
define the domain (A, B, ...)
+       stmt *edge_src = NULL, *edge_dst = NULL; // column of oids representing 
the src/dst of the edges
+       stmt *tmp1 = NULL; // temporary value
+       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 *spfw = NULL; // shortest path operator
+
+       // avoid to deal with the virtual OIDs (VOID) type, they are just an
+       // optimisation, unlikely to be useful for the the edge tables but
+       // for more extreme cases
+#define void2oid(statement) stmt_gr8_void2oid(be, statement)
 
        // first construct the depending relations
        left = subrel_bin(be, rel->l, refs);
@@ -4714,9 +4744,143 @@ rel2bin_graph(backend *be, sql_rel* rel,
        edges = subrel_bin(be, graph_ptr->edges, refs);
        if(!edges) return NULL; // error
 
-
-
-       return NULL;
+       // find the co-domain (set)
+       // use the union of both of efrom & eto as list values for the co-domain
+       // alternatively iff there was a FK both efrom/eto to a PK somewhere 
else, we could have used that PK
+       assert(list_length(graph_ptr->efrom) > 0 && 
list_length(graph_ptr->efrom) == list_length(graph_ptr->eto));
+       for(node *n = graph_ptr->efrom->h, *m = graph_ptr->eto->h; n && m; n = 
n->next, m = m->next){
+               stmt *s0 = NULL, *s1 = NULL; // efrom, eto
+               stmt *values = NULL; // efrom U eto
+               stmt *groupby = NULL;
+
+               s0 = exp_bin(be, n->data, edges, NULL, NULL, NULL, NULL, NULL);
+               if(!s0) return NULL;
+               s1 = exp_bin(be, m->data, edges, NULL, NULL, NULL, NULL, NULL);
+               if(!s1) return NULL;
+               values = stmt_gr8_concat(be, 
list_append(list_append(sa_list(sql->sa), s0), s1));
+               list_append(domain_list, values);
+
+               groupby = stmt_group(be, values, codomain, candidate_ids, NULL, 
!n->next);
+               codomain = stmt_result(be, groupby, 0);
+               candidate_ids = stmt_result(be, groupby, 1);
+       }
+       // the elements in the co-domain are the group ids (0, 1, 2, 3, etc...)
+
+       // find the domain
+       for(node *n = domain_list->h; n; n = n->next){
+               stmt* values = n->data;
+               n->data = stmt_project(be, candidate_ids, values);
+       }
+
+       // generate the source / destination edges
+       tmp1 = stmt_gr8_slices(be, codomain, 2);
+       edge_src = void2oid(stmt_result(be, tmp1, 0));
+       edge_dst = void2oid(stmt_result(be, tmp1, 1));
+
+       // translate the query attributes (qfrom/qto) into the OIDs of the 
domain
+       do { // limit the *** scope
+               // start with the left hand side
+               sql_exp* graph_exp = rel->exps->h->data;
+               list *lhs = sa_list(sql->sa), *rhs = sa_list(sql->sa);
+               stmt *join_left = NULL, *join_right = NULL;
+
+               assert(graph_exp->type == e_graph && list_length(graph_exp->l) 
== list_length(domain_list)
+                               && list_length(graph_exp->l) == 
list_length(graph_exp->r));
+               // start with the lhs
+               for(node *n = ((list*)graph_exp->l)->h; n; n = n->next){
+                       // right might be null, that's ok
+                       stmt* s = exp_bin(be, n->data, left, right, NULL, NULL, 
NULL, NULL);
+                       if(!s) return NULL; // error
+                       list_append(lhs, s);
+               }
+               // repeat for the rhs
+               for(node *n = ((list*)graph_exp->r)->h; n; n = n->next){
+                       stmt* s = exp_bin(be, n->data, left, right, NULL, NULL, 
NULL, NULL);
+                       if(!s) return NULL; // error
+                       list_append(rhs, s);
+               }
+
+               // join the attributes
+               join_left = releqjoin_(be, lhs, domain_list, /*used_hash = */ 
false, cmp_equal, /* need_left = */ rel->op == op_graph_select);
+               join_right = releqjoin_(be, rhs, domain_list, /*used_hash = */ 
false, cmp_equal, /* need_left = */ rel->op == op_graph_select);
+
+               // generate the query parameters
+               lst1 = sa_list(sql->sa);
+               list_append(lst1, void2oid(stmt_result(be, join_left, 0)));
+               list_append(lst1, void2oid(stmt_result(be, join_right, 0)));
+               list_append(lst1, void2oid(stmt_result(be, join_left, 1)));
+               list_append(lst1, void2oid(stmt_result(be, join_right, 1)));
+               query = stmt_list(be, lst1); lst1 = NULL;
+
+               // remove the items that are not part of the domain
+               if(rel->op == op_graph_select){
+                       query = stmt_gr8_remove_nils(be, query);
+               }
+
+               if(rel->op == op_graph_join)
+                       spfw_flags |= SPFW_JOIN;
+       } while(0);
+
+       // weights
+       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);
+               if(!s) return NULL;
+
+               list_append(lst1, s);
+       }
+       weights = stmt_list(be, lst1); lst1 = NULL;
+
+       // invoke the spfw operator
+       spfw = stmt_gr8_spfw(be, query, edge_src, edge_dst, weights, 
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;
+
+               // start with the lhs
+               jl = stmt_result(be, spfw, 0);
+               for(node* n = left->op4.lval->h; n; n = n->next ) {
+                       stmt *c = n->data;
+                       const char *rnme = table_name(sql->sa, c);
+                       const char *nme = column_name(sql->sa, c);
+                       stmt *s = stmt_project(be, jl, column(be, c));
+                       s = stmt_alias(be, s, rnme, nme);
+                       list_append(lst1, s);
+               }
+
+               // repeat with the rhs
+               if(right != NULL) {
+                       assert(rel->op == op_graph_join);
+                       jr = stmt_result(be, spfw, 1);
+                       for(node* n = right->op4.lval->h; n; n = n->next ) {
+                               stmt *c = n->data;
+                               const char *rnme = table_name(sql->sa, c);
+                               const char *nme = column_name(sql->sa, c);
+                               stmt *s = stmt_project(be, jr, column(be, c));
+                               s = stmt_alias(be, s, rnme, nme);
+                               list_append(lst1, s);
+                       }
+               }
+
+               // append the computed costs
+               for(node* n = graph_ptr->spfw->h; n; n = n->next){
+                       sql_exp* e = n->data;
+                       stmt* s = stmt_result(be, spfw, cost_index);
+                       stmt* c = stmt_alias(be, s, exp_relname(e), 
exp_name(e));
+                       list_append(lst1, c);
+                       cost_index++;
+               }
+       } while (0);
+
+       // done
+       return stmt_list(be, lst1);
+
+#undef void2oid
 }
 
 static stmt *
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
@@ -2981,6 +2981,8 @@ tail_type(stmt *st)
                return NULL;
        case st_table:
                return sql_bind_localtype("bat");
+       case st_gr8_void2oid:
+               return sql_bind_localtype("oid");
        default:
                assert(0);
                return NULL;
@@ -3107,6 +3109,11 @@ const char *
                /* fall through */
        case st_rs_column:
                return NULL;
+
+       /* graph related */
+       case st_gr8_void2oid:
+               return column_name(sa, st->op1);
+
        default:
                return NULL;
        }
@@ -3169,6 +3176,10 @@ const char *
                        return table_name(sa, st->op4.lval->h->data);
                return NULL;
 
+       /* graph related */
+       case st_gr8_void2oid:
+               return table_name(sa, st->op1);
+
        case st_var:
        case st_temp:
        case st_single:
@@ -3214,6 +3225,10 @@ schema_name(sql_allocator *sa, stmt *st)
        case st_temp:
        case st_single:
                return NULL;
+       /* graph related */
+       case st_gr8_void2oid:
+               return schema_name(sa, st->op1);
+
        case st_list:
                if (list_length(st->op4.lval))
                        return schema_name(sa, st->op4.lval->h->data);
@@ -3469,3 +3484,218 @@ const_column(backend *be, stmt *val)
        }
        return NULL;
 }
+
+stmt *
+stmt_gr8_concat(backend *be, list *l) {
+       // declarations
+       InstrPtr q = NULL;
+       stmt *s = NULL;
+       node *n = NULL;
+       int ref_cpy = -1;
+       int ref_op = -1;
+       stmt *tmp = NULL;
+
+       // generate the MAL instructions
+       assert(list_length(l) > 0);
+       n = l->h;
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to