--- a/src/main/scala/RDB2RDFMain.scala Thu Jan 07 10:48:43 2010 -0500
+++ b/src/main/scala/RDB2RDFMain.scala Thu Jan 07 11:09:08 2010 -0500
@@ -323,25 +323,24 @@
case sparql.TableConjunction(list) => {
list.foldLeft(state)((incState,s) => mapGraphPattern(db, incState, s, enforceForeignKeys))
}
- case sparql.TableDisjunction(list) => {
+ case sparql.TableDisjunction(disjoints) => {
/* SPARQL UNIONs are treated as SQL subselects.
* Set up initial state for this subselect.
*/
val unionAlias = sql.RelAlias(sql.Name("R_union" + state.joins.size))
- val initDisjoints:Set[sql.Select] = Set()
val emptyState = R2RState(
util.AddOrderedSet[sql.Join](),
Map[sparql.Var, SQL2RDFValueMapper](),
Set[sql.Expression]()
)
- val unionVars = list.foldLeft(Set[sparql.Var]())((mySet,disjoint) => mySet ++ findVars(disjoint)).toList
+ val unionVars = disjoints.foldLeft(Set[sparql.Var]())((mySet,disjoint) => mySet ++ findVars(disjoint)).toList
- /* Iterate over the disjoints, accumulating a state and a select for each
- * disjoint. The count is used for uniquely naming flags in the SELECTs
- * used to indicate which disjoint produced a tuple.
+ /* Map the disjoints to subselects.
+ * <no> is used for uniquely naming flags in the SELECTs used to
+ * indicate which disjoint produced a tuple.
*/
- val (state2, disjoints, count) = list.foldLeft((state, initDisjoints, 0))((incPair,disjoint) => {
- val (outerState, outerDisjoints, no) = incPair
+ val (subselects, _) = disjoints.foldLeft((Set[sql.Select](), 0))((incPair,disjoint) => {
+ val (subselects, no) = incPair
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_")))
@@ -360,6 +359,19 @@
case _ => Some(sql.ExprConjunction(disjointState.exprs))
}
)
+ (subselects + subselect, no+1)
+ })
+
+ /* Bind variables to the attributes projected from the subselect; handle
+ * corefs (equivalence with earlier bindings).
+ * <no> is used for uniquely naming flags in the SELECTs used to
+ * indicate which disjoint produced a tuple.
+ */
+ val (state2, _) = disjoints.foldLeft((state, 0))((incPair,disjoint) => {
+ val (outerState, no) = incPair
+ val disjointState = mapGraphPattern(db, emptyState, disjoint, enforceForeignKeys)
+ val disjointVars = findVars(disjoint)
+
val disjointNoAliasAttr = sql.RelAliasAttribute(unionAlias, sql.Attribute(sql.Name("_DISJOINT_")))
val disjointCond = sql.RelationalExpressionNe(sql.PrimaryExpressionAttr(disjointNoAliasAttr), sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + no)))
val outerState2 = disjointVars.foldLeft(outerState)((myState, v) => {
@@ -404,9 +416,9 @@
R2RState(myState.joins, myState.varmap + (v -> mapper), myState.exprs)
}
})
- (outerState2, outerDisjoints ++ Set(subselect), no+1)
+ (outerState2, no+1)
})
- val subselect = sql.Subselect(sql.Union(disjoints))
+ val subselect = sql.Subselect(sql.Union(subselects))
R2RState(state.joins + sql.InnerJoin(sql.AliasedResource(subselect,unionAlias)), state2.varmap, state2.exprs)
}
case sparql.OptionalGraphPattern(gp) => {