prestodb/presto · error · SemanticException
MATERIALIZED_VIEW_ALREADY_EXISTS
MATERIALIZED_VIEW_ALREADY_EXISTS
Error message
Destination materialized view '%s' already exists
What it means
CREATE MATERIALIZED VIEW fails when the destination materialized view (or table) name already exists, unless IF NOT EXISTS is specified. visitCreateMaterializedView checks metadataResolver.tableExists(viewName) and throws MATERIALIZED_VIEW_ALREADY_EXISTS when isNotExists() is false.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/StatementAnalyzer.java:895
accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName);
validateColumns(node, queryScope.getRelationType());
return createAndAssignScope(node, scope);
}
@Override
protected Scope visitCreateMaterializedView(CreateMaterializedView node, Optional<Scope> scope)
{
QualifiedObjectName viewName = createQualifiedObjectName(session, node, node.getName(), metadata);
analysis.setUpdateInfo(node.getUpdateInfo());
analysis.setCreateTableDestination(viewName);
if (metadataResolver.tableExists(viewName)) {
if (node.isNotExists()) {
return createAndAssignScope(node, scope);
}
throw new SemanticException(MATERIALIZED_VIEW_ALREADY_EXISTS, node, "Destination materialized view '%s' already exists", viewName);
}
validateProperties(node.getProperties(), scope);
analysis.setCreateTableProperties(mapFromProperties(node.getProperties()));
analysis.setCreateTableComment(node.getComment());
accessControl.checkCanCreateTable(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName);
accessControl.checkCanCreateView(session.getRequiredTransactionId(), session.getIdentity(), session.getAccessControlContext(), viewName);
// analyze the query that creates the table
Scope queryScope = process(node.getQuery(), scope);
validateColumns(node, queryScope.getRelationType());
validateBaseTables(analysis.getTableNodes(), node);
validateDeterministicFunctionsInMV(node);
View on GitHub (pinned to 55bb57d202)
Solutions
- Add IF NOT EXISTS: CREATE MATERIALIZED VIEW IF NOT EXISTS ...
- DROP MATERIALIZED VIEW (or TABLE) with the conflicting name first, then recreate
- Use a new destination name for the materialized view
Example fix
-- before CREATE MATERIALIZED VIEW reports.summary AS SELECT ...; -- after CREATE MATERIALIZED VIEW IF NOT EXISTS reports.summary AS SELECT ...;
Defensive patterns
Strategy: try-catch
Validate before calling
// before CREATE MATERIALIZED VIEW: // boolean exists = metadataResolver.tableExists(viewName);
Try / catch
catch (SemanticException e) { if (e.getCode() == MATERIALIZED_VIEW_ALREADY_EXISTS) { /* use IF NOT EXISTS or drop first */ } } Prevention
- Use IF NOT EXISTS when re-deploying MV definitions from VCS
- Add drop-first steps to MV deployment scripts
- Check for table name collisions before choosing the MV name
When it happens
Trigger: CREATE MATERIALIZED VIEW on an existing name without IF NOT EXISTS; note the guard uses tableExists so an ordinary table with that name also triggers it.
Common situations: Re-deploying materialized view definitions from version control without drop-first; a name collision with an existing table; re-running setup scripts.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/ea528d28c3d06b2b.
Report an issue: GitHub.