Skip to content

Commit

Permalink
Merge pull request #1924 from guitaristmo/master
Browse files Browse the repository at this point in the history
Fixed bug where alias of filter clause did not match alias of inner query.
  • Loading branch information
deusaquilus committed Aug 6, 2020
2 parents 64413d4 + c34e35a commit 7e7648d
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 2 deletions.
17 changes: 15 additions & 2 deletions quill-sql-portable/src/main/scala/io/getquill/sql/SqlQuery.scala
Expand Up @@ -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(
Expand All @@ -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(
Expand Down Expand Up @@ -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))
}

}
}
Expand Up @@ -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])
Expand Down
Expand Up @@ -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
}

Expand Down

0 comments on commit 7e7648d

Please sign in to comment.