--- a/src/main/scala/RDB2RDFMain.scala Wed Dec 16 19:26:42 2009 -0500
+++ b/src/main/scala/RDB2RDFMain.scala Thu Dec 17 00:37:34 2009 -0500
@@ -13,7 +13,7 @@
case class Enum(relaliasattr:RelAliasAttribute) extends Binding
object RDB2RDF {
- case class R2RState(allVars:Set[Var], inConstraint:Set[Var], joins:Set[AliasedResource], varmap:Map[Var, SQL2RDFValueMapper], exprs:Set[PrimaryExpression])
+ case class R2RState(joins:Set[AliasedResource], varmap:Map[Var, SQL2RDFValueMapper], exprs:Set[PrimaryExpression])
sealed abstract class SQL2RDFValueMapper(relaliasattr:RelAliasAttribute)
case class StringMapper(relaliasattr:RelAliasAttribute) extends SQL2RDFValueMapper(relaliasattr)
@@ -113,9 +113,10 @@
}
def acc(db:DatabaseDesc, state:R2RState, triple:TriplePattern, pk:PrimaryKey):R2RState = {
- var R2RState(allVars, inConstraint, joins, varmap, exprs) = state
+ var R2RState(joins, varmap, exprs) = state
val TriplePattern(s, p, o) = triple
p match {
+ case PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
case PUri(stem, spRel, spAttr) => {
val rel = Relation(Name(spRel.s))
val attr = Attribute(Name(spAttr.s))
@@ -133,7 +134,7 @@
}
joins += AliasedResource(rel,relalias)
- val target = db.relationdescs(rel).attributes(attr) match {
+ db.relationdescs(rel).attributes(attr) match {
case ForeignKey(fkrel, fkattr) => {
val oRelAlias = relAliasFromO(o)
val fkaliasattr = RelAliasAttribute(oRelAlias, fkattr)
@@ -164,7 +165,6 @@
case OLit(l) => exprs += literalConstraint(objattr, l, dt)
case OUri(u) => exprs += uriConstraint(objattr, u)
case OVar(v) => {
- allVars += v
// !! 2nd+ ref implies constraint
val binding = varConstraint(objattr, v, db, rel)
varmap += v -> binding
@@ -173,9 +173,22 @@
}
}
}
- case PVar(v) => error("variable predicates require tedious enumeration; too tedious for me.")
+
}
- R2RState(allVars, inConstraint, joins, varmap, exprs)
+ R2RState(joins, varmap, exprs)
+ }
+
+ def findVars(triple:TriplePattern):Set[Var] = {
+ val TriplePattern(s, p, o) = triple
+ val varS:Set[Var] = s match {
+ case SVar(v) => Set(v)
+ case _ => Set()
+ }
+ val varO:Set[Var] = o match {
+ case OVar(v) => Set(v)
+ case _ => Set()
+ }
+ varS ++ varO
}
def varToAttribute(varmap:Map[Var, SQL2RDFValueMapper], vvar:Var):RelAliasAttribute = {
@@ -186,11 +199,8 @@
}
}
- def filter(exprsP:Set[PrimaryExpression], inConstraintP:Set[Var], varmap:Map[Var, SQL2RDFValueMapper], f:SparqlPrimaryExpression):Tuple2[Set[PrimaryExpression], Set[Var]] = {
+ def filter(exprsP:Set[PrimaryExpression], varmap:Map[Var, SQL2RDFValueMapper], f:SparqlPrimaryExpression):Set[PrimaryExpression] = {
var exprs = exprsP
- var inConstraint = inConstraintP
- // var f = SparqlPrimaryExpressionEq
- // val e:SparqlPrimaryExpression = f(SparqlTermExpression(Term(TermVar(Var("a")))), SparqlTermExpression(Term(TermVar(Var("a")))))
val tup:Tuple3[Term, Term, String] = f match {
case SparqlPrimaryExpressionEq(l, r) => (l.term, r.term, "==")
case SparqlPrimaryExpressionLt(l, r) => (l.term, r.term, "<")
@@ -198,12 +208,10 @@
tup._1 match {
case TermUri(obj) => error("only SPARQL PrimaryExpressions with a variable on the left have been implemented: punting on " + f)
case TermVar(v) => { // :Var
- inConstraint += v
val l = varToAttribute(varmap, v)
val r = tup._2 match {
case TermUri(obj) => null // :ObjUri
case TermVar(v) => { // :Var
- inConstraint += v
RValueAttr(varToAttribute(varmap, v))
}
case TermLit(lit) => null // :SparqlLiteral => RValueTyped(SQLDatatype, lit.n)
@@ -212,27 +220,21 @@
case "==" => exprs += PrimaryExpressionEq(l, r)
case _ => exprs += PrimaryExpressionLt(l, r)
}
- (exprs, inConstraint)
+ exprs
}
case TermLit(lit) => error("only SPARQL PrimaryExpressions with a variable on the left have been implemented: punting on " + f)
}
}
- def nullGuard(exprs:Set[PrimaryExpression], inConstraint:Set[Var], varmap:Map[Var, SQL2RDFValueMapper], vvar:Var):Set[PrimaryExpression] = {
+ def nullGuard(exprs:Set[PrimaryExpression], varmap:Map[Var, SQL2RDFValueMapper], vvar:Var):Set[PrimaryExpression] = {
var ret = exprs
- inConstraint contains(vvar) match {
- case false => {
- val mapper:SQL2RDFValueMapper = varmap(vvar)
- val aattr = mapper match {
- case StringMapper(relalias) => relalias
- case IntMapper(relalias) => relalias
- case RDFNoder(relation, relalias) => relalias
- }
- ret += PrimaryExpressionNotNull(aattr)
- }
- case true =>
+ val mapper:SQL2RDFValueMapper = varmap(vvar)
+ val aattr = mapper match {
+ case StringMapper(relalias) => relalias
+ case IntMapper(relalias) => relalias
+ case RDFNoder(relation, relalias) => relalias
}
- ret
+ ret + PrimaryExpressionNotNull(aattr)
}
def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey) : Select = {
@@ -240,8 +242,6 @@
/* Create an object to hold our compilation state. */
var r2rState = R2RState(
- Set[Var](),
- Set[Var](),
Set[AliasedResource](),
Map[Var, SQL2RDFValueMapper](),
Set[PrimaryExpression]()
@@ -257,25 +257,22 @@
NamedAttribute(varToAttribute(r2rState.varmap, vvar), AttrAlias(Name("A_" + vvar.s)))
)
- var exprs:Set[PrimaryExpression] = r2rState.exprs
- var inConstraint:Set[Var] = r2rState.inConstraint
-
/* Add constraints for all the FILTERS */
- triples.filter.conjuncts.foreach(f => {
- val pair = filter(exprs, inConstraint, r2rState.varmap, f)
- exprs = pair._1
- inConstraint = pair._2
- })
- /* Add null guards for attributes associated with variables which
- * are not optional and have not been used in constraints. */
- r2rState.allVars.foreach(s => exprs = nullGuard(exprs, inConstraint, r2rState.varmap, s))
+ def it(exprs:Set[PrimaryExpression], primaryExpr:SparqlPrimaryExpression) = {
+ filter(exprs, r2rState.varmap, primaryExpr)
+ }
+
+ val exprs = triples.filter.conjuncts.foldLeft(r2rState.exprs)(it(_, _))
+
+ val allVars:Set[Var] = triples.triplepatterns.foldLeft(Set[Var]())((x, y) => x ++ findVars(y))
+ val exprWithNull = allVars.foldLeft(exprs)((exprs,s) => nullGuard(exprs, r2rState.varmap, s))
/* Construct the generated query as an abstract syntax. */
Select(
AttributeList(attrlist),
TableList(r2rState.joins),
- Expression(exprs)
+ Expression(exprWithNull)
)
}
}
--- a/src/test/scala/RDB2RDFTest.scala Wed Dec 16 19:26:42 2009 -0500
+++ b/src/test/scala/RDB2RDFTest.scala Thu Dec 17 00:37:34 2009 -0500
@@ -43,7 +43,7 @@
SELECT R_emp.id 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
+ 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")))) === sqlSelect)
true
@@ -63,7 +63,7 @@
SELECT R_emp.id AS A_emp
FROM Employee AS R_emp
INNER JOIN Employee AS R_18
- WHERE R_18.id=R_emp.manager AND R_18.id=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")))) === sqlSelect)
true
@@ -84,6 +84,8 @@
FROM Employee AS R_emp
INNER JOIN Employee AS R_manager
WHERE R_manager.id=R_emp.manager AND R_emp.lastName IS NOT NULL AND R_manager.lastName IS NOT NULL
+ 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")))) === sqlSelect)
}
@@ -102,6 +104,7 @@
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.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")))) === sqlSelect)
}
@@ -122,6 +125,8 @@
FROM Employee AS R_emp
INNER JOIN Employee AS R_manager
WHERE R_manager.id=R_emp.manager AND R_manager.lastName="Johnson" AND R_emp.lastName IS NOT NULL
+ 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")))) === sqlSelect)
}
@@ -151,6 +156,14 @@
INNER JOIN Manage AS R_upper
INNER JOIN Employee AS R_grandManager
WHERE R_emp.id=R_lower.manages AND R_manager.id=R_lower.manager AND R_manager.id=R_upper.manages AND R_grandManager.id=R_upper.manager AND R_manager.birthday < R_emp.birthday AND R_grandManager.birthday < R_manager.birthday AND R_emp.lastName IS NOT NULL AND R_grandManager.lastName IS NOT NULL
+ AND R_emp.id IS NOT NULL
+ AND R_lower.id IS NOT NULL
+ AND R_manager.id IS NOT NULL
+ AND R_upper.id IS NOT NULL
+ AND R_grandManager.id IS NOT NULL
+ AND R_emp.birthday IS NOT NULL
+ 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")))) === sqlSelect)
}