Skip to content
Closed
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
28 changes: 27 additions & 1 deletion lib/ecto/adapters/mysql.ex
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,32 @@ defmodule Ecto.Adapters.MySQL do
@behaviour Ecto.Adapter.Storage
@behaviour Ecto.Adapter.Structure

# Add dumpers functions if tagged values are supported by the driver

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We don't need the conditional here, instead we should change "mix.exs" to the minimum Mariaex version that supports this feature.

try do
DBConnection.Query.encode(
%Mariaex.Query{type: :binary, num_params: 1},
[%{__struct__: Mariaex.TypedValue, type: :binary, value: <<3, 2, 1>>}], [])

@doc false
def dumpers(:binary, type), do: [type, &encode_binary/1]
def dumpers(:string, type), do: [type, &encode_string/1]
def dumpers(type_a, type_b), do: super(type_a, type_b)

defp additional_loaders(:binary, type), do: [&decode_binary/1, type]
defp additional_loaders(:string, type), do: [&decode_binary/1, type]
defp additional_loaders(_, type), do: [type]

defp encode_binary(bin), do: {:ok, encode_typed(:binary, bin)}
defp encode_string(bin), do: {:ok, encode_typed(:string, bin)}
defp encode_typed(type, val), do: %Mariaex.TypedValue{type: type, value: val}

defp decode_binary(%{"value" => val}) when is_binary(val), do: {:ok, val}
defp decode_binary(val) when is_binary(val), do: {:ok, val}
catch
_, _ ->
defp additional_loaders(_, type), do: [type]
end

## Custom MySQL types

@doc false
Expand All @@ -119,7 +145,7 @@ defmodule Ecto.Adapters.MySQL do
def loaders(:float, type), do: [&float_decode/1, type]
def loaders(:binary_id, type), do: [Ecto.UUID, type]
def loaders({:embed, _} = type, _), do: [&json_decode/1, &Ecto.Adapters.SQL.load_embed(type, &1)]
def loaders(_, type), do: [type]
def loaders(type_a, type_b), do: additional_loaders(type_a, type_b)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

All the loaders are inlined for the reasons of efficiency. This code is called very often, even a function call is a big overhead here - we should avoid it, if we can.


defp bool_decode(<<0>>), do: {:ok, false}
defp bool_decode(<<1>>), do: {:ok, true}
Expand Down
4 changes: 4 additions & 0 deletions lib/ecto/adapters/mysql/connection.ex
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,10 @@ if Code.ensure_loaded?(Mariaex) do
defp expr(true, _sources, _query), do: "TRUE"
defp expr(false, _sources, _query), do: "FALSE"

defp expr(%{__struct__: Mariaex.TypedValue, value: bin}, sources, query) when is_binary(bin) do
expr(bin, sources, query)
end

defp expr(literal, _sources, _query) when is_binary(literal) do
[?', escape_string(literal), ?']
end
Expand Down