SimplifyNullChecks
io.getquill.norm.SimplifyNullChecks
class SimplifyNullChecks(equalityBehavior: EqualityBehavior) extends StatelessTransformer
Due to the introduction of null checks in map
, flatMap
, and exists
, in FlattenOptionOperation
in order to resolve #1053, as well as to support non-ansi compliant string concatenation as outlined in #1295, large conditional composites became common. For example:
case class
Holder(value:Option[String])
// The following statement query[Holder].map(h => h.value.map(_ + "foo")) //
Will yield the following result SELECT CASE WHEN h.value IS NOT NULL THEN
h.value || 'foo' ELSE null END FROM Holder h
Now, let's add a
getOrElse
statement to the clause that requires an additional wrapped null check. We cannot rely on there being a map
call beforehand since we could be reading value
as a nullable field directly from the database).
// The following statement
query[Holder].map(h => h.value.map(_ + "foo").getOrElse("bar")) // Yields the
following result: SELECT CASE WHEN CASE WHEN h.value IS NOT NULL THEN h.value
\|| 'foo' ELSE null END IS NOT NULL THEN CASE WHEN h.value IS NOT NULL THEN
h.value || 'foo' ELSE null END ELSE 'bar' END FROM Holder h
This of course is highly redundant and can be reduced to simply: SELECT CASE WHEN h.value IS NOT NULL AND (h.value || 'foo') IS NOT NULL THEN
h.value || 'foo' ELSE 'bar' END FROM Holder h
This reduction is done by the "Center Rule." There are some other simplification rules as well. Note how we are force to null-check both `h.value` as well as `(h.value || 'foo')` because a user may use `Option[T].flatMap` and explicitly transform a particular value to `null`.
Attributes
- Graph
-
- Supertypes
Members list
In this article