LuciferYang opened a new pull request, #9647:
URL: https://github.com/apache/paimon/pull/9647
### Purpose
close #9646
`Between.optimize` merges `<=` and `>=` predicates on one field into a
`BETWEEN`, and it ordered the two bounds without checking them:
```java
Object lowerBound = greaterOrEqual.literals().get(0);
Object upperBound = lessOrEqual.literals().get(0);
if (compareLiteral(type, lowerBound, upperBound) >= 0) {
```
With a null bound that is a `NullPointerException` from `compareTo(null)`,
or `RuntimeException("Unsupported type")` when the null is the first argument.
`CALL sys.compact(table => 'db.t', where => 'dt >= 1 AND dt <= null')` hits it:
procedure filters go through `ExpressionHelper.resolveFilter`, which runs
`ConstantFolding` but not `NullPropagation`, so the null literal reaches Paimon
intact.
A null bound has no order, so the pair is now left unmerged and evaluated by
the rules that already handle this: `LeafBinaryFunction.test` treats a null
literal as no match. Merging into a `BETWEEN` is an optimization, and skipping
it changes nothing semantically.
`compareLiteral` also gained a guard, since it is the function whose
contract was implicit: a null literal now gets an `IllegalArgumentException`
naming the type instead of a `NullPointerException` from inside `compareTo`.
Its other callers (`NotIn`, `NotBetween`, `LessThan`) either null-check first
or are only reached with non-null bounds, so nothing else changes.
I did consider short-circuiting the merge to `alwaysFalse()`, since `k >= 1
AND k <= NULL` really does match nothing. I left it out: `optimize`'s job is
merging predicates, and having it start producing `alwaysFalse` reaches past
what `PredicateBuilder.and` asked for, while the evaluation layer already
answers false for these.
### Tests
`BetweenTest.testNullLiteralBoundsDoNotCrash` builds `k >= 1 AND k <= null`
through `PredicateBuilder.and`, asserts it does not throw, and asserts the
merged predicate evaluates to false for a row. It also covers a null lower
bound and two `BETWEEN`s where one carries a null.
Against the unfixed optimizer the test errors with a `NullPointerException`.
`mvn -pl paimon-common -Dtest=BetweenTest,PredicateTest test` on JDK 8: 50
tests, 0 failures. `spotless:check` and `checkstyle:check` on paimon-common are
clean.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]