Re: PostgreSQL 10 changes in exclusion constraints - did something change? CASE WHEN behavior oddity

From: Mark Dilger <hornschnorter(at)gmail(dot)com>
To: Andres Freund <andres(at)anarazel(dot)de>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Regina Obe <lr(at)pcorp(dot)us>, PostgreSQL-development <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: PostgreSQL 10 changes in exclusion constraints - did something change? CASE WHEN behavior oddity
Date: 2017-06-04 21:32:24
Message-ID: FB5BA655-95A0-4EC5-900D-2582D3E98A74@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers


> On Jun 4, 2017, at 2:19 PM, Andres Freund <andres(at)anarazel(dot)de> wrote:
>
> On 2017-06-04 14:16:14 -0700, Mark Dilger wrote:
>> Sorry, I was not clear. What I meant to get at was that if you remove from the
>> executor all support for SRFs inside case statements, you might foreclose the option
>> of extending the syntax at some later date to allow aggregates over
>> SRFs.
>
> Seems very unlikely that we'd ever want to do that. The right way to do
> this is to simply move the SRF into the from list. Having the executor
> support arbitrary sources of tuples would just complicate and slow down
> already complicated and slow code...
>
>
>> I'm
>> not saying that this works currently, but in principle if you allowed that SUM() that
>> I put up there, you'd get back exactly one row from it, same as you get from the
>> ELSE clause. That would seem to solve the problem without going so far as
>> completely disallowing the SRF altogether.
>
> But what would the benefit be?

In my example, the aggregate function is taking a column from the table as
an argument, so the output of the aggregate function needs to be computed per row,
not just once. And if the function is expensive, or has side-effects, you might
only want it to execute for those rows where the CASE statement is true, rather
than for all of them. You may get that same behavior using lateral or some such,
I'm uncertain, but in a complicated CASE statement, it be more straightforward
to write something like:

SELECT
CASE
WHEN t.x = 'foo' THEN expensive_aggfunc1(srf1(t.y,t.z))
WHEN t.x = 'bar' THEN expensive_aggfunc2(srf2(t.y,t.z))
WHEN t.x = 'baz' THEN expensive_aggfunc3(srf3(t.y,t.z))
....
WHEN t.x = 'zzz' THEN expensive_aggfuncN(srfN(t.y,t.z))
ELSE 5
END
FROM mytable t;

Than to try to write it any other way.

I'm not advocating anything here, even though it may sound that way to you.
I'm just thinking this thing through, given that you may be committing a removal
of functionality that we want back at some later time.

Out of curiosity, how would you rewrite what I have above such that the
aggregate function is not inside the case statement, and the expensive_aggfuncs
are only called for those (t.y,t.z) that are actually appropriate?

Mark Dilger

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Noah Misch 2017-06-04 22:24:30 Re: BUG #14680: startup process on standby encounter a deadlock of TwoPhaseStateLock when redo 2PC xlog
Previous Message Tom Lane 2017-06-04 21:30:29 Make ANALYZE more selective about what is a "most common value"?