+ DISTINCT
authorEric Prud'hommeaux <eric@w3.org>
Sun, 13 Jun 2010 09:56:13 -0400
changeset 213 941993f6828e
parent 212 edd471aefc0c
child 214 32e8f17bf5ce
+ DISTINCT
+ OFFSET
+ LIMIT
src/main/scala/SPARQL.scala
src/main/scala/SQL.scala
src/main/scala/SparqlToSparql.scala
src/main/scala/SparqlToSparqlToSql.scala
src/main/scala/SparqlToSql.scala
src/test/scala/SQLTest.scala
src/test/scala/SparqlToSparqlToSqlTest.scala
--- a/src/main/scala/SPARQL.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/main/scala/SPARQL.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -18,15 +18,16 @@
 
 case class Select(distinct:Boolean, attrs:SparqlAttributeList, gp:GraphPattern, order:List[OrderElt], offset:Option[Int], limit:Option[Int]) {
   override def toString =
+    "SELECT "+
     { if (distinct) "DISTINCT " else "" }+
-    attrs+"\n"+gp+
-    { if (order.size > 0) { "ORDER BY " + order.map(o => o.toString).mkString(" ") } else "" }+
-    { if (offset.isDefined) {"OFFSET " + offset } else "" }+
-    { if (limit.isDefined) {"LIMIT " + limit } else "" }
+    attrs+"\n"+gp+" "+
+    { if (order.size > 0) {order.map(o => o.toString).mkString("ORDER BY ", " ", " ") } else "" }+
+    { if (offset.isDefined) {"OFFSET " + offset + " "} else "" }+
+    { if (limit.isDefined) {"LIMIT " + limit + " "} else "" }
 }
 case class Construct(head:TriplesBlock, gp:GraphPattern)
 case class SparqlAttributeList(attributelist:List[Var]) {
-  override def toString = "SELECT "+(attributelist.toList.sortWith((l, r) => l.s < r.s).mkString(" "))
+  override def toString = attributelist.toList.sortWith((l, r) => l.s < r.s).mkString(" ")
 }
 
 sealed abstract class GraphPattern {
--- a/src/main/scala/SQL.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/main/scala/SQL.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -19,11 +19,16 @@
   override def toString = "(\n       " + sel.toString.replace("\n", "\n       ") + "\n                  )"
 }
 sealed abstract class SelectORUnion
-case class Select(attributelist:AttributeList, tablelist:TableList, expression:Option[Expression]) extends SelectORUnion {
-  override def toString = expression match {
-    case Some(expr) => attributelist+"\n"+tablelist+"\n WHERE "+expr
-    case None => attributelist+"\n"+tablelist
-  }
+case class Select(distinct:Boolean, attributelist:AttributeList, tablelist:TableList, expression:Option[Expression], order:List[OrderElt], offset:Option[Int], limit:Option[Int]) extends SelectORUnion {
+  override def toString = 
+    "SELECT "+
+    { if (distinct) "DISTINCT " else "" }+
+    attributelist+"\n"+
+    tablelist+
+    { if (expression.isDefined) {"\b WHERE " + expression.get + " "} else "" }+
+    { if (order.size > 0) {order.map(o => o.toString).mkString("ORDER BY ", " ", " ") } else "" }+
+    { if (offset.isDefined) {"OFFSET " + offset + " "} else "" }+
+    { if (limit.isDefined) {"LIMIT " + limit + " "} else "" }
 }
 case class Relation(n:Name) extends RelationORSubselect {
   override def toString = n.s /* "'" + n.s + "'" */
@@ -33,7 +38,7 @@
 }
 case class AttributeList(attributes:Set[NamedAttribute]) {
   // foo, bar
-  override def toString = "SELECT "+(attributes.toList.sortWith((l, r) => l.attralias.toString < r.attralias.toString).mkString(", "))
+  override def toString = attributes.toList.sortWith((l, r) => l.attralias.toString < r.attralias.toString).mkString(", ")
 }
 case class NamedAttribute(value:RelVarAttrORExpression, attralias:AttrAlias) {
   override def toString = value + " AS " + attralias
@@ -136,6 +141,9 @@
       case _ => "\"" + i.s + "\""
     }
 }
+case class OrderElt(desc:Boolean, expr:Expression) {
+  override def toString = { if (desc) "DESC" else "ASC" } + "(" + expr.toString + ")"
+}
 case class ConstNULL() extends PrimaryExpression {
   override def toString = "NULL"
 }
@@ -254,9 +262,9 @@
     rep1sep(select, "UNION") ^^ { l => if (l.size == 1) l(0) else Union(l.toSet) }
 
   def select:Parser[Select] =
-    "SELECT" ~ attributelist ~ opt(tablelist) ~ opt(where) ^^
+    "SELECT" ~ opt("DISTINCT") ~ attributelist ~ opt(tablelist) ~ opt(where) ~ opt(order) ~ opt(offset) ~ opt(limit) ^^
     {
-      case "SELECT" ~ attributes ~ tablesANDons ~ whereexpr => {
+      case "SELECT" ~ distinct ~ attributes ~ tablesANDons ~ whereexpr ~ order ~ offset ~ limit => {
 	val (tables, onExpressions) =
 	  tablesANDons.getOrElse((TableList(AddOrderedSet[Join]()), Set[Expression]()))
 	val t:Set[Expression] = onExpressions
@@ -276,10 +284,25 @@
 	  case 1 => Some(conjoints.toList(0))
 	  case _ => Some(ExprConjunction(conjoints))
 	}
-	Select(attributes, tables, expr)
+	Select(distinct.isDefined, attributes, tables, expr, order.getOrElse(List[OrderElt]()), offset, limit)
       }
     }
 
+  def order:Parser[List[OrderElt]] = 
+    "ORDER" ~ "BY" ~ rep(orderelt) ^^ { case o~b~elts => elts }
+
+  def orderelt:Parser[OrderElt] = (
+      "ASC" ~ "(" ~ expression ~ ")" ^^ { case a~o~expr~c => OrderElt(false, expr) }
+    | "DESC" ~ "(" ~ expression ~ ")" ^^ { case a~o~expr~c => OrderElt(true, expr) }
+    | fqattribute ^^ { case v => OrderElt(false, PrimaryExpressionAttr(v)) }
+  )
+    
+  def offset:Parser[Int] =
+    "OFFSET" ~ int ^^ { case o~i => i.toInt }
+
+  def limit:Parser[Int] =
+    "LIMIT" ~ int ^^ { case o~i => i.toInt }
+
   def where:Parser[Expression] =
     "WHERE" ~ expression ^^ { case "WHERE" ~ expression => expression }
 
@@ -375,7 +398,7 @@
 
 case class PrettySql(select:Select) {
   def makePretty():Select = {
-    val Select(attributelist, tablelist, expression) = select
+    val Select(distinct, attributelist, tablelist, expression, order, offset, limit) = select
     val nullStripped =
       if (expression.isDefined) {
 	val nonNullAttrs = PrettySql.findNonNullRelVarAttrs(expression.get)
@@ -400,7 +423,7 @@
 	  case r:Relation => r
 	}}, as), on)
       }})
-    Select(attributelist, TableList(strippedTables), XeqXStripped)
+    Select(distinct, attributelist, TableList(strippedTables), XeqXStripped, order, offset, limit)
   }
 }
 
--- a/src/main/scala/SparqlToSparql.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/main/scala/SparqlToSparql.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -302,10 +302,10 @@
     })
     //println("ruleMap: " + ruleMap)
     sparql.Select(
-      false,
+      query.distinct,
       query.attrs,
       mapGraphPattern(query.gp, ruleMap, "_"),
-      List[sparql.OrderElt](), None, None
+      query.order, query.offset, query.limit
     )
   }
 
--- a/src/main/scala/SparqlToSparqlToSql.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/main/scala/SparqlToSparqlToSql.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -50,11 +50,11 @@
 	val asStem = sparql2sparql.SparqlToSparql(select, List(rule))
 	// println("triple: "+triple)
 	// println("asStem: "+asStem)
-	val sql.Select(sql.AttributeList(attributes), tablelist, expression) = sparql2sql.SparqlToSql(schema, asStem, stemUri, false, true)._1
+	val sql.Select(distinct, sql.AttributeList(attributes), tablelist, expression, order,  offset, limit) = sparql2sql.SparqlToSql(schema, asStem, stemUri, false, true)._1
 	// println("SQL: "+sql.Select(sql.AttributeList(attributes ++ sconsts ++ pconsts ++ oconsts), tablelist, expression))
 
 	/* Add resulting SELECT to list of graph patterns. */
-	gps :+ sql.Select(sql.AttributeList(attributes ++ sconsts ++ pconsts ++ oconsts), tablelist, expression)
+	gps :+ sql.Select(distinct, sql.AttributeList(attributes ++ sconsts ++ pconsts ++ oconsts), tablelist, expression, order, offset, limit)
       })
     })
 
--- a/src/main/scala/SparqlToSql.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/main/scala/SparqlToSql.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -743,13 +743,15 @@
 			   sql.AttrAlias(attrAliasNameFromVar(sparql.VarAssignable(v))))
     ) + pathNo // add join number to selections
     val subselect = sql.Select(
+      false,
       sql.AttributeList(attrlist),
       sql.TableList(nestedState.joins),
       nestedState.exprs.size match {
       	case 0 => None
       	case 1 => Some(nestedState.exprs.toList(0))
       	case _ => Some(sql.ExprConjunction(nestedState.exprs))
-      }
+      },
+      List[sql.OrderElt](), None, None
     )
 
     /** Create a condition to test if this OPTIONAL was matched (called
@@ -854,10 +856,11 @@
 	     */
 	    R2RState(state.joins + sql.InnerJoin(sql.AliasedResource(sql.Subselect(
 	      sql.Select(
+		false, 
 		sql.AttributeList(Set(sql.NamedAttribute(sql.PrimaryExpressionTyped(sql.Datatype.INTEGER,sql.Name("1")),
 							 sql.AttrAlias(sql.Name("_EMPTY_"))))),
 		sql.TableList(util.AddOrderedSet()),
-		None
+		None, List[sql.OrderElt](), None, None
 	      )), sql.RelVar(sql.Name("_EMPTY_"))), None), state.varmap, state.exprs)
 	  else
 	    state
@@ -938,13 +941,14 @@
 	  })
 
 	  val subselect = sql.Select(
+	    false,
 	    sql.AttributeList(attrlist),
 	    sql.TableList(disjointState.joins),
 	    disjointState.exprs.size match {
 	      case 0 => None
 	      case 1 => Some(disjointState.exprs.toList(0))
 	      case _ => Some(sql.ExprConjunction(disjointState.exprs))
-	    }
+	    }, List[sql.OrderElt](), None, None
 	  )
 	  subselects + subselect
 	})
@@ -1031,13 +1035,15 @@
 
     /** Construct the generated query as an abstract syntax. */
     val select = sql.Select(
+      sparquery.distinct,
       sql.AttributeList(attrlist),
       sql.TableList(r2rState.joins),
       r2rState.exprs.size match {
 	case 0 => None
 	case 1 => Some(r2rState.exprs.toList(0))
 	case _ => Some(sql.ExprConjunction(r2rState.exprs))
-      }
+      },
+      List[sql.OrderElt](), sparquery.offset, sparquery.limit
     )
     // println("r2rState.varmap: " + r2rState.varmap)
     // println("select.expression: " + select.expression)
--- a/src/test/scala/SQLTest.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/test/scala/SQLTest.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -54,10 +54,12 @@
     val e = """
 SELECT 1 AS _TEST_
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(PrimaryExpressionTyped(Datatype.INTEGER,Name("1")),
-							   AttrAlias(Name("_TEST_"))))),
-			  TableList(AddOrderedSet()),
-			  None)
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(PrimaryExpressionTyped(Datatype.INTEGER,Name("1")),
+				       AttrAlias(Name("_TEST_"))))),
+      TableList(AddOrderedSet()),
+      None, List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -70,14 +72,17 @@
             INNER JOIN Employee AS R_manager
  WHERE R_manager.id=R_emp.manager
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									     Attribute(Name("lastName"))),
-							   AttrAlias(Name("A_empName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-						  InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
-			  Some(
-			    RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
-						   PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
+      Some(
+	RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
+			       PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -89,14 +94,17 @@
        FROM Employee AS R_emp
             INNER JOIN Employee AS R_manager ON R_manager.id=R_emp.manager
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									     Attribute(Name("lastName"))),
-							   AttrAlias(Name("A_empName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-						  InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
-			  Some(
-			    RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
-						   PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
+      Some(
+	RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
+			       PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -109,19 +117,22 @@
             INNER JOIN Employee AS R_manager
  WHERE R_manager.id=R_emp.manager AND R_emp.lastName IS NOT NULL AND R_manager.lastName IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									      Attribute(Name("lastName"))),
-							    AttrAlias(Name("A_empName"))),
-					     NamedAttribute(RelVarAttr(RelVar(Name("R_manager")),
-									      Attribute(Name("lastName"))),
-							    AttrAlias(Name("A_managName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
-			  Some(ExprConjunction(Set(
-			    RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
-						   PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager"))))),
-			    RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))))),
-			    RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName")))))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))),
+			NamedAttribute(RelVarAttr(RelVar(Name("R_manager")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_managName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
+      Some(ExprConjunction(Set(
+	RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
+			       PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager"))))),
+	RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))))),
+	RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName")))))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -132,13 +143,16 @@
   FROM Employee AS R_emp
  WHERE R_emp.manager=18 AND R_emp.lastName IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									      Attribute(Name("lastName"))),
-							    AttrAlias(Name("A_empName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
-			  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))),
-									  PrimaryExpressionTyped(Datatype.INTEGER,Name("18"))),
-					  RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
+      Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))),
+						      PrimaryExpressionTyped(Datatype.INTEGER,Name("18"))),
+			       RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -150,16 +164,19 @@
        INNER JOIN Employee AS R_manager
 WHERE R_emp.manager=R_manager.id AND R_manager.lastName="Johnson" AND R_emp.lastName IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									      Attribute(Name("lastName"))),
-							    AttrAlias(Name("A_empName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
-			  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))),
-									  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
-					  RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName")))),
-								 PrimaryExpressionTyped(Datatype.STRING,Name("Johnson"))),
-					  RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None))),
+      Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("manager")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
+			       RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName")))),
+						      PrimaryExpressionTyped(Datatype.STRING,Name("Johnson"))),
+			       RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -178,29 +195,32 @@
    AND R_grandManager.birthday < R_manager.birthday
    AND R_emp.lastName IS NOT NULL AND R_grandManager.lastName IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")), Attribute(Name("lastName"))),
-							   AttrAlias(Name("A_empName"))),
-					    NamedAttribute(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("lastName"))),
-							   AttrAlias(Name("A_grandManagName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_lower"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_upper"))), None),
-					InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_grandManager"))), None))),
-			  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_lower")),Attribute(Name("manages")))),
-									  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id"))))),
-					 RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_lower")),Attribute(Name("manager"))))),
-					 RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("birthday")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("birthday"))))),
-					 RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_upper")),Attribute(Name("manages")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
-					 RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("id")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_upper")),Attribute(Name("manager"))))),
-					 RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("birthday")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("birthday"))))),
-					 RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))))),
-					 RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("lastName")))))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")), Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))),
+			NamedAttribute(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_grandManagName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_lower"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_upper"))), None),
+			      InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_grandManager"))), None))),
+      Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_lower")),Attribute(Name("manages")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id"))))),
+			       RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_lower")),Attribute(Name("manager"))))),
+			       RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("birthday")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("birthday"))))),
+			       RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_upper")),Attribute(Name("manages")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
+			       RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("id")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_upper")),Attribute(Name("manager"))))),
+			       RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("birthday")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("birthday"))))),
+			       RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))))),
+			       RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_grandManager")),Attribute(Name("lastName")))))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -222,37 +242,46 @@
        ) AS R_union1
  WHERE R_union1.A_who=R_who.id AND R_who.lastName="Smith"
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_union1")), Attribute(Name("name"))),
-							   AttrAlias(Name("A_name"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_who"))), None),
-					InnerJoin(AliasedResource(Subselect(Union(Set(
-					  Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_manager")), Attribute(Name("lastName"))),
-										  AttrAlias(Name("A_name"))), 
-								   NamedAttribute(RelVarAttr(RelVar(Name("R_above")), Attribute(Name("manages"))),
-										  AttrAlias(Name("A_who"))))),
-						 TableList(AddOrderedSet(
-						   InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None),
-						   InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None)
-						 )), 
-						 Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("manager")))),
-												 PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
-								RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName"))))))))), 
-					  Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_managed")), Attribute(Name("lastName"))),
-										  AttrAlias(Name("A_name"))), 
-								   NamedAttribute(RelVarAttr(RelVar(Name("R_below")), Attribute(Name("manager"))),
-										  AttrAlias(Name("A_who"))))),
-						 TableList(AddOrderedSet(
-						   InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_below"))), None),
-						   InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_managed"))), None)
-						 )), 
-						 Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_below")),Attribute(Name("manages")))),
-												 PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_managed")),Attribute(Name("id"))))),
-								RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_managed")),Attribute(Name("lastName")))))))))))),
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_union1")), Attribute(Name("name"))),
+				       AttrAlias(Name("A_name"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_who"))), None),
+			      InnerJoin(AliasedResource(Subselect(Union(Set(
+				Select(
+				  false,
+				  AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_manager")), Attribute(Name("lastName"))),
+								   AttrAlias(Name("A_name"))), 
+						    NamedAttribute(RelVarAttr(RelVar(Name("R_above")), Attribute(Name("manages"))),
+								   AttrAlias(Name("A_who"))))),
+				  TableList(AddOrderedSet(
+				    InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None),
+				    InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_manager"))), None)
+				  )), 
+				  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("manager")))),
+										  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("id"))))),
+							   RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_manager")),Attribute(Name("lastName")))))))),
+				  List[OrderElt](), None, None), 
+				Select(
+				  false,
+				  AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_managed")), Attribute(Name("lastName"))),
+								   AttrAlias(Name("A_name"))), 
+						    NamedAttribute(RelVarAttr(RelVar(Name("R_below")), Attribute(Name("manager"))),
+								   AttrAlias(Name("A_who"))))),
+				  TableList(AddOrderedSet(
+				    InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_below"))), None),
+				    InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_managed"))), None)
+				  )), 
+				  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_below")),Attribute(Name("manages")))),
+										  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_managed")),Attribute(Name("id"))))),
+							   RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_managed")),Attribute(Name("lastName")))))))),
+				  List[OrderElt](), None, None)))),
 							RelVar(Name("R_union1"))), None))), 
-			  Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_union1")),Attribute(Name("A_who")))),
-									  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_who")),Attribute(Name("id"))))),
-					 RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_who")),Attribute(Name("lastName")))),
-								PrimaryExpressionTyped(Datatype.STRING,Name("Smith")))))))
+      Some(ExprConjunction(Set(RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_union1")),Attribute(Name("A_who")))),
+						      PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_who")),Attribute(Name("id"))))),
+			       RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_who")),Attribute(Name("lastName")))),
+						      PrimaryExpressionTyped(Datatype.STRING,Name("Smith")))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -263,14 +292,17 @@
                 FROM Manage AS R_above
           WHERE R_above.id IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_above")),
-									      Attribute(Name("manages"))),
-							    AttrAlias(Name("A_who"))),
-					     NamedAttribute(ConstNULL(),
-							    AttrAlias(Name("A_bday"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None))),
-			  Some(
-			    RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_above")),
+						  Attribute(Name("manages"))),
+				       AttrAlias(Name("A_who"))),
+			NamedAttribute(ConstNULL(),
+				       AttrAlias(Name("A_bday"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None))),
+      Some(
+	RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -281,16 +313,17 @@
 SELECT CONCAT(""" + QuotedBaseURI + """, "Employee", "/", "id", ".", R_emp.id, "#record") AS A_emp
        FROM Employee AS R_emp
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(Concat(List(PrimaryExpressionTyped(Datatype("String"),Name("http://hr.example/DB/")),
-								       PrimaryExpressionTyped(Datatype("String"),Name("Employee")),
-								       PrimaryExpressionTyped(Datatype("String"),Name("/")),
-								       PrimaryExpressionTyped(Datatype("String"),Name("id")),
-								       PrimaryExpressionTyped(Datatype("String"),Name(".")),
-								       PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))),
-								       PrimaryExpressionTyped(Datatype("String"),Name("#record")))),
-							    AttrAlias(Name("A_emp"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
-			  None)
+    val expected = Select(
+      false, AttributeList(Set(NamedAttribute(Concat(List(PrimaryExpressionTyped(Datatype("String"),Name("http://hr.example/DB/")),
+							  PrimaryExpressionTyped(Datatype("String"),Name("Employee")),
+							  PrimaryExpressionTyped(Datatype("String"),Name("/")),
+							  PrimaryExpressionTyped(Datatype("String"),Name("id")),
+							  PrimaryExpressionTyped(Datatype("String"),Name(".")),
+							  PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))),
+							  PrimaryExpressionTyped(Datatype("String"),Name("#record")))),
+					      AttrAlias(Name("A_emp"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
+      None, List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -301,21 +334,24 @@
                 FROM Manage AS R_above
           WHERE (R_above.id IS NOT NULL) OR (R_above.id < 5 AND R_above.id < 3)
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_above")),
-									      Attribute(Name("manages"))),
-							    AttrAlias(Name("A_who"))),
-					     NamedAttribute(ConstNULL(),
-							    AttrAlias(Name("A_bday"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None))),
-			  Some(
-			    ExprDisjunction(Set(
-			      RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id"))))),
-			      ExprConjunction(Set(
-				RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))),
-						       PrimaryExpressionTyped(Datatype.INTEGER,Name("5"))),
-				RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))),
-						       PrimaryExpressionTyped(Datatype.INTEGER,Name("3")))
-			      ))))))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_above")),
+						  Attribute(Name("manages"))),
+				       AttrAlias(Name("A_who"))),
+			NamedAttribute(ConstNULL(),
+				       AttrAlias(Name("A_bday"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_above"))), None))),
+      Some(
+	ExprDisjunction(Set(
+	  RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id"))))),
+	  ExprConjunction(Set(
+	    RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))),
+				   PrimaryExpressionTyped(Datatype.INTEGER,Name("5"))),
+	    RelationalExpressionLt(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_above")),Attribute(Name("id")))),
+				   PrimaryExpressionTyped(Datatype.INTEGER,Name("3")))
+	  ))))),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -327,20 +363,23 @@
             LEFT OUTER JOIN Manage AS R_mang ON R_mang.emp=R_emp.id
  WHERE R_emp.lastName IS NOT NULL
 """
-    val expected = Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-									     Attribute(Name("lastName"))),
-							    AttrAlias(Name("A_empName"))),
-					     NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),
-									      Attribute(Name("manageName"))),
-							    AttrAlias(Name("A_manageName"))))),
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-					LeftOuterJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_mang"))),
-						      RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("emp")))),
-									     PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id"))))
-									   )))),
-			  Some(
-			      RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))
-			    ))
+    val expected = Select(
+      false,
+      AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+						  Attribute(Name("lastName"))),
+				       AttrAlias(Name("A_empName"))),
+			NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),
+						  Attribute(Name("manageName"))),
+				       AttrAlias(Name("A_manageName"))))),
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+			      LeftOuterJoin(AliasedResource(Relation(Name("Manage")),RelVar(Name("R_mang"))),
+					    RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("emp")))),
+								   PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id"))))
+								 )))),
+      Some(
+	RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))
+      ),
+      List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -356,18 +395,23 @@
  WHERE R_emp.lastName IS NOT NULL
 """
     val expected = 
-      Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))),AttrAlias(Name("A_empName"))),
-			       NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("manageName"))),AttrAlias(Name("A_manageName"))))),
-	     TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
-			   LeftOuterJoin(AliasedResource(
-			     Subselect(Select(AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))),AttrAlias(Name("A_empName"))),
-						      NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("manageName"))),AttrAlias(Name("A_manageName"))))),
-				    TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
-				    None)),
-			     RelVar(Name("R_mang"))),
-					 RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("emp")))),
-								PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))))))),
-	     Some(RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))))
+      Select(
+	false,
+	AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))),AttrAlias(Name("A_empName"))),
+			  NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("manageName"))),AttrAlias(Name("A_manageName"))))),
+	TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None),
+				LeftOuterJoin(AliasedResource(
+				  Subselect(Select(
+				    false,
+				    AttributeList(Set(NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName"))),AttrAlias(Name("A_empName"))),
+								     NamedAttribute(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("manageName"))),AttrAlias(Name("A_manageName"))))),
+						   TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
+				    None, List[OrderElt](), None, None)),
+				  RelVar(Name("R_mang"))),
+					      RelationalExpressionEq(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_mang")),Attribute(Name("emp")))),
+								     PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))))))),
+	Some(RelationalExpressionNotNull(PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("lastName")))))),
+	List[OrderElt](), None, None)
     assert(expected === (a.parseAll(a.select, e).get))
   }
 
@@ -496,22 +540,24 @@
             R_emp.lastName AS O
        FROM Employee AS R_emp
 """ // "
-    val expected = View(Relation(Name("triples")), Select(AttributeList(Set(
-      NamedAttribute(Concat(List(PrimaryExpressionTyped(Datatype("String"),Name("http://hr.example/DB/")),
-				 PrimaryExpressionTyped(Datatype("String"),Name("Employee")),
-				 PrimaryExpressionTyped(Datatype("String"),Name("/")),
-				 PrimaryExpressionTyped(Datatype("String"),Name("empid")),
-				 PrimaryExpressionTyped(Datatype("String"),Name(".")),
-				 PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))),
-				 PrimaryExpressionTyped(Datatype("String"),Name("#record")))),
-		     AttrAlias(Name("S"))),
-      NamedAttribute(PrimaryExpressionTyped(Datatype.STRING,Name("<http://hr.example/DB/Employee#lastName>")),
-		     AttrAlias(Name("P"))),
-      NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
-				Attribute(Name("lastName"))),
-		     AttrAlias(Name("O"))))), 
-			  TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
-			  None))
+    val expected = View(Relation(Name("triples")), Select(
+      false,
+      AttributeList(Set(
+	NamedAttribute(Concat(List(PrimaryExpressionTyped(Datatype("String"),Name("http://hr.example/DB/")),
+				   PrimaryExpressionTyped(Datatype("String"),Name("Employee")),
+				   PrimaryExpressionTyped(Datatype("String"),Name("/")),
+				   PrimaryExpressionTyped(Datatype("String"),Name("empid")),
+				   PrimaryExpressionTyped(Datatype("String"),Name(".")),
+				   PrimaryExpressionAttr(RelVarAttr(RelVar(Name("R_emp")),Attribute(Name("id")))),
+				   PrimaryExpressionTyped(Datatype("String"),Name("#record")))),
+		       AttrAlias(Name("S"))),
+	NamedAttribute(PrimaryExpressionTyped(Datatype.STRING,Name("<http://hr.example/DB/Employee#lastName>")),
+		       AttrAlias(Name("P"))),
+	NamedAttribute(RelVarAttr(RelVar(Name("R_emp")),
+				  Attribute(Name("lastName"))),
+		       AttrAlias(Name("O"))))), 
+      TableList(AddOrderedSet(InnerJoin(AliasedResource(Relation(Name("Employee")),RelVar(Name("R_emp"))), None))),
+      None, List[OrderElt](), None, None))
     assert(expected === (a.parseAll(a.createview, e).get))
   }
 
--- a/src/test/scala/SparqlToSparqlToSqlTest.scala	Sun Jun 13 07:42:37 2010 -0400
+++ b/src/test/scala/SparqlToSparqlToSqlTest.scala	Sun Jun 13 09:56:13 2010 -0400
@@ -551,12 +551,12 @@
 
     val bsbmQuery = sparqlParser.parseAll(sparqlParser.select, queryStr).get
 
-    val stemQuery = sparqlParser.parseAll(sparqlParser.select, """
+    val stemExpected = sparqlParser.parseAll(sparqlParser.select, """
 PREFIX product: <http://bsbm.example/db/product#>
 PREFIX pfp: <http://bsbm.example/db/productfeatureproduct#>
 PREFIX ptp: <http://bsbm.example/db/producttypeproduct#>
 
-SELECT ?product ?label WHERE {
+SELECT DISTINCT ?product ?label WHERE {
   ?product product:label        ?label .
   ?product product:propertyNum1 ?value1 .
   <http://bsbm.example/db/producttypeproduct/productType.59#record>   ptp:product ?product .
@@ -564,28 +564,31 @@
   <http://bsbm.example/db/productfeatureproduct/productFeature.7#record> pfp:product ?product .
   FILTER (?value1 > 578)
 }
+ORDER BY ?label
+LIMIT 10
 """).get
 
     val sqlParser = Sql()
-    val sqlQuery = sqlParser.parseAll(sqlParser.select, """
-SELECT R_product.label AS label, R_product.nr AS product
+    val sqlExpected = sqlParser.parseAll(sqlParser.select, """
+SELECT DISTINCT R_product.label AS label, R_product.nr AS product
   FROM product AS R_product
+       INNER JOIN producttypeproduct AS R_productType59
+	       ON R_productType59.product=R_product.nr
+                  AND R_productType59.productType=59
        INNER JOIN productfeatureproduct AS R_productFeature5
                ON R_productFeature5.product=R_product.nr
                   AND R_productFeature5.productFeature=5
        INNER JOIN productfeatureproduct AS R_productFeature7
                ON R_productFeature7.product=R_product.nr
                   AND R_productFeature7.productFeature=7
-       INNER JOIN producttypeproduct AS R_productType59
-	       ON R_productType59.product=R_product.nr
-              AND R_productType59.productType=59
  WHERE R_product.propertyNum1 > 578
    AND R_product.label IS NOT NULL
+LIMIT 10
 """).get
     val asStem = SparqlToSparql(bsbmQuery, List(db2bsbm))
-    assert(asStem === stemQuery)
+    assert(stemExpected === asStem)
     val (asSql, _) = SparqlToSql(bsbmDb, asStem, StemURI("http://bsbm.example/db/"), false, false)
-    assert(asSql === sqlQuery)
+    assert(sqlExpected === asSql)
     val output = """
 """
   }