the other half are modifying queries on an entity where I’d imagine the return type of the calculation should be known
Right, that’s what I was alluding to when I said:
there are some related cases where we probably could do better
though I was thinking more of the case of such an expression occurring in a where clause. But it’s really not as simple as you imagine, since we can have quite complex expressions involving parameters and functions and operators and allowing things like this would mean not type checking the whole expression as soon as the expression involves a parameter and a numeric operator. That’s a bit nasty. And yes, of course we could make it work in a piecemeal way for some special cases. But that’s a bad way to design languages. I much prefer bright-line rules about what is allowed and what is disallowed. Otherwise you end up with Perl. So it’s simply unclear whether this is something we should even try to fix. (I need to talk it over with Steve.)
I guess it might just have copied over the anticipated type of the operand it does know (test.intField) to the operand it does not know.
Right, that’s exactly what it does: it infers the parameter type from the other operand. This is the best it can do in general. What you’re asking the query compiler to do is an implicit numeric type promotion to a type it has no way of knowing. That’s asking for rather a lot. In general, it’s asking for the impossible. Now, one option which I’ve toyed with a bit is allowing the type of parameters to be declared explicitly, something like:
select test.intField * BigDecimal?1
select test.intField * BigDecimal:name
or:
select test.intField * (?1 as BigDecimal)
select test.intField * (:name as BigDecimal)
or whatever. This would solve the problem completely. In the meantime, I don’t think the obvious workaround is that terrible:
This is just barely more verbose than the proposed new syntax (one extra token). Implicit type promotions can always be rewritten as explicit casts, so this workaround always works. |