{"record":{"id":"741ba1bee19f5c2d","repo":"prestodb/presto","slug":"druid-pushdown-unsupported-expression-741ba1","errorCode":"DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION","errorMessage":"Druid does not support lambda: ${lambda}","messagePattern":"Druid does not support lambda: (.+?)","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-druid/src/main/java/com/facebook/presto/druid/DruidProjectExpressionConverter.java","lineNumber":71,"sourceCode":"        this.typeManager = requireNonNull(typeManager, \"type manager\");\n        this.standardFunctionResolution = requireNonNull(standardFunctionResolution, \"standardFunctionResolution is null\");\n    }\n\n    @Override\n    public DruidExpression visitVariableReference(\n            VariableReferenceExpression reference,\n            Map<VariableReferenceExpression, Selection> context)\n    {\n        Selection input = requireNonNull(context.get(reference), format(\"Input column %s does not exist in the input\", reference));\n        return new DruidExpression(input.getDefinition(), input.getOrigin());\n    }\n\n    @Override\n    public DruidExpression visitLambda(\n            LambdaDefinitionExpression lambda,\n            Map<VariableReferenceExpression, Selection> context)\n    {\n        throw new PrestoException(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION, \"Druid does not support lambda: \" + lambda);\n    }\n\n    protected boolean isImplicitCast(Type inputType, Type resultType)\n    {\n        if (typeManager.canCoerce(inputType, resultType)) {\n            return true;\n        }\n        return resultType.getTypeSignature().getBase().equals(StandardTypes.TIMESTAMP) && TIME_EQUIVALENT_TYPES.contains(inputType.getTypeSignature().getBase());\n    }\n\n    private DruidExpression handleCast(\n            CallExpression cast,\n            Map<VariableReferenceExpression, Selection> context)\n    {\n        if (cast.getArguments().size() == 1) {\n            RowExpression input = cast.getArguments().get(0);\n            Type expectedType = cast.getType();\n            if (isImplicitCast(input.getType(), expectedType)) {","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-druid/src/main/java/com/facebook/presto/druid/DruidProjectExpressionConverter.java#L53-L89","documentation":"Druid pushdown of a projected expression encountered a RowExpression lambda (e.g. from higher-order functions like filter/transform/any_match). The Druid connector's expression converter has no translation for lambda definitions, so instead of silently degrading it throws to abort pushdown of this expression. The query should then fall back to non-pushdown execution, but the exception surfaces if pushdown failure is fatal or is being debugged.","triggerScenarios":"Calling DruidProjectExpressionConverter.visitLambda via accept() on a LambdaDefinitionExpression while converting a project/aggregation expression for pushdown — i.e. the expression tree contains a higher-order-function lambda.","commonSituations":"Pushing down predicates or projections using higher-order functions (filter, all_match, reduce, transform) over Druid tables.","solutions":["Rewrite the query to avoid higher-order functions with lambdas in columns/predicates sent to Druid","Compute the lambda expression outside the Druid pushdown (e.g. in an outer projection after the scan)","Wrap the expression in a cast/context marker that prevents pushdown so it is evaluated in Presto instead"],"exampleFix":"// before\nSELECT filter(a, x -> x > 10) FROM druid_table;\n// after\nSELECT a FROM druid_table; -- filter evaluated in Presto, not pushed to Druid","handlingStrategy":"try-catch","validationCode":"// before relying on pushdown, scan the expression tree for lambdas\nboolean hasLambda = rowExpression.accept(new Visitor<Void, Void>() {\n    @Override public Void visitLambda(LambdaDefinitionExpression l, Void c) { throw new HasLambda(); }\n}, null);","typeGuard":"boolean isPushableToDruid(RowExpression e) {\n    return !(e instanceof LambdaDefinitionExpression);\n}","tryCatchPattern":"try {\n    converter.project(rowExpressions, context);\n} catch (PrestoException e) {\n    if (e.getErrorCode().equals(DRUID_PUSHDOWN_UNSUPPORTED_EXPRESSION.toErrorCode())) {\n        // fall back: evaluate expression in Presto, not pushed to Druid\n    } else { throw e; }\n}","preventionTips":["Avoid higher-order functions (filter, transform, any_match) in columns/predicates on Druid tables","Keep lambda computation in an outer projection above the Druid scan","Test new queries with EXPLAIN to see what gets pushed down"],"tags":["druid","pushdown","lambda","unsupported-expression"],"backgroundTag":"pushdown-unsupported-expression","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}