Обсуждение: parse_coerce question

Поиск
Список
Период
Сортировка

parse_coerce question

От
Tom Lane
Дата:
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


Re: [HACKERS] parse_coerce question

От
Bruce Momjian
Дата:
> 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?

You are right.  The textin/out trick is an old one, and one we only did
because we _had_ to make some conversion at that point.  No problem
making it more general.


--  Bruce Momjian                        |  http://www.op.net/~candle maillist@candle.pha.pa.us            |  (610)
853-3000+  If your life is a hard drive,     |  830 Blythe Avenue +  Christ can be your backup.        |  Drexel Hill,
Pennsylvania19026
 


Re: [HACKERS] parse_coerce question

От
Thomas Lockhart
Дата:
> > 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?
> You are right.  The textin/out trick is an old one, and one we only did
> because we _had_ to make some conversion at that point.  No problem
> making it more general.

Sure, as long as we don't use textin/out to do it. It's an old trick
with more limitations than benefits. The Right Way to approach it is
to use type-specific conversion functions, so that real conversions
can take place. textin/out relies on the fact that the printed format
of a type is *precisely* the same as the format for the target type,
which is true for only a very limited number of cases.

There is already code for doing type coersion. As Tom points out, it
currently wraps a type conversion function around the constant, to be
evaluated later. It should be easy to pre-evaluate that function,
which btw should happen anyway. afaik it does, but not until after the
optimizer has had its look at the query, and by then it is too late to
select an index properly, for example.

For the index selection problem, I was thinking to move some of the
parse_coerce techniques to that part of the code, so that functions on
constants are allowed to be considered as candidate constants in a
query.

In any case, you'll need to make sure that you only promote types one
direction, so that (for example)
 select intcol from table where intcol < 33.5;

gets evaluated correctly.
                       - Thomas

-- 
Thomas Lockhart                lockhart@alumni.caltech.edu
South Pasadena, California


Re: [HACKERS] parse_coerce question

От
Tom Lane
Дата:
Thomas Lockhart <lockhart@alumni.caltech.edu> writes:
>>>> 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?
>> You are right.  The textin/out trick is an old one, and one we only did
>> because we _had_ to make some conversion at that point.  No problem
>> making it more general.

> Sure, as long as we don't use textin/out to do it. It's an old trick
> with more limitations than benefits. The Right Way to approach it is
> to use type-specific conversion functions, so that real conversions
> can take place.

Right --- the revision I committed last night looks up the
type-conversion function the same as before, but then applies it
immediately if the input is a constant.

> It should be easy to pre-evaluate that function,
> which btw should happen anyway. afaik it does, but not until after the
> optimizer has had its look at the query,

I'm not aware of any post-optimizer place where that might happen.
In any case, the optimizer would be much happier if constant-expression
reduction happened before it rather than after.

> For the index selection problem, I was thinking to move some of the
> parse_coerce techniques to that part of the code, so that functions on
> constants are allowed to be considered as candidate constants in a
> query.

I still think we want a generalized constant-expression folder, applied
after rule rewrite and before the optimizer.  This particular case was
just something I thought the parser should handle, since it was already
handling closely related cases...

> In any case, you'll need to make sure that you only promote types one
> direction, so that (for example)
>   select intcol from table where intcol < 33.5;
> gets evaluated correctly.

That is not parse_coerce()'s problem --- it just does what it's told.
        regards, tom lane


Re: [HACKERS] parse_coerce question

От
Thomas Lockhart
Дата:
> > In any case, you'll need to make sure that you only promote types one
> > direction, so that (for example)
> >   select intcol from table where intcol < 33.5;
> > gets evaluated correctly.
> That is not parse_coerce()'s problem --- it just does what it's told.

Right. I wasn't sure how you were going to implement it. If you are
doing everything the same, but just pre-evaluating the result, we
should be OK.
                      - Thomas

-- 
Thomas Lockhart                lockhart@alumni.caltech.edu
South Pasadena, California