databendlabs/databend · error

not implemented

Error message

not implemented

What it means

`list_databases_history` in the IcebergCatalog panics with `unimplemented!()`. The Iceberg catalog only lists current databases (see list_databases combining immutable and iceberg databases); the drop/history database listing is not supported for external Iceberg catalogs. Any call panics with "not implemented".

Solutions

  1. Avoid database history commands on Iceberg catalogs; use the default catalog for those operations.
  2. Guard the command with a catalog-type check before execution.
  3. Replace the panic with a structured unsupported-operation error.

Example fix

// before
async fn list_databases_history(&self, _tenant: &Tenant) -> Result<Vec<Arc<dyn Database>>> {
    unimplemented!()
}
// after
async fn list_databases_history(&self, _tenant: &Tenant) -> Result<Vec<Arc<dyn Database>>> {
    Err(ErrorCode::Unsupported(format!("list databases history is not supported on iceberg catalog")))
}
Defensive patterns

Strategy: validation

Validate before calling

// only call history listing on the default catalog
if is_iceberg_catalog(catalog.as_ref()) {
    return Err(ErrorCode::Unsupported("SHOW DATABASES HISTORY not supported on iceberg catalog"));
}

Type guard

fn is_iceberg_catalog(catalog: &dyn Catalog) -> bool {
    catalog.name().to_lowercase().contains("iceberg")
}

Try / catch

match catalog.list_databases_history(tenant).await {
    Ok(dbs) => dbs,
    Err(e) if is_unimplemented(&e) => Vec::new(),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling SHOW DATABASES HISTORY / catalog.list_databases_history on a session whose catalog is the Iceberg catalog.

Common situations: Running UNDROP/history-oriented SHOW commands against an Iceberg catalog; clients assuming all catalogs support database history.

Related errors


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

Appendix: source

Thrown at src/query/service/src/catalogs/iceberg/iceberg_catalog.rs:169

        Ok(self)
    }

    #[async_backtrace::framed]
    async fn get_database(&self, tenant: &Tenant, db_name: &str) -> Result<Arc<dyn Database>> {
        let res = self
            .immutable_catalog
            .get_database(tenant, db_name)
            .await
            .or_unknown_database()?;
        if let Some(db) = res {
            return Ok(db);
        }
        self.iceberg_catalog.get_database(tenant, db_name).await
    }

    #[async_backtrace::framed]
    async fn list_databases_history(&self, _tenant: &Tenant) -> Result<Vec<Arc<dyn Database>>> {
        unimplemented!()
    }

    #[async_backtrace::framed]
    async fn list_databases(&self, tenant: &Tenant) -> Result<Vec<Arc<dyn Database>>> {
        let mut dbs = self.immutable_catalog.list_databases(tenant).await?;
        let mut other = self.iceberg_catalog.list_databases(tenant).await?;
        dbs.append(&mut other);
        Ok(dbs)
    }

    #[async_backtrace::framed]
    async fn create_database(&self, req: CreateDatabaseReq) -> Result<CreateDatabaseReply> {
        info!("Create database from req:{:?}", req);

        if self
            .immutable_catalog
            .exists_database(req.name_ident.tenant(), req.name_ident.database_name())
            .await?

View on GitHub (pinned to 288d84d76e)