Re: BUG #16968: Planner does not recognize optimization

Поиск
Список
Период
Сортировка
От Eugen Konkov
Тема Re: BUG #16968: Planner does not recognize optimization
Дата
Msg-id 1035195294.20210515173416@yandex.ru
обсуждение исходный текст
Ответ на Re: BUG #16968: Planner does not recognize optimization  (David Rowley <dgrowleyml@gmail.com>)
Ответы Re: BUG #16968: Planner does not recognize optimization  (David Rowley <dgrowleyml@gmail.com>)
Re: BUG #16968: Planner does not recognize optimization  (David Rowley <dgrowleyml@gmail.com>)
Список pgsql-bugs
Hello David,

I found a case when `not assigning a ressortgroupref to the whole-row var` cause
wrong window function calculations.

I  use  same  query.  The  difference  come  when I wrap my query into
function. (see full queries in attachment)

1.
SELECT *
FROM agreement_totals( tstzrange( '2020-07-01', '2020-08-01' ) )
WHERE agreement_id = 161::int  AND  (o).period_id = 10::int

2.
SELECT *
  sum( .... ) over wagreement
FROM ....
WHERE agreement_id = 161::int  AND  (o).period_id = 10::int
WINDOW wagreement AS ( PARTITION BY agreement_id )

For  first  query  window function calculates SUM over all agreements,
then some are filtered out by (o).period_id condition.

But for second query agreements with "wrong" (o).period_id are filtered out,
then SUM is calculated.

I suppose here is problem with `not assigning a ressortgroupref to the whole-row var`
which cause different calculation when I try to filter: (o).period_id

I will also attach plans for both queries.


Friday, May 14, 2021, 2:52:33 AM, you wrote:

> On Fri, 14 May 2021 at 02:38, Eugen Konkov <kes-kes@yandex.ru> wrote:
>> Now I create minimal reproducible test case.
>> https://dbfiddle.uk/?rdbms=postgres_13&fiddle=761a00fb599789d3db31b120851d6341

>> Optimization is not applyed when I filter/partition by column using composite type name.

> You probably already know this part, but let me explain it just in
> case it's not clear.

> The pushdown of the qual from the top-level query into the subquery,
> or function, in this case, is only legal when the qual references a
> column that's in the PARTITION BY clause of all window functions in
> the subquery.  The reason for this is, if we filter rows before
> calling the window function, then it could affect which rows are in
> see in the window's frame. If it did filter, that could cause
> incorrect results.  We can relax the restriction a bit if we can
> eliminate entire partitions at once. The window function results are
> independent between partitions, so we can allow qual pushdowns that
> are in all PARTITION BY clauses.

> As for the reason you're having trouble getting this to work, it's
> down to the way you're using whole-row vars in your targetlist.

> A slightly simplified case which shows this problem is:

> create table ab(a int, b int);
> explain select * from (select ab as wholerowvar,row_number() over
> (partition by a) from ab) ab where (ab.wholerowvar).a=1;

> The reason it does not work is down to how this is implemented
> internally.   The details are, transformGroupClause() not assigning a
> ressortgroupref to the whole-row var.  It's unable to because there is
> no way to track which actual column within the whole row var is in the
> partition by clause.  When it comes to the code that tries to push the
> qual down into the subquery, check_output_expressions() checks if the
> column in the subquery is ok to accept push downs or not. One of the
> checks is to see if the query has windowing functions and to ensure
> that the column is in all the PARTITION BY clauses of each windowing
> function.  That check is done by checking if a ressortgroupref is
> assigned and matches a tleSortGroupRef in the PARTITION BY clause.  In
> this case, it does not match.  We didn't assign any ressortgroupref to
> the whole-row var.

> Unfortunately, whole-row vars are a bit to 2nd class citizen when it
> comes to the query planner. Also, it would be quite a bit of effort to
> make the planner push down the qual in this case. We'd need some sort
> of ability to assign ressortgroupref to a particular column within a
> whole-row var and we'd need to adjust the code to check for that when
> doing subquery pushdowns to allow it to mention which columns within
> whole-row vars can legally accept pushdowns.  I imagine that's
> unlikely to be fixed any time soon.  Whole-row vars just don't seem to
> be used commonly enough to warrant going to the effort of making this
> stuff work.

> To work around this, you should include a reference to the actual
> column in the targetlist of the subquery, or your function, in this
> case, and ensure you use that same column in the PARTITION BY clause.
> You'll then need to write that column in your condition that you need
> pushed into the subquery. I'm sorry if that messes up your design.
> However, I imagine this is not the only optimisation that you'll miss
> out on by doing things the way you are.

> David



-- 
Best regards,
Eugen Konkov
Вложения

В списке pgsql-bugs по дате отправления:

Предыдущее
От: varun kamal
Дата:
Сообщение: Re: BUG #17007: server process (PID XXXX) was terminated by signal 11: Segmentation fault
Следующее
От: David Rowley
Дата:
Сообщение: Re: BUG #16968: Planner does not recognize optimization