--- a/src/main/scala/SparqlToSql.scala Thu May 20 11:55:05 2010 +0200
+++ b/src/main/scala/SparqlToSql.scala Thu May 20 12:55:21 2010 +0200
@@ -897,13 +897,26 @@
mySet ++ disjoint.findVars).toList // all variables nested in the disjoints.
/**
- * Map the disjoints to subselects.
+ * Map the list of disjoints to a list of nested R2RStates, nested variable lists, and unique SQL constants identifying that disjoint.
* Non-Functional var <code>number</code> is used for projecting unique
* constants to indicate which disjoint produced a tuple.
*/
var number = 0
- val subselects = disjoints.foldLeft(Set[sql.Select]())((subselects, disjoint) => {
+ val nestedStates = disjoints.map(disjoint => {
val disjointState = mapGraphPattern(db, emptyState, disjoint, enforceForeignKeys)
+ val disjointVars = disjoint.findVars
+ val uniqueConst = sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + number))
+ number = number + 1 // non-functional, but clearer than wrapping as a parameter in a foldLeft
+ (disjointState, disjointVars, uniqueConst)
+ })
+
+ /**
+ * Map the list of nested R2RStates to a set of subselects.
+ * <code>uniqueConst</code> is used for projecting a value
+ * to indicate which disjoint produced a tuple.
+ */
+ val subselects = nestedStates.foldLeft(Set[sql.Select]())((subselects, state) => {
+ val (disjointState, disjointVars, uniqueConst) = state
/**
* Select a constant as _DISJOINT_ so later constraints can be
* sensitive to whether a variable was bound.
@@ -914,7 +927,7 @@
* coreference constraints against ?v2 should only be enforced for
* tuples from the right side of this union.
*/
- val pathNo = sql.NamedAttribute(sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + number)),
+ val pathNo = sql.NamedAttribute(uniqueConst,
sql.AttrAlias(sql.Name("_DISJOINT_")))
val attrlist:Set[sql.NamedAttribute] = unionVars.foldLeft(Set(pathNo))((attrs, v) => {
@@ -931,24 +944,21 @@
case _ => Some(sql.ExprConjunction(disjointState.exprs))
}
)
- number = number + 1 // non-functional, but clearer than wrapping as a parameter in a foldLeft
subselects + subselect
})
/**
* Connect the variables projected from the nested selects into the outer variable bindings and constraints.
* <code>state2</code> will have no additional tables in the TableList.
- * <code>number</code> is again used for projecting unique
- * constants to indicate which disjoint produced a tuple.
+ * <code>uniqueConst</code> is used this time to constraint coreferences between the
+ * subselects and the outer context.
*/
- number = 0
- val state2 = disjoints.foldLeft(state)((outerState, disjoint) => {
- val disjointState = mapGraphPattern(db, emptyState, disjoint, enforceForeignKeys)
- val disjointVars = disjoint.findVars
+ val state2 = nestedStates.foldLeft(state)((outerState, state) => {
+ val (disjointState, disjointVars, uniqueConst) = state
/** Create a condition to test if this disjoint was matched. */
val disjointCond = sql.RelationalExpressionNe(sql.PrimaryExpressionAttr(sql.RelVarAttr(unionAlias, sql.Attribute(sql.Name("_DISJOINT_")))),
- sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("" + number)))
+ uniqueConst)
val outerState2 = disjointVars.foldLeft(outerState)((myState, v) =>
subselectVars(myState, sparql.VarAssignable(v), unionAlias, disjointCond, outerState.varmap, disjointState.varmap, false))
number = number + 1 // non-functional, but clearer than wrapping as a parameter in a foldLeft