StringLiteral to IntegerType/LongType silently truncates fractional strings, changing predicate meaning

Đang mở Phù hợp với người mới
#4,382 2 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

@Shahzeb-DataEngineer đang làm issue này rồi.

Từ ngày 15/11/2026.

  • #4383 của @Shahzeb-DataEngineer — đ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
68/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python, sql
Lĩnh vực
data

Hướng nghiên cứu

Lỗi nằm ở phép chuyển đổi StringLiteral.to() cho IntegerType và LongType trong pyiceberg/expressions/literals.py. Phép chuyển đổi này nên đi qua hàm trợ giúp _to_integral có sẵn mà DecimalLiteral đang dùng. Bắt đầu bằng cách tái hiện literal("2.6").to(IntegerType()), sau đó đọc test_string_literal trong tests/expressions/test_literals.py. Hoàn thành khi các chuỗi có phần thập phân ném ValueError cho cả hai kiểu số nguyên, còn các chuỗi nguyên như "2.0" và "1e3" vẫn được chuyển đổi chính xác.

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

Mô tả

kind:bug
Apache Iceberg version

0.12.0 (latest release)

Please describe the bug 🐞

literal("2.6").to(IntegerType()) returns LongLiteral(2) instead of raising, while DecimalLiteral(Decimal("2.6")).to(IntegerType()) raises ValueError. A bound predicate such as x < "2.6" on an int column therefore becomes x < 2 and wrongly drops rows with x = 2 (verified with expression_evaluator); the same bound literal feeds partition pruning, so files can be skipped too.

The sibling DecimalLiteral.to(IntegerType/LongType) already rejects fractional values via the existing _to_integral helper, with a test spelling out why: rounding would change the predicate (e.g. x > 2.6 becoming x > 3 drops x = 3). The StringLiteral path was missed. The reference Java implementation has no INTEGER/LONG case in StringLiteral.to() and refuses the conversion.

Suggested fix: use the existing _to_integral helper in both StringLiteral.to(IntegerType) and StringLiteral.to(LongType), and update test_string_literal to expect ValueError for fractional strings.

Reproduction (pyiceberg 0.12.0, main @ fce8185):

  • literal("2.6").to(IntegerType()) returns LongLiteral(2); same for LongType
  • literal("-2.5").to(IntegerType()) returns LongLiteral(-2); literal("0.1").to(LongType()) returns LongLiteral(0)
  • LessThan("x", "2.6") bound to an int column becomes x < 2, and expression_evaluator returns False for a row with x = 2, although x < 2.6 is True
  • Integral strings still convert exactly: literal("2.0").to(IntegerType()) returns 2, literal("1e3").to(IntegerType()) returns 1000
Willingness to contribute
  • I can contribute a fix for this bug independently
  • I would be willing to contribute a fix for this bug with guidance from the Iceberg community
  • I cannot contribute a fix for this bug at this time
Ngôn ngữ chính
Python
Star
1.2k
Fork
664
Merge trung bình
2 ngày 10 giờ
Pull request đã merge (30 ngày)
131

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

  • Không có Dockerfile hay tệp Docker Compose
  • Có mẫu pull request
  • Không có hướng dẫn đóng góp

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/iceberg-python

Tất cả issue của apache/iceberg-python

Issue tương tự

Thêm issue về Python

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.