{"record":{"id":"743d41dfdf6a4037","repo":"prestodb/presto","slug":"clickhouse-pushdown-unsupported-expression-743d41","errorCode":"CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION","errorMessage":"ClickHouse does not support lambda: ","messagePattern":"ClickHouse does not support lambda: ","errorType":"error_code","errorClass":"PrestoException","httpStatus":null,"severity":"error","filePath":"presto-clickhouse/src/main/java/com/facebook/presto/plugin/clickhouse/optimization/ClickHouseProjectExpressionConverter.java","lineNumber":75,"sourceCode":"        this.typeManager = requireNonNull(typeManager, \"type manager\");\n        this.standardFunctionResolution = requireNonNull(standardFunctionResolution, \"standardFunctionResolution is null\");\n    }\n\n    @Override\n    public ClickHouseColumnExpression 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 ClickHouseColumnExpression(input.getDefinition(), input.getOrigin());\n    }\n\n    @Override\n    public ClickHouseColumnExpression visitLambda(\n            LambdaDefinitionExpression lambda,\n            Map<VariableReferenceExpression, Selection> context)\n    {\n        throw new PrestoException(CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION, \"ClickHouse 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(TIMESTAMP) && TIME_EQUIVALENT_TYPES.contains(inputType.getTypeSignature().getBase());\n    }\n\n    private ClickHouseColumnExpression 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":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-clickhouse/src/main/java/com/facebook/presto/plugin/clickhouse/optimization/ClickHouseProjectExpressionConverter.java#L57-L93","documentation":"ClickHouseProjectExpressionConverter.visitLambda unconditionally throws CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION because lambda expressions (LambdaDefinitionExpression, e.g. from higher-order functions like filter, transform, all_match) cannot be translated into ClickHouse SQL by this connector. Any projection containing a lambda is therefore not pushable.","triggerScenarios":"A projection (SELECT list) or computed expression pushed to ClickHouse that contains a higher-order function producing a LambdaDefinitionExpression, e.g. transform(arr, x -> x + 1) or filter(a, x -> x > 0).","commonSituations":"Users SELECTing array/map higher-order function results directly from a ClickHouse table in a query that also tries to push down projections; commonly hit with ARRAY/ MAP typed columns.","solutions":["Rewrite the query so higher-order/lambda expressions are computed outside the pushed-down projection (inner query returning raw columns, lambda applied in an outer Presto-side step)","Avoid higher-order functions over ClickHouse columns; use plain scalar functions that the connector supports","Materialize the lambda result as a stored ClickHouse column instead of computing it at query time"],"exampleFix":"// before (lambda pushed down)\nSELECT transform(tags, x -> upper(x)) AS t FROM ch_events;\n// after (lambda applied outside pushdown)\nSELECT transform(tags, x -> upper(x)) AS t FROM (SELECT tags FROM ch_events) -- conversion restricted to inner projection","handlingStrategy":"validation","validationCode":"// Java-side check before relying on pushdown\nboolean containsLambda(RowExpression expr) {\n    if (expr instanceof LambdaDefinitionExpression) return true;\n    for (RowExpression arg : ((CallExpression) expr).getArguments()) {\n        if (containsLambda(arg)) return true;\n    }\n    return false;\n}","typeGuard":"boolean isLambda(RowExpression e) { return e instanceof LambdaDefinitionExpression; }","tryCatchPattern":"try {\n    return projectConverter.convert(expression);\n} catch (PrestoException e) {\n    if (e.getErrorCode() == CLICKHOUSE_PUSHDOWN_UNSUPPORTED_EXPRESSION.toErrorCode()) {\n        return Optional.empty(); // evaluate without pushdown\n    }\n    throw e;\n}","preventionTips":["Don't use higher-order functions (transform/filter/reduce) on ClickHouse columns in pushed projections","Keep SELECT lists to plain column references and supported scalar functions","Materialize lambda results as ClickHouse columns if needed frequently"],"tags":["clickhouse","pushdown","lambda","higher-order-functions"],"backgroundTag":"connector-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"}