`ScalarValue::to_array_of_size` panics when a `Utf8` or `Binary` scalar repeated `size` times passes `i32::MAX` bytes

Đang mở
#27,277 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Maintainer thường phản hồi trong vòng 1 ngày

@ETS2K7 đang làm issue này rồi.

Từ ngày 10/11/2026.

  • #27291 của @ETS2K7 — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
35/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Đình trệ
Công nghệ
rust
Lĩnh vực
backend, databases

Hướng nghiên cứu

Start in datafusion/common/src/scalar/mod.rs at ScalarValue::to_array_of_size, focusing on the Utf8 and Binary arms and comparing them with the Utf8View arm. Check how repeated values handle offset overflow and look for relevant tests. Done means oversized values return an error instead of panicking; a linked pull request is already open.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

bug

Describe the bug

ScalarValue::to_array_of_size returns a Result, but for a Utf8 or Binary scalar it panics when the value's length times size is more than i32::MAX bytes. The Utf8 and Binary arms call GenericByteArray::new_repeated, which builds its offsets with OffsetBuffer::from_repeated_length, and that panics on offset overflow. The Utf8View and BinaryView arms use the fallible try_append_value_n instead.

A query reaches it: a projection turns a scalar result into an array of the batch's rows through ColumnarValue::into_array_of_size, which calls to_array_of_size. The panic happens before the value bytes are allocated, so it needs no memory beyond the scalar.

To Reproduce

use datafusion_common::ScalarValue;

fn main() {
    // 2^20 bytes in each of 2^11 rows is 2^31 bytes, one past i32::MAX
    let value = "a".repeat(1 << 20);

    let view = ScalarValue::Utf8View(Some(value.clone())).to_array_of_size(1 << 11);
    println!("Utf8View: {:?}", view.map(|a| a.len()));
    // Utf8View: Ok(2048)

    let utf8 = ScalarValue::Utf8(Some(value)).to_array_of_size(1 << 11);
    // panics: offset overflow: 2147483648 does not fit in i32
    println!("Utf8: {:?}", utf8.map(|a| a.len()));
}

The same panic from SQL, through ProjectionExec:

use datafusion::prelude::SessionContext;

#[tokio::main]
async fn main() {
    let ctx = SessionContext::new();
    let r = ctx
        .sql("SELECT repeat('a', 1048576) AS s FROM generate_series(1, 2048)")
        .await
        .unwrap()
        .collect()
        .await;
    // panics: offset overflow: 2147483648 does not fit in i32
    println!("{:?}", r.map(|b| b.iter().map(|b| b.num_rows()).sum::<usize>()));
}

The backtrace of the second runs through Projector::project_batch, ColumnarValue::into_array_of_size, ScalarValue::to_array_of_size and StringArray::new_repeated.

Expected behavior

to_array_of_size returns an error, as it does for Utf8View. The query fails with that error instead of panicking. GenericByteArray::new_repeated has no fallible form, so the Utf8 and Binary arms could check value.len().checked_mul(size) against i32::MAX before calling it.

Additional context

Property-based tests found this on main at 14b3edd9a3, when a test broadcast a scalar result of repeat to the call's rows. Both reproductions panic on main at 14b3edd9a3, which builds on arrow 60.1.0. The LargeUtf8 and LargeBinary arms have i64 offsets, so for them the size limit is the allocation, not the offsets.

Ngôn ngữ chính
Rust
Star
9.6k
Fork
2.6k
Merge trung bình
3 ngày 4 giờ
Pull request đã merge (30 ngày)
345

Chuẩn bị môi trường

Mở trong Codespaces

Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của apache/datafusion

Tất cả issue của apache/datafusion

Issue tương tự

Thêm issue về Rust

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.