Skip to content

Commit

Permalink
Do not require mocks for ARRAY JOIN clause arguments
Browse files Browse the repository at this point in the history
The `ARRAY JOIN` clause in Clickhouse is currently recognised as a table
that requires a mock by the library. This is not the case as this clause
is used for expanding arrays in the source table into separate rows.
This commit adds an additional clause to the `get_source_tables` helper
function to ignore joins of kind `ARRAY`.

Closes #48
  • Loading branch information
smoothml committed Apr 2, 2024
1 parent 6b9ec4a commit 8b224f7
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Add default target path for dbt
* Improve replacement of tables (also taking into account missing alias)
* Do not require mocks for ARRAY JOIN clause arguments

## [0.6.0]

Expand Down
4 changes: 4 additions & 0 deletions src/sql_mock/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,10 @@ def get_source_tables(query, dialect) -> List[str]:
# then `source` will be a Table instance.
for alias, (node, source) in scope.selected_sources.items()
if isinstance(source, sqlglot.exp.Table)
# When using ARRAY joins sqlglot percieves the inputs as tables even though they are infact not.
# This fixes it but does not allow for multiple types of joins to be mixed with the ARRAY JOIN,
# For now we consider it a reasonable solution.
and not (node.parent.key == "join" and any(join.kind == "ARRAY" for join in node.parent_select.args["joins"]))
}

return list(tables)
Expand Down
24 changes: 24 additions & 0 deletions tests/sql_mock/test_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -321,3 +321,27 @@ def test_query_with_comment(self):

expected = ["table_1"]
assert res == expected

def test_query_with_array_joins(self):
"""...then the array join fields should not be treated as tables to be mocked"""

query = """
SELECT
sum(1) AS impressions,
city,
browser
FROM
(
SELECT
['Istanbul', 'Berlin', 'Bobruisk'] AS cities,
['Firefox', 'Chrome', 'Chrome'] AS browsers
)
ARRAY JOIN
cities AS city,
browsers AS browser
"""

res = get_source_tables(query, dialect="clickhouse")

expected = []
assert res == expected

0 comments on commit 8b224f7

Please sign in to comment.