ash-project / ash_postgres

The PostgreSQL data layer for Ash Framework
https://hexdocs.pm/ash_postgres
MIT License
140 stars 73 forks source link

first aggregate on NativeDateTime fails with Postgres version parsing #380

Closed dmitriid closed 2 months ago

dmitriid commented 2 months ago

Describe the bug

Attempting to use first aggregate on a field with :date type fails with

** (EXIT from #PID<0.794.0>) shell process exited with reason: an exception was raised:
    ** (RuntimeError) Could not parse postgres version from version string: "PostgreSQL 16.3, compiled by Visual C++ build 1939, 64-bit"

You may need to define the `min_version/0` callback yourself.

Error:

%Version.InvalidVersionError{version: "16.3,.0"}

        (elixir 1.17.2) lib/version.ex:409: Version.parse!/1
        (getevents 0.1.0) lib/getevents/repo.ex:2: Getevents.Repo.lookup_version/0
        (elixir 1.17.2) lib/agent/server.ex:8: Agent.Server.init/1
        (stdlib 6.0.1) gen_server.erl:2057: :gen_server.init_it/2
        (stdlib 6.0.1) gen_server.erl:2012: :gen_server.init_it/6
        (stdlib 6.0.1) proc_lib.erl:329: :proc_lib.init_p_do_apply/3

Other aggregates work fine.

To Reproduce

An event may have multiple associated dates. So we're using :first to get the earliest date aka start date.

Note: :first fails even if it's defined without any other constraints such as sort

Getevents.Events.TempEvent (where the aggregate is) ```elixir defmodule Getevents.Events.TempEvent do use Ash.Resource, data_layer: AshPostgres.DataLayer, notifiers: [Ash.Notifier.PubSub], domain: Getevents.Events postgres do table "temp_events" repo Getevents.Repo end code_interface do define :recent end actions do defaults [:read] read :recent do # prepare build(sort: [start_date: :desc, end_date: :desc]) prepare build(load: [:start_date]) pagination do default_limit 100 max_page_size 100 required? false offset? true end end end attributes do uuid_primary_key :id attribute :name, :string do allow_nil? true constraints trim?: true, allow_empty?: false, max_length: 1000 public? true end end relationships do has_many :dates, Getevents.Events.TempDate do public? true end end aggregates do first :start_date, :dates, :start_date do sort id: :desc public? true end end end ```
Getevents.Events.TempDate (the related table) ```elixir defmodule Getevents.Events.TempDate do require Ash.Resource.Change.Builtins use Ash.Resource, data_layer: AshPostgres.DataLayer, notifiers: [Ash.Notifier.PubSub], domain: Getevents.Events postgres do table "temp_dates" repo Getevents.Repo end actions do defaults [:read] end attributes do uuid_primary_key :id attribute :start_date, :naive_datetime do allow_nil? true public? true end attribute :start_time, :string do allow_nil? true public? true constraints trim?: true, allow_empty?: false, max_length: 1000 end attribute :end_date, :naive_datetime do allow_nil? true public? true end attribute :end_time, :string do allow_nil? true public? true constraints trim?: true, allow_empty?: false, max_length: 1000 end end relationships do belongs_to :temp_event, Getevents.Events.TempEvent do allow_nil? true public? true end end end ```

Expected behavior

The aggregate should return the first matching field or a related error

Runtime

Additional context Add any other context about the problem here.

zachdaniel commented 2 months ago

In new versions of ash_postgres we actually don't attempt to infer this at all, so this issue should not be present.

dmitriid commented 2 months ago

Just to verify: Upgraded to 2.3.0, and it works 👍