ShivamSharma43 opened a new issue, #2457:
URL: https://github.com/apache/iceberg-go/issues/2457

   ### Apache Iceberg version
   
   main (development)
   
   ### Please describe the bug 🐞
   
   Converting a string literal to a decimal type rounds it to the type's scale 
without any error. If a predicate's bound has more fractional digits than the 
column's scale, the bound gets rounded, and the filter returns the wrong rows.
   
   Reproduced on main (2e69b8a):
   
   ```go
   dec92 := iceberg.MustDecimalTypeOf(9, 2)
   
   lit, err := iceberg.NewLiteral("12.345").To(dec92)
   fmt.Println(lit, err)
   
   sc := iceberg.NewSchema(0,
        iceberg.NestedField{ID: 1, Name: "price", Type: dec92, Required: true})
   bound, err := iceberg.BindExpr(sc,
        iceberg.GreaterThan(iceberg.Reference("price"), "12.345"), true)
   fmt.Println(bound, err)
   ```
   
   Output:
   
   ```
   12.35 <nil>
   BoundGreaterThan(term=BoundReference(field=1: price: required decimal(9, 2), 
accessor=Accessor(position=0, inner=<nil>)), literal=12.35) <nil>
   ```
   
   `price > 12.345` is bound as `price > 12.35`, so a row with `price = 12.35` 
gets filtered out even though 12.35 > 12.345. In the same way, `price = 
"12.345"` matches rows with 12.35 when it should match none. Decimal values in 
expression JSON are always strings (spec Appendix D), so decimal filters parsed 
with `ParseExpr` take this path too.
   
   **Cause:** `StringLiteral.To` in `literals.go` calls arrow's 
`decimal128.FromString(s, precision, scale)`. That function scales the value, 
then adds or subtracts 0.5 and truncates, so any extra digits are rounded away.
   
   **Other implementations:**
   - Java's `StringLiteral.to(DECIMAL)` keeps the exact `BigDecimal` ("do not 
change decimal scale"), so `12.35 > 12.345` evaluates correctly.
   - PyIceberg's `StringLiteral.to(DecimalType)` raises `ValueError` when the 
scales differ.
   - This repo already avoids rounding in a similar spot: 
`DecimalLiteral.integral` returns `ErrBadCast` rather than binding `qty < 
12.34` as `qty < 12` (#2096).
   
   **Proposed fix:** have `StringLiteral.To(DecimalType)` return `ErrBadCast` 
when the string has more significant fractional digits than the scale. Values 
that the scale represents exactly still convert as they do today (`"12.3"` 
becomes `12.30`, `"12.340"` stays allowed), so callers that pass shorter 
strings keep working.
   
   I'd like to work on this. I have a fix and a unit test ready.
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to