+ SQL to Turtle node mappers
authorEric Prud'hommeaux <bertails@w3.org>
Sun, 03 Jan 2010 17:41:20 -0500
changeset 104 855838f67c98
parent 103 c1d12b781d00
child 106 f9b231e01256
+ SQL to Turtle node mappers
src/main/scala/RDB2RDFMain.scala
src/main/scala/SQL.scala
src/test/scala/RDB2RDFTest.scala
src/test/scala/SQLTest.scala
--- a/src/main/scala/RDB2RDFMain.scala	Sun Jan 03 16:11:18 2010 -0500
+++ b/src/main/scala/RDB2RDFMain.scala	Sun Jan 03 17:41:20 2010 -0500
@@ -248,6 +248,33 @@
     }
   }
 
+  def varToConcat(varmap:Map[Var, SQL2RDFValueMapper], vvar:Var, stem:StemURI):Expression = {
+    varmap(vvar) match {
+      case IntMapper(relalias, _) => PrimaryExpressionAttr(relalias)
+      case StringMapper(relalias, _) => 
+	Concat(List(PrimaryExpressionTyped(SQLDatatype("String"),Name("\\\"")),
+		    PrimaryExpressionAttr(relalias),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name("\\\"^^<http://www.w3.org/2001/XMLSchema#string>"))))
+      case DateMapper(relalias, _) => PrimaryExpressionAttr(relalias)
+      case RDFNoder(relation, relalias, _) => 
+	Concat(List(PrimaryExpressionTyped(SQLDatatype("String"),Name(stem.s)),
+		    PrimaryExpressionTyped(SQLDatatype("String"),relation.n),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name("/")),
+		    PrimaryExpressionTyped(SQLDatatype("String"),relalias.attribute.n),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name(".")),
+		    PrimaryExpressionAttr(relalias),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name("#record"))))
+      case RDFBNoder(relation, relalias, _) => 
+	Concat(List(PrimaryExpressionTyped(SQLDatatype("String"),Name("_:")),
+		    PrimaryExpressionTyped(SQLDatatype("String"),relation.n),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name(".")),
+		    PrimaryExpressionTyped(SQLDatatype("String"),relalias.attribute.n),
+		    PrimaryExpressionTyped(SQLDatatype("String"),Name(".")),
+		    PrimaryExpressionAttr(relalias)))
+    }
+    
+  }
+
   def filter2expr(varmap:Map[Var, SQL2RDFValueMapper], f:SparqlPrimaryExpression):RelationalExpression = {
     val (lTerm:Term, rTerm:Term, sqlexpr) = f match { // sqlexpr::((RelAliasAttribute,PrimaryExpressionAttr)=>RelationalExpression)
       case SparqlPrimaryExpressionEq(l, r) => (l.term, r.term, RelationalExpressionEq(_,_))
@@ -416,7 +443,6 @@
       	      else
       		Set(constraint)
       	    }
-	    println("" + v + " begets " + newMap + " and " + newConstraints)
       	    R2RState(myState.joins, myState.varmap ++ newMap, myState.exprs ++ newConstraints)
       	  } else {
       	    /* This variable is new to the outer context. */
@@ -443,7 +469,7 @@
     }
   }
 
-  def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey, enforeForeignKeys:Boolean) : Select = {
+  def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey, enforeForeignKeys:Boolean, concat:Boolean) : Select = {
     val SparqlSelect(attrs, triples) = sparql
 
     /* Create an object to hold our compilation state. */
@@ -458,7 +484,11 @@
     /* Select the attributes corresponding to the variables
      * in the SPARQL SELECT.  */
     val attrlist:Set[NamedAttribute] = attrs.attributelist.foldLeft(Set[NamedAttribute]())((attrs, vvar) => 
-      attrs ++ Set(NamedAttribute(varToAttribute(r2rState.varmap, vvar), AttrAlias(Name("A_" + vvar.s)))))
+      attrs + NamedAttribute({
+	if (concat) varToConcat(r2rState.varmap, vvar, stem)
+	else varToAttribute(r2rState.varmap, vvar)
+      } , AttrAlias(Name("A_" + vvar.s))
+      ))
 
     /* Construct the generated query as an abstract syntax. */
     Select(
--- a/src/main/scala/SQL.scala	Sun Jan 03 16:11:18 2010 -0500
+++ b/src/main/scala/SQL.scala	Sun Jan 03 17:41:20 2010 -0500
@@ -5,7 +5,7 @@
 object SQLParsers extends RegexParsers {
 
   val int = """[0-9]+""".r
-  val chars = "\"[^\"]*\"".r
+  val chars = "\"([^\"\\\\\n\r]|\\\\[tbnrf\\\"'])*\"".r
 }
 
 import SQLParsers._
@@ -42,16 +42,6 @@
 case class RelAliasAttribute(relalias:RelAlias, attribute:Attribute) extends RelAliasAttributeORExpression {
   override def toString = relalias + "." + attribute
 }
-// sealed abstract class Const extends RelAliasAttributeORPrimaryExpression
-// case class ConstNULL() extends Const {
-//   override def toString = "NULL"
-// }
-// case class ConstInt(i:String) extends Const {
-//   override def toString = "" + i
-// }
-// case class ConstChars(s:String) extends Const {
-//   override def toString = "\"" + s + "\""
-// }
 
 case class Attribute(n:Name) {
   override def toString = n.s /* "'" + n.s + "'" */
--- a/src/test/scala/RDB2RDFTest.scala	Sun Jan 03 16:11:18 2010 -0500
+++ b/src/test/scala/RDB2RDFTest.scala	Sun Jan 03 17:41:20 2010 -0500
@@ -45,7 +45,46 @@
             INNER JOIN Employee AS R_id18
  WHERE R_id18.id=R_emp.manager AND R_id18.id=18 AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
+    true
+  }
+
+  test("SELECT <x> { ?sf <p> <x>} (in-SQL Nodizer)") {
+    val sparqlParser = Sparql()
+    val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+SELECT ?emp {
+?emp  empP:manager    <http://hr.example/DB/Employee/id.18#record>
+}
+""").get
+    val sqlParser = Sql()
+    val StemUrlString = "\"http://hr.example/DB/\""
+    val sqlSelect = sqlParser.parseAll(sqlParser.select, """
+SELECT CONCAT(""" + StemUrlString + """, "Employee", "/", "id", ".", R_emp.id, "#record") AS A_emp
+       FROM Employee AS R_emp
+            INNER JOIN Employee AS R_id18
+ WHERE R_id18.id=R_emp.manager AND R_id18.id=18 AND R_emp.id IS NOT NULL
+""").get
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, true) === sqlSelect)
+    true
+  }
+
+  test("SELECT <x> { ?sf <p> \"asdf\"} (in-SQL Nodizer)") {
+    val sparqlParser = Sparql()
+    val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+SELECT ?name {
+?emp  empP:lastName  ?name
+}
+""").get
+    val sqlParser = Sql()
+    val StemUrlString = "\"http://hr.example/DB/\""
+    val sqlSelect = sqlParser.parseAll(sqlParser.select, """
+SELECT CONCAT("\"", R_emp.lastName, "\"^^<http://www.w3.org/2001/XMLSchema#string>") AS A_name
+       FROM Employee AS R_emp
+ WHERE R_emp.id IS NOT NULL AND R_emp.lastName IS NOT NULL
+""").get
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, true) === sqlSelect)
     true
   }
 
@@ -64,7 +103,7 @@
             INNER JOIN Employee AS R_manager
  WHERE R_manager.id=R_id18.manager AND R_id18.id=18 AND R_manager.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
     true
   }
 
@@ -86,7 +125,7 @@
             INNER JOIN Employee AS R_18
  WHERE R_18.id=R_emp.manager AND R_18.id=18 AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
     true
   }
 
@@ -106,7 +145,7 @@
             INNER JOIN Employee AS R_emp2
  WHERE R_emp1.lastName=R_emp2.lastName AND R_emp1.id IS NOT NULL AND R_emp1.lastName IS NOT NULL AND R_emp2.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
     true
   }
 
@@ -129,7 +168,7 @@
  AND R_emp.id IS NOT NULL
  AND R_manager.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
   }
 
   test("transform tup1 no-enforce") {
@@ -148,7 +187,7 @@
  WHERE R_emp.manager=18 AND R_emp.lastName IS NOT NULL
  AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform tup1 enforce") {
@@ -168,7 +207,7 @@
  WHERE R_id18.id=R_emp.manager AND R_id18.id=18 AND R_emp.lastName IS NOT NULL
  AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
   }
 
 
@@ -192,7 +231,7 @@
  AND R_emp.id IS NOT NULL
  AND R_manager.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
   }
 
   test("transform filter1") {
@@ -231,7 +270,7 @@
  AND R_manager.birthday IS NOT NULL
  AND R_grandManager.birthday IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), true, false) === sqlSelect)
   }
 
   test("transform disj1") {
@@ -272,7 +311,7 @@
        (R_union1._DISJOINT_!=0 OR R_who.id=R_union1.A_who) AND
        (R_union1._DISJOINT_!=1 OR R_who.id=R_union1.A_who)
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform assymDisj1") {
@@ -318,7 +357,7 @@
        R_union0.A_who IS NOT NULL AND
        R_union0.A_bday IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform assymDisj1 reversed") {
@@ -366,7 +405,7 @@
        R_who.id IS NOT NULL AND
        R_who.birthday IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform assymDisj1 interspersed") {
@@ -414,7 +453,7 @@
        R_who.id IS NOT NULL AND
        R_union1.A_bday IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform optJoin1") {
@@ -458,7 +497,7 @@
  WHERE R_emp.lastName IS NOT NULL
    AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 
   test("transform nestOpt") {
@@ -499,6 +538,6 @@
              ) AS R_opt1 ON R_emp.id=R_opt1.A_emp
  WHERE R_emp.lastName IS NOT NULL AND R_emp.id IS NOT NULL
 """).get
-    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
+    assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
   }
 }
--- a/src/test/scala/SQLTest.scala	Sun Jan 03 16:11:18 2010 -0500
+++ b/src/test/scala/SQLTest.scala	Sun Jan 03 17:41:20 2010 -0500
@@ -225,18 +225,18 @@
     val a = Sql()
     val QuotedBaseURI = "\"http://hr.example/DB/\""
     val e = """
-SELECT CONCAT(""" + QuotedBaseURI + """, "Employee", "/", "id", ".", R_emp1.id, "#record") AS A_emp1
-       FROM Employee AS R_emp1
+SELECT CONCAT(""" + QuotedBaseURI + """, "Employee", "/", "id", ".", R_emp.id, "#record") AS A_emp
+       FROM Employee AS R_emp
 """
     val expected = Select(AttributeList(Set(NamedAttribute(Concat(List(PrimaryExpressionTyped(SQLDatatype("String"),Name("http://hr.example/DB/")),
 								       PrimaryExpressionTyped(SQLDatatype("String"),Name("Employee")),
 								       PrimaryExpressionTyped(SQLDatatype("String"),Name("/")),
 								       PrimaryExpressionTyped(SQLDatatype("String"),Name("id")),
 								       PrimaryExpressionTyped(SQLDatatype("String"),Name(".")),
-								       PrimaryExpressionAttr(RelAliasAttribute(RelAlias(Name("R_emp1")),Attribute(Name("id")))),
+								       PrimaryExpressionAttr(RelAliasAttribute(RelAlias(Name("R_emp")),Attribute(Name("id")))),
 								       PrimaryExpressionTyped(SQLDatatype("String"),Name("#record")))),
-							    AttrAlias(Name("A_emp1"))))),
-			  TableList(Set(InnerJoin(AliasedResource(Relation(Name("Employee")),RelAlias(Name("R_emp1")))))),
+							    AttrAlias(Name("A_emp"))))),
+			  TableList(Set(InnerJoin(AliasedResource(Relation(Name("Employee")),RelAlias(Name("R_emp")))))),
 			  None)
     assert(expected === (a.parseAll(a.select, e).get))
   }