andygrove opened a new pull request, #2765:
URL: https://github.com/apache/datafusion-ballista/pull/2765

   # Which issue does this PR close?
   
   Closes #1953.
   
   # Rationale for this change
   
   When a query reads the same subplan more than once, such as a common table 
expression joined to itself or TPC-H q15's revenue view, the adaptive planner 
places one exchange per copy and runs the subplan once per reader. #1954 added 
exchange reuse to the static planner only, which now runs only when AQE is 
switched off, so it was closed in favour of doing this in AQE.
   
   # What changes are included in this PR?
   
   - **`ReuseExchangeRule`**, the last rule of the AQE replan chain (after an 
embedder's replan rules, so keys cover each stage as it will run).
     - Each `ExchangeExec` is keyed by the protobuf encoding of its subtree 
under the job's physical extension codec. Nested exchanges are encoded by what 
they write (partitioning, broadcast), never by stage id. A subtree the codec 
can't encode is left alone.
     - Each duplicate becomes a reader of one stage. It shares the canonical 
exchange's stage id, shuffle partitions, column statistics and range routing, 
and keeps its own coalesce and skew-join slots, since each consuming stage 
makes those decisions for its own alignment group.
     - The canonical exchange of a key is one already resolved, else one 
already running, else the first met bottom-up. An exchange already running a 
stage of its own is never re-pointed, so a copy found after its twin finished 
just reads the finished output.
     - Never shared: subtrees with a volatile expression (`random()`), and 
range-shuffled subtrees and the window rewrites built on them, whose completion 
reads state off a single consumer.
     - A pending stage whose readers diverged, for example one reader turned 
into a broadcast, is split back into separate stages before launch.
   - **`identify_runnable_stages`** launches each stage id once, since every 
reader of a shared stage is found.
   - **Helpers on `ExchangeExec`:** `share_stage_of`, `shares_stage_with`, 
`with_own_stage`.
   - **New config `ballista.planner.adaptive.reuse_exchange`**, default `true`.
   - **Tests:** planner and graph tests for union, self-join and q15-shaped 
queries, the config switch, volatile subtrees, late duplicates, already-running 
stages and diverged readers; a test that losing a shared stage's output rolls 
back that stage once along with its reader; and an end-to-end standalone test 
comparing rows with reuse on and off against the static planner.
   
   Losing the executor that holds a finished stage's output still can't be 
recovered under AQE, with or without reuse (#1986, #2539). This PR doesn't 
change that: a shared stage is reset once and its readers are rolled back, as 
for a single-reader stage.
   
   # Are there any user-facing changes?
   
   Yes. Queries that read a subplan more than once run fewer stages under AQE. 
The new config `ballista.planner.adaptive.reuse_exchange` (default `true`) 
switches it off. It's documented in the configuration reference and in the 
tuning guide's AQE section. `SessionConfigExt` gains 
`ballista_adaptive_reuse_exchange_enabled` / 
`with_ballista_adaptive_reuse_exchange_enabled`.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


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