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