--- a/src/main/scala/SPARQL.scala Wed Dec 30 11:57:13 2009 -0500
+++ b/src/main/scala/SPARQL.scala Wed Dec 30 21:16:35 2009 -0500
@@ -17,7 +17,6 @@
sealed abstract class GraphPattern
case class TriplesBlock(triplepatterns:List[TriplePattern]) extends GraphPattern
-case class EmptyGraphPattern() extends GraphPattern
case class TableConjunction(gps:List[GraphPattern]) extends GraphPattern
case class TableDisjunction(gps:List[GraphPattern]) extends GraphPattern
case class TableFilter(gp:GraphPattern, expr:SparqlExpression) extends GraphPattern
@@ -96,24 +95,35 @@
"{" ~ opt(triplesblock) ~ rep(graphpatternnottriplesORfilter ~ opt(triplesblock)) ~ "}" ^^
{
case "{"~tbOPT~gpntORf_tbOPT~"}" => {
- var init = tbOPT match {
- case Some(x) => x
- case _ => EmptyGraphPattern()
- }
+
+// case class TriplesBlock(triplepatterns:List[TriplePattern]) extends GraphPattern
+// case class TableConjunction(gps:List[GraphPattern]) extends GraphPattern
+// case class TableDisjunction(gps:List[GraphPattern]) extends GraphPattern
+// case class TableFilter(gp:GraphPattern, expr:SparqlExpression) extends GraphPattern
+// case class OptionalGraphPattern(gp:GraphPattern) extends GraphPattern
+// case class GraphGraphPattern(gp:GraphPattern) extends GraphPattern
+
// println("groupgraphpattern: " + tbOPT + " " + gpntORf_tbOPT)
- gpntORf_tbOPT.foldLeft(init)((gp, lentry) => lentry match {
- case ~(TableFilter(null, expr), None) => TableFilter(gp, expr)
- case ~(TriplesBlock(triples), None) => gp match {
- case EmptyGraphPattern() => TriplesBlock(triples)
- case TriplesBlock(triples2) => TableConjunction(List(gp, TriplesBlock(triples2)))
- }
- case ~(TableDisjunction(list), None) => gp match {
- case EmptyGraphPattern() => TableDisjunction(list)
- case x => TableConjunction(List(gp, TableDisjunction(list)))
- }
- case ~(OptionalGraphPattern(gp2), None) => TableConjunction(List(gp, OptionalGraphPattern(gp2)))
+ val init:Option[GraphPattern] = tbOPT
+ gpntORf_tbOPT.foldLeft(init)((gp, lentry) => {//println("match: " + (gp, lentry))
+(gp, lentry) match {
+ case (Some(TriplesBlock(l)), ~(TableFilter(null, expr), None )) => Some(TableFilter(TriplesBlock(l), expr))
+ case (None, ~(TableFilter(null, expr), Some(TriplesBlock(r)))) => Some(TableFilter(TriplesBlock(r), expr))
+ case (Some(TriplesBlock(l)), ~(TableFilter(null, expr), Some(TriplesBlock(r)))) => Some(TableFilter(TriplesBlock(l ++ r), expr))
+ case (Some(TableFilter(TriplesBlock(l), SparqlExpression(lexp))), ~(TableFilter(null, SparqlExpression(expr)), Some(TriplesBlock(r)))) => Some(TableFilter(TriplesBlock(l ++ r), SparqlExpression(lexp ++ expr)))
+
+ // case (None, ~(TableConjunction(gps), None )) => TableConjunction(gps)
+ // case (Some(gp), ~(TableConjunction(gps), None )) => TableConjunction(List(List(gp) ++ gps))
+ // case (None, ~(TableConjunction(gps), Some(tb))) => TableConjunction(List(gps ++ List(tb)))
+ // case (Some(gp), ~(TableConjunction(gps), Some(tb))) => TableConjunction(List(List(gp) ++ gps ++ List(tb)))
+
+ case (None, ~(x, None )) => Some(x )
+ case (Some(gp), ~(x, None )) => Some(TableConjunction(List(gp, x )))
+ case (None, ~(x, Some(tb))) => Some(TableConjunction(List( x, tb)))
+ case (Some(gp), ~(x, Some(tb))) => Some(TableConjunction(List(gp, x, tb)))
+
case x => error("found " + x)
- })
+ }}).get
}
}
)
--- a/src/main/scala/SQL.scala Wed Dec 30 11:57:13 2009 -0500
+++ b/src/main/scala/SQL.scala Wed Dec 30 21:16:35 2009 -0500
@@ -1,6 +1,16 @@
package w3c.sw
import scala.util.parsing.combinator._
+
+object SQLParsers extends RegexParsers {
+
+ val int = """[0-9]+""".r
+ val chars = "\"[^\"]*\"".r
+}
+
+import SQLParsers._
+
+import scala.util.parsing.combinator._
import java.net.URI
case class Union(disjoints:Set[Select]) {
@@ -13,13 +23,25 @@
// foo, bar
override def toString = "SELECT "+(attributes mkString (",\n "))
}
-case class NamedAttribute(fqattribute:RelAliasAttribute, attralias:AttrAlias) {
- override def toString = fqattribute + " AS " + attralias
+case class NamedAttribute(value:RelAliasAttributeORConst, attralias:AttrAlias) {
+ override def toString = value + " AS " + attralias
}
//case class RelAttribute(relation:Relation, attribute:Attribute) c.f. ForeignKey
-case class RelAliasAttribute(relalias:RelAlias, attribute:Attribute) {
+sealed abstract class RelAliasAttributeORConst
+case class RelAliasAttribute(relalias:RelAlias, attribute:Attribute) extends RelAliasAttributeORConst {
override def toString = relalias + "." + attribute
}
+sealed abstract class Const extends RelAliasAttributeORConst
+case class ConstNULL() extends Const {
+ override def toString = "NULL"
+}
+case class ConstInt(i:String) extends Const {
+ override def toString = "" + i
+}
+case class ConstChars(s:String) extends Const {
+ override def toString = "\"" + s + "\""
+}
+
case class Attribute(n:Name) {
override def toString = n.s /* "'" + n.s + "'" */
}
@@ -108,14 +130,25 @@
repsep(namedattribute, ",") ^^ { l => AttributeList(l.toSet) }
def namedattribute:Parser[NamedAttribute] =
- fqattribute ~ "AS" ~ attralias ^^
- { case fqattribute ~ "AS" ~ attralias =>
- NamedAttribute(fqattribute, attralias) }
+ fqattributeORconst ~ "AS" ~ attralias ^^
+ { case fqattributeORconst ~ "AS" ~ attralias =>
+ NamedAttribute(fqattributeORconst, attralias) }
+
+ def fqattributeORconst:Parser[RelAliasAttributeORConst] = (
+ fqattribute ^^ { case fqattribute => fqattribute }
+ | const ^^ { case const => const }
+ )
def fqattribute:Parser[RelAliasAttribute] =
relalias ~ "." ~ attribute ^^
{ case relalias ~ "." ~ attribute => RelAliasAttribute(relalias, attribute) }
+ def const:Parser[Const] = (
+ "NULL" ^^ { case "NULL" => ConstNULL() }
+ | int ^^ { case i => ConstInt(i) }
+ | chars ^^ { case ch => ConstChars(ch) }
+ )
+
def attribute:Parser[Attribute] =
"""[a-zA-Z_]\w*""".r ^^ { x => Attribute(Name(x)) }
--- a/src/test/scala/SQLTest.scala Wed Dec 30 11:57:13 2009 -0500
+++ b/src/test/scala/SQLTest.scala Wed Dec 30 21:16:35 2009 -0500
@@ -161,4 +161,23 @@
assert(expected === (a.parseAll(a.select, e).get))
}
+ test("parse NULL as A_foo") {
+ // AliasedResource(Relation(Name("Employee")),RelAlias(Name("R_emp")))
+ val a = Sql()
+ val e = """
+SELECT R_above.manages AS A_who, NULL AS A_bday
+ FROM Manage AS R_above
+ WHERE R_above.id IS NOT NULL
+"""
+ val expected = Select(AttributeList(Set(NamedAttribute(RelAliasAttribute(RelAlias(Name("R_above")),
+ Attribute(Name("manages"))),
+ AttrAlias(Name("A_who"))),
+ NamedAttribute(ConstNULL(),
+ AttrAlias(Name("A_bday"))))),
+ TableList(Set(AliasedResource(Relation(Name("Manage")),RelAlias(Name("R_above"))))),
+ Expression(Set(
+ PrimaryExpressionNotNull(RelAliasAttribute(RelAlias(Name("R_above")),Attribute(Name("id")))))))
+ assert(expected === (a.parseAll(a.select, e).get))
+ }
+
}
--- a/src/test/scala/SparqlTest.scala Wed Dec 30 11:57:13 2009 -0500
+++ b/src/test/scala/SparqlTest.scala Wed Dec 30 21:16:35 2009 -0500
@@ -283,15 +283,13 @@
val tps =
SparqlSelect(
SparqlAttributeList(List(Var("x"))),
- TableConjunction(List(
- EmptyGraphPattern(),
- OptionalGraphPattern(
- TriplesBlock(
- List(
- TriplePattern(
- SVar(Var("x")),
- PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
- OVar(Var("y")))))))))
+ OptionalGraphPattern(
+ TriplesBlock(
+ List(
+ TriplePattern(
+ SVar(Var("x")),
+ PUri(Stem("http://hr.example/DB"),Rel("Employee"),Attr("manager")),
+ OVar(Var("y")))))))
assert(tps === a.parseAll(a.select, e).get)
}