CREATE OR REPLACE FUNCTION text2jsonb (text) RETURNS jsonb LANGUAGE plperl TRANSFORM FOR TYPE jsonb AS $$ my $x = shift; my $ret = {a=>$x}; return $ret; $$; SELECT text2jsonb(NULL); SELECT text2jsonb('11'); SELECT text2jsonb(NULL);
The last SELECT produces a strange error.
ERROR: cannot transform this Perl type to jsonb
A brief research has shown that the problem is in an incomplete logic inside the transform function. The reason can be illustrated by the flollowing Perl one-liner:
perl -MDevel::Peek -e 'sub x { my $x = shift; Dump $x; warn "----\n\n"; }; x(undef); x("a"); x(undef); '
It outputs: SV = NULL(0x0) at 0x73a1b8 REFCNT = 1 FLAGS = (PADMY) ----
SV = PV(0x71da50) at 0x73a1b8 REFCNT = 1 FLAGS = (PADMY,POK,pPOK) PV = 0x7409a0 "a"\0 CUR = 1 LEN = 16 ----
SV = PV(0x71da50) at 0x73a1b8 REFCNT = 1 FLAGS = (PADMY) PV = 0x7409a0 "a"\0 CUR = 1 LEN = 16 ----
This shows that internal representation of the same undef in perl is different in first and third function calls. It is the way Perl reuses the the lexical variable, probably, for optimization reasons.
Current jsonb_plperl implementation works good for the first (most evident) case, but does not work at all for the third, which results in the abovementioned error.
The attached patch solves this issue and defines corresponding tests.