prestodb/presto · error · SemanticException
NOT_SUPPORTED
NOT_SUPPORTED
Error message
Limit clause is not supported in query optimizer
What it means
When extracting metadata from a materialized view's SQL definition, MaterializedViewInformationExtractor walks the parsed AST. A LIMIT clause in the view definition breaks the assumption that the view is a pure, unbounded derivation of base-table data, so rewriting queries onto it could return wrong rows. The extractor therefore rejects the definition up front with NOT_SUPPORTED.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewInformationExtractor.java:51
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import static com.facebook.presto.sql.ExpressionUtils.removeGroupingElementPrefix;
import static com.facebook.presto.sql.ExpressionUtils.removeSingleColumnPrefix;
import static com.facebook.presto.sql.analyzer.SemanticErrorCode.NOT_SUPPORTED;
import static com.google.common.base.Preconditions.checkState;
public class MaterializedViewInformationExtractor
extends DefaultTraversalVisitor<Void, Void>
{
private final MaterializedViewInfo materializedViewInfo = new MaterializedViewInfo();
@Override
protected Void visitQuerySpecification(QuerySpecification node, Void context)
{
if (node.getLimit().isPresent()) {
throw new SemanticException(NOT_SUPPORTED, node, "Limit clause is not supported in query optimizer");
}
if (node.getHaving().isPresent()) {
throw new SemanticException(NOT_SUPPORTED, node, "Having clause is not supported in query optimizer");
}
if (!node.getFrom().isPresent()) {
throw new SemanticException(NOT_SUPPORTED, node, "Materialized view with no From clause is not supported in query optimizer");
}
materializedViewInfo.setBaseTable(node.getFrom().get());
materializedViewInfo.setWhereClause(node.getWhere());
return super.visitQuerySpecification(node, context);
}
protected Void visitSelect(Select node, Void context)
{
super.visitSelect(node, context);
materializedViewInfo.setDistinct(node.isDistinct());
return null;
}View on GitHub (pinned to 55bb57d202)
Solutions
- Remove the LIMIT clause from the materialized view definition.
- If a row cap is needed, filter in the WHERE clause instead (e.g. date-range predicate).
- Enforce top-N semantics in the consumer query at read time, not in the view.
Example fix
// before CREATE MATERIALIZED VIEW mv AS SELECT * FROM orders ORDER BY ts LIMIT 1000; // after CREATE MATERIALIZED VIEW mv AS SELECT * FROM orders; -- apply ORDER BY/LIMIT in the reading query
Defensive patterns
Strategy: validation
Validate before calling
// Validate the MV definition before DDL: the query must not contain LIMIT.
function validateMvDefinition(sql) {
if (/\bLIMIT\b/i.test(extractSelectBody(sql))) {
throw new Error("Materialized view definition must not contain LIMIT");
}
} Try / catch
catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.NOT_SUPPORTED && e.getMessage().contains("Limit clause is not supported")) {
// rewrite the DDL without LIMIT and retry creation
} else { throw e; }
} Prevention
- Never put ORDER BY/LIMIT inside MV definitions; apply at read time.
- Add DDL linting that rejects LIMIT in CREATE MATERIALIZED VIEW.
- Use WHERE filters to bound view size.
When it happens
Trigger: CREATE MATERIALIZED VIEW ... AS SELECT ... FROM ... LIMIT n — visitQuerySpecification sees node.getLimit().isPresent() during MV metadata extraction (at view creation or refresh).
Common situations: Copy-pasting a top-N reporting query into a materialized view definition; porting views from databases that allow LIMIT in views; users trying to cap MV size with LIMIT.
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/3a27f76b6d2cc904.
Report an issue: GitHub.