AshGraphQL: Filtering on Calculations that use Aggregates

(ash 2.21, ash_graphql 0.28.1)

I have a Order Resource that defines the following:

  aggregates do
    sum :subtotal, :order_items, :subtotal
    sum :tax_total, :order_taxes, :percentage
    sum :total_transactions, :transactions, :amount
  end

  calculations do
    calculate :total, :decimal, expr(subtotal * tax_total)
    calculate :balance, :decimal, expr(total - total_transactions)
    calculate :is_locked, :boolean, expr(register_id != nil)
  end

When querying with GraphQL using this filter:

 orders(filter: { balance: { greaterThan: 0 } }) {
    ...OrderGQL
  }

I get the error:

[warning] 389a80eb-5eca-4aab-8d5d-d537f1c937fb: AshGraphql.Error not implemented for error:

** (Ash.Error.Unknown) Unknown Error

  • ** (Postgrex.Error) ERROR 42725 (ambiguous_function) function sum(unknown) is not unique

    query: SELECT o0.“cart_id”, o0.“id”, o0.“client_group_id”, s1.“subtotal”::decimal::decimal, s2.“tax_total”::decimal::decimal, s3.“total_transactions”::decimal::decimal, (s1.“subtotal”::decimal * s2.“tax_total”::decimal)::decimal::decimal, ((s1.“subtotal”::decimal * s2.“tax_total”::decimal)::decimal - s3.“total_transactions”::decimal)::decimal::decimal, (o0.“register_id”::uuid != $1::uuid)::boolean::boolean FROM “dreambean”.“orders” AS o0 LEFT OUTER JOIN LATERAL (SELECT so0.“order_id” AS “order_id”, sum($2)::decimal AS “subtotal” FROM “dreambean”.“order_items” AS so0 WHERE (o0.“id” = so0.“order_id”) GROUP BY so0.“order_id”) AS s1 ON TRUE LEFT OUTER JOIN LATERAL (SELECT so0.“order_id” AS “order_id”, sum(so0.“percentage”::decimal)::decimal AS “tax_total” FROM “dreambean”.“order_taxes” AS so0 WHERE (o0.“id” = so0.“order_id”) GROUP BY so0.“order_id”) AS s2 ON TRUE LEFT OUTER JOIN LATERAL (SELECT st0.“order_id” AS “order_id”, sum(st0.“amount”::decimal)::decimal AS “total_transactions” FROM “dreambean”.“transactions” AS st0 WHERE (o0.“id” = st0.“order_id”) GROUP BY st0.“order_id”) AS s3 ON TRUE WHERE (((s1.“subtotal”::decimal * s2.“tax_total”::decimal)::decimal - s3.“total_transactions”::decimal)::decimal > $3::decimal) AND (o0.“client_group_id”::uuid IN ($4::uuid))

    hint: Could not choose a best candidate function. You might need to add explicit type casts.
    at orders
    (ecto_sql 3.11.1) lib/ecto/adapters/sql.ex:1054: Ecto.Adapters.SQL.raise_sql_call_error/1
    (ecto_sql 3.11.1) lib/ecto/adapters/sql.ex:952: Ecto.Adapters.SQL.execute/6
    (ecto 3.11.2) lib/ecto/repo/queryable.ex:232: Ecto.Repo.Queryable.execute/4
    (ecto 3.11.2) lib/ecto/repo/queryable.ex:19: Ecto.Repo.Queryable.all/3
    (ash_postgres 1.5.23) lib/data_layer.ex:701: anonymous fn/3 in AshPostgres.DataLayer.run_query/2
    (ash_postgres 1.5.23) lib/data_layer.ex:700: AshPostgres.DataLayer.run_query/2
    (ash 2.21.12) lib/ash/actions/read/read.ex:1996: Ash.Actions.Read.run_query/4
    (ash 2.21.12) lib/ash/actions/read/read.ex:407: anonymous fn/5 in Ash.Actions.Read.do_read/4
    (ash 2.21.12) lib/ash/engine/engine.ex:514: anonymous fn/4 in Ash.Engine.async/2
    (elixir 1.16.1) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
    (elixir 1.16.1) lib/task/supervised.ex:36: Task.Supervised.reply/4
    (elixir 1.16.1) lib/process.ex:860: Process.info/2
    (ash 2.21.12) lib/ash/error/exception.ex:59: Ash.Error.Unknown.“exception (overridable 2)”/1
    (ash 2.21.12) lib/ash/error/error.ex:602: Ash.Error.choose_error/2
    (ash 2.21.12) lib/ash/error/error.ex:260: Ash.Error.to_error_class/2
    (ash 2.21.12) lib/ash/actions/read/read.ex:292: Ash.Actions.Read.do_run/3
    (ash 2.21.12) lib/ash/actions/read/read.ex:50: anonymous fn/3 in Ash.Actions.Read.run/3
    (ash 2.21.12) lib/ash/actions/read/read.ex:49: Ash.Actions.Read.run/3
    (ash 2.21.12) lib/ash/actions/read/relationships.ex:467: anonymous fn/3 in Ash.Actions.Read.Relationships.do_fetch_related_records/3
    (ash 2.21.12) lib/ash/engine/engine.ex:514: anonymous fn/4 in Ash.Engine.async/2
    (elixir 1.16.1) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
    (elixir 1.16.1) lib/task/supervised.ex:36: Task.Supervised.reply/4

So, this is a bug I believe, can you open an issue for it on ash_postgres? In the meantime, adding explicit type casts to your calculations should probably help. calculate :foo, :decimal, expr(type(thing, :decimal))

1 Like

Did some more debugging and it’s only subTotal and total that cause an error.

I will add the type annotations and try again.

Also, total likely doesn’t work because subTotal doesn’t.

subTotal’s calculations + aggregates goes 3 resources deep Order → OrderItem → OrderItemModifier