prestodb/presto · error · SemanticException
MISSING_TABLE
MISSING_TABLE
Error message
Table does not exist
What it means
extractScope in MaterializedViewQueryOptimizer resolves the base table of a materialized view via the metadata resolver. If the catalog/schema/table name of the base table does not resolve to a TableHandle, the optimizer throws MISSING_TABLE because it cannot build a Scope over a nonexistent base table to rewrite the query.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewQueryOptimizer.java:909
if (coercion != null) {
rewritten = new Cast(
original.getLocation(),
rewritten,
coercion.getTypeSignature().toString(),
false,
analysis.isTypeOnlyCoercion(original));
}
return rewritten;
}
}
private Scope extractScope(Table table, QuerySpecification node, Expression whereClause)
{
QualifiedObjectName baseTableName = createQualifiedObjectName(session, table, table.getName(), metadata);
Optional<TableHandle> tableHandle = metadata.getMetadataResolver(session).getTableHandle(baseTableName);
if (!tableHandle.isPresent()) {
throw new SemanticException(MISSING_TABLE, node, "Table does not exist");
}
ImmutableList.Builder<Field> fields = ImmutableList.builder();
for (ColumnHandle columnHandle : metadata.getColumnHandles(session, tableHandle.get()).values()) {
ColumnMetadata columnMetadata = metadata.getColumnMetadata(session, tableHandle.get(), columnHandle);
fields.add(Field.newUnqualified(whereClause.getLocation(), columnMetadata.getName(), columnMetadata.getType()));
}
return Scope.builder()
.withRelationType(RelationId.anonymous(), new RelationType(fields.build()))
.build();
}
private MaterializedViewStatus getMaterializedViewStatus(QuerySpecification querySpecification)
{
TupleDomain<String> baseQueryDomain = TupleDomain.all();
View on GitHub (pinned to 55bb57d202)
Solutions
- Verify the base table exists: run SHOW TABLES / SELECT from the base table directly in the same catalog/schema.
- Recreate the missing/renamed base table, or drop and recreate the materialized view pointing at a valid table.
- Check the catalog is configured on the coordinator (etc/catalog/<name>.properties) and the connector is loaded.
Example fix
// before (mv_definition references dropped table) CREATE MATERIALIZED VIEW mv AS SELECT * FROM staging.events_old; // after DROP MATERIALIZED VIEW mv; CREATE MATERIALIZED VIEW mv AS SELECT * FROM staging.events;
Defensive patterns
Strategy: try-catch
Validate before calling
// verify the MV's base table resolves before querying -- SHOW TABLES FROM <catalog>.<schema>; -- confirm base table present -- SELECT 1 FROM <base_table> LIMIT 1; -- probes resolution
Try / catch
try {
runQuery("SELECT * FROM mv");
} catch (SemanticException e) {
if ("MISSING_TABLE".equals(e.getCode().name())) {
// recreate base table or drop/recreate the materialized view
} else throw e;
} Prevention
- Run DROP TABLE checks in migration scripts before dropping tables that back materialized views.
- Recreate or refresh MVs as part of any base-table rename/drop migration.
- Keep catalog configuration consistent across coordinators.
When it happens
Trigger: Querying a materialized view whose underlying base table was dropped, renamed, or lives in a catalog that is not registered in the current session; also when the materialized view definition references a table name that the connector cannot resolve.
Common situations: Base table dropped or renamed after the materialized view was created; stale materialized view definitions after schema migrations; missing catalog configuration in the coordinator's catalog directory.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/3885b61f8f8f51e1.
Report an issue: GitHub.