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

CODEGEN: select semantics for the graph operator


diffs (294 lines):

diff --git a/monetdb5/mal/mal_listing.c b/monetdb5/mal/mal_listing.c
--- a/monetdb5/mal/mal_listing.c
+++ b/monetdb5/mal/mal_listing.c
@@ -290,13 +290,14 @@ instruction2str(MalBlkPtr mb, MalStkPtr 
        case PATcall:
        case CMDcall:
        case ASSIGNsymbol :
-               // is any variable explicit or used
-               for (i = 0; i < p->retc; i++)
-                       if ( !isTmpVar(mb,getArg(p,i)) || isVarUsed(mb, 
getArg(p, i)) || isVarUDFtype(mb,getArg(p,i)))
-                               break;
-
-               if (i == p->retc)
-                       break;
+               // Dean: for debugging purposes, always show all the assignments
+//             // is any variable explicit or used
+//             for (i = 0; i < p->retc; i++)
+//                     if ( !isTmpVar(mb,getArg(p,i)) || isVarUsed(mb, 
getArg(p, i)) || isVarUDFtype(mb,getArg(p,i)))
+//                             break;
+//
+//             if (i == p->retc)
+//                     break;
 
                /* display multi-assignment list */
                if (p->retc > 1)
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
@@ -1585,23 +1585,26 @@ 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 ){
+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 (list_length(l1) <= 1) {
                l = l1->h->data;
                r = l2->h->data;
-               r =  stmt_join(be, l, r, 0, cmp_op);
+               r =  stmt_join(be, l, r, 0, need_left? cmp_left : cmp_op);
                if (need_left)
                        r->flag = cmp_left;
                return r;
        }
        if (used_hash) {
-               l = l1->h->data;
-               r = l2->h->data;
+               l = n1->data;
+               r = n2->data;
+               n1 = n1->next;
+               n2 = n2->next;
                res = stmt_join(be, l, r, 0, cmp_op);
        } else { /* need hash */
                l = join_hash_key(be, l1);
@@ -1610,22 +1613,6 @@ releqjoin_( backend *be, list *l1, list 
        }
        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) {
@@ -4801,20 +4788,49 @@ rel2bin_graph(backend *be, sql_rel* rel,
                }
 
                // 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
+               join_left = releqjoin(be, lhs, domain_list, /*used_hash = */ 
false, cmp_equal, /* need_left = */ false);
+               join_right = releqjoin(be, rhs, domain_list, /*used_hash = */ 
false, cmp_equal, /* need_left = */ false);
+
+
+               // intersect the two lists, so that we have only the columns 
part of the domain
                if(rel->op == op_graph_select){
-                       query = stmt_gr8_remove_nils(be, query);
+                       stmt *jll = stmt_result(be, join_left, 0);
+                       stmt *jlr = stmt_result(be, join_left, 1);
+                       stmt *jrl = stmt_result(be, join_right, 0);
+                       stmt *jrr = stmt_result(be, join_right, 1);
+
+                       // sort left & right
+                       jll = stmt_order(be, jll, /* direction (0 = DESC, 1 = 
ASC) = */ 1);
+                       jlr = stmt_project(be, stmt_result(be, jll, 1), jlr);
+                       jrl = stmt_order(be, jrl, /* direction (0 = DESC, 1 = 
ASC) = */ 1);
+                       jrr = stmt_project(be, stmt_result(be, jrl, 1), jrr);
+
+                       // remove those damn VOIDs
+                       jll = void2oid(jll);
+                       jlr = void2oid(jlr);
+                       jrl = void2oid(jrl);
+                       jrr = void2oid(jrr);
+
+                       // intersect the elements
+                       lst1 = sa_list(sql->sa);
+                       list_append(lst1, jll);
+                       list_append(lst1, jrl);
+                       list_append(lst1, jlr);
+                       list_append(lst1, jrr);
+                       query = stmt_gr8_intersect_join_lists(be, stmt_list(be, 
lst1));
+                       lst1 = NULL;
+
+               } else { // this is join
+                       assert(rel->op == op_graph_join);
+
+                       // 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;
                }
 
                if(rel->op == op_graph_join)
@@ -4976,6 +4992,7 @@ subrel_bin(backend *be, sql_rel *rel, li
        case op_graph_join:
        case op_graph_select:
                s = rel2bin_graph(be, rel, refs);
+               printf("MAL instruction: %s\n", mal2str(be->mb, 0, 
be->mb->stop));
                break;
        }
        if (s && rel_is_ref(rel)) {
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
@@ -3594,50 +3594,73 @@ stmt_gr8_void2oid(backend *be, stmt *op)
 }
 
 
+static void copy_params(stmt* from, stmt* to){
+       to->op1 = from;
+       to->flag = from->flag;
+       to->nrcols = from->nrcols;
+       to->key = from->key; // maybe
+       to->aggr = from->aggr;
+
+}
+
 // this statement doesn't have a st_type counterpart, i.e. it's a fake 
statement
 stmt*
-stmt_gr8_remove_nils(backend *be, stmt* query){
+stmt_gr8_intersect_join_lists(backend *be, stmt* query){
        InstrPtr q = NULL;
        list* l = NULL;
-       int i = -1;
        int num_operands = -1; // expected 4
 
+
        // generate the MAL instruction
        assert(query->type == st_list && "Invalid input type");
        num_operands = list_length(query->op4.lval);
        assert(num_operands == 4); // candidate list left and right + 
projection list left and right
-       q = newStmt(be->mb, "graph", "remove_nils");
+       q = newStmt(be->mb, "graph", "intersect_join_lists");
        if(!q) return NULL;
+
+       // add the return values
+       getArg(q, 0) = newTmpVariable(be->mb, TYPE_bat); // candidate list
+       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat));
+       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat));
        for(node *n = query->op4.lval->h; n; n = n->next){
                stmt *s = n->data;
                if(s->nr < 0) return NULL; // error
-               pushArgument(be->mb, q, s->nr);
-               pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat));
+               q = pushArgument(be->mb, q, s->nr);
        }
 
        // ABI convention
-       for(int i = 1; i < num_operands; i++) {
+       for(int i = 1; i < num_operands -1; i++) {
                snprintf(be->mb->var[getArg(q, i)]->id, IDLENGTH, "r%d_%d", i, 
getDestVar(q));
        }
 
        // generate the MIL statement
        l = sa_list(be->mvc->sa);
-       i = 0;
-       for(node* n = query->op4.lval->h; n; n = n->next, i++){
-               stmt* r = stmt_create(be->mvc->sa, st_result);
-               r->op1 = n->data;
-               if(i > 0){
-                       r->nr = getArg(q, i);
-               } else {
-                       r->nr = getDestVar(q);
-               }
-               r->flag = r->op1->flag;
-               r->nrcols = r->op1->nrcols;
-               r->key = r->op1->key; // maybe
-               r->aggr = r->op1->aggr;
-
-               list_append(l, r);
-       }
+       do { // again, restrict the scope
+               node *n = query->op4.lval->h;
+               stmt *s = NULL; // temporary stmt
+
+               s = stmt_create(be->mvc->sa, st_result);
+               s->nr = getDestVar(q);
+               copy_params(n->data, s);
+               list_append(l, s);
+               n = n->next->next;
+
+               // second parameter is easy
+               list_append(l, stmt_none(be));
+
+
+               // third & four parameters
+               s = stmt_create(be->mvc->sa, st_result);
+               s->nr = getArg(q, 1);
+               copy_params(n->data, s);
+               list_append(l, s);
+               n = n->next;
+               s = stmt_create(be->mvc->sa, st_result);
+               s->nr = getArg(q, 2);
+               copy_params(n->data, s);
+               list_append(l, s);
+       } while (0);
+
        return stmt_list(be, l);
 }
 
@@ -3655,14 +3678,15 @@ stmt_gr8_spfw(backend *be, stmt *query, 
        assert(weights->type == st_list && "Invalid parameter type");
 
        // I can use macros too..
-#define EVIL_PUSH(S) if(((stmt*)S)->nr < 0) { return NULL; } else { q = 
pushArgument(be->mb, q, ((stmt*) S)->nr); }
+#define EVIL_PUSH(S) if (((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
        q = newStmt(be->mb, "graph", "spfw");
        if(q == NULL) return NULL; // error
        // output values
-       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_any)); // left 
candidate list
-       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_any)); // right 
candidate list
+       getArg(q, 0) = newTmpVariable(be->mb, TYPE_bat); // left candidate list
+       q = pushReturn(be->mb, q, newTmpVariable(be->mb, TYPE_bat)); // 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_any));
@@ -3682,7 +3706,7 @@ stmt_gr8_spfw(backend *be, stmt *query, 
 
        // ABI convention
        dest = getDestVar(q); // jl
-       renameVariable(be->mb, getArg(q, 1), "r1_%d", s->nr); // jr
+       renameVariable(be->mb, getArg(q, 1), "r1_%d", dest); // jr
        i = 2;
        for(node *n = weights->op4.lval->h; n; n = n->next){ // shortest paths
                snprintf(be->mb->var[getArg(q, i)]->id, IDLENGTH, "r%d_%d", i, 
dest);
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
@@ -243,7 +243,7 @@ extern stmt *stmt_assign(backend *be, co
 extern stmt *stmt_gr8_concat(backend *be, list *l); // create a new column by 
concatenating the given list of columns
 extern stmt *stmt_gr8_slices(backend *be, stmt *op, int num); // the opposite 
of concat, split a column in
 extern stmt *stmt_gr8_void2oid(backend *be, stmt *op); // transform a BAT of 
type voids into oids
-extern stmt *stmt_gr8_remove_nils(backend *be, stmt* query); // remove nils 
from the given query list (used after a left outer join)
+extern stmt *stmt_gr8_intersect_join_lists(backend *be, stmt* query); // 
remove mismatching tuples from the given query list (needed for the select 
semantic)
 extern stmt *stmt_gr8_spfw(backend *be, stmt *query, stmt *edge_from, stmt 
*edge_to, stmt *weights, int flags); // shortest path op~
 
 extern sql_subtype *tail_type(stmt *st);
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to