Re: plperl and inline functions -- first draft

Tim Bunce <tim.bunce@pobox.com>

From: Tim Bunce <Tim.Bunce@pobox.com>
To: Joshua Tolley <eggyknap@gmail.com>
Cc: Alexey Klyukin <alexk@commandprompt.com>, Andrew Dunstan <andrew@dunslane.net>, pgsql-hackers@postgresql.org
Date: 2009-11-20T13:50:04Z
Lists: pgsql-hackers
On Thu, Nov 19, 2009 at 05:04:22PM -0700, Joshua Tolley wrote:
>      The body of the function is ordinary Perl code. In fact, the PL/Perl
> !    glue code wraps it inside a Perl subroutine. Anonymous code blocks cannot
> !    return a value; PL/Perl functions created with CREATE FUNCTION must always
> !    return a scalar value. You can return more complex structures (arrays,
> !    records, and sets) by returning a reference, as discussed below.  Never
> !    return a list.
>     </para>

The "must always" and "Never return a list" seem needlessly strong, not
very helpful, and slightly misleading. The key point is that the call is
made in a scalar context. The implications of that follow naturally.

I'd suggest:

    ...; PL/Perl functions created with CREATE FUNCTION are called in a
    scalar context, so can't return a list.  You can return more complex
    structures (arrays, records, and sets) by returning a reference, as
    discussed below.

That only mentions "functions created with CREATE FUNCTION" though.
Perhaps it needs to be generalized to cover DO as well.

> + Datum
> + plperl_inline_handler(PG_FUNCTION_ARGS)
> + {

> + 	desc.proname = "Do Inline Block";

> + 	PG_TRY();
> + 	{
> + 
> + 		desc.reference = plperl_create_sub("DO Inline Block",
> + 									   codeblock->source_text,
> + 									   desc.lanpltrusted);
> + 
> + 		(void) plperl_call_perl_func(&desc, &fake_fcinfo);
> + 	}
> + 	PG_CATCH();
> + 	{
> + 		error_context_stack = pl_error_context.previous;
> + 		current_call_data = save_call_data;
> + 		restore_context(oldcontext);
> + 		PG_RE_THROW();
> + 	}
> + 	PG_END_TRY();
> + 
> + 	if (SPI_finish() != SPI_OK_FINISH)
> + 		elog(ERROR, "SPI_finish() failed");
> + 
> + 	error_context_stack = pl_error_context.previous;
> + 	current_call_data = save_call_data;
> + 	restore_context(oldcontext);
> + 
> + 	PG_RETURN_VOID();

When does the reference held by desc.reference get freed?
At the moment it looks like this would leak memory for each DO.

> + static void
> + plperl_inline_callback(void *arg)
> + {
> + 	errcontext("PL/Perl anonymous code block");
> + }

I'd like to see more consistent terminlogy:

          desc.proname = "Do Inline Block";
       plperl_create_sub("DO Inline Block",
 errcontext("PL/Perl anonymous code block");

Tim.