Re: CTE inlining

From: Tomas Vondra <tomas(dot)vondra(at)2ndquadrant(dot)com>
To: Joe Conway <mail(at)joeconway(dot)com>, Andrew Dunstan <andrew(dot)dunstan(at)2ndquadrant(dot)com>, Alvaro Herrera <alvherre(at)2ndquadrant(dot)com>
Cc: "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Serge Rielau <serge(at)rielau(dot)com>, Gavin Flower <GavinFlower(at)archidevsys(dot)co(dot)nz>, Craig Ringer <craig(dot)ringer(at)2ndquadrant(dot)com>, Ilya Shkuratov <motr(dot)ilya(at)ya(dot)ru>, PostgreSQL Hackers <pgsql-hackers(at)postgresql(dot)org>, Mario Becroft <mb(at)true(dot)group>
Subject: Re: CTE inlining
Date: 2017-05-04 18:39:31
Message-ID: ffb2c8a3-7086-7f57-f9fe-19a632e4011d@2ndquadrant.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On 5/4/17 8:03 PM, Joe Conway wrote:
> On 05/04/2017 10:56 AM, Andrew Dunstan wrote:
>>
>>
>> On 05/04/2017 01:52 PM, Joe Conway wrote:
>>> On 05/04/2017 10:33 AM, Alvaro Herrera wrote:
>>>> I'm not sure what your point is. We know that for some cases the
>>>> optimization barrier semantics are useful, which is why the proposal is
>>>> to add a keyword to install one explicitely:
>>>>
>>>> with materialized r as
>>>> (
>>>> select json_populate_record(null::mytype, myjson) as x
>>>> from mytable
>>>> )
>>>> select (x).*
>>>> from r;
>>>>
>>>> this would preserve the current semantics.
>>> I haven't been able to follow this incredibly long thread, so please
>>> excuse me if way off base, but are we talking about that a CTE would be
>>> silently be rewritten as an inline expression potentially unless it is
>>> decorated with some new syntax?
>>>
>>> I would find that very disconcerting myself. For example, would this CTE
>>> potentially get rewritten with multiple evaluation as follows?
>>>
>>> DROP SEQUENCE IF EXISTS foo_seq;
>>> CREATE SEQUENCE foo_seq;
>>>
>>> WITH a(f1) AS (SELECT nextval('foo_seq'))
>>> SELECT a.f1, a.f1 FROM a;
>>> f1 | ?column?
>>> ----+----------
>>> 1 | 1
>>> (1 row)
>>>
>>> ALTER SEQUENCE foo_seq RESTART;
>>> SELECT nextval('foo_seq'), nextval('foo_seq');
>>> nextval | ?column?
>>> ---------+----------
>>> 1 | 2
>>> (1 row)
>>>
>>
>> I think that would be a change in semantics, which we should definitely
>> not be getting. Avoiding a change in semantics might be an interesting
>> exercise, but we have lots of clever coders ...
>
> Well I think my point is that I always have understood CTEs to be
> executed precisely once producing a temporary result set that is then
> referenced elsewhere. I don't think that property of CTEs should change.
> Somewhere else in the thread someone mentioned predicate push down --
> that makes sense and maybe some clever coder can come up with a patch
> that does that, but I would not be in favor of CTEs being inlined and
> therefore evaluated multiple times.
>

I agree with this, but there's a difference between "executed exactly
once" and "producing the same result as if executed exactly once".

I may be misunderstanding what other people proposed in this thread, but
I think the plan was to only inline CTEs where we know it won't change
the results, etc. So e.g. CTEs with volatile functions would not get
inlined, which includes nextval() for example.

regards

--
Tomas Vondra http://www.2ndQuadrant.com
PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Joshua D. Drake 2017-05-04 18:44:30 Potential issue with alter system
Previous Message Tom Lane 2017-05-04 18:37:46 Re: CTE inlining