databendlabs/databend · error

Hash Table is finished

Error message

Hash Table is finished

What it means

In the probe transform's wait_build, the hash table status is checked; HashTableType::UnFinished inside a branch that only runs after the build has finished is asserted to be impossible, so it panics with 'Hash Table is finished'. Hitting it means the probe observed a table state inconsistent with the barrier/synchronization that should guarantee the build completed — an internal synchronization invariant violation.

Solutions

  1. Check whether the build phase aborted or errored before finalize_done updated the table type; surface that original error instead of panicking
  2. Verify the status transition to Finished happens under the same synchronization that unblocks waiters
  3. Add the actual HashTableType value to the panic message for diagnosis
  4. If triggered by an aborted build, ensure probes observe the failure and return AbortedQuery rather than waiting

Example fix

// before
HashTableType::UnFinished => {
    unreachable!("Hash Table is finished")
}
// after
HashTableType::UnFinished => Err(ErrorCode::AbortedQuery(
    "Aborted query, because the hash table build did not finish",
)),
Defensive patterns

Strategy: try-catch

Validate before calling

// Before waiting, confirm the build will finalize or abort cleanly
if build_aborted.load(Ordering::Acquire) {
    return Err(ErrorCode::AbortedQuery("hash table build aborted"));
}

Type guard

fn build_finished(t: &HashTableType) -> bool {
    !matches!(t, HashTableType::UnFinished)
}

Try / catch

match wait_build_result {
    Err(e) if e.code() == ErrorCode::ABORTED_QUERY => { log::warn!("build aborted: {}", e); propagate_abort(); }
    other => other,
}

Prevention

When it happens

Trigger: wait_build proceeds after deciding the build is done, but the shared table type still reports UnFinished; caused by a race between build finalization and probe reads, or incorrect status updates in finalize_done.

Common situations: Distributed/multi-threaded builds where barriers fail or partial builds abort; hangs or errors during build (e.g. aborted query) leaving the status stale; regressions in build-probe synchronization code.

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


AI-assisted analysis of databendlabs/databend@288d84d76e (2026-09-11). Data as JSON: /api/errors/7aa2e38721fa18fe. Report an issue: GitHub.

Appendix: source

Thrown at src/query/service/src/pipelines/processors/transforms/hash_join/transform_hash_join_probe.rs:294

        }

        self.next_round()
    }

    fn wait_build(&mut self) -> Result<Event> {
        if self.is_build_finished() {
            match self.hash_table_type {
                HashTableType::FirstRound => self.probe(),
                HashTableType::Restored => self.next_step(Step::Async(AsyncStep::Restore)),
                HashTableType::Empty => {
                    if self.can_fast_return() {
                        self.next_step(Step::Finish)
                    } else {
                        self.probe()
                    }
                }
                HashTableType::UnFinished => {
                    unreachable!("Hash Table is finished")
                }
            }
        } else {
            self.next_step(Step::Async(AsyncStep::WaitBuild))
        }
    }
}

#[async_trait::async_trait]
impl Processor for TransformHashJoinProbe {
    fn name(&self) -> String {
        "HashJoinProbe".to_string()
    }

    fn as_any(&mut self) -> &mut dyn Any {
        self
    }

View on GitHub (pinned to 288d84d76e)