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
31 changes: 31 additions & 0 deletions lib/ecto/adapters/clickhouse/api.ex
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,35 @@ defmodule Ecto.Adapters.ClickHouse.API do
# %{query | sources: {nil, schema}}
query
end

@doc """
Builds a common table expression with an (constant) expression instead of a subquery.

`with_query` must be a fragment to be evaluated as an expression.

## Options

- as: must be a compile-time literal string that is used in the main query to select
the static value.

https://clickhouse.com/docs/en/sql-reference/statements/select/with#syntax
"""
defmacro with_cte_expression(query, with_query, opts) do
name = opts[:as]

if !name do
Ecto.Query.Builder.error!("`as` option must be specified")
end

# :HACK: We override the operation to :update_all to pass context to the connection.
# :update_all is not used within ClickHouse adapter otherwise.
Ecto.Query.Builder.CTE.build(
query,
name,
with_query,
opts[:materialized],
:update_all,
__CALLER__
)
end
end
8 changes: 6 additions & 2 deletions lib/ecto/adapters/clickhouse/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -369,8 +369,12 @@ defmodule Ecto.Adapters.ClickHouse.Connection do
recursive_opt = if recursive, do: "RECURSIVE ", else: ""

ctes =
intersperse_map(queries, ?,, fn {name, _opts, cte} ->
[quote_name(name), " AS ", cte_query(cte, sources, params, query)]
intersperse_map(queries, ?,, fn {name, opts, cte} ->
if opts[:operation] == :update_all do
[cte_query(cte, sources, params, query), " AS ", quote_name(name)]
else
[quote_name(name), " AS ", cte_query(cte, sources, params, query)]
end
end)

["WITH ", recursive_opt, ctes, " "]
Expand Down
11 changes: 11 additions & 0 deletions test/ecto/adapters/clickhouse/connection_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ defmodule Ecto.Adapters.ClickHouse.ConnectionTest do

import Ecto.Query
import Ecto.Migration, only: [table: 1, table: 2, index: 3, constraint: 3]
require Ecto.Adapters.ClickHouse.API
import Ecto.Adapters.ClickHouse.API, only: [with_cte_expression: 3]

defmodule Comment do
use Ecto.Schema
Expand Down Expand Up @@ -233,6 +235,15 @@ defmodule Ecto.Adapters.ClickHouse.ConnectionTest do
"""
end

test "common table expression with expression instead of subquery" do
query =
Schema
|> with_cte_expression(fragment("123"), as: "value")
|> select([], fragment("value"))

assert all(query) == "WITH 123 AS \"value\" SELECT value FROM \"schema\" AS s0"
end

test "reference common table in union" do
comments_scope_query =
"comments"
Expand Down
Loading