qzyu999 opened a new pull request, #3716:
URL: https://github.com/apache/iceberg-python/pull/3716

   ## Which issue does this PR close?
   
   Closes #3715
   Closes #1210 
   Closes #3270
   Closes #3554
   
   ## Rationale for this change
   
   PyIceberg's I/O and compute logic lives in a single 3,000+ line file 
(`pyiceberg/io/pyarrow.py`) with no separation of concerns. PyArrow is a kernel 
library without memory management or spill-to-disk, causing OOM crashes on 
production-scale operations (CoW deletes, equality delete resolution, scan 
planning).
   
   This PR introduces a pluggable interface that:
   1. Decouples PyIceberg from PyArrow, enabling alternative backends
   2. Integrates DataFusion for bounded-memory compute with spill-to-disk
   3. Fixes OOM patterns while maintaining full backward compatibility
   
   ## What changes are included in this PR?
   
   ### New Modules (`pyiceberg/execution/`)
   
   | Module | Purpose |
   |--------|---------|
   | `protocol.py` | `ReadBackend`, `WriteBackend`, `ComputeBackend` protocol 
definitions |
   | `engine.py` | Backend resolution, instantiation, config helpers |
   | `_orchestrate.py` | Per-task scan execution with delete resolution |
   | `planning.py` | `InMemoryPlanner` + `BoundedMemoryPlanner` |
   | `backends/pyarrow_backend.py` | Default implementation (always available) |
   | `backends/datafusion_backend.py` | Bounded-memory implementation 
(optional) |
   
   ### Operations Delivered
   
   | Operation | Before | After |
   |-----------|--------|-------|
   | Equality delete resolution | `ValueError` | ✅ Works (Grace Hash Join with 
spill) |
   | CoW delete (large files) | OOM | ✅ Two-pass streaming, O(batch_size) 
memory |
   | Positional deletes (millions) | OOM | ✅ Size-based routing to anti-join |
   | Sort-on-write | Not implemented | ✅ External merge sort (best-effort) |
   | Scan planning (>100K deletes) | OOM | ✅ BoundedMemoryPlanner with SQL join 
|
   
   ### Migration
   
   All data paths in `table/__init__.py` now route through `orchestrate_scan()` 
instead of `ArrowScan`. The old `ArrowScan` class is deprecated (0.11.0) and 
scheduled for removal in 0.12.0.
   
   ## Are there any user-facing changes?
   
   **No breaking changes.** All existing APIs work identically.
   
   **New behavior** (when `datafusion` is installed):
   - Tables with equality deletes now return correct results (previously 
`ValueError`)
   - Large file operations complete without OOM
   - Files are sorted on write if table defines a sort order
   
   **New optional dependency**:
   ```bash
   pip install 'pyiceberg[datafusion]'
   ```
   
   When DataFusion is not installed, behavior is identical to before (may OOM 
on large data).
   
   **New configuration** (optional, sensible defaults):
   ```yaml
   # .pyiceberg.yaml
   execution:
     compute-backend: datafusion  # auto-detected when installed
     memory-limit: 536870912      # 512 MB
     planning-threshold: 100000   # switch to bounded planner
     cow-threshold: 67108864      # 64 MB for two-pass streaming
   ```
   
   ## Testing
   
   - `test_arrowscan_parity.py`: verifies new path matches deprecated ArrowScan
   - `test_property_based.py`: Hypothesis tests for PyArrow/DataFusion 
equivalence
   - `test_positional_deletes.py`: DataFusion positional delete resolution
   - `test_equality_deletes.py`: equality delete resolution with sequence 
number gating
   - `test_cow_streaming.py`: two-pass streaming for large files
   - All existing integration tests pass without modification
   


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