{"record":{"id":"cffe6656e5f04201","repo":"databendlabs/databend","slug":"hashjoinhashtable-nestedloop-unreachable","errorCode":null,"errorMessage":"HashJoinHashTable::NestedLoop(_) => unreachable!()","messagePattern":"HashJoinHashTable::NestedLoop\\(_\\) => unreachable!\\(\\)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/service/src/pipelines/processors/transforms/hash_join/hash_join_build_state.rs","lineNumber":775,"sourceCode":"            },\n            HashJoinHashTable::KeysU32(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u32,\n            },\n            HashJoinHashTable::KeysU64(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u64,\n            },\n            HashJoinHashTable::KeysU128(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u128,\n            },\n            HashJoinHashTable::KeysU256(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, U256,\n            },\n            HashJoinHashTable::Null => {\n                return Err(ErrorCode::AbortedQuery(\n                    \"Aborted query, because the hash table is uninitialized.\",\n                ));\n            }\n            HashJoinHashTable::NestedLoop(_) => unreachable!(),\n            HashJoinHashTable::UniqueSerializer(table) => insert_binary_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces,\n            },\n            HashJoinHashTable::UniqueSingleBinary(table) => insert_binary_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces,\n            },\n            HashJoinHashTable::UniqueKeysU8(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u8,\n            },\n            HashJoinHashTable::UniqueKeysU16(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u16,\n            },\n            HashJoinHashTable::UniqueKeysU32(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u32,\n            },\n            HashJoinHashTable::UniqueKeysU64(table) => insert_key! {\n              &mut table.hash_table, &table.hash_method, chunk, build_keys, valids, chunk_index as u32, entry_size, &mut local_raw_entry_spaces, u64,\n            },","sourceCodeStart":757,"sourceCodeEnd":793,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/pipelines/processors/transforms/hash_join/hash_join_build_state.rs#L757-L793","documentation":"When finalizing a hash join build, the code dispatches on the HashJoinHashTable enum. The NestedLoop variant represents a join executed as a nested loop (no hash table), which should never reach the hash-table build/finalize path. Reaching this arm means the pipeline selected a nested-loop join but then attempted hash-table build finalization — an internal scheduling/type dispatch bug, so the code panics.","triggerScenarios":"finalize is called on a build state whose hash table type is NestedLoop. This happens if join strategy selection (hash vs nested loop) and the build transform's expectations disagree, e.g. after plan rewrites, cross joins, or join hints forcing a strategy mismatch.","commonSituations":"Queries with cross joins or inequality-only conditions that get planned as nested loops; misconfigured join hints; code changes to the hash table type negotiation between planner and executor.","solutions":["Check why the plan chose NestedLoop while a hash build transform was instantiated; align join strategy selection with the build transform","Guard finalize to no-op or return an error for NestedLoop instead of panicking","Reproduce with the failing query's EXPLAIN output and check join type/hints","Upgrade or patch to a version where strategy negotiation is fixed"],"exampleFix":"// before\nHashJoinHashTable::NestedLoop(_) => unreachable!(),\n// after\nHashJoinHashTable::NestedLoop(_) => Ok(()), // nested loop join has no hash table to finalize","handlingStrategy":"validation","validationCode":"// Before creating the build transform, verify the table type is hash-based\nif matches!(hash_table_type, HashJoinHashTable::NestedLoop(_)) {\n    return Err(ErrorCode::Internal(\"nested loop join must not use hash build pipeline\"));\n}","typeGuard":"fn is_hash_join_table(t: &HashJoinHashTable) -> bool {\n    !matches!(t, HashJoinHashTable::NestedLoop(_))\n}","tryCatchPattern":null,"preventionTips":["Keep join strategy selection and transform construction in one place to avoid mismatch","Add tests for cross joins and non-equi joins asserting they never instantiate the hash build path","Return ErrorCode::Unimplemented instead of unreachable! for cross-strategy dispatch"],"tags":["rust","panic","hash-join","join-strategy"],"backgroundTag":"internal-invariant-violation","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}