Thread: '\0' characters in procedural languages.

'\0' characters in procedural languages.

From
Dawid Kuroczko
Date:
Hello, recently I've been trying to write a plperlu function like this:
CREATE FUNCTION foo RETURNS bytea AS '  use Storable qw(freeze thaw);  my @a = (1,2,3,4,5);  return freeze (\@a);
' LANGUAGE plperlu;

In other words, serialize some data (maybe some rows, would be a great
aggregate function :)) and store it in some table.

And I also wrote similar function which thaws the data from bytea argument.

PostgreSQL however seems to be doing two things:
1) when returning any data from function (including bytea return
type), it copies it up to first '\0' character.  Looking at the
plperl.c sources, solution would be changing lines like this:  result = FunctionCall3(&prodesc->result_in_func,
             PointerGetDatum(SvPV(*svp, PL_na)),                       ObjectIdGetDatum(prodesc->result_typioparam),
                  Int32GetDatum(-1));
 
into something like this:  size_t ret_length; /* size_t? */  (...)  result = FunctionCall3(&prodesc->result_in_func,
                  PointerGetDatum(SvPV(*svp, ret_length)),
ObjectIdGetDatum(prodesc->result_typioparam),                      Int32GetDatum(-1));
 

In other words, use the fact that SvPV's second argument is used to
pass string length ... but I don't know where to pass the returned
length.  I don't suppose (-1) is the right place...

2) When function receives bytea as an argument it converts it into
\NNN-escaped string.  I think it would be more natural to pass
unescaped string to a perl function.

Ah, and while we are at it -- I think it could be nice to embed
Storable module (functions freeze, nfreeze and thaw) into plperl --
ability to pass "raw serialized" perl data between functions, and
store it in tables could be quite useful.
  Regards,       Dawid


Re: '\0' characters in procedural languages.

From
Andrew Dunstan
Date:
For now, yes, plperl needs to return the text representation of bytea 
data. perhaps we can change that in a future release.

Storable in general is definitely not appropriate for plperl, as it does 
IO which is forbidden for trusted languages. I at least do not have the 
energy to go through every function in every standard perl module trying 
to decide if it is safe or not. However, in 8.0 we have provided a safe 
place for both trusted and untrusted plperl functions to stash objects - 
the %_SHARED hash. This might help with what you wanted to achieve with 
freeze/thaw.

cheers

andrew

Dawid Kuroczko wrote:

>Hello, recently I've been trying to write a plperlu function like this:
>CREATE FUNCTION foo RETURNS bytea AS '
>   use Storable qw(freeze thaw);
>   my @a = (1,2,3,4,5);
>   return freeze (\@a);
>' LANGUAGE plperlu;
>
>In other words, serialize some data (maybe some rows, would be a great
>aggregate function :)) and store it in some table.
>
>And I also wrote similar function which thaws the data from bytea argument.
>
>PostgreSQL however seems to be doing two things:
>1) when returning any data from function (including bytea return
>type), it copies it up to first '\0' character.  Looking at the
>plperl.c sources, solution would be changing lines like this:
>   result = FunctionCall3(&prodesc->result_in_func,
>                        PointerGetDatum(SvPV(*svp, PL_na)),
>                        ObjectIdGetDatum(prodesc->result_typioparam),
>                        Int32GetDatum(-1));
>into something like this:
>   size_t ret_length; /* size_t? */
>   (...)
>   result = FunctionCall3(&prodesc->result_in_func,
>                        PointerGetDatum(SvPV(*svp, ret_length)),
>                        ObjectIdGetDatum(prodesc->result_typioparam),
>                        Int32GetDatum(-1));
>
>In other words, use the fact that SvPV's second argument is used to
>pass string length ... but I don't know where to pass the returned
>length.  I don't suppose (-1) is the right place...
>
>2) When function receives bytea as an argument it converts it into
>\NNN-escaped string.  I think it would be more natural to pass
>unescaped string to a perl function.
>
>Ah, and while we are at it -- I think it could be nice to embed
>Storable module (functions freeze, nfreeze and thaw) into plperl --
>ability to pass "raw serialized" perl data between functions, and
>store it in tables could be quite useful.
>
>   Regards,
>        Dawid
>
>---------------------------(end of broadcast)---------------------------
>TIP 7: don't forget to increase your free space map settings
>
>  
>