Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Scalar optimization & better discriminator column picking:
- A new compiler phase `optimizeScalar` performs the required local optimizations to eliminate unnecessary null checks arising from outer joins after `expandSums`. - `expandSums` now keeps track of paths referenced within OptionApply nodes in Join and Filter predicates. These are preferred over other fields when picking a discriminator column for an outer join. The goal is to avoid NVL2 checks of the discriminator column in Join and Filter conditions (where this could prevent the use of an index). In the long term this may not be enough. A more complex alternative would be to pick *all* possible discriminators in `expandSums` and narrow them down to the best one in a later phase on a case by case basis.
- Loading branch information
Showing
5 changed files
with
104 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package slick.compiler | ||
|
||
import slick.ast.TypeUtil._ | ||
import slick.ast.Util._ | ||
import slick.ast._ | ||
|
||
/** Optimize scalar expressions */ | ||
class OptimizeScalar extends Phase { | ||
val name = "optimizeScalar" | ||
|
||
def apply(state: CompilerState) = state.map(_.tree.replace({ | ||
// (if(p) a else b) == v | ||
case n @ Library.==(IfThenElse(Seq(p, Const(a), Const(b))), Const(v)) => | ||
val checkTrue = v == a | ||
val checkFalse = v == b | ||
val res = | ||
if(checkTrue && checkFalse) LiteralNode(true) | ||
else if(checkTrue && !checkFalse) p | ||
else if(checkFalse) Library.Not.typed(p.nodeType, p) | ||
else LiteralNode(false) | ||
cast(n.nodeType, res).infer() | ||
|
||
// if(v != null) v else null | ||
case n @ IfThenElse(Seq(Library.Not(Library.==(v, LiteralNode(null))), v2, LiteralNode(z))) | ||
if v == v2 && (z == null || z == None) => | ||
v | ||
|
||
// Redundant cast to non-nullable within OptionApply | ||
case o @ OptionApply(Library.SilentCast(n)) if o.nodeType == n.nodeType => n | ||
|
||
// Rownum comparison with offset 1, arising from zipWithIndex | ||
case n @ Library.<(Library.-(r: RowNumber, LiteralNode(1L)), v) => | ||
Library.<=.typed(n.nodeType, r, v).infer() | ||
|
||
// Some(v).getOrElse(_) | ||
case n @ Library.IfNull(OptionApply(ch), _) => | ||
cast(n.nodeType, ch) | ||
|
||
}, keepType = true, bottomUp = true)) | ||
|
||
object Const { | ||
def unapply(n: Node): Option[Node] = n match { | ||
case _: LiteralNode => Some(n) | ||
case Apply(Library.SilentCast, Seq(ch)) => unapply(ch) | ||
case OptionApply(ch) => unapply(ch) | ||
case _ => None | ||
} | ||
} | ||
|
||
def cast(tpe: Type, n: Node): Node = { | ||
val n2 = n.infer() | ||
if(n2.nodeType == tpe) n2 else Library.SilentCast.typed(tpe, n2) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters