Re: question

From: Andres Freund <andres(at)anarazel(dot)de>
To: Andrzej Barszcz <abusinf(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: question
Date: 2019-11-06 22:51:16
Message-ID: 20191106225116.dm3xwqrjgo5joj7m@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

Please keep the discussion on the list... Also, on PG lists we try to
quote inline, and trim messages nicely.

On 2019-11-06 23:03:06 +0100, Andrzej Barszcz wrote:
> Your answer make me a bit confused. I thought that ExprState is in one to
> one relation with ExprContext.

They're definitely not 1:1. We commonly evaluate both a node's qual and
projection using the same ExprContext, but there's nodes doing more than
those. E.g. looking at part of the nestloop code:

...
static TupleTableSlot *
ExecNestLoop(PlanState *pstate)
{
...
ExprContext *econtext;
...
econtext = node->js.ps.ps_ExprContext;

...
if (ExecQual(joinqual, econtext))
{
node->nl_MatchedOuter = true;

/* In an antijoin, we never return a matched tuple */
if (node->js.jointype == JOIN_ANTI)
{
node->nl_NeedNewOuter = true;
continue; /* return to top of loop */
}

/*
* If we only need to join to the first matching inner tuple, then
* consider returning this one, but after that continue with next
* outer tuple.
*/
if (node->js.single_match)
node->nl_NeedNewOuter = true;

if (otherqual == NULL || ExecQual(otherqual, econtext))
{
/*
* qualification was satisfied so we project and return the
* slot containing the result tuple using ExecProject().
*/
ENL1_printf("qualification succeeded, projecting tuple");

return ExecProject(node->js.ps.ps_ProjInfo);
}
else
InstrCountFiltered2(node, 1);
}
else
InstrCountFiltered1(node, 1);
...

NestLoopState *
ExecInitNestLoop(NestLoop *node, EState *estate, int eflags)
{
...
ExecAssignExprContext(estate, &nlstate->js.ps);
...
ExecAssignProjectionInfo(&nlstate->js.ps, NULL);
...

void
ExecAssignProjectionInfo(PlanState *planstate,
TupleDesc inputDesc)
{
planstate->ps_ProjInfo =
ExecBuildProjectionInfo(planstate->plan->targetlist,
planstate->ps_ExprContext,
planstate->ps_ResultTupleSlot,
planstate,
inputDesc);
}

we're executing two quals (joinqual and otherqual), and the projection
using the same qual. There's cases that do more than that.

An ExprContext basically just contains the references to the external
data that may be referenced by an expression - e.g. for a join the tuple
from the outer and from the inner side of the join - and a memory
context which is used to evaluate expressions without leaking memory.
There's no restriction about the number of different ExprState's may be
executed within one such context, and other operations than just
expression evaluation may be executed using it.

> I made a patch "function calls optimization" at last. Regression test
> shows no failes.

Hard to comment on without seeing the current version of that patch. I
assume this is the one from
https://www.postgresql.org/message-id/CAOUVqAzyoEzvKbjipiS4J3JnTR8sY%2B-x%2BNPQhbq-B4Bmo1k%3DZA%40mail.gmail.com
?

Please don't start separate threads for the same topic. This now is the
third thread.

> The main difficulty was reset ExprContext in qual evaluation.

You cannot reset an expression context within qual evaluation, there
very well may be life references to that memory.

Greetings,

Andres Freund

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2019-11-06 23:01:11 Re: SKIP_LOCKED test causes random buildfarm failures
Previous Message Thomas Munro 2019-11-06 22:13:32 Re: TAP tests aren't using the magic words for Windows file access