lets-order-some-fries opened a new pull request, #67008:
URL: https://github.com/apache/doris/pull/67008
### What problem does this PR solve?
Problem Summary: LIMIT and OFFSET reach the SHOW paging code as unbounded
64-bit
values. `limitClause` accepts a bare digit sequence, `LogicalPlanBuilder`
parses
it with `Long.parseLong` and checks only that it is non-negative, and
`LimitElement` stores both as `long`. Every paging site then narrowed them to
`int` before clamping, so a value above `Integer.MAX_VALUE` wrapped.
Two failure modes on a 5-row result:
- `LIMIT 4294967296` -> `(int) (0 + 4294967296L)` is 0, the `endIndex > size`
clamp does not fire, and `subList(0, 0)` returns an empty result. The user
gets
zero rows back with no error.
- `LIMIT 3000000000` -> `(int) 3000000000L` is -1294967296, which is not
greater
than size so it is not clamped; the `beginIndex > endIndex` branch then
sets
`beginIndex` to the same negative value and `subList` throws
`IndexOutOfBoundsException`. `OFFSET 3000000000` reaches the same throw.
The same block was duplicated at eight sites across four proc dirs, backing
`SHOW PARTITIONS`, `SHOW ALTER TABLE COLUMN`, `SHOW ALTER TABLE ROLLUP` and
`SHOW BUILD INDEX`. `RollupProcDir` additionally lacked the `beginIndex >
endIndex`
guard that its three siblings have, so it could call `subList` with
`beginIndex > endIndex` and throw `IllegalArgumentException`.
`ShowCommand.applyLimit`, which pages `SHOW LOAD`, `SHOW RESOURCES` and
`SHOW PARTITIONS`, has the same defect in a different shape: `(limit +
offsetValue)`
is computed in long but can overflow to a negative value, which then passes
the
`< showResult.size()` test and is narrowed for `subList`.
### What is changed and how does it work?
Added `LimitElement.applyTo(List)`, which owns both values already, and
computes
the window in long, saturating at `rows.size()` before narrowing:
- the offset is clamped into `[0, size]` first, so an out-of-range offset
yields
an empty window instead of a negative index;
- `begin + limit` is checked for a negative result, which is the signature
of the
long addition overflowing;
- with no limit set the window runs to the end of the list.
The eight duplicated blocks now delegate to it, which also gives
`RollupProcDir`
the guard it was missing. `ShowCommand.applyLimit` delegates too, keeping its
existing `limit == -1` contract (no limit means return the list unchanged) so
behaviour is identical apart from the overflow.
Net effect is 36 fewer lines and one tested implementation instead of eight
copies.
### Release note
Fix `SHOW PARTITIONS`, `SHOW ALTER TABLE`, `SHOW BUILD INDEX`, `SHOW LOAD`
and
`SHOW RESOURCES` returning an empty result or failing with
`IndexOutOfBoundsException` when LIMIT or OFFSET exceeds the 32-bit range.
### Check List (For Author)
- Test <!-- At least one of them must be included. -->
- [ ] Regression test
- [x] Unit Test
- [ ] Manual test (add detailed scripts or steps below)
- [ ] No need to test or manual test. Explain why:
- [ ] This is a refactor/code format and no logic has been changed.
- [ ] Previous test can cover this change.
- [ ] No code files have been changed.
- [ ] Other reason <!-- Add your reason? -->
Added `LimitElementTest` (7 cases) covering both failure modes, an offset
past the end, `offset + limit` overflowing long, and the no-limit path.
```
mvn -f fe/pom.xml -pl :fe-core -am test \
-Dtest=LimitElementTest,PartitionsProcDirTest,AlterProcDirFilterExpressionTest,ShowPartitionsCommandTest
-> Tests run: 13, Failures: 0, Errors: 0, Skipped: 0
cd fe && mvn clean checkstyle:check
-> BUILD SUCCESS
```
I confirmed the new tests fail against the original arithmetic, so they
genuinely cover the defect rather than passing vacuously - 6 of 7 fail, 3 as
silently empty results and 3 as the predicted crash:
```
testLimitAboveIntMaxReturnsAllRows expected: <[0, 1, 2, 3, 4]> but was:
<[]>
testOffsetPlusLimitOverflowIsClamped expected: <[1, 2, 3, 4]> but was:
<[]>
testLimitTruncatingToNegativeIntReturnsAllRows
IndexOutOfBoundsException: fromIndex
= -1294967296
```
No end-to-end regression test was added: this environment has no running
Doris cluster, so the failure modes are demonstrated at the arithmetic level by
the unit test above rather than through SQL. Happy to add a regression case if
you would prefer one.
- Behavior changed:
- [ ] No.
- [x] Yes. <!-- Explain the behavior change -->
These statements now return the correct rows instead of an empty result or
an exception. Nothing changes for LIMIT and OFFSET values inside the 32-bit
range.
- Does this need documentation?
- [x] No.
- [ ] Yes. <!-- Add document PR link here. eg:
https://github.com/apache/doris-website/pull/1214 -->
### Check List (For Reviewer who merge this PR)
- [ ] Confirm the release note
- [ ] Confirm test cases
- [ ] Confirm document
- [ ] Add branch pick label <!-- Add branch pick label that this PR should
merge into -->
--
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]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]