Re: Residual cleanups for tied objects in PL/Perl

From: Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: andrew(at)dunslane(dot)net, pgsql-hackers(at)lists(dot)postgresql(dot)org
Subject: Re: Residual cleanups for tied objects in PL/Perl
Date: 2026-08-16 21:40:28
Message-ID: CAB8bMisdLJVgRt5nvUfU=ivCG6V778x225m93fwKXcq2zFvA-w@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

пн, 17 авг. 2026 г. в 01:26, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>:

> But to my previous point, where
> else would we need to call it, if we're going to try to support
> such cases? Also, what exactly are the preconditions for that
> function?

If we want a tied hash or array to convert like an ordinary one, GETMAGIC
is still needed before SvOK() / SvROK() in plperl_sv_to_datum() and
jsonb_plperl's SV_to_JsonbValue(). plperl_build_tuple_result() still
uses HeVAL() and will crash on a tied hash the same way hstore_plperl
did. That loop also calls hek2cstr(), which uses FREETMPS, so
hek2cstr() has to run before hv_iterval().

The trigger path does not return a hash. After "MODIFY",
plperl_modify_tuple() walks $_TD->{new} with HeVAL(). PL/Perl already
filled that hash from the tuple, so it is not tied. A crash would
need the trigger to tie that hash itself, for example

tie %{$_TD->{new}}, 'SomeTie';
$_TD->{new}{v} = 'from_tie';
return 'MODIFY';

Looking at the perl header files here, it looks like
> sv being nonnull is required and sufficient ... but your patch
> is inconsistent about checking that.
>
> Yes. Non-NULL is required and sufficient.

The extra NULL checks on the hstore side are not needed after
hv_iterval(). I left the old HeVAL() guards in because the point was
to show that FETCH results are available, and why a NULL check on
HeVAL() always yields SQL NULL. The if (svp) in the SETOF loop is
only because av_fetch() returns NULL for a missing element.

> That seems odd, given that we use Tie::Hash and Tie::StdHash in
> src/pl/plperl/plc_trusted.pl

Trusted plperl replaces require with pp_require_safe, which only
succeeds if the module is already in %INC. Otherwise it dies with
"Unable to load Tie/Array.pm into plperl". tie itself is allowed.
plperlu can load the modules as usual.

Proof:
```
\set ON_ERROR_STOP off

CREATE EXTENSION IF NOT EXISTS plperl;
CREATE EXTENSION IF NOT EXISTS plperlu;

\echo === 1) plperl: use Tie::Array ===
CREATE OR REPLACE FUNCTION try_use_tie_array() RETURNS text
LANGUAGE plperl AS $$
use Tie::Array;
return 'loaded';
$$;
SELECT try_use_tie_array();

\echo === 3) plperl: tie with inline class (no use) ===
CREATE OR REPLACE FUNCTION try_tie_inline() RETURNS text
LANGUAGE plperl AS $$
{
package PLPerlProofTie;
sub TIEARRAY { bless [], $_[0] }
sub STORE { $_[0][$_[1]] = $_[2] }
sub FETCH { $_[0][$_[1]] }
sub FETCHSIZE { scalar @{$_[0]} }
}
my @a;
tie @a, 'PLPerlProofTie';
$a[0] = 'ok';
return $a[0];
$$;
SELECT try_tie_inline();

\echo === 4) plperlu: use Tie::Array ===
CREATE OR REPLACE FUNCTION try_use_tie_array_u() RETURNS text
LANGUAGE plperlu AS $$
use Tie::Array;
return 'loaded';
$$;
SELECT try_use_tie_array_u();
```

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Andrey Rachitskiy 2026-08-16 22:24:09 Re: Residual cleanups for tied objects in PL/Perl
Previous Message Andrew Dunstan 2026-08-16 21:10:50 Re: Residual cleanups for tied objects in PL/Perl