risingwavelabs/risingwave · warning · unimplemented!

table {} not found

Error message

table {} not found

What it means

load_table in MockIcebergCatalog only recognizes its two hard-coded table names (SPARSE_TABLE, RANGE_TABLE); any other name hits unimplemented!("table {} not found", ...), which panics. Unlike todo!(), this marks a deliberately unsupported input in the mock rather than unwritten code.

Source

Thrown at src/connector/src/connector_common/iceberg/mock_catalog.rs:223

    ) -> iceberg::Result<()> {
        todo!()
    }

    /// Create a new table inside the namespace.
    async fn create_table(
        &self,
        _namespace: &NamespaceIdent,
        _creation: TableCreation,
    ) -> iceberg::Result<Table> {
        todo!()
    }

    /// Load table from the catalog.
    async fn load_table(&self, table: &TableIdent) -> iceberg::Result<Table> {
        match table.name.as_ref() {
            Self::SPARSE_TABLE => Ok(Self::sparse_table()),
            Self::RANGE_TABLE => Ok(Self::range_table()),
            _ => unimplemented!("table {} not found", table.name()),
        }
    }

    /// Drop a table from the catalog.
    async fn drop_table(&self, _table: &TableIdent) -> iceberg::Result<()> {
        todo!()
    }

    async fn purge_table(&self, table: &TableIdent) -> iceberg::Result<()> {
        self.drop_table(table).await
    }

    /// Check if a table exists in the catalog.
    async fn table_exists(&self, table: &TableIdent) -> iceberg::Result<bool> {
        match table.name.as_ref() {
            Self::SPARSE_TABLE => Ok(true),
            Self::RANGE_TABLE => Ok(true),
            _ => Ok(false),

View on GitHub (pinned to 6469eb736d)

Solutions

  1. Use exactly Self::SPARSE_TABLE or Self::RANGE_TABLE as the table name in tests
  2. Extend the match to return Ok(Self::sparse_table()) (or a new fixture) for additional names
  3. Point code requiring arbitrary table names at a real catalog instead of this mock

Example fix

// before
_ => unimplemented!("table {} not found", table.name()),
// after
name => Err(iceberg::Error::new(
    iceberg::ErrorKind::Unexpected,
    format!("table {name} not found in mock catalog"),
))
Defensive patterns

Strategy: validation

Validate before calling

const VALID: [&str; 2] = ["sparse_table", "range_table"]; // values of SPARSE_TABLE / RANGE_TABLE
assert!(VALID.contains(&table.name().as_str()), "table {} not in mock catalog", table.name());

Type guard

fn is_mock_fixture_table(ident: &TableIdent) -> bool {
    ident.name() == MockIcebergCatalog::SPARSE_TABLE || ident.name() == MockIcebergCatalog::RANGE_TABLE
}

Try / catch

// unimplemented! panics; catch only if probing:
let ok = std::panic::catch_unwind(AssertUnwindSafe(|| rt.block_on(catalog.load_table(&ident)))).is_ok();

Prevention

When it happens

Trigger: Calling load_table (directly or via higher-level helpers) with a TableIdent whose name is neither SPARSE_TABLE nor RANGE_TABLE, including missing/mistyped test table names.

Common situations: Tests referencing a table name that does not match the mock's constants; production-like code paths pointed at the mock in unit tests with real table names.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/343be445f78a32ea. Report an issue: GitHub.