andygrove opened a new issue, #6854:
URL: https://github.com/apache/datafusion-comet/issues/6854

   ### What is the problem the feature request solves?
   
   Comet's native Iceberg scan never passes iceberg-rust a predicate on a 
decimal column. `IcebergReflection.pageIndexUnsupportedColumns` lists every 
`decimal`, `uuid`, `fixed` and `binary` column. 
`CometIcebergNativeScan.icebergExprToProto` then drops any residual predicate 
that references one, including the `IS NOT NULL` that Iceberg adds for every 
filtered column.
   
   Results stay correct. Iceberg's planning still prunes files on manifest 
statistics, and the filter runs after the scan. But the native reader never 
prunes row groups or pages on a decimal column. A selective decimal filter 
therefore reads every row group and page of every file that survives planning.
   
   #4982 added the gate because iceberg-rust, at the pins before #6649, could 
not handle these columns in the page index:
   
   - A `FIXED_LEN_BYTE_ARRAY` column index failed the scan with 
`FeatureUnsupported`. That layout backs `uuid`, `fixed`, and decimals of 
precision 19 and above.
   - A `binary` page bound that was not UTF-8 panicked in 
`String::from_utf8(..).unwrap()`.
   - Pruning on an `INT32` or `INT64` decimal (precision 18 and below) could 
drop pages that held matching rows (apache/iceberg-rust#3314).
   
   None of these holds at the current pins:
   
   - `main` has been at af1da4c since #6649, and that pin includes 
apache/iceberg-rust#3314. It skips a `FIXED_LEN_BYTE_ARRAY` or `INT96` column 
index instead of failing, and it decodes `binary` bounds as bytes.
   - #6851 moves the pin to 1f3bc34, which adds page-index pruning for 
`FIXED_LEN_BYTE_ARRAY` decimals (apache/iceberg-rust#3328).
   - iceberg-rust's row-group statistics path decodes decimals of every 
precision at both pins.
   
   The Scaladoc on `pageIndexUnsupportedColumns` still describes the behavior 
from before #6649.
   
   ### Describe the potential solution
   
   Push decimal predicates through to iceberg-rust:
   
   - `CometIcebergNativeScan.predicateLiteralToProto`:
     - Build `IcebergLiteral.decimal_val` for a `DecimalType` column, at the 
column's precision and scale.
     - If a literal can't be represented exactly at that scale, drop that 
predicate on its own. A literal that fails to bind would make iceberg-rust drop 
the whole residual.
   - `iceberg_literal_to_datum` in `planner.rs`: turn `DecimalVal` into a 
`Datum` with `Datum::decimal_with_precision`. iceberg-rust's `Decimal` is now 
`fastnum::D128`, so all 38 digits fit.
   - `IcebergReflection.pageIndexUnsupportedColumns`: stop listing decimals.
   - Update three comments that say decimal pushdown is deferred: the Scaladoc 
on `pageIndexUnsupportedColumns`, the doc comment on 
`iceberg_literal_to_datum`, and the comment on `IcebergDecimal` in 
`operator.proto`.
   
   What works at which pin:
   
   - At `main`'s pin: page pruning for decimals of precision 18 and below, and 
row-group pruning for every precision.
   - Page pruning for wider decimals needs #6851.
   
   The other gated types:
   
   - `uuid` and `fixed` should stay in the list. iceberg-rust still skips their 
page indexes, and a `uuid` predicate's string literal doesn't bind to a `uuid` 
field.
   - `binary` could come out too, but there is no binary predicate literal, so 
only `IS [NOT] NULL` would gain anything.
   
   Tests should compare against Spark with `checkIcebergNativeScan`. The data 
should be decimal columns at precisions 9, 18 and 38, written in order over 
many small pages (`write.parquet.page-row-limit`). Cover:
   
   - values on both sides of zero;
   - range, equality and `IN` predicates;
   - a literal at a different scale from the column.
   
   A pruned page that held a match loses rows silently, so these comparisons 
are the main guard. A check that the scan actually prunes, for example on the 
scan's `bytes_scanned` metric, would show the change has an effect.
   
   ### Additional context
   
   Found while reviewing #6851. A probe on that branch wrote a sorted 
`decimal(38, 2)` column over 200 pages, from -10100.00 to 10098.99, and ran 
nine predicates through the native scan. All nine matched Spark. But they only 
exercised the filter that runs after the scan, because the gate kept the 
predicates away from iceberg-rust.
   


-- 
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