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

  1. 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).
  2. 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.
  3. Query the materialized view directly instead of the base table so the rewrite pass is not needed.
  4. 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

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.