| From: | Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com> |
|---|---|
| To: | pgsql-hackers mailing list <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> |
| Subject: | [PATCH] Catch croak during PL/Perl result conversion |
| Date: | 2026-09-16 20:54:31 |
| Message-ID: | CAB8bMit1h4PqwXsCRa4qeAzsxidgMV0wzGuL97Q78jQ=bQ6HDA@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-hackers |
Hi,
plperl_call_perl_func() invokes the user's sub with call_sv(G_EVAL).
A die inside the sub becomes ERRSV and we report it as ERROR.
After the sub returns we convert the result in C. That path can
dispatch Perl magic: SvGETMAGIC(), av_fetch(), hv_iternext(), and
transform functions such as plperl_to_hstore(). A croak from FETCH
then finds no CXt_EVAL on Perl's cx stack. die_where() treats it as
uncaught, writes the message to stderr, and my_exit_jump() does
JMPENV_JUMP(2). The backend exits with status 2. The postmaster
runs crash recovery.
A tied scalar that RETURNS text already becomes ERROR, because
return $s runs FETCH inside pp_leavesub while G_EVAL is still
active. return \(at)tied or \%tied only returns a reference. The
element FETCHes happen later, after call_sv has returned.
The hole is any Perl croak from that C conversion, not only tie.
A trigger that returns an overloaded object dies in sv2cstr().
JMPENV_PUSH around the handler is not an eval context. It would
catch JMPENV_JUMP(2) after Perl has already unwound its stacks.
The interpreter is then in exit state, so the honest mapping is
FATAL, not ERROR.
The conversion needs a live Perl eval context. Register
PostgreSQL::InServer::_eval with newXS, next to
SPI::bootstrap. After SPI_finish, plperl_func_handler and
plperl_trigger_handler call that XSUB with call_sv(G_VOID | G_EVAL).
The XSUB runs the existing conversion. Postgres errors are turned
into croak_cstr(), the same pattern as plperl_spi_exec(). After
call_sv returns we restore PG_exception_stack and
error_context_stack, because a croak from FETCH longjmps to call_sv
and skips PG_TRY inside the XSUB. Nested conversion from
return_next() is already under the user's eval, so the trampoline
just calls the C function.
A croak from FETCH is then JMPENV_JUMP(3). call_sv returns with
ERRSV set. We report ERROR. The interpreter stays usable. The
same session can run another PL/Perl function.
A regress case is included. It covers die in FETCH, a missing
FETCH method, and die in FIRSTKEY. A plperlu case covers croak
from overload stringify on a trigger return.
--
Regards,
Rachitskiy Andrey
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Catch-croak-during-PL-Perl-result-conversion.patch | text/x-patch | 20.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Dmitry Dolgov | 2026-09-16 20:56:35 | Re: Routed ON CONFLICT inserts broken by partition-local deferrable unique constraints in 19 and master |
| Previous Message | Robert Haas | 2026-09-16 20:47:31 | Re: PGQ catalog representation and pg_dump support |