Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions sqlglot/generators/clickhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class ClickHouseGenerator(generator.Generator):
exp.ArrayConcat: rename_func("arrayConcat"),
exp.ArrayContains: rename_func("has"),
exp.ArrayFilter: lambda self, e: self.func("arrayFilter", e.expression, e.this),
exp.Transform: lambda self, e: self.func("arrayMap", e.expression, e.this),
exp.ArrayRemove: remove_from_array_using_filter,
exp.ArrayReverse: rename_func("arrayReverse"),
exp.ArraySlice: rename_func("arraySlice"),
Expand Down
6 changes: 6 additions & 0 deletions sqlglot/parsers/clickhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,12 @@ class ClickHouseParser(parser.Parser):
"ARRAYMIN": exp.ArrayMin.from_arg_list,
"ARRAYREVERSE": exp.ArrayReverse.from_arg_list,
"ARRAYSLICE": exp.ArraySlice.from_arg_list,
# ClickHouse higher-order array functions: the lambda comes first, the array second.
# This is the opposite of exp.ArrayFilter(this=array, expression=lambda) convention.
Comment on lines +265 to +266

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's remove the comments here, to simplify the code.

"ARRAYFILTER": lambda args: exp.ArrayFilter(
this=seq_get(args, 1), expression=seq_get(args, 0)
),
"ARRAYMAP": lambda args: exp.Transform(this=seq_get(args, 1), expression=seq_get(args, 0)),
"CURRENTDATABASE": exp.CurrentDatabase.from_arg_list,
"CURRENTSCHEMAS": exp.CurrentSchemas.from_arg_list,
"COUNTIF": _build_count_if,
Expand Down
22 changes: 22 additions & 0 deletions tests/dialects/test_clickhouse.py
Original file line number Diff line number Diff line change
Expand Up @@ -1768,6 +1768,28 @@ def test_functions(self):
self.validate_identity(
"SELECT TRANSFORM(foo, [1, 2], ['first', 'second'], 'default') FROM table"
)
self.validate_all(
"SELECT arrayMap(x -> x + 1, arr) FROM t",
read={
"duckdb": "SELECT LIST_TRANSFORM(arr, x -> x + 1) FROM t",
"spark": "SELECT TRANSFORM(arr, x -> x + 1) FROM t",
},
write={
"clickhouse": "SELECT arrayMap(x -> x + 1, arr) FROM t",
"duckdb": "SELECT LIST_TRANSFORM(arr, x -> x + 1) FROM t",
"spark": "SELECT TRANSFORM(arr, x -> x + 1) FROM t",
},
)
Comment on lines +1772 to +1782

@geooo109 geooo109 Jun 25, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are cases that the transpilation results into different semantics.

clickhouse (input):
SELECT arrayMap(NULL, [1, 2]) AS res

Query id: 0db4a81e-03b1-4253-8593-6a73112a447f

   ┌─res──┐
1. │ ᴺᵁᴸᴸ │
   └──────┘

1 row in set. Elapsed: 0.002 sec. 

transpiled duckdb (output):
memory D SELECT LIST_TRANSFORM([1,2], NULL) AS res;
Binder Error:
Invalid lambda expression!

transpiled spark 4 (output):
spark-sql (default)> SELECT TRANSFORM(array(1,2), NULL);
[null,null]
Time taken: 0.051 seconds, Fetched 1 row(s)

self.validate_all(
"SELECT arrayFilter(x -> x > 0, arr) FROM t",
read={
"duckdb": "SELECT LIST_FILTER(arr, x -> x > 0) FROM t",
},
write={
"clickhouse": "SELECT arrayFilter(x -> x > 0, arr) FROM t",
"duckdb": "SELECT LIST_FILTER(arr, x -> x > 0) FROM t",
},
)
Comment on lines +1783 to +1792

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as https://github.com/tobymao/sqlglot/pull/7794/changes#r3473795554 :

clickhouse (input):
SELECT arrayFilter(NULL, [1, 2, 3])

Query id: 2b70a67e-8db5-47e5-b60a-02551e878843

   ┌─arrayFilter(NULL, [1, 2, 3])─┐
1. │ ᴺᵁᴸᴸ                         │
   └──────────────────────────────┘

1 row in set. Elapsed: 0.002 sec. 

transpiled duckdb(output): 
memory D SELECT LIST_FILTER([1, 2, 3], NULL);
Binder Error:
Invalid lambda expression!


def test_array_offset(self):
with self.assertLogs(helper_logger) as cm:
Expand Down
Loading