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

未關閉 適合新手
#4,382 2 則留言 0 個 reaction 已指派 0 人 在 GitHub 檢視

維護者通常 1 天內回覆

@Shahzeb-DataEngineer 已經在處理了。

開始於 2026年11月15日。

  • #4383 來自 @Shahzeb-DataEngineer —— 未關閉

評估

難度
2/5
預估耗時
1-3 小時
新手友好度
68/100
Issue 類型
缺陷
描述清晰度
描述清楚
活躍度
活躍
技術堆疊
python, sql
領域
data

研究方向

問題出在 pyiceberg/expressions/literals.py 中 IntegerType 和 LongType 的 StringLiteral.to() 轉換上。它應該走 DecimalLiteral 已在使用的現有輔助函式 _to_integral。請先重現 literal("2.6").to(IntegerType()),然後閱讀 tests/expressions/test_literals.py 中的 test_string_literal。完成的標準是:對於兩種整數型別,帶小數的字串都會拋出 ValueError,而 "2.0" 和 "1e3" 這類整數字串仍能被精確轉換。

由索引模型根據 Issue 內容生成。

描述

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
主要語言
Python
星號
1.2k
分支
664
平均合併
2 天 10 小時
30 天內合併 PR
131

環境準備

  • 沒有 Dockerfile 或 Docker Compose 檔案
  • 有 Pull Request 範本
  • 沒有貢獻指南

從這裡開始

  1. 先讀完整個 Issue,再讀專案的貢獻指南。
  2. 在 Issue 下留言說明你要接手 —— 這能避免兩個人做同樣的事。
  3. Fork 儲存庫,在一個分支上完成修改。
  4. 送出 Pull Request,並在描述裡引用這個 Issue 編號。

apache/iceberg-python 的其他 Issue

查看 apache/iceberg-python 的全部 Issue

相似的 Issue

更多 Python Issue

把新 issue 寄到你的電子郵件信箱

精選適合新手參與的 GitHub issue 摘要。