Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 23610da

Browse files
committed
Fix up Perl-to-Postgres datatype conversions in pl/perl.
This patch restores the pre-9.1 behavior that pl/perl functions returning VOID ignore the result value of their last Perl statement. 9.1.0 unintentionally threw an error if the last statement returned a reference, as reported by Amit Khandekar. Also, make sure it works to return a string value for a composite type, so long as the string meets the type's input format. We already allowed the equivalent behavior for arrays, so it seems inconsistent to not allow it for composites. In addition, ensure we throw errors for attempts to return arrays or hashes when the function's declared result type is not an array or composite type, respectively. Pre-9.1 versions rather uselessly returned strings like ARRAY(0x221a9a0) or HASH(0x221aa90), while 9.1.0 threw an error for the hash case and returned a garbage value for the array case. Also, clean up assorted grotty coding in Perl array conversion, including use of a session-lifespan memory context to accumulate the array value (resulting in session-lifespan memory leak on error), failure to apply the declared typmod if any, and failure to detect some cases of non-rectangular multi-dimensional arrays. Alex Hunsaker and Tom Lane
1 parent fb4340c commit 23610da

File tree

5 files changed

+289
-130
lines changed

5 files changed

+289
-130
lines changed

src/pl/plperl/expected/plperl.out

+56-2
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ SELECT * FROM perl_row();
101101
1 | hello | world | ({{1}})
102102
(1 row)
103103

104+
-- test returning a composite literal
105+
CREATE OR REPLACE FUNCTION perl_row_lit() RETURNS testrowperl AS $$
106+
return '(1,hello,world,"({{1}})")';
107+
$$ LANGUAGE plperl;
108+
SELECT perl_row_lit();
109+
perl_row_lit
110+
---------------------------
111+
(1,hello,world,"({{1}})")
112+
(1 row)
113+
104114
CREATE OR REPLACE FUNCTION perl_set() RETURNS SETOF testrowperl AS $$
105115
return undef;
106116
$$ LANGUAGE plperl;
@@ -336,7 +346,8 @@ CREATE OR REPLACE FUNCTION foo_bad() RETURNS footype AS $$
336346
return 42;
337347
$$ LANGUAGE plperl;
338348
SELECT * FROM foo_bad();
339-
ERROR: composite-returning PL/Perl function must return reference to hash
349+
ERROR: malformed record literal: "42"
350+
DETAIL: Missing left parenthesis.
340351
CONTEXT: PL/Perl function "foo_bad"
341352
CREATE OR REPLACE FUNCTION foo_bad() RETURNS footype AS $$
342353
return [
@@ -345,7 +356,7 @@ return [
345356
];
346357
$$ LANGUAGE plperl;
347358
SELECT * FROM foo_bad();
348-
ERROR: composite-returning PL/Perl function must return reference to hash
359+
ERROR: cannot convert Perl array to non-array type footype
349360
CONTEXT: PL/Perl function "foo_bad"
350361
CREATE OR REPLACE FUNCTION foo_set_bad() RETURNS SETOF footype AS $$
351362
return 42;
@@ -639,3 +650,46 @@ CONTEXT: PL/Perl anonymous code block
639650
DO $do$ use warnings FATAL => qw(void) ; my @y; my $x = sort @y; 1; $do$ LANGUAGE plperl;
640651
ERROR: Useless use of sort in scalar context at line 1.
641652
CONTEXT: PL/Perl anonymous code block
653+
-- make sure functions marked as VOID without an explicit return work
654+
CREATE OR REPLACE FUNCTION myfuncs() RETURNS void AS $$
655+
$_SHARED{myquote} = sub {
656+
my $arg = shift;
657+
$arg =~ s/(['\\])/\\$1/g;
658+
return "'$arg'";
659+
};
660+
$$ LANGUAGE plperl;
661+
SELECT myfuncs();
662+
myfuncs
663+
---------
664+
665+
(1 row)
666+
667+
-- make sure we can't return an array as a scalar
668+
CREATE OR REPLACE FUNCTION text_arrayref() RETURNS text AS $$
669+
return ['array'];
670+
$$ LANGUAGE plperl;
671+
SELECT text_arrayref();
672+
ERROR: cannot convert Perl array to non-array type text
673+
CONTEXT: PL/Perl function "text_arrayref"
674+
--- make sure we can't return a hash as a scalar
675+
CREATE OR REPLACE FUNCTION text_hashref() RETURNS text AS $$
676+
return {'hash'=>1};
677+
$$ LANGUAGE plperl;
678+
SELECT text_hashref();
679+
ERROR: cannot convert Perl hash to non-composite type text
680+
CONTEXT: PL/Perl function "text_hashref"
681+
---- make sure we can't return a blessed object as a scalar
682+
CREATE OR REPLACE FUNCTION text_obj() RETURNS text AS $$
683+
return bless({}, 'Fake::Object');
684+
$$ LANGUAGE plperl;
685+
SELECT text_obj();
686+
ERROR: cannot convert Perl hash to non-composite type text
687+
CONTEXT: PL/Perl function "text_obj"
688+
----- make sure we can't return a scalar ref
689+
CREATE OR REPLACE FUNCTION text_scalarref() RETURNS text AS $$
690+
my $str = 'str';
691+
return \$str;
692+
$$ LANGUAGE plperl;
693+
SELECT text_scalarref();
694+
ERROR: PL/Perl function must return reference to hash or array
695+
CONTEXT: PL/Perl function "text_scalarref"

src/pl/plperl/expected/plperl_array.out

+10
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,16 @@ select plperl_arrays_inout('{{1}, {2}, {3}}');
204204
{{1},{2},{3}}
205205
(1 row)
206206

207+
-- check that we can return an array literal
208+
CREATE OR REPLACE FUNCTION plperl_arrays_inout_l(INTEGER[]) returns INTEGER[] AS $$
209+
return shift.''; # stringify it
210+
$$ LANGUAGE plperl;
211+
select plperl_arrays_inout_l('{{1}, {2}, {3}}');
212+
plperl_arrays_inout_l
213+
-----------------------
214+
{{1},{2},{3}}
215+
(1 row)
216+
207217
-- make sure setof works
208218
create or replace function perl_setof_array(integer[]) returns setof integer[] language plperl as $$
209219
my $arr = shift;

0 commit comments

Comments
 (0)