prestodb/presto · error · ViewAlreadyExistsException
View already exists
Error message
View already exists
What it means
Mapped from TableAlreadyExistsException when CREATE VIEW (or CREATE OR REPLACE VIEW) finds an object already stored under the view name. If the existing table is not a Presto view (e.g. a real table), or the statement was plain CREATE VIEW without OR REPLACE, creation is rejected. Presto translates the metastore conflict into ViewAlreadyExistsException.
Source
Thrown at presto-hive/src/main/java/com/facebook/presto/hive/HiveMetadata.java:2476
@Override
public void createView(ConnectorSession session, ConnectorTableMetadata viewMetadata, String viewData, boolean replace)
{
MetastoreContext metastoreContext = getMetastoreContext(session);
SchemaTableName viewName = viewMetadata.getTable();
Table table = createTableObjectForViewCreation(
session,
viewMetadata,
createViewProperties(session, prestoVersion),
typeTranslator,
metastoreContext,
encodeViewData(viewData));
PrincipalPrivileges principalPrivileges = buildInitialPrivilegeSet(session.getUser());
Optional<Table> existing = metastore.getTable(metastoreContext, viewName.getSchemaName(), viewName.getTableName());
if (existing.isPresent()) {
if (!replace || !MetastoreUtil.isPrestoView(existing.get())) {
throw new ViewAlreadyExistsException(viewName);
}
metastore.replaceView(metastoreContext, viewName.getSchemaName(), viewName.getTableName(), table, principalPrivileges);
return;
}
try {
metastore.createTable(session, table, principalPrivileges, Optional.empty(), false, new PartitionStatistics(createEmptyStatistics(), ImmutableMap.of()), emptyList());
}
catch (TableAlreadyExistsException e) {
throw new ViewAlreadyExistsException(e.getTableName());
}
}
@Override
public void dropView(ConnectorSession session, SchemaTableName viewName)
{
ConnectorViewDefinition view = getViews(session, viewName.toSchemaTablePrefix()).get(viewName);View on GitHub (pinned to 55bb57d202)
Solutions
- Use CREATE OR REPLACE VIEW — works only if the existing object is a Presto view
- If a real Hive table occupies the name, DROP TABLE <name> first, then create the view
- Use CREATE VIEW IF NOT EXISTS to skip when it already exists
- Pick a different view name
Example fix
-- before CREATE VIEW analytics.daily_revenue AS SELECT ...; -- after CREATE OR REPLACE VIEW analytics.daily_revenue AS SELECT ...; -- or defensively: CREATE VIEW IF NOT EXISTS analytics.daily_revenue AS SELECT ...;
Defensive patterns
Strategy: validation
Validate before calling
-- guard in deploy tooling SELECT true FROM system.metadata.tables WHERE schema_name = 'analytics' AND table_name = 'daily_revenue'; -- if true: use CREATE OR REPLACE VIEW or drop first
Try / catch
try {
createView(ddl);
} catch (ViewAlreadyExistsException e) {
// deliberate idempotency: verify then replace
run("CREATE OR REPLACE VIEW " + viewName + " AS " + sql);
} Prevention
- Make DDL idempotent with IF NOT EXISTS / OR REPLACE
- Never give views the same name as existing tables
- Clean up legacy tables before migrating names to views
- Version-control view DDL and detect drift before deploy
When it happens
Trigger: CREATE VIEW on an existing name; CREATE OR REPLACE VIEW where the existing object is a native Hive table (not isPrestoView); metastore already contains a table/view with that schema.table name.
Common situations: Re-running a deployment script that creates views idempotently without IF NOT EXISTS; a stale Hive table occupying the intended view name; switching a name from table to view without dropping it first.
Related errors
- View not found
- Materialized view already exists
- ALREADY_EXISTS
- Materialized view not found
- HIVE_COLUMN_ORDER_MISMATCH
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b9b3095750b37ca5.
Report an issue: GitHub.