databendlabs/databend · error
Invalid join type during building physical hash join.
Error message
Invalid join type {} during building physical hash join. What it means
create_output_schema computes the output schema for a physical hash join and supports all regular join types, but ASOF joins (Asof/LeftAsof/RightAsof/FullAsof) are implemented by a dedicated ASOF join operator. Encountering an ASOF type here means a hash join was built for a join that must use the ASOF path, so the code panics via unreachable!.
Solutions
- Check the query's join type and planner dispatch; ensure ASOF joins route to the ASOF physical join builder.
- Upgrade to a version where ASOF joins are dispatched correctly.
- Rewrite the query without ASOF JOIN (use a subquery with ORDER BY/LIMIT per key) as a workaround.
- File a bug with the query and EXPLAIN plan showing the ASOF join reaching hash join build.
Defensive patterns
Strategy: validation
Validate before calling
-- Confirm the join type dispatch before physical planning -- ASOF joins must route to the ASOF builder, not hash join EXPLAIN ASOF JOIN ...; -- inspect the physical plan nodes
Type guard
fn needs_asof_builder(jt: &JoinType) -> bool {
matches!(jt, JoinType::Asof | JoinType::LeftAsof | JoinType::RightAsof | JoinType::FullAsof)
} Prevention
- Add dispatch tests: every JoinType must route to its correct physical builder
- Extend the dispatcher (not the hash join) when adding new join types
- Run ASOF JOIN query suites in CI after planner changes
When it happens
Trigger: build_hash_join is invoked for a join whose JoinType is Asof, LeftAsof, RightAsof, or FullAsof — i.e. the physical planner dispatched an ASOF join to the hash-join builder.
Common situations: Writing ASOF JOIN queries and hitting a planner dispatch bug; optimizer rule changes that reroute ASOF joins into hash join construction; version regressions in join planning.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- logic error: expected CreateTable plan
- Input plan must be Query, but it's
- Input plan must be Query, but it's
- internal error: entered unreachable code
- internal error: entered unreachable code
AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11).
Data as JSON: /api/errors/b7890d74243bb5d9.
Report an issue: GitHub.
Appendix: source
Thrown at src/query/service/src/physical_plans/physical_hash_join.rs:1158
DataType::Nullable(Box::new(DataType::Boolean)),
));
result
}
JoinType::RightMark => {
let name = if let Some(idx) = join.marker_index {
idx.to_string()
} else {
"marker".to_string()
};
let mut result = probe_fields;
result.push(DataField::new(
name.as_str(),
DataType::Nullable(Box::new(DataType::Boolean)),
));
result
}
JoinType::Asof | JoinType::LeftAsof | JoinType::RightAsof | JoinType::FullAsof => {
unreachable!(
"Invalid join type {} during building physical hash join.",
join.join_type
)
}
};
// Create projections and output schema
let mut projections = BTreeSet::new();
let projected_schema = DataSchema::new(merged_fields.clone());
for column in column_projections.iter() {
if let Some((index, _)) = projected_schema.column_with_name(&column.to_string()) {
projections.insert(index);
}
}
let mut output_fields = Vec::with_capacity(column_projections.len());
for (i, field) in merged_fields.iter().enumerate() {View on GitHub (pinned to 288d84d76e)