prestodb/presto · error · SemanticException
NOT_SUPPORTED
NOT_SUPPORTED
Error message
Cross-catalog materialized views require legacy_materialized_views=false.
What it means
Presto throws this SemanticException(NOT_SUPPORTED) from CreateMaterializedViewTask.execute when a CREATE MATERIALIZED VIEW references a base table in a different catalog while the session still runs in legacy materialized-view mode. Legacy mode does not support cross-catalog MVs, so the statement is rejected up front. Setting legacy_materialized_views=false unlocks the newer cross-catalog path (which additionally requires cross-catalog support to be enabled).
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/execution/CreateMaterializedViewTask.java:153
session,
metadata,
parameterLookup);
ConnectorTableMetadata viewMetadata = new ConnectorTableMetadata(
toSchemaTableName(viewName),
columnMetadata,
properties,
statement.getComment());
String sql = getFormattedSql(statement.getQuery(), sqlParser, Optional.of(parameters));
List<String> baseTableCatalogsList = new ArrayList<>();
Map<String, QualifiedObjectName> uniqueTables = new LinkedHashMap<>();
analysis.getTableNodes().forEach(table -> {
QualifiedObjectName tableName = createQualifiedObjectName(session, table, table.getName(), metadata);
if (!viewName.getCatalogName().equals(tableName.getCatalogName())) {
if (isLegacyMaterializedViews(session)) {
throw new SemanticException(
NOT_SUPPORTED,
statement,
"Cross-catalog materialized views require legacy_materialized_views=false.");
}
if (!isCrossCatalogEnabled(properties)) {
throw new SemanticException(NOT_SUPPORTED,
format("Cross-catalog materialized views are not enabled. " +
"Materialized view %s cannot be created from a base table %s in a different catalog %s.",
viewName, tableName, tableName.getCatalogName()));
}
}
String key = String.format("%s.%s.%s", tableName.getCatalogName(), tableName.getSchemaName(), tableName.getObjectName());
uniqueTables.putIfAbsent(key, tableName);
});
List<SchemaTableName> baseTables = uniqueTables.values().stream()
.map(tableName -> {
baseTableCatalogsList.add(tableName.getCatalogName());
return toSchemaTableName(tableName);View on GitHub (pinned to 55bb57d202)
Solutions
- Set the session property: SET SESSION legacy_materialized_views = false; before running CREATE MATERIALIZED VIEW.
- Disable the legacy default in the coordinator's config properties or for the relevant resource group/session so cross-catalog MVs are allowed.
- Rewrite the MV so all base tables live in the same catalog as the MV if you must stay in legacy mode.
- Verify cross-catalog support is enabled for the connector (isCrossCatalogEnabled) after disabling legacy mode.
Example fix
-- before SET SESSION legacy_materialized_views = true; CREATE MATERIALIZED VIEW reporting.mv AS SELECT * FROM hive.ods.events; -- after SET SESSION legacy_materialized_views = false; CREATE MATERIALIZED VIEW reporting.mv AS SELECT * FROM hive.ods.events;
Defensive patterns
Strategy: validation
Validate before calling
boolean legacy = session.getProperty(SESSION_LEGACY_MATERIALIZED_VIEWS, Boolean.class);
boolean crossCatalog = baseTables.stream().anyMatch(t -> !t.getCatalogName().equals(viewName.getCatalogName()));
if (crossCatalog && legacy) {
throw new IllegalStateException("Disable legacy_materialized_views before creating cross-catalog MVs");
} Type guard
boolean isCrossCatalogPlan(Session session, QualifiedObjectName viewName, Collection<QualifiedObjectName> baseTables) {
return baseTables.stream().anyMatch(t -> !t.getCatalogName().equals(viewName.getCatalogName()))
&& isLegacyMaterializedViews(session);
} Try / catch
try {
createMaterializedView(session, statement);
} catch (SemanticException e) {
if (e.getCode() == NOT_SUPPORTED && e.getMessage().contains("legacy_materialized_views")) {
// retry with legacy_materialized_views=false session
} else {
throw e;
}
} Prevention
- Set legacy_materialized_views=false in cluster defaults before authoring cross-catalog MVs
- Keep MV definitions and their base tables in the same catalog where possible
- Add a DDL lint step that flags cross-catalog MV references
- Document the session property requirement for teams migrating off legacy MVs
When it happens
Trigger: CREATE MATERIALIZED VIEW whose analysis.getTableNodes() contains a base table whose catalog differs from the target view's catalog, while session property legacy_materialized_views=true.
Common situations: Clusters upgraded from older Presto where legacy_materialized_views defaults to true; users defining an MV in catalog A over a table in catalog B (e.g. hive.ods feeding an iceberg reporting MV); session property set globally in a legacy config.
Understand the failure class
Background: Presto NOT_SUPPORTED error: what "not supported" means and how to fix it — this error's family across 3 libraries.
Related errors
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/b148af6cc837fdbe.
Report an issue: GitHub.