Re: WIP Patch: Precalculate stable functions, infrastructure v1

From: Andres Freund <andres(at)anarazel(dot)de>
To: Marina Polyakova <m(dot)polyakova(at)postgrespro(dot)ru>
Cc: Aleksander Alekseev <a(dot)alekseev(at)postgrespro(dot)ru>, Alexander Korotkov <a(dot)korotkov(at)postgrespro(dot)ru>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Subject: Re: WIP Patch: Precalculate stable functions, infrastructure v1
Date: 2017-05-18 16:38:13
Message-ID: 20170518163812.eidcarwwgahx436k@alap3.anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

On 2017-05-18 19:00:09 +0300, Marina Polyakova wrote:
> > Here's v2 of the patches. Changes from v1:
>
> And here there's v3 of planning and execution: common executor steps for all
> types of cached expression.

I've not followed this thread, but just scanned this quickly because it
affects execExpr* stuff.

> + case T_CachedExpr:
> + {
> + int adjust_jump;
> +
> + /*
> + * Allocate and fill scratch memory used by all steps of
> + * CachedExpr evaluation.
> + */
> + scratch.d.cachedexpr.isExecuted = (bool *) palloc(sizeof(bool));
> + scratch.d.cachedexpr.resnull = (bool *) palloc(sizeof(bool));
> + scratch.d.cachedexpr.resvalue = (Datum *) palloc(sizeof(Datum));
> +
> + *scratch.d.cachedexpr.isExecuted = false;
> + *scratch.d.cachedexpr.resnull = false;
> + *scratch.d.cachedexpr.resvalue = (Datum) 0;

Looks like having something like struct CachedExprState would be better,
than these separate allocations? That also allows to aleviate some size
concerns when adding new fields (see below)

> @@ -279,6 +279,7 @@ ExecInterpExpr(ExprState *state, ExprContext *econtext, bool *isnull)
> TupleTableSlot *innerslot;
> TupleTableSlot *outerslot;
> TupleTableSlot *scanslot;
> + MemoryContext oldContext; /* for EEOP_CACHEDEXPR_* */

I'd rather not have this on function scope - a) the stack pressure in
ExecInterpExpr is quite noticeable in profiles already b) this is going
to trigger warnings because of unused vars, because the compiler doesn't
understand that EEOP_CACHEDEXPR_IF_CACHED always follows
EEOP_CACHEDEXPR_SUBEXPR_END.

How about instead storing oldcontext in the expression itself?

I'm also not sure how acceptable it is to just assume it's ok to leave
stuff in per_query_memory, in some cases that could prove to be
problematic.

> + case T_CachedExpr:
> + {
> + CachedExpr *cachedexpr = (CachedExpr *) node;
> + Node *new_subexpr = eval_const_expressions_mutator(
> + get_subexpr(cachedexpr), context);
> + CachedExpr *new_cachedexpr;
> +
> + /*
> + * If unsafe transformations are used cached expression should
> + * be always simplified.
> + */
> + if (context->estimate)
> + Assert(IsA(new_subexpr, Const));
> +
> + if (IsA(new_subexpr, Const))
> + {
> + /* successfully simplified it */
> + return new_subexpr;
> + }
> + else
> + {
> + /*
> + * The expression cannot be simplified any further, so build
> + * and return a replacement CachedExpr node using the
> + * possibly-simplified arguments of subexpression.
> + */

Is this actually a meaningful path? Shouldn't always have done const
evaluation before adding CachedExpr's?

Greetings,

Andres Freund

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2017-05-18 16:47:17 Re: Cached plans and statement generalization
Previous Message Tom Lane 2017-05-18 16:13:36 Re: [COMMITTERS] pgsql: Preventive maintenance in advance of pgindent run.