### Description

The IS NULL/IS NOT NULL only care about the nullability not the value of an expression.
Given the expression x + 1 / 2, the actual result does not matter only if it's null or not - that is, it only matters if x is null or not.
So x + 1 / 2 IS NULL becomes x IS NULL - which can be opportunistically pushed down or evaluated.
x-pack/plugin/ql/src/test/java/org/elasticsearch/xpack/ql/optimizer/OptimizerRulesTests.java
public void testRangesOverlappingNoLowerBoundary() {
        FieldAttribute fa = getFieldAttribute();
        Range r2 = rangeOf(fa, L(0), false, TWO, false);
        Range r1 = rangeOf(fa, L(0), false, ONE, true);
        Or or = new Or(EMPTY, r1, r2);
        CombineBinaryComparisons rule = new CombineBinaryComparisons();
        Expression exp = rule.rule(or);
        assertEquals(r2, exp);
    }
    public void testBinaryComparisonAndOutOfRangeNotEqualsDifferentFields() {
        FieldAttribute doubleOne = fieldAttribute("double", DOUBLE);
        FieldAttribute doubleTwo = fieldAttribute("double2", DOUBLE);
        FieldAttribute intOne = fieldAttribute("int", INTEGER);
        FieldAttribute datetimeOne = fieldAttribute("datetime", INTEGER);
        FieldAttribute keywordOne = fieldAttribute("keyword", KEYWORD);
        FieldAttribute keywordTwo = fieldAttribute("keyword2", KEYWORD);
        List<And> testCases = asList(
            
            new And(EMPTY, greaterThanOf(doubleOne, L(10)), notEqualsOf(intOne, L(-10))),
            
            new And(EMPTY, greaterThanOf(keywordOne, L("5")), notEqualsOf(keywordTwo, L("48"))),
            
            new And(EMPTY, notEqualsOf(keywordOne, L("2021")), lessThanOrEqualOf(datetimeOne, L("2020-12-04T17:48:22.954240Z"))),
            
            new And(EMPTY, greaterThanOf(doubleOne, L(10.1d)), notEqualsOf(doubleTwo, L(-10.1d)))
        );
        for (And and : testCases) {
            CombineBinaryComparisons rule = new CombineBinaryComparisons();
            Expression exp = rule.rule(and);