Skip to content

Commit

Permalink
Merge pull request #920 from getquill/fix-919
Browse files Browse the repository at this point in the history
push filter within joins to outer scope
  • Loading branch information
fwbrasil authored Sep 24, 2017
2 parents 34c8340 + 466dabb commit e716688
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,8 @@ import io.getquill.ast.BinaryOperation
import io.getquill.ast.BooleanOperator
import io.getquill.ast.Filter
import io.getquill.ast.FlatMap
import io.getquill.ast.Join
import io.getquill.ast.Map
import io.getquill.ast.Query
import io.getquill.ast.Tuple
import io.getquill.ast.Union
import io.getquill.ast.UnionAll

Expand All @@ -25,12 +23,6 @@ object AdHocReduction {
val er = BetaReduction(e, d -> b)
Some(Filter(a, b, BinaryOperation(c, BooleanOperator.`&&`, er)))

// a.join(b).on((c, d) => e).filter(f => g)
// a.join(b).on((c, d) => e && g[f := (c, d)])
case Filter(Join(t, a, b, c, d, e), f, g) =>
val gr = BetaReduction(g, f -> Tuple(List(c, d)))
Some(Join(t, a, b, c, d, BinaryOperation(e, BooleanOperator.`&&`, gr)))

// ---------------------------
// flatMap.*

Expand Down
19 changes: 19 additions & 0 deletions quill-core/src/main/scala/io/getquill/norm/SymbolicReduction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import io.getquill.ast.FlatMap
import io.getquill.ast.Query
import io.getquill.ast.Union
import io.getquill.ast.UnionAll
import io.getquill.ast.Join
import io.getquill.ast.Ident
import io.getquill.ast.Property

object SymbolicReduction {

Expand Down Expand Up @@ -33,6 +36,22 @@ object SymbolicReduction {
case FlatMap(UnionAll(a, b), c, d) =>
Some(UnionAll(FlatMap(a, c, d), FlatMap(b, c, d)))

// a.filter(b => c).join(d).on((e, f) => g) =>
// a.join(d).on((e, f) => g).filter(x => c[b := x._1])
case Join(tpe, Filter(a, b, c), d, e, f, g) =>
val x = Ident("x")
val x1 = Property(x, "_1")
val cr = BetaReduction(c, b -> x1)
Some(Filter(Join(tpe, a, d, e, f, g), x, cr))

// a.join(b.filter(c => d)).on((e, f) => g) =>
// a.join(b).on((e, f) => g).filter(x => d[c := x._2])
case Join(tpe, a, Filter(b, c, d), e, f, g) =>
val x = Ident("x")
val x2 = Property(x, "_2")
val dr = BetaReduction(d, c -> x2)
Some(Filter(Join(tpe, a, b, e, f, g), x, dr))

case other => None
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,6 @@ class AdHocReductionSpec extends Spec {
}
AdHocReduction.unapply(q.ast) mustEqual Some(n.ast)
}
"a.join(b).on((c, d) => e).filter(f => g)" in {
val q = quote {
qr1.join(qr2).on((c, d) => c.i == d.i).filter(t => t._1.i == 1)
}
val n = quote {
qr1.join(qr2).on((c, d) => c.i == d.i && c.i == 1)
}
AdHocReduction.unapply(q.ast) mustEqual Some(n.ast)
}
}

"flatMap.*" - {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,24 @@ class SymbolicReductionSpec extends Spec {
}
SymbolicReduction.unapply(q.ast) mustEqual Some(n.ast)
}

"a.filter(b => c).join(d).on((e, f) => g) => a.join(d).on((e, f) => g).filter(x => c[b := x._1])" in {
val q = quote {
qr1.filter(a => a.i == 1).join(qr2).on((a, b) => a.i == b.i)
}
val n = quote {
qr1.join(qr2).on((a, b) => a.i == b.i).filter(x => x._1.i == 1)
}
SymbolicReduction.unapply(q.ast) mustEqual Some(n.ast)
}

"a.join(b.filter(c => d)).on((e, f) => g) => a.join(b).on((e, f) => g).filter(x => d[c := x._2])" in {
val q = quote {
qr1.join(qr2.filter(b => b.i == 1)).on((a, b) => a.i == b.i)
}
val n = quote {
qr1.join(qr2).on((a, b) => a.i == b.i).filter(x => x._2.i == 1)
}
SymbolicReduction.unapply(q.ast) mustEqual Some(n.ast)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,18 @@ class SqlQuerySpec extends Spec {
"SELECT a.s, a.i, a.l, a.o, b.s, b.i, b.l, b.o FROM TestEntity a LEFT JOIN TestEntity2 b ON (a.s IS NOT NULL) AND (b.i > a.i)"
}

"join + map + filter" in {
val q = quote {
qr1
.leftJoin(qr2)
.on((a, b) => a.i == b.i)
.map(t => (t._1.i, t._2.map(_.i)))
.filter(_._2.forall(_ == 1))
}
testContext.run(q).string mustEqual
"SELECT a.i, b.i FROM TestEntity a LEFT JOIN TestEntity2 b ON a.i = b.i WHERE (b.i IS NULL) OR (b.i = 1)"
}

"flat outer join" in {
val q = quote {
for {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,21 +192,21 @@ class RenamePropertiesSpec extends Spec {
e.join(f).on((a, b) => a.s == b.s).map(t => t._1.s)
}
testContext.run(q).string mustEqual
"SELECT a.field_s FROM test_entity a INNER JOIN (SELECT t.s FROM TestEntity t WHERE t.i = 1) t ON a.field_s = t.s"
"SELECT a.field_s FROM test_entity a INNER JOIN TestEntity t ON a.field_s = t.s WHERE t.i = 1"
}
"left" in {
val q = quote {
e.leftJoin(f).on((a, b) => a.s == b.s).map(t => t._1.s)
}
testContext.run(q).string mustEqual
"SELECT a.field_s FROM test_entity a LEFT JOIN (SELECT t.s FROM TestEntity t WHERE t.i = 1) t ON a.field_s = t.s"
"SELECT a.field_s FROM test_entity a LEFT JOIN TestEntity t ON a.field_s = t.s WHERE t.i = 1"
}
"right" in {
val q = quote {
f.rightJoin(e).on((a, b) => a.s == b.s).map(t => t._2.s)
}
testContext.run(q).string mustEqual
"SELECT b.field_s FROM (SELECT t.s FROM TestEntity t WHERE t.i = 1) t RIGHT JOIN test_entity b ON t.s = b.field_s"
"SELECT b.field_s FROM TestEntity t RIGHT JOIN test_entity b ON t.s = b.field_s WHERE t.i = 1"
}
"flat inner" in {
val q = quote {
Expand Down

0 comments on commit e716688

Please sign in to comment.