prestodb/presto · error · PinotException

PINOT_UNSUPPORTED_EXPRESSION

PINOT_UNSUPPORTED_EXPRESSION

Error message

Pinot does not support lambda 

What it means

PinotProjectExpressionConverter.visitLambda unconditionally throws PINOT_UNSUPPORTED_EXPRESSION because Pinot's query language has no lambda expression support. Any projected expression containing a LambdaDefinitionExpression (e.g. from higher-order functions like filter, transform, any_match) cannot be translated and pushdown of that projection fails.

Source

Thrown at presto-pinot-toolkit/src/main/java/com/facebook/presto/pinot/query/PinotProjectExpressionConverter.java:94

        this.standardFunctionResolution = requireNonNull(standardFunctionResolution, "standardFunctionResolution is null");
        this.session = requireNonNull(session, "session is null");
    }

    @Override
    public PinotExpression visitVariableReference(
            VariableReferenceExpression reference,
            Map<VariableReferenceExpression, Selection> context)
    {
        Selection input = requireNonNull(context.get(reference), format("Input column %s does not exist in the input", reference));
        return new PinotExpression(input.getDefinition(), input.getOrigin());
    }

    @Override
    public PinotExpression visitLambda(
            LambdaDefinitionExpression lambda,
            Map<VariableReferenceExpression, Selection> context)
    {
        throw new PinotException(PINOT_UNSUPPORTED_EXPRESSION, Optional.empty(), "Pinot does not support lambda " + lambda);
    }

    protected boolean isImplicitCast(Type inputType, Type resultType)
    {
        if (typeManager.canCoerce(inputType, resultType)) {
            return true;
        }
        return resultType.getTypeSignature().getBase().equals(StandardTypes.TIMESTAMP) && TIME_EQUIVALENT_TYPES.contains(inputType.getTypeSignature().getBase());
    }
    protected PinotExpression handleArithmeticExpression(
            CallExpression expression,
            OperatorType operatorType,
            Map<VariableReferenceExpression, PinotQueryGeneratorContext.Selection> context)
    {
        List<RowExpression> arguments = expression.getArguments();
        if (arguments.size() == 2) {
            PinotExpression left = arguments.get(0).accept(this, context);
            PinotExpression right = arguments.get(1).accept(this, context);

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Rewrite the query without higher-order/lambda functions — use flat scalar expressions or UNNEST instead of transform/filter/any_match
  2. Move the lambda-based computation outside the Pinot scan (compute it in an enclosing projection after the connector returns raw columns)
  3. If the lambda must be evaluated, extract the raw array column from Pinot and perform the lambda logic in a separate Presto-side step
  4. Contribute lambda-to-Pinot-expression support in visitLambda if Pinot gains equivalent functions

Example fix

// before
SELECT transform(scores, x -> x * 2) AS doubled FROM pinot_table
// after
SELECT scores FROM pinot_table -- then compute transform(...) in an outer Presto query
Defensive patterns

Strategy: validation

Validate before calling

// Reject lambda-based higher-order functions before querying Pinot:
java.util.regex.Pattern LAMBDA_FNS = Pattern.compile(
    "(?i)(any_match|all_match|none_match|filter|transform|reduce|zip_with|map_filter|map_transform)\\s*\\(");
boolean isPushdownSafeProjection(String selectExpr) {
    return !LAMBDA_FNS.matcher(selectExpr).find();
}

Try / catch

try {
    result = queryPinot(sql);
} catch (PinotException e) {
    if (String.valueOf(e.getMessage()).startsWith("Pinot does not support lambda")) {
        // rewrite query without lambda / compute in Presto, then retry once
    } else { throw e; }
}

Prevention

When it happens

Trigger: A SELECT (or filter/project expression being pushed down) contains a higher-order function that the Presto planner represents as a LambdaDefinitionExpression, e.g. any_match(arr, x -> x > 0), transform(arr, x -> x * 2), filter(arr, x -> x IS NOT NULL).

Common situations: Querying Pinot tables that contain array/map columns and applying lambda-based array functions in SELECT; recent Presto versions compile many array functions through lambdas, hitting this path even when the function looks ordinary.

Related errors


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