comparing against range_lower raises on ash_postgres
- Dominant language
- Elixir
- Stars
- 2.5k
- Forks
- 422
- Avg merge
- 23h 26m
- Merged PRs (30d)
- 46
Description
### Code of Conduct
- [x] I agree to follow this project's Code of Conduct
### AI Policy
- [x] I agree to follow this project's AI Policy, or I agree that AI was not used while creating this issue.
### Versions
Elixir 1.20.2
Erlang/OTP 29 (erts-17.0.3)
ash main @ https://github.com/ash-project/ash/commit/f3a27d9f5f786db07e8a32fcff57c42b1c528b67 (unreleased; mix.exs still says 3.31.3)
### Operating system
macOS 26.5.2 (Darwin 25.5.0) aarch64
### Current Behavior
range_lower(stay) == ^datetime raises on ash_postgres, and works on Ash.DataLayer.Ets.
### Reproduction
in iex:
```elixir
Mix.install([{:ash, github: "ash-project/ash", ref: "f3a27d9f5"}])
{:ok, c} = Ash.Type.init(Ash.Type.Range, inner_type: :datetime)
ref = %Ash.Query.Ref{
attribute: %Ash.Resource.Attribute{name: :stay, type: Ash.Type.Range, constraints: c},
relationship_path: [],
resource: nil
}
Ash.Expr.determine_types(
Ash.Query.Operator.Eq,
[%Ash.Query.Function.RangeLower{arguments: [ref]}, ~U[2026-03-01 00:00:00Z]]
)
#=> {[{Ash.Type.Range, [...]}, {Ash.Type.Range, [...]}], {Ash.Type.Boolean, []}}
```
Both operands come back as `Ash.Type.Range`, including the `DateTime`.
### Expected Behavior
The other operand should be typed as the range's inner type. `type/2` around the literal is the workaround.
Contributor guide
Research direction
Start with Ash.Expr.determine_types/2 and the Ash.Query.Function.RangeLower arguments shown in the reproduction. Reproduce the result in iex, then trace how the range's inner_type is handled when comparing against the DateTime literal. Done means the literal is typed as the range's inner type and the comparison no longer raises on ash_postgres while preserving the ETS behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- elixir
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100