prestodb/presto · error · SemanticException
NOT_SUPPORTED
NOT_SUPPORTED
Error message
Unsupported function for materialized view rewrite: %s
What it means
During materialized-view-based query rewrite, Presto rewrites aggregate functions over base tables into references to pre-computed columns in the materialized view. Only a fixed whitelist of associative functions (and designated non-associative rewrite functions) is supported. When a function call is neither whitelisted nor a scalar function, the rewriter cannot safely map it onto the view, so it throws NOT_SUPPORTED.
Source
Thrown at presto-main-base/src/main/java/com/facebook/presto/sql/analyzer/MaterializedViewExpressionRewriter.java:108
{
Map<Expression, Identifier> columnMap = mvInfo.getBaseToViewColumnMap();
if (!columnMap.containsKey(node)) {
throw new IllegalStateException("Materialized view definition does not contain mapping for the column: " + node.getValue());
}
return new Identifier(columnMap.get(node).getValue(), node.isDelimited());
}
public Expression rewriteFunctionCall(FunctionCall node, Function<Expression, Expression> argRewriter)
{
Map<Expression, Identifier> baseToViewColumnMap = mvInfo.getBaseToViewColumnMap();
if (NON_ASSOCIATIVE_REWRITE_FUNCTIONS.containsKey(node.getName())) {
return MaterializedViewUtils.rewriteNonAssociativeFunction(node, baseToViewColumnMap);
}
if (!ASSOCIATIVE_REWRITE_FUNCTIONS.contains(node.getName())) {
if (!isScalarFunction(node)) {
throw new SemanticException(NOT_SUPPORTED, node, "Unsupported function for materialized view rewrite: " + node.getName());
}
return rebuildWithRewrittenArgs(node, argRewriter);
}
if (baseToViewColumnMap.containsKey(node)) {
return rewriteAssociativeFunction(node, baseToViewColumnMap.get(node));
}
if (mvInfo.getGroupBy().isPresent()) {
throw new SemanticException(NOT_SUPPORTED, node, "Materialized view does not pre-compute aggregate: " + node.getName());
}
return rebuildWithRewrittenArgs(node, argRewriter);
}
public boolean isScalarFunction(FunctionCall functionCall)
{
return !functionCall.getWindow().isPresent()View on GitHub (pinned to 55bb57d202)
Solutions
- Rewrite the query or materialized view to use supported associative functions (SUM, COUNT, MIN, MAX, etc.) and derive other aggregates from them (e.g. AVG = SUM/COUNT).
- Add the function to ASSOCIATIVE_REWRITE_FUNCTIONS (or NON_ASSOCIATIVE_REWRITE_FUNCTIONS with a corresponding rewrite rule in MaterializedViewUtils.rewriteNonAssociativeFunction) if it can be safely rewritten.
- Query the materialized view directly instead of the base table so the rewrite pass is not needed.
- Disable materialized view rewrite routing for that query/session.
Example fix
// before (query) SELECT dept, AVG(salary) FROM employee GROUP BY dept; -- MV holds AVG(salary) // after SELECT dept, SUM(salary)/SUM(salary_count) AS avg_salary FROM employee GROUP BY dept; -- MV stores SUM(salary) and COUNT(salary)
Defensive patterns
Strategy: try-catch
Validate before calling
// Before relying on MV rewrite, ensure the view only uses supported aggregates: // Supported: SUM, COUNT, MIN, MAX (associative whitelist) plus AVG etc. via // MaterializedViewUtils.rewriteNonAssociativeFunction. Check ASSOCIATIVE_REWRITE_FUNCTIONS / // NON_ASSOCIATIVE_REWRITE_FUNCTIONS in MaterializedViewExpressionRewriter before creating the MV.
Try / catch
try {
planner.execute(query);
} catch (SemanticException e) {
if (e.getCode() == SemanticErrorCode.NOT_SUPPORTED && e.getMessage().contains("Unsupported function for materialized view rewrite")) {
// fall back to base-table query without MV rewrite
} else { throw e; }
} Prevention
- Only use whitelisted associative aggregates in MV definitions.
- Derive AVG/variance-style aggregates from SUM/COUNT columns stored in the view.
- Test MV-backed queries in CI to catch rewrite failures early.
- Keep function whitelist changes documented for view authors.
When it happens
Trigger: Querying a base table with an aggregate expression (e.g. AVG, MEDIAN, or any custom aggregate function) whose materialized view definition contains the same function but it is not in ASSOCIATIVE_REWRITE_FUNCTIONS or NON_ASSOCIATIVE_REWRITE_FUNCTIONS, and it is not a scalar function; rewriteFunctionCall is invoked from the MV rewrite visitor during planning.
Common situations: Users create a materialized view computing a non-whitelisted aggregate (e.g. AVG(x), STDDEV, custom UDA) and then query the base table expecting automatic rewrite; adding new SQL functions without extending the whitelist; connector/plugin functions that are aggregates but not registered as rewriteable.
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/120209457ddde7ea.
Report an issue: GitHub.