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

Ouverte Adaptée aux débutants
#4,382 2 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@Shahzeb-DataEngineer y travaille déjà.

Depuis le 15/11/2026.

  • #4383 par @Shahzeb-DataEngineer — ouverte

Évaluation

Difficulté
2/5
Temps estimé
1-3 heures
Accessibilité débutants
68/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
python, sql
Domaine
data

Piste de recherche

Le bogue se situe dans la conversion StringLiteral.to() pour IntegerType et LongType, dans pyiceberg/expressions/literals.py. Elle devrait passer par l'helper existant _to_integral que DecimalLiteral utilise déjà. Commence par reproduire literal("2.6").to(IntegerType()), puis lis test_string_literal dans tests/expressions/test_literals.py. C'est terminé lorsque les chaînes fractionnaires lèvent ValueError pour les deux types entiers, et que les chaînes entières comme "2.0" et "1e3" se convertissent toujours exactement.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Description

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
Langage dominant
Python
Étoiles
1.2k
Forks
664
Merge moyen
2 j 10 h
PR mergées (30 j)
131

Préparer son environnement

  • Aucun Dockerfile ni fichier Docker Compose
  • Propose un modèle de pull request
  • Aucun guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Autres issues de apache/iceberg-python

Toutes les issues de apache/iceberg-python

Issues similaires

Plus d'issues Python

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.