Hi Thomas,
I have been noticing that if I write something like... WHERE float8column < 33;
the system is not very smart about it, whereas... WHERE float8column < 33.0;
works fine. The reason is that what the optimizer gets handed in the
first case is actually... WHERE float8column < float8(33);
ie, the parse tree reflects a run-time type coercion function call;
and the optimizer doesn't recognize that as a potential indexqual
restriction --- it wants "var op constant".
Of course the long-run answer for problems of this ilk is to insert a
constant-expression-folding stage, but for this particular case it seems
to me that the parser is wasting a lot of cycles by not outputting a
constant node of the right type in the first place. Especially since it
does convert constants to the desired type in other cases.
Looking into this, I find that the reason for the difference is that
parse_coerce() only performs parse-time coercion of constants if they
are of type UNKNOWNOID --- ie, the constant is of string type. And
indeed... WHERE float8column < '33';
produces a pre-coerced float8 constant! But make_const produces type
INT4OID or INT8OID for integer or float constants.
It seems to me that parse_coerce ought to do parse-time coercion if
the input tree is a constant of either UNKNOWNOID, INT4OID, or FLOAT8OID
type, and only fall back to inserting a function call if it's unable
to do the coercion. Am I missing anything?
It also looks like parser_typecast2() could be dispensed with, or more
accurately folded into parse_coerce(). Is there a reason not to?
regards, tom lane