~ migrating RelDesc to RDB.Relation
authorEric Prud'hommeaux <eric@w3.org>
Fri, 15 Oct 2010 14:58:18 -0400
changeset 236 ab7e05cec247
parent 235 012a9d4711ac
child 237 ad153b9f0d13
~ migrating RelDesc to RDB.Relation
~ moved key information into RelDesc
src/main/scala/SQL.scala
src/main/scala/Servlet.scala
src/main/scala/SparqlToSql.scala
src/test/scala/SQLTest.scala
src/test/scala/SparqlToSparqlToSqlTest.scala
src/test/scala/SparqlToSqlTest.scala
--- a/src/main/scala/SQL.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/main/scala/SQL.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -130,7 +130,7 @@
 case class ProjectAttribute(value:RelVarAttrORExpression, attralias:AttrAlias) {
   override def toString = value + " AS " + attralias
 }
-//case class RelAttribute(relation:Relation, attribute:RDB.AttrName) c.f. ForeignKey
+//case class RelAttribute(relation:Relation, attribute:RDB.AttrName) c.f. ForeignKey999
 sealed abstract class RelVarAttrORExpression
 case class RelVarAttr(relvar:RelVar, attribute:RDB.AttrName) extends RelVarAttrORExpression {
   override def toString = relvar + "." + attribute
@@ -255,9 +255,9 @@
   val DATETIME = Datatype("Datetime")
 }
 
-sealed abstract class ValueDescription
-case class Value(datatype:Datatype) extends ValueDescription
-case class ForeignKey(rel:RDB.RelName, attr:RDB.CandidateKey) extends ValueDescription
+// sealed abstract class ValueDescription
+// case class Value(datatype:Datatype) extends ValueDescription
+// case class ForeignKey999(rel:RDB.RelName, attr:RDB.CandidateKey) extends ValueDescription
 
 case class DatabaseDesc(relationdescs:Map[RDB.RelName,RelationDesc])
 object DatabaseDesc {
@@ -265,9 +265,9 @@
     DatabaseDesc(rs.map{r => (r.name -> r)}.toMap)
 }
 // case class Relation (name:RDB.RelName, header:RDB.Header, body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey], fks:RDB.ForeignKeys)
-case class RelationDesc(name:RDB.RelName, attributes:Map[RDB.AttrName, ValueDescription], body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey], fks:RDB.ForeignKeys)
+case class RelationDesc(name:RDB.RelName, attributes:Map[RDB.AttrName, Datatype], body:List[RDB.Tuple], candidates:List[RDB.CandidateKey], pk:Option[RDB.CandidateKey], fks:RDB.ForeignKeys)
 sealed abstract class FieldDescOrKeyDeclaration
-case class FieldDesc(attr:RDB.AttrName, value:Value, pkness:Boolean) extends FieldDescOrKeyDeclaration
+case class FieldDesc(attr:RDB.AttrName, value:Datatype, pkness:Boolean) extends FieldDescOrKeyDeclaration // @@ rename value
 sealed abstract class KeyDeclaration extends FieldDescOrKeyDeclaration
 case class PrimaryKeyDeclaration(key:RDB.CandidateKey) extends KeyDeclaration
 case class ForeignKeyDeclaration(fk:List[RDB.AttrName], rel:RDB.RelName, pk:RDB.CandidateKey) extends KeyDeclaration
@@ -295,41 +295,31 @@
   {
     case "CREATE"~"TABLE"~relation~"("~reldesc~")" => {
       val pk0:Option[RDB.CandidateKey] = None
-      val attrs0 = Map[RDB.AttrName, ValueDescription]()
+      val attrs0 = Map[RDB.AttrName, Datatype]()
       val candidates0 = List[RDB.CandidateKey]()
-      val oldfks0 = Map[List[RDB.AttrName], ForeignKey]()
       val fks0 = Map[List[RDB.AttrName], RDB.Target]()
       /* <pk>: (most recently parsed) PRIMARY KEY
        * <attrs>: map of attribute to type (e.g. INTEGER)
-       * <oldfks>: map holding FOREIGN KEY relation REFERENCES attr
+       * <fks>: map holding FOREIGN KEY relation REFERENCES attr
        */
-      val (pk, attrs, candidates, oldfks, fks) =
-	reldesc.foldLeft((pk0, attrs0, candidates0, oldfks0, fks0))((p, rd) => {
-	  val (pkopt, attrs, candidates, oldfks, fks) = p
+      val (pk, attrs, candidates, fks) =
+	reldesc.foldLeft((pk0, attrs0, candidates0, fks0))((p, rd) => {
+	  val (pkopt, attrs, candidates, fks) = p
 	  rd match {
 	    case FieldDesc(attr, value, pkness) => {
 	      val (pkNew, candNew) =
 		if (pkness) (Some(RDB.CandidateKey(List(attr))), candidates ++ List(RDB.CandidateKey(attr.n)))
 		else (pkopt, candidates)
-	      (pkNew, attrs + (attr -> value), candNew, oldfks, fks)
+	      (pkNew, attrs + (attr -> value), candNew, fks)
 	    }
 	    case PrimaryKeyDeclaration(key) =>
 	      // @@ why doesn't [[ candidates + RDB.CandidateKey(attr.n) ]] work?
-	      (Some(key), attrs, candidates ++ List(RDB.CandidateKey(key map {attr => RDB.AttrName(attr.n)})), oldfks, fks)
+	      (Some(key), attrs, candidates ++ List(RDB.CandidateKey(key map {attr => RDB.AttrName(attr.n)})), fks)
 	    case ForeignKeyDeclaration(fk, rel, pk) =>
-	      (pkopt, attrs, candidates, oldfks + (fk -> ForeignKey(rel, pk)), fks + (fk -> RDB.Target(rel, pk)))
+	      (pkopt, attrs, candidates, fks + (fk -> RDB.Target(rel, pk)))
 	  }
 	})
-      /* Change data type of foreign key attributes to ForeignKey.
-       * The type isn't really lost -- it's the same as the referenced type.
-       */
-      val attrs2 = attrs.map(x => {
-	val (attr:RDB.AttrName, value:Value) = x
-	val asKey = RDB.CandidateKey(List(attr))
-	if (oldfks.contains(asKey)) (attr -> oldfks(asKey))
-	else (attr -> value)
-      })
-      val rd = RelationDesc(relation, attrs2, List(), candidates, pk, RDB.ForeignKeys(fks))
+      val rd = RelationDesc(relation, attrs, List(), candidates, pk, RDB.ForeignKeys(fks))
       (relation -> rd)
     }
   }
@@ -343,12 +333,12 @@
       { case "FOREIGN"~"KEY"~"("~fk~")"~"REFERENCES"~relation~"("~pk~")" => ForeignKeyDeclaration(fk, relation, RDB.CandidateKey(pk)) }
   )
 
-  def typpe:Parser[Value] = (
-      "INT" ^^ { case _ => Value(Datatype.INTEGER) }
-    | "DOUBLE" ^^ { case _ => Value(Datatype.DOUBLE) }
-    | "STRING" ^^ { case _ => Value(Datatype.STRING) }
-    | "DATETIME" ^^ { case _ => Value(Datatype.DATETIME) }
-    | "DATE" ^^ { case _ => Value(Datatype.DATE) }
+  def typpe:Parser[Datatype] = (
+      "INT" ^^ { case _ => Datatype.INTEGER }
+    | "DOUBLE" ^^ { case _ => Datatype.DOUBLE }
+    | "STRING" ^^ { case _ => Datatype.STRING }
+    | "DATETIME" ^^ { case _ => Datatype.DATETIME }
+    | "DATE" ^^ { case _ => Datatype.DATE }
   )
 
   def selectORunion:Parser[SelectORUnion] =
--- a/src/main/scala/Servlet.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/main/scala/Servlet.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -9,7 +9,7 @@
 
 import java.net.URI
 import w3c.sw.sql.RDB.{RelName,AttrName}
-import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Value,Datatype,ForeignKey,Name}
+import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Datatype,Name}
 import w3c.sw.sparql
 import w3c.sw.sparql.Sparql
 import w3c.sw.sql
--- a/src/main/scala/SparqlToSql.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/main/scala/SparqlToSql.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -291,17 +291,19 @@
       /** <pre>varConstraint(R_emp, Some(empid), VarAssignable(?emp), Employee) -&gt; RDFNoder(Employee,FullBinding(R_emp.empid))</pre> */
       case Some(sql.RDB.CandidateKey(List(sql.RDB.AttrName(constrainMe.attribute.n)))) => RDFNoder(rel, boundTo)
       case _ => {
-
-	if (reldesc.attributes.contains(constrainMe.attribute)) {
+	val asKey = sql.RDB.CandidateKey(List(constrainMe.attribute))
+	if (reldesc.fks.contains(asKey)) { // !! (0)
+	  /** varConstraint(R_patient, Some(SexDE), VarAssignable(?_0_sexEntry), Person) -&gt; RDFNoder(Person,FullBinding(R_patient.SexDE)) */
+	  val sql.RDB.Target(fkrel, fkattr) = reldesc.fks(asKey)
+	  RDFNoder(rel, boundTo)
+	} else if (reldesc.attributes.contains(constrainMe.attribute)) {
 	  reldesc.attributes(constrainMe.attribute) match {
-	    /** varConstraint(R_patient, Some(SexDE), VarAssignable(?_0_sexEntry), Person) -&gt; RDFNoder(Person,FullBinding(R_patient.SexDE)) */
-	    case sql.ForeignKey(fkrel, fkattr) => RDFNoder(rel, boundTo)
 	    /** varConstraint(R__0_indicDE, Some(NDC), VarAssignable(?_0_indicNDC), Medication_DE) -&gt; IntMapper(FullBinding(R__0_indicDE.NDC)) */
-	    case sql.Value(sql.Datatype("Int")) => IntMapper(boundTo)
+	    case sql.Datatype("Int") => IntMapper(boundTo)
 	    /** varConstraint(R_emp, Some(lastName), VarAssignable(?name), Employee) -&gt; StringMapper(FullBinding(R_emp.lastName)) */
-	    case sql.Value(sql.Datatype("String")) => StringMapper(boundTo)
+	    case sql.Datatype("String") => StringMapper(boundTo)
 	    /** varConstraint(R_patient, Some(DateOfBirth), VarAssignable(?dob), Person) -&gt; DateMapper(FullBinding(R_patient.DateOfBirth)) */
-	    case sql.Value(sql.Datatype("Date")) => DateMapper(boundTo)
+	    case sql.Datatype("Date") => DateMapper(boundTo)
 	  }
 	} else {
 	  /** Default behavior for unknown attributes. */
@@ -431,21 +433,25 @@
 	 * fkrel.fkattr (e.g. Employee.manager) may be a foreign key.
 	 * Calculate final relvarattr and relation.
 	 */
-	val (targetattr:sql.RelVarAttr, targetrel, dt, state_fkeys:R2RState) = db.relationdescs(rel).attributes(attr) match {
-	  case sql.ForeignKey(fkrel, fkattr) => {
+	val asKey = sql.RDB.CandidateKey(List(attr))
+	val (targetattr:sql.RelVarAttr, targetrel, dt, state_fkeys:R2RState) =
+	  if (db.relationdescs(rel).fks.contains(asKey)) { // !! (0)
+	    val sql.RDB.Target(fkrel, fkattr) = db.relationdescs(rel).fks(asKey)
 	    try { db.relationdescs(fkrel).attributes(fkattr.attrs(0)) } catch { // !! (0)
 	      /** Foreign key relation.attribute was not found in the database description. */
 	      case e:java.util.NoSuchElementException =>
 		throw new Exception("db.relationdescs(" + fkrel + ").attributes(" + fkattr + ") not found in " + db)
 	    }
-	    val fkdt = db.relationdescs(fkrel).attributes(fkattr.attrs(0)) match { // !! (0)
+	    val fkdt =
+	      if (db.relationdescs(fkrel).fks.contains(fkattr)) {
 	      /** Foreign key to something which is a foreign key. May have use
 	       * cases, but signal error until we figure out that they are. */
-	      case sql.ForeignKey(dfkrel, dfkattr) => error("foreign key " + rel.n + "." + attr.n + 
-							"->" + fkrel.n + "." + fkattr.attrs(0).n +  // !! (0)
-							"->" + dfkrel.n + "." + dfkattr.attrs(0).n) // !! (0)
-	      case sql.Value(x) => x
-	    }
+		val sql.RDB.Target(dfkrel, dfkattr) = db.relationdescs(fkrel).fks(fkattr)
+		error("foreign key " + rel.n + "." + attr.n + 
+		      "->" + fkrel.n + "." + fkattr.attrs(0).n +  // !! (0)
+		      "->" + dfkrel.n + "." + dfkattr.attrs(0).n) // !! (0)
+	      } else
+		db.relationdescs(fkrel).attributes(fkattr(0)) // !! (0)
 	    if (enforceForeignKeys) {
 	      /**
 	       * Create an extra join on the foreign key relvar. For instance,
@@ -470,11 +476,11 @@
 	      (objattr, rel, fkdt, state_subjJoin)
 	    }
 	  }
-	  case sql.Value(dt) =>
-	    /** not a foreign key, so use the relvarattr and relation calculated
-	     * from the predicate. */
-	    (objattr, rel, dt, state_subjJoin)
-	}
+	else
+	  /** not a foreign key, so use the relvarattr and relation calculated
+	   * from the predicate. */
+	  (objattr, rel, db.relationdescs(rel).attributes(attr), state_subjJoin)
+
 	o match {
 	  case sparql.TermLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
 	  case sparql.TermUri(u) => uriConstraint    (state_fkeys, targetattr, parseObjectURI(u))
--- a/src/test/scala/SQLTest.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/test/scala/SQLTest.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -423,7 +423,7 @@
     val e = """
 ID INT PRIMARY KEY
 """
-    val expected = FieldDesc(RDB.AttrName("ID"), Value(Datatype.INTEGER), true)
+    val expected = FieldDesc(RDB.AttrName("ID"), Datatype.INTEGER, true)
     assert(expected === (a.parseAll(a.fielddescorkeydef, e).get))
   }
 
@@ -434,7 +434,7 @@
 """
     val expected = DatabaseDesc(
       RelationDesc("Sex_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
@@ -450,8 +450,8 @@
 """
     val expected = DatabaseDesc(
       RelationDesc("Sex_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("EnterpriseEntryID") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
@@ -467,8 +467,8 @@
 """
     val expected = DatabaseDesc(
       RelationDesc("Sex_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("EnterpriseEntryID") -> Value(Datatype.INTEGER)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("EnterpriseEntryID") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
@@ -485,17 +485,17 @@
     """
     val expected:DatabaseDesc = DatabaseDesc(
       RelationDesc("Person",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("MiddleName") -> Value(Datatype.STRING),
-		       RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
-		       RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.CandidateKey("ID"))),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("MiddleName") -> Datatype.STRING,
+		       RDB.AttrName("DateOfBirth") -> Datatype.DATE,
+		       RDB.AttrName("SexDE") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys(List("SexDE") -> RDB.Target("Sex_DE", RDB.CandidateKey("ID")))),
       RelationDesc("Sex_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("EntryName") -> Datatype.STRING),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
@@ -516,50 +516,50 @@
 """
     val expected:DatabaseDesc = DatabaseDesc(
       RelationDesc("Person",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("MiddleName") -> Value(Datatype.STRING),
-		       RDB.AttrName("DateOfBirth") -> Value(Datatype.DATE),
-		       RDB.AttrName("SexDE") -> ForeignKey(RDB.RelName("Sex_DE"), RDB.CandidateKey("ID"))),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("MiddleName") -> Datatype.STRING,
+		       RDB.AttrName("DateOfBirth") -> Datatype.DATE,
+		       RDB.AttrName("SexDE") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys(List("SexDE") -> RDB.Target("Sex_DE", RDB.CandidateKey("ID")))),
       RelationDesc("Sex_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("EntryName") -> Datatype.STRING),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys()),
       RelationDesc("Item_Medication",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("PatientID") -> ForeignKey(RDB.RelName("Person"), RDB.CandidateKey("ID")),
-		       RDB.AttrName("PerformedDTTM") -> Value(Datatype.DATE),
-		       RDB.AttrName("EntryName") -> Value(Datatype.STRING)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("PatientID") -> Datatype.INTEGER,
+		       RDB.AttrName("PerformedDTTM") -> Datatype.DATE,
+		       RDB.AttrName("EntryName") -> Datatype.STRING),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys(List("PatientID") -> RDB.Target("Person", RDB.CandidateKey("ID")))),
       RelationDesc("Medication",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("ItemID") -> ForeignKey(RDB.RelName("Item_Medication"), RDB.CandidateKey("ID")),
-		       RDB.AttrName("MedDictDE") -> ForeignKey(RDB.RelName("Medication_DE"), RDB.CandidateKey("ID"))),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("ItemID") -> Datatype.INTEGER,
+		       RDB.AttrName("MedDictDE") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys(List("ItemID") -> RDB.Target("Item_Medication", RDB.CandidateKey("ID")),
 				   List("MedDictDE") -> RDB.Target("Medication_DE", RDB.CandidateKey("ID")))),
       RelationDesc("Medication_DE",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("NDC") -> Value(Datatype.INTEGER)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("NDC") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
 		   RDB.ForeignKeys()),
       RelationDesc("NDCcodes",
-		   Map(RDB.AttrName("ID") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("NDC") -> Value(Datatype.INTEGER),
-		       RDB.AttrName("ingredient") -> Value(Datatype.INTEGER)),
+		   Map(RDB.AttrName("ID") -> Datatype.INTEGER,
+		       RDB.AttrName("NDC") -> Datatype.INTEGER,
+		       RDB.AttrName("ingredient") -> Datatype.INTEGER),
 		   List(),
 		   List(RDB.CandidateKey("ID")),
 		   Option(RDB.CandidateKey("ID")),
--- a/src/test/scala/SparqlToSparqlToSqlTest.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/test/scala/SparqlToSparqlToSqlTest.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -10,7 +10,7 @@
 import w3c.sw.sparql.Sparql
 import w3c.sw.sparql2sparql.{SparqlToSparql,NodePatternMap,NodePattern,SparqlMap}
 import w3c.sw.sql.RDB.{RelName,AttrName}
-import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Value,Datatype,ForeignKey,Name}
+import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Datatype,Name}
 import w3c.sw.sparql2sql.{SparqlToSql,StemURI}
 import w3c.sw.sparql2sparql2sql.SparqlToSparqlToSql.toView
 
--- a/src/test/scala/SparqlToSqlTest.scala	Fri Oct 15 13:44:06 2010 -0400
+++ b/src/test/scala/SparqlToSqlTest.scala	Fri Oct 15 14:58:18 2010 -0400
@@ -7,7 +7,7 @@
 import org.scalatest.FunSuite
 import java.net.URI
 import w3c.sw.sql.RDB.{RelName,AttrName}
-import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Value,Datatype,ForeignKey,Name}
+import w3c.sw.sql.{Sql,DatabaseDesc,RelationDesc,Datatype,Name}
 import w3c.sw.sparql.Sparql
 import w3c.sw.sparql2sql.{SparqlToSql,StemURI,SqlToXMLRes}