--- a/src/main/scala/RDB2RDFMain.scala Sun Dec 27 15:05:58 2009 -0800
+++ b/src/main/scala/RDB2RDFMain.scala Sun Dec 27 16:44:52 2009 -0800
@@ -196,6 +196,15 @@
varS ++ varO
}
+ def findVars(gp:GraphPattern):Set[Var] = {
+ gp match {
+ case BasicGraphPattern(triplepatterns, filter:SparqlExpression) => {
+ /* Examine each triple, updating the compilation state. */
+ triplepatterns.foldLeft(Set[Var]())((x, y) => x ++ findVars(y))
+ }
+ }
+ }
+
def varToAttribute(varmap:Map[Var, SQL2RDFValueMapper], vvar:Var):RelAliasAttribute = {
varmap(vvar) match {
case StringMapper(relalias) => relalias
@@ -205,8 +214,8 @@
}
}
- def filter(varmap:Map[Var, SQL2RDFValueMapper], f:SparqlPrimaryExpression):PrimaryExpression = {
- val (lTerm:Term, rTerm:Term, sqlexpr:((RelAliasAttribute,RValueAttr)=>PrimaryExpression)) = f match {
+ def filter2expr(varmap:Map[Var, SQL2RDFValueMapper], f:SparqlPrimaryExpression):PrimaryExpression = {
+ val (lTerm:Term, rTerm:Term, sqlexpr) = f match { // sqlexpr::((RelAliasAttribute,RValueAttr)=>PrimaryExpression)
case SparqlPrimaryExpressionEq(l, r) => (l.term, r.term, PrimaryExpressionEq(_,_))
case SparqlPrimaryExpressionLt(l, r) => (l.term, r.term, PrimaryExpressionLt(_,_))
}
@@ -242,6 +251,27 @@
PrimaryExpressionNotNull(aattr)
}
+ def mapGraphPattern(db:DatabaseDesc, stateP:R2RState, gp:GraphPattern, pk:PrimaryKey, enforeForeignKeys:Boolean):R2RState = {
+ var state = stateP
+ gp match {
+ case BasicGraphPattern(triplepatterns, filter:SparqlExpression) => {
+ /* Examine each triple, updating the compilation state. */
+ triplepatterns.foreach(s => state = bindOnPredicate(db, state, s, pk, true))
+
+ /* Add constraints for all the FILTERS */
+ val filterExprs:Set[PrimaryExpression] =
+ filter.conjuncts.toSet map ((x:SparqlPrimaryExpression) => filter2expr(state.varmap, x))
+
+ // val allVars:Set[Var] = triples.triplepatterns.foldLeft(Set[Var]())((x, y) => x ++ findVars(y))
+ val allVars:Set[Var] = findVars(gp)
+ val nullExprs = allVars map (nullGuard(state.varmap, _))
+ //val exprWithNull = allVars.foldLeft(exprs)((exprs,s) => nullGuard(exprs, r2rState.varmap, s))
+
+ R2RState(state.joins, state.varmap, state.exprs ++ filterExprs ++ nullExprs)
+ }
+ }
+ }
+
def apply (db:DatabaseDesc, sparql:SparqlSelect, stem:StemURI, pk:PrimaryKey) : Select = {
val SparqlSelect(attrs, triples) = sparql
@@ -252,8 +282,7 @@
Set[PrimaryExpression]()
)
- /* Examine each triple, updating the compilation state. */
- triples.triplepatterns.foreach(s => r2rState = bindOnPredicate(db, r2rState, s, pk, true))
+ r2rState = mapGraphPattern(db, r2rState, sparql.gp, pk, true)
/* Select the attributes corresponding to the variables
* in the SPARQL SELECT. */
@@ -262,20 +291,11 @@
NamedAttribute(varToAttribute(r2rState.varmap, vvar), AttrAlias(Name("A_" + vvar.s)))
)
- /* Add constraints for all the FILTERS */
-
- val filterExprs:Set[PrimaryExpression] =
- triples.filter.conjuncts.toSet map ((x:SparqlPrimaryExpression) => filter(r2rState.varmap, x))
-
- val allVars:Set[Var] = triples.triplepatterns.foldLeft(Set[Var]())((x, y) => x ++ findVars(y))
- val nullExprs = allVars map (nullGuard(r2rState.varmap, _))
- //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(r2rState.exprs ++ filterExprs ++ nullExprs)
+ Expression(r2rState.exprs)
// Expression(exprWithNull)
)
}
--- a/src/main/scala/SPARQL.scala Sun Dec 27 15:05:58 2009 -0800
+++ b/src/main/scala/SPARQL.scala Sun Dec 27 16:44:52 2009 -0800
@@ -11,14 +11,15 @@
import MyParsers._
-case class SparqlSelect(attrs:SparqlAttributeList, triples:BasicGraphPattern)
+case class SparqlSelect(attrs:SparqlAttributeList, gp:GraphPattern)
case class SparqlAttributeList(attributelist:List[Var])
-case class BasicGraphPattern(triplepatterns:List[TriplePattern], filter:SparqlExpression)
+sealed abstract class GraphPattern
+case class BasicGraphPattern(triplepatterns:List[TriplePattern], filter:SparqlExpression) extends GraphPattern
+case class GroupGraphPattern(gps:List[GraphPattern]) extends GraphPattern
+
case class TriplePattern(s:S, p:P, o:O)
-
case class ObjUri(stem:Stem, rel:Rel, attr:Attr, v:CellValue)
-
case class CellValue(s:String)
sealed abstract class S
@@ -57,7 +58,7 @@
case class Sparql() extends JavaTokenParsers {
def select:Parser[SparqlSelect] =
- "SELECT" ~ attributelist ~ "{" ~ basicgraphpattern ~ "}" ^^ { case "SELECT"~a~"{"~t~"}" => SparqlSelect(a, t) }
+ "SELECT" ~ attributelist ~ "{" ~ graphpattern ~ "}" ^^ { case "SELECT"~a~"{"~t~"}" => SparqlSelect(a, t) }
def filter:Parser[SparqlExpression] =
"FILTER" ~ "(" ~ expression ~ ")" ^^ { case "FILTER"~"("~expression~")" => expression }
@@ -82,6 +83,16 @@
def attributelist:Parser[SparqlAttributeList] =
rep(varr) ^^ { SparqlAttributeList(_) }
+ def graphpattern:Parser[GraphPattern] = (
+ // "{"~graphpattern~"}" ^^ { case "{"~x~"}" => GroupGraphPattern(List(x)) }
+ groupgraphpattern ^^ { ggp => ggp }
+ | basicgraphpattern ^^ { bgp => bgp }
+ )
+
+ def groupgraphpattern:Parser[GraphPattern] = (
+ "{"~graphpattern~"}" ^^ { case "{"~x~"}" => GroupGraphPattern(List(x)) }
+ )
+
def basicgraphpattern:Parser[BasicGraphPattern] =
repsep(triplepattern, ".") ~ opt(filter) ^^ {
case pats~filter =>
--- a/src/test/scala/SparqlTest.scala Sun Dec 27 15:05:58 2009 -0800
+++ b/src/test/scala/SparqlTest.scala Sun Dec 27 16:44:52 2009 -0800
@@ -162,13 +162,13 @@
a.parseAll(a.select, e).get
}
-// test("parse a nested bgp") {
-// val a = Sparql()
-// val e = """
-// SELECT ?x { { ?x <p> ?y} }
-// """
-// a.parseAll(a.select, e).get
-// }
+ test("parse a nested bgp") {
+ val a = Sparql()
+ val e = """
+SELECT ?x { { ?x <p> ?y} }
+"""
+ a.parseAll(a.select, e).get
+ }
// test("parse a conjunction") {
// val a = Sparql()