Skip to content

HashJoinExec / NestedLoopJoinExec projection Some(vec![]) becomes None after ser/de #23083

Closed

Description

@haohuaijin

Describe the bug

HashJoinExec.projection: Option<Vec<usize>> (and the same field on NestedLoopJoinExec) is serialized as a bare repeated uint32. Proto3 cannot tell None from Some(vec![]), and the decoder treats empty as None:

let projection = if !hashjoin.projection.is_empty() {
    Some(hashjoin.projection.iter().map(|i| *i as usize).collect())
} else {
    None                              // Some(vec![]) folded in here
};

Some(vec![]) means "emit zero columns"; None means "emit the full join schema". The round-trip silently changes the output schema. FilterExec already has a workaround for the same proto3 limitation — these two execs were missed.

To Reproduce

No response

Expected behavior

No response

Additional context

datafusion 53.x, 54.x, and main

Activity

  1. added theissue type on Jun 22, 2026
  2. haohuaijin commented on Jun 22, 2026

    @haohuaijin
    ContributorAuthor

    take

  3. added a commit that references this issue on Jun 25, 2026
    a0e9887
  4. added a commit that references this issue on Aug 4, 2026
    ea7ae7e
  5. added a commit that references this issue on Sep 4, 2026
    c499077
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions