{"record":{"id":"1a341cbba4442da7","repo":"databendlabs/databend","slug":"hashjoinhashtable-nestedloop-unreachable-1a341c","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_probe_state.rs","lineNumber":169,"sourceCode":"        match self.hash_join_state.hash_join_desc.join_type {\n            JoinType::Cross => self.cross_join(input, probe_state),\n            _ => self.probe_join(input, probe_state),\n        }\n    }\n\n    pub fn next_probe(&self, probe_state: &mut ProbeState) -> Result<Vec<DataBlock>> {\n        let process_state = probe_state.process_state.as_ref().unwrap();\n        let hash_table = unsafe { &*self.hash_join_state.hash_table.get() };\n        with_join_hash_method!(|T| match hash_table {\n            HashJoinHashTable::T(table) => {\n                // Build `keys` and get the hashes of `keys`.\n                let keys = table\n                    .hash_method\n                    .build_keys_accessor(process_state.keys_state.clone())?;\n                // Continue to probe hash table and process data blocks.\n                self.result_blocks(probe_state, keys, &table.hash_table)\n            }\n            HashJoinHashTable::NestedLoop(_) => unreachable!(),\n            HashJoinHashTable::Null => Err(ErrorCode::AbortedQuery(\n                \"Aborted query, because the hash table is uninitialized.\",\n            )),\n        })\n    }\n\n    pub fn probe_join(\n        &self,\n        mut input: DataBlock,\n        probe_state: &mut ProbeState,\n    ) -> Result<Vec<DataBlock>> {\n        let input_num_rows = input.num_rows();\n        let mut _nullable_data_block = None;\n        let evaluator = if matches!(\n            self.hash_join_state.hash_join_desc.join_type,\n            JoinType::Right | JoinType::RightAny | JoinType::RightSingle | JoinType::Full\n        ) {\n            let nullable_columns = input","sourceCodeStart":151,"sourceCodeEnd":187,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/service/src/pipelines/processors/transforms/hash_join/hash_join_probe_state.rs#L151-L187","documentation":"During the probe phase (next_probe), the code matches on the join's hash table type. A NestedLoop join has no hash table to probe, so hitting that arm means the executor is probing a join that was planned as a nested loop — an internal state/dispatch contradiction. The code panics rather than returning an error because this should be impossible.","triggerScenarios":"next_probe is invoked on a probe state whose hash table is NestedLoop(_), i.e. the pipeline built a nested-loop join but routed data through the hash-probe path, typically due to plan/executor mismatch or missing NestedLoop handling in the probe transform.","commonSituations":"Inequality or cross joins misrouted into hash join execution; custom join strategies; regressions after refactoring HashJoinHashTable dispatch.","solutions":["Ensure nested-loop joins take a separate execution path and never instantiate the hash probe transform","Return a proper ErrorCode (e.g. Unimplemented) for NestedLoop in the probe dispatch","Check EXPLAIN of the failing query for strategy selection inconsistencies","Patch or upgrade the join planner/executor integration"],"exampleFix":"// before\nHashJoinHashTable::NestedLoop(_) => unreachable!(),\n// after\nHashJoinHashTable::NestedLoop(_) => Err(ErrorCode::Unimplemented(\n    \"Nested loop join should not be probed via hash table\",\n)),","handlingStrategy":"validation","validationCode":"// Guard before probing\nif matches!(table_type, HashJoinHashTable::NestedLoop(_)) {\n    return Err(ErrorCode::Unimplemented(\"cannot probe a nested loop join\"));\n}","typeGuard":"fn probeable(t: &HashJoinHashTable) -> bool {\n    matches!(t, HashJoinHashTable::Serializer(_) | HashJoinHashTable::SingleBinary(_) | HashJoinHashTable::UniqueSerializer(_) | HashJoinHashTable::UniqueSingleBinary(_))\n}","tryCatchPattern":null,"preventionTips":["Ensure nested-loop joins are executed by a dedicated transform, never the hash probe","Add plan-level tests for inequality/cross joins verifying executor selection","Convert such panics into ErrorCode::Unimplemented returns"],"tags":["rust","panic","hash-join","probe"],"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"}