Skip to content

Commit

Permalink
optmize null checking of nullable columns
Browse files Browse the repository at this point in the history
  • Loading branch information
deusaquilus committed Feb 19, 2019
1 parent 95767bc commit f5e5092
Show file tree
Hide file tree
Showing 9 changed files with 320 additions and 75 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ services:
addons:
postgresql: "9.6"
script:
- ./build/build.sh
- ./build/build.sh
branches:
except:
- release
Expand All @@ -31,5 +31,5 @@ jobs:
include:
stage: release
if: type != pull_request
script:
script:
- travis_retry ./build/release.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.getquill.context.cassandra

import io.getquill.ast._
import io.getquill.norm.ConcatBehavior.AnsiConcat
import io.getquill.norm.{ FlattenOptionOperation, Normalize, RenameProperties, SimplifyNullChecks }

object CqlNormalize {
Expand All @@ -10,7 +11,7 @@ object CqlNormalize {

private[this] val normalize =
(identity[Ast] _)
.andThen(FlattenOptionOperation.apply _)
.andThen(new FlattenOptionOperation(AnsiConcat).apply _)
.andThen(SimplifyNullChecks.apply _)
.andThen(Normalize.apply _)
.andThen(RenameProperties.apply _)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.getquill.norm

trait ConcatBehavior
object ConcatBehavior {
case object AnsiConcat extends ConcatBehavior
case object NonAnsiConcat extends ConcatBehavior
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,42 @@ package io.getquill.norm

import io.getquill.ast._
import io.getquill.ast.Implicits._
import io.getquill.norm.ConcatBehavior.NonAnsiConcat

object FlattenOptionOperation extends StatelessTransformer {
class FlattenOptionOperation(concatBehavior: ConcatBehavior) extends StatelessTransformer {

private def emptyOrNot(b: Boolean, ast: Ast) =
if (b) OptionIsEmpty(ast) else OptionNonEmpty(ast)

def uncheckedReduction(ast: Ast, alias: Ident, body: Ast) =
apply(BetaReduction(body, alias -> ast))

def uncheckedForall(ast: Ast, alias: Ident, body: Ast) = {
val reduced = BetaReduction(body, alias -> ast)
apply((IsNullCheck(ast) +||+ reduced): Ast)
}

def containsNonFallthroughElement(ast: Ast) =
CollectAst(ast) {
case If(_, _, _) => true
case Infix(_, _) => true
case BinaryOperation(_, StringOperator.`+`, _) if (concatBehavior == NonAnsiConcat) => true
}.nonEmpty

override def apply(ast: Ast): Ast =
ast match {

// TODO Check if there is an optional in here, if there is, warn the user about changing behavior

case OptionTableFlatMap(ast, alias, body) =>
apply(BetaReduction(body, alias -> ast))
uncheckedReduction(ast, alias, body)

case OptionTableMap(ast, alias, body) =>
apply(BetaReduction(body, alias -> ast))
uncheckedReduction(ast, alias, body)

case OptionTableExists(ast, alias, body) =>
apply(BetaReduction(body, alias -> ast))
uncheckedReduction(ast, alias, body)

case OptionTableForall(ast, alias, body) =>
val reduced = BetaReduction(body, alias -> ast)
apply((IsNullCheck(ast) +||+ reduced): Ast)
uncheckedForall(ast, alias, body)

case OptionFlatten(ast) =>
apply(ast)
Expand All @@ -50,20 +63,36 @@ object FlattenOptionOperation extends StatelessTransformer {
apply(If(IsNotNullCheck(ast), ast, body))

case OptionFlatMap(ast, alias, body) =>
val reduced = BetaReduction(body, alias -> ast)
apply(IfExistElseNull(ast, reduced))
if (containsNonFallthroughElement(body)) {
val reduced = BetaReduction(body, alias -> ast)
apply(IfExistElseNull(ast, reduced))
} else {
uncheckedReduction(ast, alias, body)
}

case OptionMap(ast, alias, body) =>
val reduced = BetaReduction(body, alias -> ast)
apply(IfExistElseNull(ast, reduced))
if (containsNonFallthroughElement(body)) {
val reduced = BetaReduction(body, alias -> ast)
apply(IfExistElseNull(ast, reduced))
} else {
uncheckedReduction(ast, alias, body)
}

case OptionForall(ast, alias, body) =>
val reduction = BetaReduction(body, alias -> ast)
apply((IsNullCheck(ast) +||+ (IsNotNullCheck(ast) +&&+ reduction)): Ast)
if (containsNonFallthroughElement(body)) {
val reduction = BetaReduction(body, alias -> ast)
apply((IsNullCheck(ast) +||+ (IsNotNullCheck(ast) +&&+ reduction)): Ast)
} else {
uncheckedForall(ast, alias, body)
}

case OptionExists(ast, alias, body) =>
val reduction = BetaReduction(body, alias -> ast)
apply((IsNotNullCheck(ast) +&&+ reduction): Ast)
if (containsNonFallthroughElement(body)) {
val reduction = BetaReduction(body, alias -> ast)
apply((IsNotNullCheck(ast) +&&+ reduction): Ast)
} else {
uncheckedReduction(ast, alias, body)
}

case OptionContains(ast, body) =>
apply((ast +==+ body): Ast)
Expand Down
Loading

0 comments on commit f5e5092

Please sign in to comment.