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

   ## Which issue does this PR close?
   
   - Closes #23642.
   
   ## Rationale for this change
   
   `EmptyExecNode` and `PlaceholderRowExecNode` encoded only a schema, so the 
partition count set by `EmptyExec::with_partitions(n)` was silently lost across 
a physical-plan round-trip: a plan reporting `n` partitions before 
serialization reported `1` after.
   
   This is silent data loss rather than an error — the decoded plan is 
well-formed but describes a different plan than the one encoded. It bites any 
setup that plans in one process and executes in another. In Ballista, an 
optimizer rule collapses provably-empty sub-plans into an `EmptyExec` 
inheriting the replaced node's partition count; the scheduler sizes the stage's 
task count from that count, ships the plan to an executor, and every task above 
partition 0 fails with:
   
   ```
   Internal("Assertion failed: partition < self.partitions: EmptyExec invalid 
partition 1 (expected less than 1)")
   ```
   
   ## What changes are included in this PR?
   
   - Add a `uint32 partitions` field to `EmptyExecNode` and 
`PlaceholderRowExecNode` in `datafusion.proto`, and regenerate the prost/pbjson 
code via `regen.sh`.
   - Add a public `partitions()` accessor to `EmptyExec` and 
`PlaceholderRowExec`, since the field was private and the encoder had no way to 
read it.
   - Write `partitions` on encode and apply it via `with_partitions(...)` on 
decode.
   
   The wire format stays compatible in both directions. Plans encoded before 
this field existed carry no value for it, which prost surfaces as `0`; decode 
maps that to the previous default of `1`. Plans encoded after this change add a 
field that older readers skip.
   
   Note for #23501, which migrates these nodes to the `try_to_proto` / 
`try_from_proto` pattern: that issue specifies "schema only" and a 
byte-for-byte identical wire format, which would reintroduce this bug. The 
`partitions` field should be folded into that rewrite.
   
   ## Are these changes tested?
   
   Yes, three new tests in `roundtrip_physical_plan.rs`: partition-count 
round-trips for `EmptyExec` and `PlaceholderRowExec`, plus one decoding 
`partitions: 0` nodes directly to pin the backward-compatibility mapping. The 
round-trip tests were confirmed to fail against the unfixed decoder with 
exactly the reported symptom (4 partitions decoding to 1).
   
   ## Are there any user-facing changes?
   
   `EmptyExec::partitions()` and `PlaceholderRowExec::partitions()` are new 
public accessors; no existing API changes. Encoded plans gain a new protobuf 
field, which is backward and forward compatible as described above.


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