LuciferYang opened a new pull request, #9630:
URL: https://github.com/apache/paimon/pull/9630

   ### Purpose
   
   close #9629
   
   `Range.toRanges` compresses row ids with a linear scan that merges 
consecutive values, so it only works on ascending, deduplicated input, and 
`Range.and` intersects with two forward-moving pointers, so it needs the same. 
Nothing established either precondition: `RowIdPredicateVisitor` passed the IN 
literals through in whatever order the engine produced them. A descending 
`_ROW_ID IN (...)` list intersected with a `BETWEEN` therefore lost most of its 
ranges, and since `DataEvolutionBatchScan.withFilter` feeds the result to 
`withRowRanges`, the dropped ranges are rows that are never read.
   
   The precondition now lives in `toRanges`, which sorts its own copy and skips 
repeated ids, and says so in its javadoc. That is where it belongs: the 
signature is `Iterable<Long>`, so no caller could guess the requirement, and 
the method has one production caller to keep in step.
   
   Two more problems in the same extraction path, both reachable and both fixed 
here:
   
   `BETWEEN 10 AND 5` is legal SQL that matches nothing, but the visitor built 
`new Range(10, 5)` and broke the `from <= to` invariant the constructor 
asserts. It now yields no range.
   
   `Range.sortAndMergeOverlap` returned `Collections.emptyList()` for empty 
input while the visitor's OR branch accumulates into the list it gets back, so 
the next child's `addAll` threw `UnsupportedOperationException`. It now returns 
a mutable list. `(_ROW_ID BETWEEN 1 AND 5 AND _ROW_ID BETWEEN 10 AND 20) OR 
_ROW_ID = 100` reaches that, and the inverted-BETWEEN fix above makes empty 
children easier to produce, which is why the two go together.
   
   ### Tests
   
   `RowIdPredicateVisitorTest.testUnsortedInLiteralsIntersectCorrectly` builds 
a descending 21-literal IN list (long enough that `PredicateBuilder` keeps a 
real `In` leaf), intersects it with `BETWEEN 1 AND 6`, and asserts the single 
expected range; a second case feeds 21 copies of one literal and asserts one 
range rather than overlapping duplicates.
   
   `RowIdPredicateVisitorTest.testInvertedBetweenIsEmpty` asserts the inverted 
bounds produce no range, then puts that inverted BETWEEN on the left of an OR 
to cover the accumulation path.
   
   Against the unfixed visitor both tests fail.
   
   `mvn -pl paimon-common 
-Dtest=RowIdPredicateVisitorTest,RangeTest,RowRangeIndexTest test` on JDK 8: 43 
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]

Reply via email to