improvement: implement Comp for atoms & strings, comparing atoms as strings

This commit is contained in:
Zach Daniel 2024-08-08 11:38:16 -04:00
parent da91e2891e
commit e4dcd1c397
3 changed files with 21 additions and 1 deletions

View file

@ -10,7 +10,17 @@ Ash.Expr.expr(post.title <> " | " <> post.subtitle)
> ### Ash Expressions are SQL-ish {: .info}
>
> Ash expressions have some interesting properties in their evaluation, primarily because they are made to be portable, i.e executable in some data layer (like SQL) or executable in Elixir. In general, these expressions will behave the same way they do in Elixir. The primary difference is how `nil` values work. They behave the way that `NULL` values behave in SQL. This is primarily because this pattern is easier to replicate to various popular data layers, and is generally safer when using expressions for things like authentication. The practical implications of this are that `nil` values will "poison" many expressions, and cause them to return `nil`. For example, `x + nil` would always evaluate to `nil`. Additionally, `true and nil` will always result in `nil`, _this is also true with or and not_, i.e `true or nil` will return `nil`, and `not nil` will return `nil`.
> Ash expressions have some interesting properties in their evaluation, primarily because they are made to be
> portable, i.e executable in some data layer (like SQL) or executable in Elixir. In general, these expressions
> will behave the same way they do in Elixir. The primary difference is how `nil` values work. They behave the way
> that `NULL` values behave in SQL. This is primarily because this pattern is easier to replicate to various popular
> data layers, and is generally safer when using expressions for things like authentication. The practical
> implications of this are that `nil` values will "poison" many expressions, and cause them to return `nil`.
> For example, `x + nil` would always evaluate to `nil`. Additionally, `true and nil` will always result in
> `nil`, _this is also true with or and not_, i.e `true or nil` will return `nil`, and `not nil` will return `nil`.
>
> Additionally, atoms and strings compare as if the atom was a string. This is because most external data layers
> do not know about atoms, and so they are converted to strings before comparison.
## Operators

View file

@ -171,6 +171,10 @@ defmodule Ash.Query.Operator.Basic do
{:known, Comp.greater_or_equal?(left, right)}
end
defp do_evaluate(:==, left, right) do
{:known, Comp.equal?(left, right)}
end
defp do_evaluate(op, left, right)
when Decimal.is_decimal(left) or Decimal.is_decimal(right) do
case op do

View file

@ -106,3 +106,9 @@ defmodule Ash.Type.Atom do
def dump_to_native(_, _), do: :error
end
import Ash.Type.Comparable
defcomparable left :: BitString, right :: Atom do
Comp.compare(left, to_string(right))
end