databendlabs/databend · error
HashJoinHashTable::NestedLoop(_) => unreachable!()
Error message
HashJoinHashTable::NestedLoop(_) => unreachable!()
What it means
InnerHashJoin::probe_block panics when the probe side encounters a NestedLoop hash table variant, which by design never participates in hash probing. The match otherwise returns AbortedQuery for an uninitialized (Null) table, so this arm is a pure internal invariant check.
Solutions
- Check join-type/equi-condition detection upstream so nested-loop joins never build InnerHashJoin probe processors
- Ensure the processor used matches the HashJoinHashTable variant chosen at build time
- Convert the arm to ErrorCode::Internal with context to make future hits diagnosable instead of a bare panic
- Run new_hash_join inner-join integration tests after executor-routing changes
Example fix
// before
HashJoinHashTable::NestedLoop(_) => unreachable!(),
// after
HashJoinHashTable::NestedLoop(_) => Err(ErrorCode::Internal(
"NestedLoop table cannot be probed by inner hash join")), Defensive patterns
Strategy: validation
Validate before calling
debug_assert!(!matches!(*self.basic_state.state.hash_table.deref(), HashJoinHashTable::NestedLoop(_)), "NestedLoop table in inner join probe path");
Type guard
fn probeable(t: &HashJoinHashTable) -> bool {
!matches!(t, HashJoinHashTable::NestedLoop(_))
} Prevention
- Ensure cross/non-equi joins never attach inner hash join probe processors
- Check executor selection when changing join dispatch in the planner
- Convert unreachable arms to ErrorCode::Internal for diagnosability
- Run new_hash_join integration tests after routing changes
When it happens
Trigger: A nested-loop join (cross or non-equi) is executed through the memory hash-join probe path, i.e. probe_block runs while state.hash_table holds HashJoinHashTable::NestedLoop.
Common situations: Incorrect executor selection for cross joins, refactor where inner-join probe processors are attached to a nested-loop pipeline, or tests wiring a NestedLoop table into InnerHashJoin.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- HashJoinHashTable::NestedLoop(_) => unreachable!()
- _ => unreachable!()
- HashJoinHashTable::NestedLoop(_) => unreachable!()
- _ => unreachable!()
- _ => unreachable!()
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/02c2e09d811f8f57.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/pipelines/processors/transforms/new_hash_join/memory/inner_join.rs:153
let probe_block = data.project(&self.desc.probe_projection);
let joined_stream = with_join_hash_method!(|T| match self.basic_state.hash_table.deref() {
HashJoinHashTable::T(table) => {
let probe_hash_statistics = &mut self.performance_context.probe_hash_statistics;
probe_hash_statistics.clear(probe_block.num_rows());
let probe_data = ProbeData::new(keys, valids, probe_hash_statistics);
let probe_keys_stream = table.probe_matched(probe_data)?;
InnerHashJoinStream::create(
probe_block,
self.basic_state.clone(),
probe_keys_stream,
self.desc.clone(),
&mut self.performance_context.probe_result,
)
}
HashJoinHashTable::NestedLoop(_) => unreachable!(),
HashJoinHashTable::Null => {
return Err(ErrorCode::AbortedQuery(
"Aborted query, because the hash table is uninitialized.",
));
}
});
match &mut self.performance_context.filter_executor {
None => Ok(joined_stream),
Some(filter_executor) => Ok(InnerHashJoinFilterStream::create(
joined_stream,
filter_executor,
)),
}
}
}
struct InnerHashJoinStream<'a> {View on GitHub (pinned to 288d84d76e)