--- a/src/main/scala/RDB2RDFMain.scala Tue Jan 05 13:39:13 2010 -0500
+++ b/src/main/scala/RDB2RDFMain.scala Wed Jan 06 17:24:50 2010 -0500
@@ -86,11 +86,12 @@
* type String -> RDFStringConstructor // adds ^^xsd:string
* type primary key -> RDFNodeConstructor // prefixes with stemURL + relation + attribute and adds #record
* */
- def varConstraint(state:R2RState, constrainMe:sql.RelAliasAttribute, v:sparql.Var, db:sql.DatabaseDesc, rel:sql.Relation):R2RState = {
+ def varConstraint(state:R2RState, alias:sql.RelAlias, optAttr:Option[sql.Attribute], v:sparql.Var, db:sql.DatabaseDesc, rel:sql.Relation):R2RState = {
/* e.g. Employee _emp.id
** Employee _emp.lastName
** Employee _emp.manager
*/
+ val constrainMe = if (optAttr.isDefined) sql.RelAliasAttribute(alias, optAttr.get) else sql.RelAliasAttribute(alias, sql.Attribute(sql.Name("_no_such_attribute")))
val reldesc = db.relationdescs(rel)
if (state.varmap.contains(v) && varToAttribute(state.varmap, v) != constrainMe) {
/* The variable has already been bound to another attribute. */
@@ -142,7 +143,7 @@
}
}
- def bindOnPredicate(db:sql.DatabaseDesc, stateP:R2RState, triple:sparql.TriplePattern, pk:PrimaryKey, enforceForeignKeys:Boolean):R2RState = {
+ def bindOnPredicate(db:sql.DatabaseDesc, stateP:R2RState, triple:sparql.TriplePattern, enforceForeignKeys:Boolean):R2RState = {
val sparql.TriplePattern(s, p, o) = triple
p match {
case sparql.PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
@@ -153,11 +154,10 @@
val relalias = relAliasFromS(s)
/* Attributes that come from the subject: */
- val subjattr = sql.RelAliasAttribute(relalias, pk.attr)
val objattr = sql.RelAliasAttribute(relalias, attr)
val state_postSubj = s match {
- case sparql.SUri(u) => uriConstraint(stateP, subjattr, u, true)
- case sparql.SVar(v) => varConstraint(stateP, subjattr, v, db, rel)
+ case sparql.SUri(u) => uriConstraint(stateP, sql.RelAliasAttribute(relalias, db.relationdescs(rel).primarykey.get), u, true)
+ case sparql.SVar(v) => varConstraint(stateP, relalias, db.relationdescs(rel).primarykey, v, db, rel)
}
val state_subjJoin = R2RState(state_postSubj.joins + sql.InnerJoin(sql.AliasedResource(rel,relalias)), state_postSubj.varmap, state_postSubj.exprs)
@@ -186,7 +186,7 @@
o match {
case sparql.OLit(l) => literalConstraint(state_fkeys, targetattr, l, dt)
case sparql.OUri(u) => uriConstraint (state_fkeys, targetattr, u, enforceForeignKeys)
- case sparql.OVar(v) => varConstraint (state_fkeys, targetattr, v, db, targetrel)
+ case sparql.OVar(v) => varConstraint (state_fkeys, targetattr.relalias, Some(targetattr.attribute), v, db, targetrel)
}
}
}
@@ -232,7 +232,7 @@
case StringMapper(relalias, disjoints) => relalias
case DateMapper(relalias, disjoints) => relalias
case RDFNoder(relation, relalias, disjoints) => relalias
- case RDFBNoder(relation, relalias, disjoints) => relalias
+ case RDFBNoder(relation, relalias, disjoints) => relalias // error("BNode should not need relalias " + relalias)
}
}
@@ -242,7 +242,7 @@
case StringMapper(relalias, disjoints) => disjoints
case DateMapper(relalias, disjoints) => disjoints
case RDFNoder(relation, relalias, disjoints) => disjoints
- case RDFBNoder(relation, relalias, disjoints) => disjoints
+ case RDFBNoder(relation, relalias, disjoints) => disjoints // error("BNode should not need join constraints " + relalias)
}
}
@@ -299,10 +299,10 @@
}
}
- def mapGraphPattern(db:sql.DatabaseDesc, state:R2RState, gp:sparql.GraphPattern, pk:PrimaryKey, enforceForeignKeys:Boolean):R2RState = {
+ def mapGraphPattern(db:sql.DatabaseDesc, state:R2RState, gp:sparql.GraphPattern, enforceForeignKeys:Boolean):R2RState = {
gp match {
case sparql.TableFilter(gp2:sparql.GraphPattern, expr:sparql.Expression) => {
- val state2 = mapGraphPattern(db, state, gp2, pk, enforceForeignKeys)
+ val state2 = mapGraphPattern(db, state, gp2, enforceForeignKeys)
/* Add constraints for all the FILTERS */
val filterExprs:Set[sql.RelationalExpression] =
@@ -312,12 +312,16 @@
}
case sparql.TriplesBlock(triplepatterns) => {
/* Examine each triple, updating the compilation state. */
- val state2 = triplepatterns.foldLeft(state)((incState,s) => bindOnPredicate(db, incState, s, pk, enforceForeignKeys))
- val nullExprs = findVars(gp) map (vvar => sql.RelationalExpressionNotNull(sql.PrimaryExpressionAttr(varToAttribute(state2.varmap, vvar))))
+ val state2 = triplepatterns.foldLeft(state)((incState,s) => bindOnPredicate(db, incState, s, enforceForeignKeys))
+ val nullExprs = findVars(gp).foldLeft(Set[sql.Expression]())((s, vvar) => {
+ state2.varmap(vvar) match {
+ case RDFBNoder(relation, relalias, disjoints) => s
+ case _ => s ++ Set(sql.RelationalExpressionNotNull(sql.PrimaryExpressionAttr(varToAttribute(state2.varmap, vvar))))
+ }})
R2RState(state2.joins, state2.varmap, state2.exprs ++ nullExprs)
}
case sparql.TableConjunction(list) => {
- list.foldLeft(state)((incState,s) => mapGraphPattern(db, incState, s, pk, enforceForeignKeys))
+ list.foldLeft(state)((incState,s) => mapGraphPattern(db, incState, s, enforceForeignKeys))
}
case sparql.TableDisjunction(list) => {
val unionAlias = sql.RelAlias(sql.Name("R_union" + state.joins.size))
@@ -330,7 +334,7 @@
val unionVars = list.foldLeft(Set[sparql.Var]())((mySet,disjoint) => mySet ++ findVars(disjoint)).toList
val (state2, disjoints, count) = list.foldLeft((state, initDisjoints, 0))((incPair,disjoint) => {
val (outerState, outerDisjoints, no) = incPair
- val disjointState = mapGraphPattern(db, emptyState, disjoint, pk, enforceForeignKeys)
+ val disjointState = mapGraphPattern(db, emptyState, disjoint, enforceForeignKeys)
val disjointVars = findVars(disjoint)
val disjointNo = sql.NamedAttribute(sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + no)), sql.AttrAlias(sql.Name("_DISJOINT_")))
@@ -405,7 +409,7 @@
Map[sparql.Var, SQL2RDFValueMapper](),
Set[sql.Expression]()
)
- val optionalState = mapGraphPattern(db, emptyState, gp, pk, enforceForeignKeys)
+ val optionalState = mapGraphPattern(db, emptyState, gp, enforceForeignKeys)
val optionalVars = findVars(gp)
val disjointNo = sql.NamedAttribute(sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + state.joins.size)), sql.AttrAlias(sql.Name("_DISJOINT_")))
@@ -478,7 +482,7 @@
}
}
- def apply (db:sql.DatabaseDesc, sparquery:sparql.Select, stem:StemURI, pk:PrimaryKey, enforceForeignKeys:Boolean, concat:Boolean) : sql.Select = {
+ def apply (db:sql.DatabaseDesc, sparquery:sparql.Select, stem:StemURI, enforceForeignKeys:Boolean, concat:Boolean) : sql.Select = {
val sparql.Select(attrs, triples) = sparquery
/* Create an object to hold our compilation state. */
@@ -488,7 +492,7 @@
Set[sql.Expression]()
)
- val r2rState = mapGraphPattern(db, initState, sparquery.gp, pk, enforceForeignKeys)
+ val r2rState = mapGraphPattern(db, initState, sparquery.gp, enforceForeignKeys)
/* Select the attributes corresponding to the variables
* in the SPARQL SELECT. */
--- a/src/test/scala/RDB2RDFTest.scala Tue Jan 05 13:39:13 2010 -0500
+++ b/src/test/scala/RDB2RDFTest.scala Wed Jan 06 17:24:50 2010 -0500
@@ -29,7 +29,7 @@
Attribute("manager") -> Value(Datatype.INTEGER),
Attribute("address") -> Value(Datatype.INTEGER))),
Relation("Manage") ->
- RelationDesc(None,
+ RelationDesc(Option(Attribute("id")),
Map(Attribute("manager") -> ForeignKey(Relation("Employee"), Attribute("id")),
Attribute("manages") -> ForeignKey(Relation("Employee"), Attribute("id"))))
))
@@ -50,7 +50,7 @@
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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
}
test("SELECT <x> { ?sf <p> <x>} (in-SQL Nodizer)") {
@@ -69,7 +69,7 @@
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)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true) === sqlSelect)
true
}
@@ -88,7 +88,7 @@
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)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, true) === sqlSelect)
true
}
@@ -107,7 +107,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
true
}
@@ -129,7 +129,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
true
}
@@ -149,7 +149,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
true
}
@@ -172,7 +172,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
}
test("transform tup1 no-enforce") {
@@ -191,7 +191,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform tup1 enforce") {
@@ -211,7 +211,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
}
@@ -235,7 +235,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, false) === sqlSelect)
+ assert(RDB2RDF(db, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
}
test("transform filter1") {
@@ -274,7 +274,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), true, false) === sqlSelect)
}
test("transform disj1") {
@@ -315,7 +315,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform assymDisj1") {
@@ -361,7 +361,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform assymDisj1 reversed") {
@@ -409,7 +409,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform assymDisj1 interspersed") {
@@ -457,7 +457,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform optJoin1") {
@@ -501,7 +501,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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform nestOpt") {
@@ -542,7 +542,7 @@
) 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, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}
test("transform equivOpt1") {
@@ -597,7 +597,7 @@
AND R_emp1.lastName IS NOT NULL
AND R_opt1.A_birthday IS NOT NULL
""").get
- assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false, false) === sqlSelect)
+ assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), false, false) === sqlSelect)
}