Repository navigation
fix: return an error instead of aborting in repeat for huge LargeUtf8 results - #26957
Conversation
…f8 results `repeat` capped LargeUtf8 results at i64::MAX bytes, which admits sizes no allocation can satisfy, so the process aborted or panicked instead of returning an error. Cap LargeUtf8 results at u32::MAX bytes in both the scalar and array paths. Closes apache#26948
The per-row cap alone still let many rows add up to an allocation no system can satisfy, which panicked in the Arrow buffer instead of returning an error.
mbutrovich
left a comment
There was a problem hiding this comment.
Thanks @shahwazreza for the fix, and for catching the total-size case in the second commit.
Co-authored-by: Matt Butrovich <6855576+mbutrovich@users.noreply.github.com>
mbutrovich
left a comment
There was a problem hiding this comment.
Thanks for the PR @shahwazreza! Approved pending CI.
|
CI failed on the new total test. Looking into it. Please give me a few minutes! |
|
Hey, @mbutrovich. CI fails on the new total test. CI runs the tests with the |
mbutrovich
left a comment
There was a problem hiding this comment.
Thanks @shahwazreza for folding in the changes.
Sorry, that one came from my suggestion. |
|
Thank you very much for you help! |
Which issue does this PR close?
repeatonLargeUtf8aborts the process on a result size no allocation can satisfy #26948.Rationale for this change
repeaton a LargeUtf8 string with a huge count, e.g.repeat(arrow_cast('a', 'LargeUtf8'), 1152921504606846976), aborts the process (scalar case) or panics (array case) instead of returning an error. Utf8 and Utf8View already error abovei32::MAXbytes, but LargeUtf8 was capped ati64::MAX, which is way past anything that can actually be allocated.What changes are included in this PR?
LargeUtf8 now uses a fixed cap of
u32::MAXbytes (LARGE_UTF8_MAX_SIZE). In the array path the cap applies to each value and to the total size of the output, since the builder allocates the whole output up front. My first version only checked each value, so lots of rows could still add up to an allocation that panics. The second commit fixes that.The issue asked whether to use a cap or fallible allocation. I went with a cap because the builder has no fallible way to allocate, and changing that would be a bigger separate change. A cap also behaves the same way Utf8 already does.
u32::MAXmatches DuckDB's string size limit and still lets LargeUtf8 go past the Utf8 limit. Happy to change it, e.g. to Postgres' 1 GB, if it is preferred.This doesn't help when an allocation under the cap succeeds and then fails later because of overcommit, same as the issue says.
What is the testing strategy for this PR?
Unit tests in
repeat.rs:1 << 60(used to abort the test process)1 << 60(used to panic)Are there any user-facing changes?
repeatreturns an error for LargeUtf8 results overu32::MAXbytes instead of trying to allocate them.