We used to optimize the following:
op(a, b) == true -> op(a, b)
op(a, b) != false -> op(a, b)
op(a, b) == false -> !op(a, b)
op(a, b) != true -> !op(a, b)
We were able to do that, because null semantics rewrite would prune all nulls. This is no longer safe with "simple" null semantics rewrite, which doesnt distinguish between false and null.
We can do it by:
- adding optimization to null semantics directly (we will miss optimizations done in query optimizer later)
- add null detection logic to sql expression optimizer (i.e. duplicate some of the null semantics code)
- merge null semantics with sql optimizer (too complex?),
- add IsNullable property to SqlExpression, so optimizer can just read the value and know what to do (extra API + metadata in SqlExpression, potential problems with extensibility?)