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

Abierto Apto para principiantes
#4,382 2 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

@Shahzeb-DataEngineer ya está trabajando en esto.

Desde el 15/11/2026.

  • #4383 de @Shahzeb-DataEngineer — abierto

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
68/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
python, sql
Área
data

Línea de trabajo

El error está en la conversión StringLiteral.to() para IntegerType y LongType en pyiceberg/expressions/literals.py, que debería pasar por el helper existente _to_integral que ya usa DecimalLiteral. Empieza reproduciendo literal("2.6").to(IntegerType()) y luego lee test_string_literal en tests/expressions/test_literals.py. Está terminado cuando las cadenas fraccionarias lanzan ValueError para ambos tipos enteros, y las cadenas enteras como "2.0" y "1e3" siguen convirtiéndose de forma exacta.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

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
Lenguaje dominante
Python
Estrellas
1.2k
Forks
664
Merge medio
2 d 10 h
PR fusionados (30 d)
131

Preparar el entorno

  • Sin Dockerfile ni archivo de Docker Compose
  • Tiene una plantilla de pull request
  • Sin guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de apache/iceberg-python

Todos los issues de apache/iceberg-python

Issues similares

Más issues de Python

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.