ash icon indicating copy to clipboard operation
ash copied to clipboard

Incompatible type coercion/casting in main-branch, breaking ash_money

Open Torkan opened this issue 1 year ago • 2 comments

Describe the bug Type coercion/casting number values when translating ash-expressions into sql-queries doesn't always cast to decimal anymore, resulting in breakage with for example the ash_money-extension.

To Reproduce Example expression:

expr(visiting_service.base_hourly_rate_billing *
                  (duration / 60 *
                     if(type == :daily_interval, do: 364 / daily_interval / 12, else: 1))
              )

In ash 3.4.39, this generates the following SQL:

SELECT v0."id", (v1."base_hourly_rate_billing"::money_with_currency * (((v0."duration"::bigint::numeric)::decimal / 60::decimal) * (CASE WHEN v0."type"::varchar = 'daily_interval'::varchar THEN (364::bigint::decimal / v0."daily_interval"::bigint::decimal)::decimal / 12.0::float::decimal ELSE 1::decimal END)))::money_with_currency::money_with_currency FROM "visiting_service_subscriptions" AS v0 LEFT OUTER JOIN "public"."visiting_services" AS v1 ON v0."visiting_service_id" = v1."id" WHERE (v0."id"::uuid = 'd4e6f89f-b260-4de7-b473-af82626f5a87'::uuid)

Now, in the current main-branch, this generates the following SQL:

SELECT v0."id", (v1."base_hourly_rate_billing"::money_with_currency * (((v0."duration"::bigint::numeric)::decimal / 60::decimal) * (CASE WHEN v0."type"::varchar = 'daily_interval'::varchar THEN (364::bigint::decimal / v0."daily_interval"::bigint::decimal)::decimal / 12.0::float::decimal ELSE 1::float END)))::money_with_currency::money_with_currency FROM "visiting_service_subscriptions" AS v0 LEFT OUTER JOIN "public"."visiting_services" AS v1 ON v0."visiting_service_id" = v1."id" WHERE (v0."id"::uuid = 'd4e6f89f-b260-4de7-b473-af82626f5a87'::uuid)

This results in the following error:

* ** (Postgrex.Error) ERROR 42883 (undefined_function) operator does not exist: money_with_currency * double precision

ash_money/ex_money only defines Postgres-functions for interacting with decimal values.

The only difference in the two queries, is this section:

ELSE 1::decimal (3.4.39)
ELSE 1::float

The reason I'm not using 3.4.40 through 3.4.43 is that there were some other errors in those releases that caused other issues with ash_money, that @zachdaniel kindly has fixed in main already.

Expected behavior All number values should end up being casted to decimal, like in previous versions.

Runtime

  • 1.17.3
  • 27.1
  • MacOS
  • ash: main-branch
  • all relevant extensions are on latest versions.

Torkan avatar Nov 30 '24 10:11 Torkan

@Torkan I've made some improvements to our typing logic in main. Mind giving it a shot?

zachdaniel avatar Dec 01 '24 23:12 zachdaniel

Please also try main of ash_money with it.

zachdaniel avatar Dec 01 '24 23:12 zachdaniel