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

Offen Anfängerfreundlich
#4,382 2 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

@Shahzeb-DataEngineer arbeitet bereits daran.

Seit 15.11.2026.

  • #4383 von @Shahzeb-DataEngineer — offen

Bewertung

Schwierigkeit
2/5
Geschätzter Aufwand
1-3 Stunden
Anfängerfreundlichkeit
68/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
python, sql
Bereich
data

Rechercherichtung

Der Fehler liegt in der Konvertierung StringLiteral.to() für IntegerType und LongType in pyiceberg/expressions/literals.py. Sie sollte über den vorhandenen Helper _to_integral laufen, den DecimalLiteral bereits verwendet. Beginne damit, literal("2.6").to(IntegerType()) zu reproduzieren, und lies dann test_string_literal in tests/expressions/test_literals.py. Fertig ist es, wenn gebrochene Strings für beide Ganzzahltypen ein ValueError auslösen, ganzzahlige Strings wie "2.0" und "1e3" aber weiterhin exakt konvertiert werden.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

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
Vorherrschende Sprache
Python
Sterne
1.2k
Forks
664
Ø Merge
2 T. 10 Std.
Gemergte PRs (30 T.)
131

Entwicklungsumgebung

  • Kein Dockerfile und keine Docker-Compose-Datei
  • Hat eine Pull-Request-Vorlage
  • Kein Beitragsleitfaden

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus apache/iceberg-python

Alle Issues in apache/iceberg-python

Ähnliche Issues

Weitere Issues zu Python

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.