Derive the database type and cast to it for a query parameter when the parameter is a custom type like a Ecto.ParameterizedType.
When a query involves a predicate where the right hand side is a custom type, the query builder knows to call the `dump/3` function of the type (in this case a parameterised type). So it knows the database type involved, but it doesn't use the database type to cast the parameter.
Example:
Repo.all(
from(o in Organization,
where: o.value > ^Money.new(:USD, 100)
)
)
% Fails because the parameter is not cast to it type:
SELECT o0."value" FROM "organizations" AS o0 WHERE (o0."value" > $1) [Money.new(:USD, "0")].
Where "value" is a `Money.Ecto.Composite.Type` type. The query builder correctly calls `dump/3` for the type. But it doesn't use the database type from `Money.Ecto.CompositeType.type/1` to cast the parameter. Therefore the error "cannot encode anonymous tuple {"USD", Decimal.new("0")}". Note the underlying database type is a composite type, which in Postgrex is represented as a tuple.
This example:
Repo.all(
from(o in Organization,
where: o.value > type(^Money.zero(:USD), o.value)
)
)
% Passes because the type is cast manually. Even though the query builder
% knows the type of the parameter.
SELECT o0."value" FROM "organizations" AS o0 WHERE (o0."value" > $1::money_with_currency) [Money.new(:USD, "0")]
works as expected, casting the parameter to the `money_with_currency` database type. But in this case, using the `type/2` macro seems unergonomic and unnecessary given that the query builder already knows the type of the parameter given that it called the `dump/3` function of the correct type.