Re: [HACKERS] WIP Patch: Precalculate stable functions,infrastructure v1 - Mailing list pgsql-hackers

From Andres Freund
Subject Re: [HACKERS] WIP Patch: Precalculate stable functions,infrastructure v1
Date
Msg-id 20170518163812.eidcarwwgahx436k@alap3.anarazel.de
Whole thread Raw
In response to Re: [HACKERS] WIP Patch: Precalculate stable functions,infrastructure v1  (Marina Polyakova <m.polyakova@postgrespro.ru>)
Responses Re: [HACKERS] WIP Patch: Precalculate stable functions,infrastructure v1  (Marina Polyakova <m.polyakova@postgrespro.ru>)
List 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



pgsql-hackers by date:

Previous
From: Tom Lane
Date:
Subject: Re: [HACKERS] [COMMITTERS] pgsql: Preventive maintenance in advance of pgindent run.
Next
From: Andres Freund
Date:
Subject: Re: [HACKERS] Cached plans and statement generalization