Joe Conway <[EMAIL PROTECTED]> writes:
> Tom Lane wrote:
>> Adding a list of callbacks to
>> ExprContext seems pretty reasonable, but you'd also need some link in
>> ReturnSetInfo to let the function find the ExprContext to register
>> itself with.  Then FreeExprContext would call the callbacks.

> I've made changes which fix this and will send them in with a revised 
> SRF patch later today. Summary of design:
> 1.) moved the execution_state struct and ExecStatus enum to executor.h
> 2.) added "void *es" member to ExprContext
> 3.) added econtext member to ReturnSetInfo
> 4.) set rsi->econtext on the way in at ExecMakeFunctionResult()
> 5.) set rsi->econtext->es on the way in at fmgr_sql()
> 6.) used econtext->es on the way out at ExecFreeExprContext() to call 
> ExecutorEnd() if needed (because postquel_execute() never got the chance).

Um.  I don't like that; it assumes not only that ExecutorEnd is the only
kind of callback needed, but also that there is at most one function
per ExprContext that needs a shutdown callback.  Neither of these
assumptions hold water IMO.

The design I had in mind was more like this: add to ExprContext a list
header field pointing to a list of structs along the lines of

        struct exprcontext_callback {
                struct exprcontext_callback *next;
                void (*function) (Datum);
                Datum arg;
        }

and then call each specified function with given argument during
FreeExprContext.  Probably ought to be careful to do that in reverse
order of registration.  We'd also need to invent a RescanExprContext
operation to call the callbacks during a Rescan.  The use of Datum
(and not, say, void *) as PG's standard callback arg type was settled on
some time ago --- originally for on_proc_exit IIRC --- and seems to have
worked well enough.

>> Hmm ... another advantage of doing this is that the function would be
>> able to find the ecxt_per_query_memory associated with the ExprContext.
>> That would be a Good Thing.

> What does this allow done that can't be done today?

It provides a place for the function to allocate stuff that needs to
live over multiple calls, ie, until it gets its shutdown callback.
Right now a function has to use TransactionCommandContext for that,
but that's really too coarse-grained.

>> We should also think about the fcache (FunctionCache) struct and whether
>> that needs to tie into this.  See the FIXME in utils/fcache.h.

> While I was at it, I added an fcache member to ExprContext, and 
> populated it in ExecMakeFunctionResult() for SRF cases. I wasn't sure 
> what else to do with it at the moment, but at least it is a step in the 
> right direction.

Well, I was debating whether that's good or not.  The existing fcache
approach is wrong (per cited FIXME); it might be better not to propagate
access of it into more places.  Unless you can see a specific reason to
allow the function to have access to the fcache struct, I think I'm
inclined not to.

What's really more relevant here is that during the hypothetical new
RescanExprContext function, we ought to go around and clear any fcaches
in the context that have setArgsValid = true, so that they will be
restarted afresh during the next scan of the plan.  (The fact that that
doesn't happen now is another shortcoming of the existing set-functions-
in-expressions code.)  So this suggests making a callback function type
specifically to do that, and registering every fcache that is executing
a set function in the callback list...

                        regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to [EMAIL PROTECTED] so that your
message can get through to the mailing list cleanly

Reply via email to