I wrote: > I'm inclined to think that auto-dereference is indeed a good idea, > and am tempted to go make that change to make all this consistent. > Comments?
Here's a draft patch for that. I ended up only changing plperl_sv_to_datum. There is maybe a case for doing something similar in plperl_return_next_internal's fn_retistuple code path, so that you can return a reference-to-reference-to-hash there; but I was unable to muster much enthusiasm for touching that. regards, tom lane
diff --git a/src/pl/plperl/expected/plperl.out b/src/pl/plperl/expected/plperl.out index ebfba3e..d8a1ff5 100644 *** a/src/pl/plperl/expected/plperl.out --- b/src/pl/plperl/expected/plperl.out *************** $$ LANGUAGE plperl; *** 763,776 **** SELECT text_obj(); ERROR: cannot convert Perl hash to non-composite type text CONTEXT: PL/Perl function "text_obj" ! ----- make sure we can't return a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str; $$ LANGUAGE plperl; SELECT text_scalarref(); ! ERROR: PL/Perl function must return reference to hash or array ! CONTEXT: PL/Perl function "text_scalarref" -- check safe behavior when a function body is replaced during execution CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS $$ spi_exec_query('CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS \'return $_[0] * 3;\' LANGUAGE plperl;'); --- 763,779 ---- SELECT text_obj(); ERROR: cannot convert Perl hash to non-composite type text CONTEXT: PL/Perl function "text_obj" ! -- test looking through a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str; $$ LANGUAGE plperl; SELECT text_scalarref(); ! text_scalarref ! ---------------- ! str ! (1 row) ! -- check safe behavior when a function body is replaced during execution CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS $$ spi_exec_query('CREATE OR REPLACE FUNCTION self_modify(INTEGER) RETURNS INTEGER AS \'return $_[0] * 3;\' LANGUAGE plperl;'); diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c index 4342c02..4cfc506 100644 *** a/src/pl/plperl/plperl.c --- b/src/pl/plperl/plperl.c *************** plperl_sv_to_datum(SV *sv, Oid typid, in *** 1402,1412 **** return ret; } ! /* Reference, but not reference to hash or array ... */ ! ereport(ERROR, ! (errcode(ERRCODE_DATATYPE_MISMATCH), ! errmsg("PL/Perl function must return reference to hash or array"))); ! return (Datum) 0; /* shut up compiler */ } else { --- 1402,1414 ---- return ret; } ! /* ! * If it's a reference to something else, such as a scalar, just ! * recursively look through the reference. ! */ ! return plperl_sv_to_datum(SvRV(sv), typid, typmod, ! fcinfo, finfo, typioparam, ! isnull); } else { diff --git a/src/pl/plperl/sql/plperl.sql b/src/pl/plperl/sql/plperl.sql index c36da0f..b0d950b 100644 *** a/src/pl/plperl/sql/plperl.sql --- b/src/pl/plperl/sql/plperl.sql *************** $$ LANGUAGE plperl; *** 504,510 **** SELECT text_obj(); ! ----- make sure we can't return a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str; --- 504,510 ---- SELECT text_obj(); ! -- test looking through a scalar ref CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$ my $str = 'str'; return \$str;