JingsongLi commented on code in PR #10701:
URL: https://github.com/apache/paimon/pull/10701#discussion_r4332918357


##########
paimon-python/pypaimon/multimodal/lerobot/reader.py:
##########
@@ -30,15 +30,34 @@ class _PaimonTableFrameReader:
     def __init__(self, frames_table, *, columns):
         self._table, self.snapshot_id, splits = _indexed_read_table(
             frames_table, columns)
+        options = self._table.options.options
+        if not any(options.contains(option) for option in (
+                CoreOptions.READ_NATIVE_ENABLED, 
CoreOptions.SCAN_NATIVE_PLAN_ENABLED)):
+            from pypaimon.execution.native.runtime import 
native_runtime_available
+            if native_runtime_available():
+                self._table = self._table.copy_without_time_travel({
+                    CoreOptions.READ_NATIVE_ENABLED.key(): "true"})
         snapshot = self._table.snapshot_manager().get_snapshot_by_id(
             self.snapshot_id)
+        self._table = self._table._copy_with_snapshot(snapshot)
         self.num_rows = snapshot.next_row_id
         self.file_io = self._table.file_io
         self._locator = _FrameLocator(self._table, snapshot, splits)
 
     def read_indices(self, indices, columns):
-        splits, needs_filter = self._locator.locate(indices)
         builder = self._table.new_read_builder().with_projection(columns)
+        if (self._table.options.native_plan_enabled()
+                or self._table.options.native_read_enabled()):
+            from pypaimon.execution.native.runtime import 
native_runtime_available
+            if native_runtime_available():
+                # Keep lookup predicates in the native plan and residual read.
+                builder.with_filter(_index_predicate(self._table, indices))
+                scan = builder.new_scan()
+                if scan._native_plan_supported():
+                    plan = scan.plan()
+                    return builder.new_read().to_arrow(plan.splits())

Review Comment:
   [P2] Reuse the cached frame locator when native planning fails
   
   `_native_plan_supported()` returning true does not guarantee that 
`scan.plan()` used native planning: `TableScan.plan()` catches native planning 
failures and falls back to a new Python scanner. The unconditional return here 
therefore bypasses `self._locator` and discards the cached frame-index lookup 
path for every batch.
   
   A concrete trigger is an existing `viewfs://` frames table with the Rust 
extension installed and neither native option explicitly set. Python supports 
that storage scheme, the capability check does not reject it, and Rust rejects 
it during table construction. The existing 
`test_plan_falls_back_when_native_plan_raises` also models this 
unsupported-scheme failure. Each subsequent training batch then reloads 
manifests and reopens the BTree instead of reusing the fixed-snapshot locator.
   
   Local reproduction on `d5a7141d9a`:
   1. Create an indexed data-evolution frames table and a reader with 
`scan.native-plan.enabled=true`, `read.native.enabled=false` to isolate 
planning.
   2. Make `pypaimon.execution.native.read.plan.native_plan` raise 
`RuntimeError("native planner unavailable")`.
   3. Read three successive batches and count 
`DataEvolutionGlobalIndexScanner.create`.
   
   Observed: **3 scanner creations and 0 calls to the cached locator**. Taking 
the existing locator fallback creates **1 scanner for the same 3 batches**. 
Returned rows are correct in both cases. This reproduces the runtime-failure 
path locally; remote `viewfs` reads were not exercised end to end.
   
   Please distinguish actual native planning success from its Python fallback, 
and continue through `_locator.locate()` on failure while preserving residual 
filtering. Extending `test_native_plan_failure_keeps_predicate` to multiple 
batches with a scanner-reuse assertion would cover this case; the current reuse 
test only covers a false capability check.



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

Reply via email to