prestodb/presto · error · PrestoException

NOT_SUPPORTED

NOT_SUPPORTED

Error message

unsupported function: %s

What it means

IcebergMetadataOptimizer evaluates min/max expressions over partition values and only understands the scalar functions 'greatest' and 'least'. If a CallExpression in the filter predicate uses any other scalar function, evaluateMinMax throws NOT_SUPPORTED, because the optimizer cannot fold that expression into a partition-pruning range.

Source

Thrown at presto-iceberg/src/main/java/com/facebook/presto/iceberg/optimizer/IcebergMetadataOptimizer.java:352

            Type returnType = typeManager.getType(aggregationFunctionMetadata.getReturnType());
            if (arguments.isEmpty()) {
                return new ConstantExpression(Optional.empty(), null, returnType);
            }

            String scalarFunctionName = AGGREGATION_SCALAR_MAPPING.get(aggregationFunctionMetadata.getName().getObjectName());
            while (arguments.size() > 1) {
                List<RowExpression> reducedArguments = new ArrayList<>();
                // We fold for every 100 values because GREATEST/LEAST has argument count limit
                for (List<RowExpression> partitionedArguments : Lists.partition(arguments, 100)) {
                    FunctionHandle functionHandle;
                    if (scalarFunctionName.equals("greatest")) {
                        functionHandle = functionResolution.greatestFunction(partitionedArguments.stream().map(RowExpression::getType).collect(toImmutableList()));
                    }
                    else if (scalarFunctionName.equals("least")) {
                        functionHandle = functionResolution.leastFunction(partitionedArguments.stream().map(RowExpression::getType).collect(toImmutableList()));
                    }
                    else {
                        throw new PrestoException(StandardErrorCode.NOT_SUPPORTED, "unsupported function: " + scalarFunctionName);
                    }

                    RowExpression reducedValue = rowExpressionService.getExpressionOptimizer(connectorSession).optimize(
                            new CallExpression(
                                    Optional.empty(),
                                    scalarFunctionName,
                                    functionHandle,
                                    returnType,
                                    partitionedArguments),
                            Level.EVALUATED,
                            connectorSession,
                            variableReferenceExpression -> null);
                    checkArgument(reducedValue instanceof ConstantExpression, "unexpected expression type: %s", reducedValue.getClass().getSimpleName());
                    reducedArguments.add(reducedValue);
                }
                arguments = reducedArguments;
            }
            return getOnlyElement(arguments);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Rewrite the predicate to compare the partition column directly, e.g. WHERE partition_col BETWEEN '2024-01-01' AND '2024-12-31' instead of wrapping it in a function.
  2. Restructure filters so only greatest/least appear over partition values in prunable predicates.
  3. If the function is essential, disable the optimizer path or file a feature request to support it.
  4. Check EXPLAIN to confirm the rewritten predicate yields partition pruning.

Example fix

// before
SELECT * FROM t WHERE year(event_date) = 2024
// after
SELECT * FROM t WHERE event_date BETWEEN DATE '2024-01-01' AND DATE '2024-12-31'
Defensive patterns

Strategy: validation

Validate before calling

-- keep partition-column predicates function-free for pruning
SELECT * FROM t WHERE event_date BETWEEN DATE '2024-01-01' AND DATE '2024-12-31';

Try / catch

try {
  runQuery(predicate);
} catch (PrestoException e) {
  if (e.getErrorCode().getName().equals("NOT_SUPPORTED")) {
    // fall back to an unpruned query or rewrite predicate with only greatest/least
  }
}

Prevention

When it happens

Trigger: Querying an Iceberg table whose partition filters contain scalar functions other than greatest/least over partition columns — e.g. WHERE year(partition_col) = 2024 or concat(a,b) = 'x' — when the optimizer tries to evaluate the min/max bound expression.

Common situations: Users writing function-wrapped predicates on partition columns expecting partition pruning; queries auto-generated by BI tools that wrap partition columns; newer custom functions reaching this optimizer path.

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.


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/7f493727224d0622. Report an issue: GitHub.