Skip to content

Commit 526020e

Browse files
committed
improvement: better type handling using new type inference
1 parent 846a8fc commit 526020e

6 files changed

+53
-24
lines changed

.credo.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@
123123
{Credo.Check.Refactor.MatchInCondition, []},
124124
{Credo.Check.Refactor.NegatedConditionsInUnless, []},
125125
{Credo.Check.Refactor.NegatedConditionsWithElse, []},
126-
{Credo.Check.Refactor.Nesting, [max_nesting: 5]},
126+
{Credo.Check.Refactor.Nesting, [max_nesting: 7]},
127127
{Credo.Check.Refactor.UnlessWithElse, []},
128128
{Credo.Check.Refactor.WithClauses, []},
129129

lib/sql_implementation.ex

+48-19
Original file line numberDiff line numberDiff line change
@@ -229,41 +229,69 @@ defmodule AshPostgres.SqlImplementation do
229229
true ->
230230
[:any]
231231
end
232-
|> Enum.concat(Map.keys(Ash.Query.Operator.operator_overloads(name) || %{}))
233-
|> Enum.map(fn types ->
232+
|> then(fn types ->
233+
Enum.concat(Map.keys(Ash.Query.Operator.operator_overloads(name) || %{}), types)
234+
end)
235+
|> Enum.flat_map(fn types ->
234236
case types do
235237
:same ->
236238
types =
237239
for _ <- values do
238240
:same
239241
end
240242

241-
closest_fitting_type(types, values)
243+
[closest_fitting_type(types, values)]
242244

243245
:any ->
244-
for _ <- values do
245-
:any
246-
end
246+
[]
247247

248248
types ->
249-
closest_fitting_type(types, values)
249+
[types]
250250
end
251251
end)
252+
# this doesn't seem right to me
252253
|> Enum.filter(fn types ->
253254
Enum.all?(types, &(vagueness(&1) == 0))
254255
end)
255256
|> case do
256-
[type] ->
257-
if type == :any || type == {:in, :any} do
258-
nil
259-
else
260-
type
261-
end
262-
263-
# There are things we could likely do here
264-
# We only say "we know what types these are" when we explicitly know
265-
_ ->
266-
Enum.map(values, fn _ -> nil end)
257+
[types] ->
258+
types
259+
260+
types ->
261+
Enum.find_value(types, Enum.map(values, fn _ -> nil end), fn types ->
262+
if length(types) == length(values) do
263+
types
264+
|> Enum.zip(values)
265+
|> Enum.reduce_while([], fn {type, value}, vals ->
266+
type = Ash.Type.get_type(type)
267+
# this means its a known type
268+
if Ash.Type.ash_type?(type) do
269+
{type, constraints} =
270+
case type do
271+
{type, constraints} -> {type, constraints}
272+
type -> {type, []}
273+
end
274+
275+
case value do
276+
%Ash.Query.Function.Type{arguments: [_, ^type | _]} ->
277+
{:cont, vals ++ [:any]}
278+
279+
%Ash.Query.Ref{attribute: %{type: ^type}} ->
280+
{:cont, vals ++ [:any]}
281+
282+
_ ->
283+
if Ash.Type.matches_type?(type, value, constraints) do
284+
{:cont, vals ++ [parameterized_type(type, constraints)]}
285+
else
286+
{:halt, nil}
287+
end
288+
end
289+
else
290+
{:halt, nil}
291+
end
292+
end)
293+
end
294+
end)
267295
end
268296
end
269297

@@ -370,7 +398,8 @@ defmodule AshPostgres.SqlImplementation do
370398
end
371399
end
372400

373-
defp fill_in_known_type({type, value}), do: {array_to_in(type), value}
401+
defp fill_in_known_type({type, value}),
402+
do: {array_to_in(type), value}
374403

375404
defp array_to_in({:array, v}), do: {:in, array_to_in(v)}
376405

mix.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ defmodule AshPostgres.MixProject do
162162
# Run "mix help deps" to learn about dependencies.
163163
defp deps do
164164
[
165-
{:ash, ash_version("~> 3.0 and >= 3.0.13")},
165+
{:ash, ash_version("~> 3.0 and >= 3.0.15")},
166166
{:ash_sql, ash_sql_version("~> 0.2 and >= 0.2.6")},
167167
{:ecto_sql, "~> 3.9"},
168168
{:ecto, "~> 3.9"},

mix.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
%{
2-
"ash": {:hex, :ash, "3.0.13", "9111fa58362f82fd6687635c12ea96ce1958d24772e3c773fbc8b0893a7e7d47", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b5c1a9c428eac939a313bfea5e4509e8ac39beaa4707bd0deb5f7f310b1022c3"},
2+
"ash": {:hex, :ash, "3.0.15", "1cea8ca799dc8281d09e316a189fddfb27a2a29a0b0e5af369aa83d6f731ca75", [:mix], [{:comparable, "~> 1.0", [hex: :comparable, repo: "hexpm", optional: false]}, {:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:ets, "~> 0.8", [hex: :ets, repo: "hexpm", optional: false]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: false]}, {:picosat_elixir, "~> 0.2", [hex: :picosat_elixir, repo: "hexpm", optional: true]}, {:plug, ">= 0.0.0", [hex: :plug, repo: "hexpm", optional: true]}, {:reactor, ">= 0.8.1 and < 1.0.0-0", [hex: :reactor, repo: "hexpm", optional: false]}, {:simple_sat, ">= 0.1.1 and < 1.0.0-0", [hex: :simple_sat, repo: "hexpm", optional: true]}, {:spark, ">= 2.1.18 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, "~> 0.2", [hex: :splode, repo: "hexpm", optional: false]}, {:stream_data, "~> 1.0", [hex: :stream_data, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.1", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "97abfed57f2bf29c3889c51f0dfa23b382a1361a9d70e7d82d7e59a2be6bdc73"},
33
"ash_sql": {:hex, :ash_sql, "0.2.5", "8b50c3178776263b912e1b60e161e2bcf08a907a38abf703edf8a8a0a51b3fe2", [:mix], [{:ash, "~> 3.0", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "0d5d8606738a17c4e8c0be4244623df721abee5072cee69d31c2711c36d0548f"},
44
"benchee": {:hex, :benchee, "1.3.1", "c786e6a76321121a44229dde3988fc772bca73ea75170a73fd5f4ddf1af95ccf", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.0", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "76224c58ea1d0391c8309a8ecbfe27d71062878f59bd41a390266bf4ac1cc56d"},
55
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},

test/load_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
defmodule AshPostgres.Test.LoadTest do
22
use AshPostgres.RepoCase, async: false
3-
alias AshPostgres.Test.{Author, Comment, Post, Record, TempEntity, User, StatefulPostFollower}
3+
alias AshPostgres.Test.{Author, Comment, Post, Record, StatefulPostFollower, TempEntity, User}
44

55
require Ash.Query
66

test/migration_generator_test.exs

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ defmodule AshPostgres.MigrationGeneratorTest do
164164

165165
# the migration creates unique_indexes using the `source` on the attributes of the identity on the resource
166166
assert file_contents =~
167-
~S{create unique_index(:posts, ["t_w_s", "title"], name: "posts_thing_with_source_index")}
167+
~S{create unique_index(:posts, ["title", "t_w_s"], name: "posts_thing_with_source_index")}
168168
end
169169
end
170170

0 commit comments

Comments
 (0)