Skip to content

Commit c11024b

Browse files
committed
fix: add overrides for timestamptz types, config them on installation
fixes #651
1 parent 724ec69 commit c11024b

File tree

5 files changed

+109
-3
lines changed

5 files changed

+109
-3
lines changed

config/config.exs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ if Mix.env() == :test do
3535

3636
config :ash, :custom_expressions, [AshPostgres.Expressions.TrigramWordSimilarity]
3737

38+
config :ash, :known_types, [AshPostgres.Timestamptz, AshPostgres.TimestamptzUsec]
39+
3840
config :ash_postgres, AshPostgres.TestRepo,
3941
username: "postgres",
4042
database: "ash_postgres_test",

lib/mix/tasks/ash_postgres.install.ex

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,25 @@ if Code.ensure_loaded?(Igniter) do
326326
|> Igniter.Project.Config.configure_new("test.exs", otp_app, [repo, :pool_size], 10)
327327
end
328328
|> Igniter.Project.Config.configure_new("test.exs", :ash, [:disable_async?], true)
329+
|> configure_known_types()
330+
end
331+
332+
defp configure_known_types(igniter) do
333+
Igniter.Project.Config.configure(
334+
igniter,
335+
"config.exs",
336+
:ash,
337+
[:known_types],
338+
[AshPostgres.Timestamptz, AshPostgres.TimestamptzUsec],
339+
updater: fn zipper ->
340+
with {:ok, zipper} <-
341+
Igniter.Code.List.prepend_new_to_list(zipper, AshPostgres.Timestamptz),
342+
{:ok, zipper} <-
343+
Igniter.Code.List.prepend_new_to_list(zipper, AshPostgres.TimestamptzUsec) do
344+
{:ok, zipper}
345+
end
346+
end
347+
)
329348
end
330349

331350
defp setup_data_case(igniter) do

lib/types/timestamptz.ex

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,42 @@ defmodule AshPostgres.Timestamptz do
3939
def storage_type(_constraints) do
4040
:timestamptz
4141
end
42+
43+
@impl true
44+
def operator_overloads do
45+
other_types = [
46+
Ash.Type.UtcDatetimeUsec,
47+
Ash.Type.UtcDatetime,
48+
Ash.Type.DateTime
49+
]
50+
51+
# When THIS type is on the left, cast both to this type for consistent comparison
52+
left_overloads =
53+
for other <- other_types, into: %{} do
54+
{[__MODULE__, other], {[__MODULE__, __MODULE__], Ash.Type.Boolean}}
55+
end
56+
57+
# When THIS type is on the right, cast both to this type for consistent comparison
58+
right_overloads =
59+
for other <- other_types, into: %{} do
60+
{[other, __MODULE__], {[__MODULE__, __MODULE__], Ash.Type.Boolean}}
61+
end
62+
63+
# Same type comparison
64+
same_type_overload = %{
65+
[__MODULE__, __MODULE__] => Ash.Type.Boolean
66+
}
67+
68+
comparison_overloads =
69+
same_type_overload
70+
|> Map.merge(left_overloads)
71+
|> Map.merge(right_overloads)
72+
73+
%{
74+
:< => comparison_overloads,
75+
:<= => comparison_overloads,
76+
:> => comparison_overloads,
77+
:>= => comparison_overloads
78+
}
79+
end
4280
end

lib/types/timestamptz_usec.ex

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,51 @@ defmodule AshPostgres.TimestamptzUsec do
3333
def storage_type(_constraints) do
3434
:"timestamptz(6)"
3535
end
36+
37+
@impl true
38+
def operator_overloads do
39+
other_types = [
40+
Ash.Type.UtcDatetimeUsec,
41+
Ash.Type.UtcDatetime,
42+
Ash.Type.DateTime
43+
]
44+
45+
# When THIS type is on the left, cast both to this type for consistent comparison
46+
left_overloads =
47+
for other <- other_types, into: %{} do
48+
{[__MODULE__, other], {[__MODULE__, __MODULE__], Ash.Type.Boolean}}
49+
end
50+
51+
# When THIS type is on the right, cast both to this type for consistent comparison
52+
right_overloads =
53+
for other <- other_types, into: %{} do
54+
{[other, __MODULE__], {[__MODULE__, __MODULE__], Ash.Type.Boolean}}
55+
end
56+
57+
# Same type comparison
58+
same_type_overload = %{
59+
[__MODULE__, __MODULE__] => Ash.Type.Boolean
60+
}
61+
62+
# Cross-type comparisons with Timestamptz - use higher precision (this type)
63+
cross_type_overloads = %{
64+
[__MODULE__, AshPostgres.Timestamptz] =>
65+
{[__MODULE__, __MODULE__], Ash.Type.Boolean},
66+
[AshPostgres.Timestamptz, __MODULE__] =>
67+
{[__MODULE__, __MODULE__], Ash.Type.Boolean}
68+
}
69+
70+
comparison_overloads =
71+
same_type_overload
72+
|> Map.merge(left_overloads)
73+
|> Map.merge(right_overloads)
74+
|> Map.merge(cross_type_overloads)
75+
76+
%{
77+
:< => comparison_overloads,
78+
:<= => comparison_overloads,
79+
:> => comparison_overloads,
80+
:>= => comparison_overloads
81+
}
82+
end
3683
end

mix.lock

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
%{
2-
"ash": {:hex, :ash, "3.10.0", "839d696ef8a4d1f5b980a469fb19ef1383f21ddfb0e602ef91fc9811b2be529a", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, 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]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {: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.11", [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.3.14 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [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", "04b722edb6f8674fbe6ee7833e7e7ca43c404635e748bc4d17a6a1dba288dfc7"},
3-
"ash_sql": {:hex, :ash_sql, "0.3.15", "8b8daae1870ab37b4fb2f980e323194caf23cdb4218fef126c49cc11a01fa243", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, ">= 3.13.4 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "97432507b6f406eb2461e5d0fbf2e5104a8c61a2570322d11de2f124d822d8ff"},
2+
"ash": {:hex, :ash, "3.11.1", "9794620bffeb83d1803d92a64e7803f70b57372eb4addba5c12a24343cd04e1a", [:mix], [{:crux, ">= 0.1.2 and < 1.0.0-0", [hex: :crux, 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]}, {:igniter, ">= 0.6.29 and < 1.0.0-0", [hex: :igniter, repo: "hexpm", optional: true]}, {: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.11", [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.3.14 and < 3.0.0-0", [hex: :spark, repo: "hexpm", optional: false]}, {:splode, ">= 0.2.6 and < 1.0.0-0", [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", "e0074302bb88d667635fcbfdacbf8a641c53973a3902d0e744f567a49ec808fc"},
3+
"ash_sql": {:hex, :ash_sql, "0.3.16", "a4e62d2cf9b2f4a451067e5e3de28349a8d0e69cf50fc1861bad85f478ded046", [:mix], [{:ash, "~> 3.7", [hex: :ash, repo: "hexpm", optional: false]}, {:ecto, ">= 3.13.4 and < 4.0.0-0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.9", [hex: :ecto_sql, repo: "hexpm", optional: false]}], "hexpm", "f3d5a810b23e12e3e102799c68b1e934fa7f909ccaa4bd530f10c7317cfcfe56"},
44
"benchee": {:hex, :benchee, "1.5.0", "4d812c31d54b0ec0167e91278e7de3f596324a78a096fd3d0bea68bb0c513b10", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}, {:statistex, "~> 1.1", [hex: :statistex, repo: "hexpm", optional: false]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "5b075393aea81b8ae74eadd1c28b1d87e8a63696c649d8293db7c4df3eb67535"},
55
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
66
"credo": {:hex, :credo, "1.7.13", "126a0697df6b7b71cd18c81bc92335297839a806b6f62b61d417500d1070ff4e", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "47641e6d2bbff1e241e87695b29f617f1a8f912adea34296fb10ecc3d7e9e84f"},
@@ -12,7 +12,7 @@
1212
"earmark_parser": {:hex, :earmark_parser, "1.4.44", "f20830dd6b5c77afe2b063777ddbbff09f9759396500cdbe7523efd58d7a339c", [:mix], [], "hexpm", "4778ac752b4701a5599215f7030989c989ffdc4f6df457c5f36938cc2d2a2750"},
1313
"ecto": {:hex, :ecto, "3.13.5", "9d4a69700183f33bf97208294768e561f5c7f1ecf417e0fa1006e4a91713a834", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "df9efebf70cf94142739ba357499661ef5dbb559ef902b68ea1f3c1fabce36de"},
1414
"ecto_dev_logger": {:hex, :ecto_dev_logger, "0.15.0", "df5a997ffb17dca9011556857a0f5b7d8cd53ca7c452ef98828664b6e48d4400", [:mix], [{:ecto, "~> 3.7", [hex: :ecto, repo: "hexpm", optional: false]}, {:geo, "~> 3.5 or ~> 4.0", [hex: :geo, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.17", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "b2c807d7d599a4fcf288139851c09262333b193bdb41f8d65f515853d117e88a"},
15-
"ecto_sql": {:hex, :ecto_sql, "3.13.2", "a07d2461d84107b3d037097c822ffdd36ed69d1cf7c0f70e12a3d1decf04e2e1", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "539274ab0ecf1a0078a6a72ef3465629e4d6018a3028095dc90f60a19c371717"},
15+
"ecto_sql": {:hex, :ecto_sql, "3.13.3", "81f7067dd1951081888529002dbc71f54e5e891b69c60195040ea44697e1104a", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.13.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.7", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.19 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5751caea36c8f5dd0d1de6f37eceffea19d10bd53f20e5bbe31c45f2efc8944a"},
1616
"eflame": {:hex, :eflame, "1.0.1", "0664d287e39eef3c413749254b3af5f4f8b00be71c1af67d325331c4890be0fc", [:mix], [], "hexpm", "e0b08854a66f9013129de0b008488f3411ae9b69b902187837f994d7a99cf04e"},
1717
"erlex": {:hex, :erlex, "0.2.8", "cd8116f20f3c0afe376d1e8d1f0ae2452337729f68be016ea544a72f767d9c12", [:mix], [], "hexpm", "9d66ff9fedf69e49dc3fd12831e12a8a37b76f8651dd21cd45fcf5561a8a7590"},
1818
"ets": {:hex, :ets, "0.9.0", "79c6a6c205436780486f72d84230c6cba2f8a9920456750ddd1e47389107d5fd", [:mix], [], "hexpm", "2861fdfb04bcaeff370f1a5904eec864f0a56dcfebe5921ea9aadf2a481c822b"},

0 commit comments

Comments
 (0)