Re: Bytea PL/Perl transform

Поиск
Список
Период
Сортировка
От Pavel Stehule
Тема Re: Bytea PL/Perl transform
Дата
Msg-id CAFj8pRAWUEDXHtMj3aNKxunTEeQtweQ_wE5wad469d_B2-3TOQ@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Bytea PL/Perl transform  (Dagfinn Ilmari Mannsåker <ilmari@ilmari.org>)
Список pgsql-hackers


út 30. 1. 2024 v 17:18 odesílatel Dagfinn Ilmari Mannsåker <ilmari@ilmari.org> napsal:
Pavel Stehule <pavel.stehule@gmail.com> writes:

> út 30. 1. 2024 v 16:43 odesílatel Dagfinn Ilmari Mannsåker <
> ilmari@ilmari.org> napsal:
>
>> Pavel Stehule <pavel.stehule@gmail.com> writes:
>>
>> > I inserted perl reference support - hstore_plperl and json_plperl does
>> it.
>> >
>> > +<->/* Dereference references recursively. */
>> > +<->while (SvROK(in))
>> > +<-><-->in = SvRV(in);
>>
>> That code in hstore_plperl and json_plperl is only relevant because they
>> deal with non-scalar values (hashes for hstore, and also arrays for
>> json) which must be passed as references.  The recursive nature of the
>> dereferencing is questionable, and masked the bug fixed by commit
>> 1731e3741cbbf8e0b4481665d7d523bc55117f63.
>>
>> bytea_plperl only deals with scalars (specifically strings), so should
>> not concern itself with references.  In fact, this code breaks returning
>> objects with overloaded stringification, for example:
>>
>> CREATE FUNCTION plperlu_overload() RETURNS bytea LANGUAGE plperlu
>>   TRANSFORM FOR TYPE bytea
>>   AS $$
>>     package StringOverload { use overload '""' => sub { "stuff" }; }
>>     return bless {}, "StringOverload";
>>   $$;
>>
>> This makes the server crash with an assertion failure from Perl because
>> SvPVbyte() was passed a non-scalar value:
>>
>> postgres: ilmari regression_bytea_plperl [local] SELECT: sv.c:2865:
>> Perl_sv_2pv_flags:
>> Assertion `SvTYPE(sv) != SVt_PVAV && SvTYPE(sv) != SVt_PVHV && SvTYPE(sv)
>> != SVt_PVFM' failed.
>>
>> If I remove the dereferincing loop it succeeds:
>>
>> SELECT encode(plperlu_overload(), 'escape') AS string;
>>  string
>> --------
>>  stuff
>> (1 row)
>>
>> Attached is a v2 patch which removes the dereferencing and includes the
>> above example as a test.
>>
>
> But without dereference it returns bad value.

Where exactly does it return a bad value?  The existing tests pass, and
the one I included shows that it does the right thing in that case too.
If you pass it an unblessed reference it returns the stringified version
of that, as expected.

ugly test code

(2024-01-30 13:44:28) postgres=# CREATE or replace FUNCTION perl_inverse_bytes(bytea) RETURNS bytea
TRANSFORM FOR TYPE bytea
AS $$ my $bytes =  pack 'H*', '0123'; my $ref = \$bytes;
return $ref;
$$ LANGUAGE plperlu;
CREATE FUNCTION
(2024-01-30 13:44:33) postgres=# select perl_inverse_bytes(''), ' '::bytea;
┌──────────────────────────────────────┬───────┐
│          perl_inverse_bytes          │ bytea │
╞══════════════════════════════════════╪═══════╡
│ \x5343414c41522830783130656134333829 │ \x20  │
└──────────────────────────────────────┴───────┘
(1 row)

expected

(2024-01-30 13:46:58) postgres=# select perl_inverse_bytes(''), ' '::bytea;
┌────────────────────┬───────┐
│ perl_inverse_bytes │ bytea │
╞════════════════════╪═══════╡
│ \x0123             │ \x20  │
└────────────────────┴───────┘
(1 row)

 

CREATE FUNCTION plperl_reference() RETURNS bytea LANGUAGE plperl
 TRANSFORM FOR TYPE bytea
 AS $$ return []; $$;

SELECT encode(plperl_reference(), 'escape') string;
        string
-----------------------
 ARRAY(0x559a3109f0a8)
(1 row)

This would also crash if the dereferencing loop was left in place.

> Maybe there should be a check so references cannot be returned? Probably is
> not safe pass pointers between Perl and Postgres.

There's no reason to ban references, that would break every Perl
programmer's expectations.  And there are no pointers being passed,
SvPVbyte() returns the stringified form of whatever's passed in, which
is well-behaved for both blessed and unblessed references.

If we really want to be strict, we should at least allow references to
objects that overload stringification, as they are explicitly designed
to be well-behaved as strings.  But that would be a lot of extra code
for very little benefit over just letting Perl stringify everything.

- ilmari

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Dagfinn Ilmari Mannsåker
Дата:
Сообщение: Re: Bytea PL/Perl transform
Следующее
От: Gabriele Bartolini
Дата:
Сообщение: Re: Extend pgbench partitioning to pgbench_history