diff --git a/quill-sql-portable/src/main/scala/io/getquill/sql/SqlQuery.scala b/quill-sql-portable/src/main/scala/io/getquill/sql/SqlQuery.scala index 6a933e61fa..861fe80cae 100644 --- a/quill-sql-portable/src/main/scala/io/getquill/sql/SqlQuery.scala +++ b/quill-sql-portable/src/main/scala/io/getquill/sql/SqlQuery.scala @@ -173,7 +173,8 @@ object SqlQuery { case Filter(q, Ident(alias, _), p) => val b = base(q, alias) - if (b.where.isEmpty) + //If the filter body uses the filter alias, make sure it matches one of the aliases in the fromContexts + if (b.where.isEmpty && (!CollectAst.byType[Ident](p).map(_.name).contains(alias) || collectAliases(b.from).contains(alias))) b.copy(where = Some(p))(quat) else FlattenSqlQuery( @@ -185,7 +186,8 @@ object SqlQuery { case SortBy(q, Ident(alias, _), p, o) => val b = base(q, alias) val criterias = orderByCriterias(p, o) - if (b.orderBy.isEmpty) + //If the sortBy body uses the filter alias, make sure it matches one of the aliases in the fromContexts + if (b.orderBy.isEmpty && (!CollectAst.byType[Ident](p).map(_.name).contains(alias) || collectAliases(b.from).contains(alias))) b.copy(orderBy = criterias)(quat) else FlattenSqlQuery( @@ -260,4 +262,15 @@ object SqlQuery { case (a, o: PropertyOrdering) => List(OrderByCriteria(a, o)) case other => fail(s"Invalid order by criteria $ast") } + + private def collectAliases(contexts: List[FromContext]): List[String] = { + contexts.flatMap { + case c: TableContext => List(c.alias) + case c: QueryContext => List(c.alias) + case c: InfixContext => List(c.alias) + case JoinContext(_, a, b, _) => collectAliases(List(a)) ++ collectAliases(List(b)) + case FlatJoinContext(_, from, _) => collectAliases(List(from)) + } + + } } diff --git a/quill-sql/src/test/scala/io/getquill/context/sql/SqlQuerySpec.scala b/quill-sql/src/test/scala/io/getquill/context/sql/SqlQuerySpec.scala index 9a3c1cdd57..4dd1da139d 100644 --- a/quill-sql/src/test/scala/io/getquill/context/sql/SqlQuerySpec.scala +++ b/quill-sql/src/test/scala/io/getquill/context/sql/SqlQuerySpec.scala @@ -710,6 +710,16 @@ class SqlQuerySpec extends Spec { } } + "embedded sortBy" in { + case class Sim(sid: Int, name: String) + val q = quote { + query[Sim] + .map(sim => (sim.sid, sim.name)) + .sortBy(sim => sim._1) + } + SqlQuery(q.ast).toString mustEqual "SELECT sim.sid, sim.name FROM Sim sim ORDER BY sim._1 ASC NULLS FIRST" + } + "queries using options" - { case class Entity(id: Int, s: String, o: Option[String], fk: Int, io: Option[Int]) case class EntityA(id: Int, s: String, o: Option[String]) diff --git a/quill-sql/src/test/scala/io/getquill/context/sql/norm/ExpandNestedQueriesSpec.scala b/quill-sql/src/test/scala/io/getquill/context/sql/norm/ExpandNestedQueriesSpec.scala index 0300c44608..05d71c1cfe 100644 --- a/quill-sql/src/test/scala/io/getquill/context/sql/norm/ExpandNestedQueriesSpec.scala +++ b/quill-sql/src/test/scala/io/getquill/context/sql/norm/ExpandNestedQueriesSpec.scala @@ -605,6 +605,64 @@ class ExpandNestedQueriesSpec extends Spec { | ) AS tup | ) AS tup | ) AS tup + |""".collapseSpace // bad + } + + "multiple embedding levels - without nesting the filter" in { + val ctx = testContextUpperEscapeColumn + import ctx._ + + case class Sim(sid: Int) extends Embedded + case class Mam(mid: Int, sim: Sim) + + val q = quote { + query[Mam] + .map(tup => (tup.mid, tup.sim)).distinct.sortBy(_._2.sid) + .map(tup => (tup._1, tup._2)).filter(tup => tup._2.sid == 1).distinct + .map(tup => (tup._1, tup._2.sid)).distinct + .map(tup => (tup._1, Sim(tup._2))).distinct + .map(tup => Mam(tup._1, tup._2)).distinct + } + ctx.run(q).string(true).collapseSpace mustEqual + """ + |SELECT + | tup.mid, + | tup.simsid + |FROM + | ( + | SELECT + | DISTINCT tup._1 AS mid, + | tup._2sid AS simsid + | FROM + | ( + | SELECT DISTINCT tup._1, + | tup._2 AS _2sid + | FROM + | ( + | SELECT + | DISTINCT tup._1, + | tup._2sid AS _2 + | FROM + | ( + | SELECT + | DISTINCT x11._1, + | x11._2sid + | FROM + | ( + | SELECT + | DISTINCT tup."MID" AS _1, + | tup."SID" AS _2sid + | FROM + | Mam tup + | ORDER BY + | tup."SID" ASC NULLS FIRST + | ) AS x11 + | WHERE + | x11._2sid = 1 + | ) AS tup + | ) AS tup + | ) AS tup + | ) AS tup |""".collapseSpace }