[prev in list] [next in list] [prev in thread] [next in thread] 

List:       monetdb-checkins
Subject:    MonetDB: graph0 - Join columns from different tables
From:       Dean De Leo <commits+dleo=cwi.nl () monetdb ! org>
Date:       2016-09-30 15:53:27
Message-ID: hg.5e7df26ea650.1475250807.6315528441665844383 () monetdb2 ! cwi-incubator ! nl
[Download RAW message or body]

Changeset: 5e7df26ea650 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5e7df26ea650
Modified Files:
	sql/backends/monet5/rel_bin.c
	sql/include/sql_relation.h
	sql/server/rel_dump.c
	sql/server/rel_exp.c
	sql/server/rel_graph.c
	sql/server/rel_graph.h
	sql/server/rel_optimizer.c
	sql/server/rel_rel.c
	sql/server/rel_rel.h
	sql/server/rel_select.c
Branch: graph0
Log Message:

Join columns from different tables

Only considering the precarious case that the operator above the join is
the crossproduct where the two input tables are merged.


diffs (truncated from 550 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
@@ -1339,7 +1339,6 @@ rel2bin_args( mvc *sql, sql_rel *rel, li
 	case op_left: 
 	case op_right: 
 	case op_full: 
-	case op_spfw:
 
 	case op_apply: 
 	case op_semi: 
@@ -1372,6 +1371,11 @@ rel2bin_args( mvc *sql, sql_rel *rel, li
 	case op_delete:
 		args = rel2bin_args(sql, rel->r, args);
 		break;
+	case op_spfw:
+		args = rel2bin_args(sql, rel->l, args);
+		args = rel2bin_args(sql, rel->r, args);
+		args = rel2bin_args(sql, rel_edges(rel), args);
+		break;
 	}
 	return args;
 }
@@ -4551,6 +4555,20 @@ rel2bin_ddl(mvc *sql, sql_rel *rel, list
 	return s;
 }
 
+static list*
+spfw_project(mvc *sql, list* l, stmt *spfw, stmt *input){
+	for( node* n = input->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(sql->sa, spfw, column(sql->sa, c));
+
+		s = stmt_alias(sql->sa, s, rnme, nme);
+		list_append(l, s);
+	}
+	return l;
+}
+
 static stmt *
 rel2bin_spfw(mvc *sql, sql_rel *rel, list *refs)
 {
@@ -4570,8 +4588,9 @@ rel2bin_spfw(mvc *sql, sql_rel *rel, lis
 	// materialize the input relations
 	left = subrel_bin(sql, rel->l, refs);
 	if(!left) return NULL;
-	(void) right;
-	edges = subrel_bin(sql, rel->r, refs);
+	right = subrel_bin(sql, rel->r, refs);
+	if(!right) return NULL;
+	edges = subrel_bin(sql, rel_edges(rel), refs);
 	if(!edges) return NULL;
 
 	// refer to the columns
@@ -4579,7 +4598,7 @@ rel2bin_spfw(mvc *sql, sql_rel *rel, lis
 	n = rel->exps->h;
 	q_from = exp_bin(sql, n->data, left, NULL, NULL, NULL, NULL, NULL);
 	n = n->next;
-	q_to = exp_bin(sql, n->data, left, NULL, NULL, NULL, NULL, NULL);
+	q_to = exp_bin(sql, n->data, right, NULL, NULL, NULL, NULL, NULL);
 	n = n->next;
 	e_from = exp_bin(sql, n->data, edges, NULL, NULL, NULL, NULL, NULL);
 	n = n->next;
@@ -4626,15 +4645,8 @@ rel2bin_spfw(mvc *sql, sql_rel *rel, lis
 
 	// almost done, create the new resultset
 	l = sa_list(sql->sa);
-	for( 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(sql->sa, spfw, column(sql->sa, c));
-
-		s = stmt_alias(sql->sa, s, rnme, nme);
-		list_append(l, s);
-	}
+	spfw_project(sql, l, spfw, left);
+	spfw_project(sql, l, spfw, right);
 	result = stmt_list(sql->sa, l);
 
 	print_tree(sql->sa, result); // FIXME debug only
diff --git a/sql/include/sql_relation.h b/sql/include/sql_relation.h
--- a/sql/include/sql_relation.h
+++ b/sql/include/sql_relation.h
@@ -293,4 +293,12 @@ typedef struct relation {
 	void *p;	/* properties for the optimizer, distribution */
 } sql_rel;
 
+// graph extension
+typedef struct {
+	sql_rel base;
+	sql_rel *edges;
+} sql_spfw;
+
+#define rel_edges(rel_spfw) ((sql_spfw*) rel_spfw)->edges
+
 #endif /* SQL_RELATION_H */
diff --git a/sql/server/rel_dump.c b/sql/server/rel_dump.c
--- a/sql/server/rel_dump.c
+++ b/sql/server/rel_dump.c
@@ -343,13 +343,13 @@ rel_print_(mvc *sql, stream  *fout, sql_
 				mnstr_printf(fout, "%s(%s.%s)", 
 					isStream(t)?"stream":
 					isRemote(t)&&decorate?"REMOTE":
-					isReplicaTable(t)?"REPLICA":"table",
+					isReplicaTable(t)?"REPLICA":"basetable",
 					sname, tname);
 			else
 		  		mnstr_printf(fout, "%s(%s)", 
 					isStream(t)?"stream":
 					isRemote(t)&&decorate?"REMOTE":
-					isReplicaTable(t)?"REPLICA":"table",
+					isReplicaTable(t)?"REPLICA":"basetable",
 					tname);
 		}	
 		if (rel->exps) 
@@ -386,7 +386,6 @@ rel_print_(mvc *sql, stream  *fout, sql_
 	case op_union: 
 	case op_inter: 
 	case op_except: 
-	case op_spfw:
 		r = "join";
 		if (rel->op == op_left)
 			r = "left outer join";
@@ -417,8 +416,6 @@ rel_print_(mvc *sql, stream  *fout, sql_
 			r = "except";
 		else if (!rel->exps && rel->op == op_join)
 			r = "crossproduct";
-		else if(rel->op == op_spfw)
-			r = "spfw";
 		print_indent(sql, fout, depth, decorate);
 		if (need_distinct(rel))
 			mnstr_printf(fout, "distinct ");
@@ -506,6 +503,29 @@ rel_print_(mvc *sql, stream  *fout, sql_
 		if (rel->exps)
 			exps_print(sql, fout, rel->exps, depth, 1, 0);
 	} 	break;
+	case op_spfw: {
+		print_indent(sql, fout, depth, decorate);
+		mnstr_printf(fout, "spfw (");
+#define spfw_print_rel( REL ) \
+		if (rel_is_ref( REL )) { \
+			int nr = find_ref(refs, REL ); \
+			print_indent(sql, fout, depth+1, decorate); \
+			mnstr_printf(fout, "& REF %d ", nr); \
+		} else { \
+			rel_print_(sql, fout, REL, depth+1, refs, decorate); \
+		} /* macro spfw_print_rel */
+
+		spfw_print_rel(rel->l);
+		mnstr_printf(fout, ",");
+		spfw_print_rel(rel->r);
+		mnstr_printf(fout, ",");
+		spfw_print_rel( rel_edges(rel) );
+#undef spfw_print_rel
+
+		print_indent(sql, fout, depth, decorate);
+		mnstr_printf(fout, ")");
+		exps_print(sql, fout, rel->exps, depth, 1, 0);
+	} break;
 	default:
 		assert(0);
 	}
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -1214,6 +1214,7 @@ rel_find_exp( sql_rel *rel, sql_exp *e)
 		case op_right:
 		case op_full:
 		case op_join:
+		case op_spfw:
 		case op_apply:
 			ne = rel_find_exp(rel->l, e);
 			if (!ne) 
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
@@ -16,6 +16,11 @@
 #include "rel_rel.h"
 #include "rel_select.h"
 
+//sql_rel *rel_edges(sql_rel *spfw){
+//	assert(is_spfw(spfw->op));
+//	return ((sql_spfw*) spfw)->edges;
+//}
+
 sql_rel* rel_graph_reaches(mvc *sql, sql_rel *rel, symbol *sq){
 	str dump = NULL;
 	dnode* lstoperands = NULL; // temp to navigate over the operands
@@ -25,6 +30,8 @@ sql_rel* rel_graph_reaches(mvc *sql, sql
 	sql_exp* qto = NULL; // reference to the `to' column
 	exp_kind dummy = {0}; // dummy param, required by rel_value_exp
 	symbol* sym_edges_tbl = NULL; // the table edges in the ast
+	sql_rel* left = NULL; // the first input relation we want to join
+	sql_rel* right = NULL; // the second input relation we want to join
 	sql_rel* tbl_edges = NULL; // the edges table exp~
 	symbol* sym_edges_from = NULL; // reference to the `edges from' column in the ast
 	symbol* sym_edges_to = NULL; // ref to the `edges to' column in the ast
@@ -52,8 +59,33 @@ sql_rel* rel_graph_reaches(mvc *sql, sql
 	qto = rel_value_exp(sql, &rel, sym_qto, sql_where, dummy);
 	if(!qto) return NULL; // cannot refer to qto
 
-	// assume for the time being qfrom and qto come from the same table
-	// if they are not properly joined => result explosion!
+	// FIXME h0rr1bl3 h4ck
+	if(rel->op == op_join && !rel->exps){ // cross product
+		sql_rel *cpl, *cpr;
+		sql_exp *l1 = rel_value_exp(sql, (sql_rel**) &(rel->l), sym_qfrom, sql_where, dummy);
+		sql_exp *l2 = NULL;
+
+		if(l1 != NULL){
+			cpl = rel->l;
+			cpr = rel->r;
+		} else {
+			cpl = rel->r;
+			cpr = rel->l;
+		}
+
+		l2 = rel_value_exp(sql, &cpr, sym_qto, sql_where, dummy);
+		if(l2 != NULL){
+			// the horrible hack did work (doh)
+			left = cpl;
+			right = cpr;
+		} else {
+			fprintf(stderr, "[rel_graph_reaches] Hack failed, cannot replace the above xproduct\n");
+		}
+	} else {
+		fprintf(stderr, "[rel_graph_reaches] Assuming left & right are from the same relation\n");
+		left = rel;
+		right = rel;
+	}
 
 	// edges table
 	lstoperands = lstoperands->next;
@@ -82,9 +114,9 @@ sql_rel* rel_graph_reaches(mvc *sql, sql
 	if(!qto) return NULL; // cannot convert qto into the same type of eto
 
 	// build the new operator graphjoin operator
-	result = rel_spfw(sql, rel, tbl_edges, exp_spfw(sql, qfrom, qto, efrom, eto));
+	result = rel_spfw(sql, left, right, tbl_edges, exp_spfw(sql, qfrom, qto, efrom, eto));
 
-	// let's if what we are creating makes sense
+	// let us see if what we are creating makes sense
 	dump = rel_to_str(sql, result);
 	printf("[Semantic analysis] Output relation: %s\n", dump);
 
diff --git a/sql/server/rel_graph.h b/sql/server/rel_graph.h
--- a/sql/server/rel_graph.h
+++ b/sql/server/rel_graph.h
@@ -12,6 +12,9 @@
 #include "rel_semantic.h"
 #include "sql_semantic.h"
 
+// Retrieve the referred edges relation for the spfw operator
+//sql_rel *rel_edges(sql_rel *spfw);
+
 sql_rel* rel_graph_reaches(mvc *sql, sql_rel *rel, symbol *sq);
 
 #endif /* _REL_GRAPH_H_ */
diff --git a/sql/server/rel_optimizer.c b/sql/server/rel_optimizer.c
--- a/sql/server/rel_optimizer.c
+++ b/sql/server/rel_optimizer.c
@@ -241,7 +241,6 @@ rel_properties(mvc *sql, global_props *g
 	case op_union: 
 	case op_inter: 
 	case op_except: 
-	case op_spfw:
 		rel_properties(sql, gp, rel->l);
 		rel_properties(sql, gp, rel->r);
 		break;
@@ -260,6 +259,11 @@ rel_properties(mvc *sql, global_props *g
 		if (rel->r) 
 			rel_properties(sql, gp, rel->r);
 		break;
+	case op_spfw:
+		rel_properties(sql, gp, rel->l);
+		rel_properties(sql, gp, rel->r);
+		rel_properties(sql, gp, rel_edges(rel));
+		break;
 	}
 
 	switch (rel->op) {
@@ -1053,7 +1057,6 @@ rel_join_order(mvc *sql, sql_rel *rel)
 	case op_union: 
 	case op_inter: 
 	case op_except:
-	case op_spfw:
 		rel->l = rel_join_order(sql, rel->l);
 		rel->r = rel_join_order(sql, rel->r);
 		break;
@@ -1075,6 +1078,11 @@ rel_join_order(mvc *sql, sql_rel *rel)
 		rel->l = rel_join_order(sql, rel->l);
 		rel->r = rel_join_order(sql, rel->r);
 		break;
+	case op_spfw:
+		rel->l = rel_join_order(sql, rel->l);
+		rel->r = rel_join_order(sql, rel->r);
+		rel_edges(rel) = rel_join_order(sql, rel_edges(rel));
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic