gimgit opened a new pull request, #17504:
URL: https://github.com/apache/iceberg/pull/17504

   Relates to #17489.
   
   ### What
   
   Adds a read-only Spark procedure `compute_sort_order_stats` that reports, 
per partition, how well the data file layout matches the table's declared sort 
order:
   
   ```sql
   CALL catalog.system.compute_sort_order_stats(table => 'db.tbl' [, 
snapshot_id => ...]);
   ```
   
   | output | meaning |
   |---|---|
   | `max_overlap_depth` | largest number of data files whose ranges on the 
first sort field cover a single point — 1 = perfectly clustered |
   | `avg_overlap_depth` | mean overlap depth over files with bounds |
   | `file_count` / `files_missing_bounds` | files without bounds for the sort 
field are excluded from depth and surfaced explicitly |
   
   ### Why
   
   As described in #17489, `rewrite_data_files` candidate selection considers 
only file size, so a table whose files are all within the healthy size band is 
permanently excluded from sort/z-order compaction — the job reports success on 
every run while sort-key overlap never improves. Today there is no way to 
detect this state: every size-based health metric reports such a table as 
perfectly healthy. This was also the missing piece asked in #12761 ("Do you 
have a way to identify the non-sorted files somehow?").
   
   This PR intentionally starts with measurement only (no planner/selection 
changes), so operators can detect the state and decide when to trigger a 
`rewrite-all`/filtered rewrite. A follow-up could add an opt-in selection 
option as sketched in #17489.
   
   ### How
   
   - `SortOrderStatsHandler` (core): computes overlap depth purely from data 
file metadata (`lowerBounds`/`upperBounds` of the first sort field) via a sweep 
line over `[lower, upper]` ranges — no data files are opened, nothing is 
committed.
     - requires a sort order whose first field uses an order-preserving 
transform (validated)
     - only the first sort field is considered, analogous to how clustering 
depth is commonly reported for multi-column layouts
     - truncated bounds can only widen a range, so the reported depth is an 
upper-bound estimate (documented)
   - `ComputeSortOrderStatsProcedure` (Spark 4.1): thin read-only wrapper 
returning one row per partition. Scoped to Spark 4.1 first; happy to backport 
to 4.0/3.5 if this lands.
   - No `Action` layer: the computation is driver-side metadata-only, so the 
procedure calls the core handler directly (same pattern as other read-only 
procedures). Can add the action layer if preferred.
   
   ### Testing
   
   - `TestSortOrderStatsHandler` (core, 10 cases): full overlap, disjoint, 
touching boundaries, partial overlap, missing bounds (partial/all), single 
file, unsorted table, non-order-preserving transform, `snapshot_id` time travel
   - `TestComputeSortOrderStatsProcedure` (spark-extensions, 6 cases × 4 
catalogs): empty table, unsorted failure, overlap/disjoint reporting, 
per-partition reporting, `snapshot_id`
   


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