Lambda expressions (was Re: BUG #15471) - Mailing list pgsql-hackers

From Tom Lane
Subject Lambda expressions (was Re: BUG #15471)
Date
Msg-id 10355.1540926295@sss.pgh.pa.us
Whole thread Raw
Responses Re: Lambda expressions (was Re: BUG #15471)  (Andres Freund <andres@anarazel.de>)
List pgsql-hackers
[ splitting this off to a new thread ]

Andres Freund <andres@anarazel.de> writes:
> On 2018-10-30 09:30:54 -0400, Tom Lane wrote:
>> This is all some more fuel for the idea that we need a less messy
>> substitute for CaseTestExpr.  As it happens, I was just fooling with
>> that yesterday, and hope to have something to post soon.  But it'll
>> be too invasive to back-patch.  I'll try to fix this particular
>> problem more locally.

> Yea, I agree we need something better there.  I happened to also play
> around with that (more from the angle that we'd want similar
> infrastructure for the SQL function inlining case we talked about) on
> the long flights back from .eu yesterday, but didn't get that far.

Yeah, that conversation was what spurred me to do something.  The patch
as I have it right now only fixes (most of) the inlining-failure cases.
I've been thinking about how to reuse the mechanism to get rid of
CaseTestExpr, but am running into some issues.

The core idea that I'm working on is to invent a new node type
LambdaExpr that evaluates an expression and substitutes it as a
Param into another expression, notationally sort of like

    LET($n := expression1 IN ... result expression using $n ...)

and then the different values can be distinguished by having
different Param numbers.  These Params have a different ParamKind
from PARAM_EXTERNAL or PARAM_EXEC, because there's too many
assumptions about the behavior of those ParamKinds, but otherwise
they're not that much different.

The stumbling block that I'm seeing in terms of making parser output
use this is that if, say, each CaseExpr has a distinct Param number
for what had been its CaseTestExpr, then textually and logically
equivalent CASE constructs might not compare equal() because of
different Param numbers.  And that's really bad news for a bunch
of reasons, see e.g. recent bugs with DDL on partition tables.
But we can't have equal() ignore the Param numbers without
re-introducing all the same issues we have with CaseTestExpr.

So what I'm thinking about at the moment is to keep using CaseTestExpr
in parser output trees, but have the planner replace them with
(uniquely numbered) Params during eval_const_expressions.  As long
as we integrate that correctly with function inlining, it should be
safe and ensure that CASEs coming in from functions can't be confused
with ones present in the original query (because we'd renumber anything
in the inlined tree to be distinct from what we had already).  But that
seems a bit ugly, and it might interfere with late-stage optimizations.

Have you got a better idea?

            regards, tom lane


pgsql-hackers by date:

Previous
From: David Steele
Date:
Subject: Re: More issues with pg_verify_checksums and checksum verification inbase backups
Next
From: Andres Freund
Date:
Subject: Re: Lambda expressions (was Re: BUG #15471)