Skip to content

Commit

Permalink
fix query string escaping
Browse files Browse the repository at this point in the history
  • Loading branch information
ruslandoga committed Jan 4, 2024
1 parent 712788f commit 25dd32f
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 2 deletions.
10 changes: 9 additions & 1 deletion lib/ch/query.ex
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,15 @@ defimpl DBConnection.Query, for: Ch.Query do

defp encode_param(n) when is_integer(n), do: Integer.to_string(n)
defp encode_param(f) when is_float(f), do: Float.to_string(f)
defp encode_param(b) when is_binary(b), do: escape_param([{"\t", "\\t"}, {"\n", "\\n"}], b)

# TODO possibly speed up
# For more info see
# https://clickhouse.com/docs/en/interfaces/http#tabs-in-url-parameters
# "escaped" format is the same as https://clickhouse.com/docs/en/interfaces/formats#tabseparated-data-formatting
defp encode_param(b) when is_binary(b) do
escape_param([{"\\", "\\\\"}, {"\t", "\\\t"}, {"\n", "\\\n"}], b)
end

defp encode_param(b) when is_boolean(b), do: Atom.to_string(b)
defp encode_param(%Decimal{} = d), do: Decimal.to_string(d, :normal)
defp encode_param(%Date{} = date), do: Date.to_iso8601(date)
Expand Down
14 changes: 13 additions & 1 deletion test/ch/query_string_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,19 @@ defmodule Ch.QueryStringTest do
{:ok, conn: start_supervised!({Ch, database: Ch.Test.database()})}
end

# For more info see
# https://clickhouse.com/docs/en/interfaces/http#tabs-in-url-parameters
# "escaped" format is the same as https://clickhouse.com/docs/en/interfaces/formats#tabseparated-data-formatting
test "binaries are escaped properly", %{conn: conn} do
assert Ch.query!(conn, "select {s:String}", %{"s" => "\\"}).rows == []
for s <- ["\t", "\n", "\\", "'", "\b", "\f", "\r", "\0"] do
assert Ch.query!(conn, "select {s:String}", %{"s" => s}).rows == [[s]]
end

# example from https://clickhouse.com/docs/en/interfaces/http#tabs-in-url-parameters
assert Ch.query!(conn, "select splitByChar('\t', 'abc\t123')").rows ==
[[["abc", "123"]]]

assert Ch.query!(conn, "select splitByChar('\t', {arg1:String})", %{"arg1" => "abc\t123"}).rows ==
[[["abc", "123"]]]
end
end

0 comments on commit 25dd32f

Please sign in to comment.