Describe the bugAsh.CustomExpression with a passed function raises compile time error
== Compilation error in file lib/expressions/levenshtein_distance.ex ==
** (RuntimeError) The only kind of anonymous functions allowed in expressions are in the format `&Module.function/arity`.
Got: &__MODULE__.levenshtein/2
(ash 3.4.39) lib/ash/expr/expr.ex:763: Ash.Expr.do_expr/2
(elixir 1.17.2) lib/enum.ex:1703: Enum."-map/2-lists^map/1-1-"/2
(ash 3.4.39) lib/ash/expr/expr.ex:793: Ash.Expr.do_expr/2
(ash 3.4.39) expanding macro: Ash.Expr.expr/1
lib/expressions/levenshtein_distance.ex:21: Domain.Expressions.LevenshteinDistance.expression/2
To Reproduce
implement lib/expressions/levenshtein_distance.ex described in the docs for Ash.CustomExpression
defmodule Domain.Expressions.LevenshteinDistance do
use Ash.CustomExpression,
name: :levenshtein,
arguments: [
[:string, :string]
]
def expression(AshPostgres.DataLayer, [left, right]) do
{:ok, expr(fragment("levenshtein(?, ?)", left, right))}
end
# It is good practice to always define an expression for `Ash.DataLayer.Simple`,
# as that is what Ash will use to run your custom expression in Elixir.
# This allows us to completely avoid communicating with the database in some cases.
def expression(data_layer, [left, right])
when data_layer in [
Ash.DataLayer.Ets,
Ash.DataLayer.Simple
] do
{:ok, expr(fragment(&__MODULE__.levenshtein/2, left, right))}
end
# always define this fallback clause as well
def expression(_data_layer, _args), do: :unknown
@doc "Computes the levenshtein distance of two strings"
def levenshtein(left, right) do
# ......
end
end
=>
== Compilation error in file lib/expressions/levenshtein_distance.ex ==
** (RuntimeError) The only kind of anonymous functions allowed in expressions are in the format `&Module.function/arity`.
Got: &__MODULE__.levenshtein/2
(ash 3.4.39) lib/ash/expr/expr.ex:763: Ash.Expr.do_expr/2
(elixir 1.17.2) lib/enum.ex:1703: Enum."-map/2-lists^map/1-1-"/2
(ash 3.4.39) lib/ash/expr/expr.ex:793: Ash.Expr.do_expr/2
(ash 3.4.39) expanding macro: Ash.Expr.expr/1
lib/expressions/levenshtein_distance.ex:21: Domain.Expressions.LevenshteinDistance.expression/2
Bonus round; use the absolute module name instead of __MODULE__
def expression(data_layer, [left, right])
when data_layer in [
Ash.DataLayer.Ets,
Ash.DataLayer.Simple
] do
{:ok, expr(fragment(&Domain.Expressions.LevenshteinDistance.levenshtein/2, left, right))}
end
=>
== Compilation error in file lib/expressions/levenshtein_distance.ex ==
** (RuntimeError) The only kind of anonymous functions allowed in expressions are in the format `&Module.function/arity`.
**Expected behavior**
The custom expression should compile and the expression should be usable in a resource.
**Runtime**
- Elixir version
1.17.2
- Erlang version
Erlang/OTP 27 [erts-15.0.1]
- OS
Ubuntu 22.04.5 LTS
- Ash version
3.4.39
- any related extension versions
ash_postgres: 2.4.12
Describe the bug
Ash.CustomExpression
with a passed function raises compile time errorTo Reproduce
implement
lib/expressions/levenshtein_distance.ex
described in the docs forAsh.CustomExpression
=>
Add to
config/config.exs
Bonus round; use the absolute module name instead of
__MODULE__
=>
Got: &Domain.Expressions.LevenshteinDistance.levenshtein/2