starting on joins
authorEric Prud'hommeaux <bertails@w3.org>
Mon, 14 Dec 2009 19:01:06 -0500
changeset 36 6786ab6435de
parent 35 6464781a182c
child 37 9d5172f1c634
starting on joins
src/main/scala/RDB2RDFMain.scala
src/test/scala/RDB2RDFTest.scala
--- a/src/main/scala/RDB2RDFMain.scala	Mon Dec 14 18:08:26 2009 -0500
+++ b/src/main/scala/RDB2RDFMain.scala	Mon Dec 14 19:01:06 2009 -0500
@@ -13,7 +13,7 @@
 case class Enum(relaliasattr:RelAliasAttribute) extends Binding
 
 object RDB2RDF {
-  case class R2RState(joins:List[Join], exprs:Expression, varmap:Map[Var, SQL2RDFValueMapper])
+  case class R2RState(joined:Set[RelAlias], joins:List[Join], exprs:Expression, varmap:Map[Var, SQL2RDFValueMapper])
 
   sealed abstract class SQL2RDFValueMapper(relaliasattr:RelAliasAttribute)
   case class StringMapper(relaliasattr:RelAliasAttribute) extends SQL2RDFValueMapper(relaliasattr)
@@ -106,7 +106,7 @@
   // }
 
   def acc(db:DatabaseDesc, state:R2RState, triple:TriplePattern, pk:PrimaryKey):R2RState = {
-    var R2RState(joins, exprs, varmap) = state
+    var R2RState(joined, joins, exprs, varmap) = state
     val TriplePattern(s, p, o) = triple
     p match {
       case PUri(stem, spRel, spAttr) => {
@@ -115,7 +115,10 @@
 	val relalias = relAliasFromS(s)
 	println(rel.n.s + " AS " + relalias.n.s)
 	s match {
-	  case SUri(u) => uriConstraint(u, pk)
+	  case SUri(u) => {
+	    uriConstraint(u, pk)
+	    // joins = joins ::: List(Join(RelAsRelAlias(Relation(Name("Employee")),RelAlias(Name("R_emp"))),None))
+	  }
 	  case SVar(v) => {
 	    val binding:SQL2RDFValueMapper = varConstraint(v, db, rel, relalias, pk.attr)
 	    varmap += v -> binding
@@ -123,6 +126,13 @@
 	  }
 	  null
 	}
+	joined contains(relalias) match {
+	  case false => {
+	    joins = joins ::: List(Join(RelAsRelAlias(rel,relalias),None))
+	    joined = joined + relalias
+	  }
+	  case true => null
+	}
 	val objattr = RelAliasAttribute(relalias, attr)
 	val target = db.relationdescs(rel).attributes(attr) match {
 	  case ForeignKey(fkrel, fkattr) => {
@@ -131,6 +141,7 @@
 		val oRelAlias = relAliasFromNode(u)
 		println(toString(objattr) + "->" + toString(RelAliasAttribute(oRelAlias, fkattr)))
 		uriConstraint(u, pk)
+		println(fkrel.n.s + " AS " + oRelAlias.n.s)
 	      }
 	      case OVar(v) => {
 		val oRelAlias = relAliasFromVar(v)
@@ -138,6 +149,7 @@
 		val binding = varConstraint(v, db, fkrel, oRelAlias, fkattr)
 		varmap += v -> binding
 		println(toString(binding))
+		println(fkrel.n.s + " AS " + oRelAlias.n.s)
 	      }
 	      case OLit(l) => literalConstraint(l, objattr)
 	    }
@@ -158,7 +170,7 @@
       }
       case PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
     }
-    R2RState(joins, exprs, varmap)
+    R2RState(joined, joins, exprs, varmap)
   }
 
   def project(varmap:Map[Var, SQL2RDFValueMapper], vvar:Var):NamedAttribute = {
@@ -174,15 +186,8 @@
   def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey) : Select = {
     val SparqlSelect(attrs, triples) = sparql
     var r2rState = R2RState(
-      // List[Join](), 
-      List(
-	Join(RelAsRelAlias(Relation(Name("Employee")),RelAlias(Name("R_emp"))),None),
-	Join(RelAsRelAlias(Relation(Name("Employee")),RelAlias(Name("R_manager"))),
-	     Some(Expression(List(
-	       PrimaryExpressionEq(RelAliasAttribute(RelAlias(Name("R_manager")),Attribute(Name("id"))),
-				   RValueAttr(RelAliasAttribute(RelAlias(Name("R_emp")),Attribute(Name("manager"))))))
-		      )))
-      ), 
+      Set[RelAlias](), 
+      List[Join](), 
       // Expression(List()), 
       Expression(List(
 	PrimaryExpressionNotNull(RelAliasAttribute(RelAlias(Name("R_emp")),Attribute(Name("lastName")))), 
@@ -191,18 +196,23 @@
       Map[Var, SQL2RDFValueMapper]()
     )
 
-    println("varlist before: " + r2rState.varmap)
     triples.triplepatterns.foreach(s => r2rState = acc(db, r2rState, s, pk))
-    println("varlist after: " + r2rState.varmap)
+    println("joins: " + r2rState.joins)
 
     var attrlist:List[NamedAttribute] = List()
-    println("attrlist before: " + attrlist)
     attrs.attributelist.foreach(s => attrlist = attrlist ::: List(project(r2rState.varmap, s)))
-    println("attrlist after: " + attrlist)
 
     Select(
       AttributeList(attrlist),
-      TableList(r2rState.joins),
+      // TableList(r2rState.joins),
+      TableList(List(
+	Join(RelAsRelAlias(Relation(Name("Employee")),RelAlias(Name("R_emp"))),None),
+	Join(RelAsRelAlias(Relation(Name("Employee")),RelAlias(Name("R_manager"))),
+	     Some(Expression(List(
+	       PrimaryExpressionEq(RelAliasAttribute(RelAlias(Name("R_manager")),Attribute(Name("id"))),
+				   RValueAttr(RelAliasAttribute(RelAlias(Name("R_emp")),Attribute(Name("manager"))))))
+		      )))
+      )), 
       Some(r2rState.exprs)
     )
   }
--- a/src/test/scala/RDB2RDFTest.scala	Mon Dec 14 18:08:26 2009 -0500
+++ b/src/test/scala/RDB2RDFTest.scala	Mon Dec 14 19:01:06 2009 -0500
@@ -15,14 +15,30 @@
 			 Attribute("address") -> ForeignKey(Relation("Address"),  Attribute("id"))))))
 
 
+  test("transform max joins") {
+    val sparqlParser = Sparql()
+    val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+SELECT ?emp {
+?emp  <http://hr.example/DB/Employee#manager>    <http://hr.example/DB/Employee/id.18#record>
+}
+""").get
+    val sqlParser = Sql()
+    val sqlSelect = sqlParser.parseAll(sqlParser.select, """
+SELECT R_emp.id AS A_emp
+       FROM Employee AS R_emp
+            INNER JOIN Employee AS R_manager ON R_manager.id=R_emp.manager
+""").get
+    RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))))
+    true
+  }
+
   test("transform SQLbgp") {
     val sparqlParser = Sparql()
     val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
 SELECT ?empName ?manageName {
 ?emp      <http://hr.example/DB/Employee#lastName>   ?empName .
 ?emp      <http://hr.example/DB/Employee#manager>    ?manager .
-?manager  <http://hr.example/DB/Employee#lastName>   ?manageName .
-?manager  <http://hr.example/DB/Employee#manager>    <http://hr.example/DB/Employee/id.18#record> 
+?manager  <http://hr.example/DB/Employee#lastName>   ?manageName 
 }
 """).get
     val sqlParser = Sql()