--- a/src/main/scala/RDB2RDFMain.scala Fri Jan 01 13:30:44 2010 -0500
+++ b/src/main/scala/RDB2RDFMain.scala Fri Jan 01 21:27:50 2010 -0500
@@ -99,8 +99,7 @@
val constraint = RelationalExpressionEq(varToAttribute(state.varmap, v), RValueAttr(constrainMe))
R2RState(state.joins, state.varmap,
if (varToAttributeDisjoints(state.varmap, v).size > 0) {
- val s:Set[Expression] = varToAttributeDisjoints(state.varmap, v) map ((d) => ExprDisjunction(Set(d, constraint)))
- state.exprs ++ s
+ state.exprs ++ {varToAttributeDisjoints(state.varmap, v) map ((d) => ExprDisjunction(Set(d, constraint)))}
} else
state.exprs + constraint
)
@@ -320,21 +319,32 @@
val varAliasAttr = RelAliasAttribute(unionAlias, Attribute(Name("A_" + v.s)))
if (myState.varmap.contains(v)) {
/* The variable has already been bound. */
- if (varToAttribute(myState.varmap, v) == varAliasAttr) {
+ val newMap:Map[Var, SQL2RDFValueMapper] = if (varToAttribute(myState.varmap, v) == varAliasAttr) {
/* Same var was bound in an earlier disjoint. */
val oldDisjoints = varToAttributeDisjoints(myState.varmap, v)
// myState
- val mapper:SQL2RDFValueMapper = disjointState.varmap(v) match {
+ Map(v -> { disjointState.varmap(v) match {
case IntMapper(_, _) => IntMapper(varAliasAttr, oldDisjoints + disjointCond)
case StringMapper(_, _) => StringMapper(varAliasAttr, oldDisjoints + disjointCond)
- case DateMapper(_, _) => DateMapper(varAliasAttr, oldDisjoints + disjointCond)
+ case DateMapper(_, _) => DateMapper(varAliasAttr, oldDisjoints + disjointCond)
case RDFNoder(rel, _, _) => RDFNoder(rel, varAliasAttr, oldDisjoints + disjointCond)
case RDFBNoder(rel, _, _) => RDFBNoder(rel, varAliasAttr, oldDisjoints + disjointCond)
+ } } )
+ } else
+ Map()
+ val newConstraints =
+ if (varToAttribute(outerState.varmap, v) != varAliasAttr) {
+ /* Constraint against binding from earlier GP. */
+ val constraint = RelationalExpressionEq(varToAttribute(outerState.varmap, v), RValueAttr(varAliasAttr))
+ if (varToAttributeDisjoints(outerState.varmap, v).size > 0)
+ // (union0._DISJOINT_ != 0 AND union1._DISJOINT_ != 2) OR union0.x=union1.x
+ varToAttributeDisjoints(outerState.varmap, v) map ((d) => ExprDisjunction(Set(ExprConjunction(Set(d, disjointCond)), constraint)))
+ else
+ Set(ExprDisjunction(Set(disjointCond, constraint)))
+ } else {
+ Set()
}
- R2RState(myState.joins, myState.varmap + (v -> mapper), myState.exprs)
- } else
- /* Constraint against the initial binding for this variable. */
- R2RState(myState.joins, myState.varmap, myState.exprs + RelationalExpressionEq(varToAttribute(myState.varmap, v), RValueAttr(varAliasAttr)))
+ R2RState(myState.joins, myState.varmap ++ newMap, myState.exprs ++ newConstraints)
} else {
/* This variable is new to the outer context. */
val mapper:SQL2RDFValueMapper = disjointState.varmap(v) match {
--- a/src/test/scala/RDB2RDFTest.scala Fri Jan 01 13:30:44 2010 -0500
+++ b/src/test/scala/RDB2RDFTest.scala Fri Jan 01 21:27:50 2010 -0500
@@ -268,7 +268,9 @@
WHERE R_below.manages=R_managed.id AND R_managed.lastName IS NOT NULL
AND R_below.manager IS NOT NULL AND R_below.id IS NOT NULL AND R_below.manages IS NOT NULL
) AS R_union1
- WHERE R_who.id=R_union1.A_who AND R_who.lastName="Smith" AND R_who.id IS NOT NULL
+ WHERE R_who.lastName="Smith" AND R_who.id IS NOT NULL AND
+ (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)
}
@@ -318,4 +320,100 @@
""").get
assert(RDB2RDF(db2, sparqlSelect, StemURI("http://hr.example/DB/"), PrimaryKey(Attribute(Name("id"))), false) === sqlSelect)
}
+
+ test("transform assymDisj1 reversed") {
+ val sparqlParser = Sparql()
+ val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+PREFIX manP : <http://hr.example/DB/Manage#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+SELECT ?name
+ {
+ ?who empP:lastName "Smith"^^xsd:string .
+ ?who empP:birthday ?bday
+ { ?above manP:manages ?who .
+ ?above manP:manager ?manager .
+ ?manager empP:lastName ?name }
+ UNION
+ { ?below manP:manager ?who .
+ ?below manP:manages ?managed .
+ ?managed empP:lastName ?name .
+ ?managed empP:birthday ?bday }
+ }
+""").get
+ val sqlParser = Sql()
+ val sqlSelect = sqlParser.parseAll(sqlParser.select, """
+SELECT R_union1.A_name AS A_name
+ FROM Employee AS R_who
+ INNER JOIN ( SELECT 0 AS _DISJOINT_, R_above.manager AS A_manager, R_manager.lastName AS A_name, R_above.id AS A_above,
+ NULL AS A_below, NULL AS A_bday, R_above.manages AS A_who, NULL AS A_managed
+ FROM Manage AS R_above
+ INNER JOIN Employee AS R_manager
+ WHERE R_above.manager IS NOT NULL AND R_above.manager=R_manager.id AND R_above.id IS NOT NULL
+ AND R_above.manages IS NOT NULL AND R_manager.lastName IS NOT NULL
+ UNION
+ SELECT 1 AS _DISJOINT_, NULL AS A_manager, R_managed.lastName AS A_name, NULL AS A_above,
+ R_below.id AS A_below, R_managed.birthday AS A_bday, R_below.manager AS A_who, R_below.manages AS A_managed
+ FROM Manage AS R_below
+ INNER JOIN Employee AS R_managed
+ WHERE R_managed.birthday IS NOT NULL AND R_below.manager IS NOT NULL AND R_below.id IS NOT NULL
+ AND R_below.manages=R_managed.id AND R_below.manages IS NOT NULL AND R_managed.lastName IS NOT NULL
+ ) AS R_union1
+ WHERE R_who.lastName="Smith" AND
+ (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) AND
+ (R_union1._DISJOINT_!=1 OR R_who.birthday=R_union1.A_bday) AND
+ 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)
+ }
+
+ test("transform assymDisj1 interspersed") {
+ val sparqlParser = Sparql()
+ val sparqlSelect = sparqlParser.parseAll(sparqlParser.select, """
+PREFIX empP : <http://hr.example/DB/Employee#>
+PREFIX manP : <http://hr.example/DB/Manage#>
+PREFIX xsd : <http://www.w3.org/2001/XMLSchema#>
+SELECT ?name
+ {
+ ?who empP:lastName "Smith"^^xsd:string
+ { ?above manP:manages ?who .
+ ?above manP:manager ?manager .
+ ?manager empP:lastName ?name }
+ UNION
+ { ?below manP:manager ?who .
+ ?below manP:manages ?managed .
+ ?managed empP:lastName ?name .
+ ?managed empP:birthday ?bday }
+ ?who empP:birthday ?bday
+ }
+""").get
+ val sqlParser = Sql()
+ val sqlSelect = sqlParser.parseAll(sqlParser.select, """
+SELECT R_union1.A_name AS A_name
+ FROM Employee AS R_who
+ INNER JOIN ( SELECT 0 AS _DISJOINT_, R_above.manager AS A_manager, R_manager.lastName AS A_name, R_above.id AS A_above,
+ NULL AS A_below, NULL AS A_bday, R_above.manages AS A_who, NULL AS A_managed
+ FROM Manage AS R_above
+ INNER JOIN Employee AS R_manager
+ WHERE R_above.manager IS NOT NULL AND R_above.manager=R_manager.id AND R_above.id IS NOT NULL
+ AND R_above.manages IS NOT NULL AND R_manager.lastName IS NOT NULL
+ UNION
+ SELECT 1 AS _DISJOINT_, NULL AS A_manager, R_managed.lastName AS A_name, NULL AS A_above,
+ R_below.id AS A_below, R_managed.birthday AS A_bday, R_below.manager AS A_who, R_below.manages AS A_managed
+ FROM Manage AS R_below
+ INNER JOIN Employee AS R_managed
+ WHERE R_managed.birthday IS NOT NULL AND R_below.manager IS NOT NULL AND R_below.id IS NOT NULL
+ AND R_below.manages=R_managed.id AND R_below.manages IS NOT NULL AND R_managed.lastName IS NOT NULL
+ ) AS R_union1
+ WHERE R_who.lastName="Smith" AND
+ (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) AND
+ (R_union1._DISJOINT_!=1 OR R_union1.A_bday=R_who.birthday) AND
+ 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)
+ }
}