Skip to content

Commit 06fb610

Browse files
committed
Make plperl work with OUT parameters.
1 parent 943178f commit 06fb610

File tree

3 files changed

+90
-19
lines changed

3 files changed

+90
-19
lines changed

src/pl/plperl/plperl.c

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
* ENHANCEMENTS, OR MODIFICATIONS.
3434
*
3535
* IDENTIFICATION
36-
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.70 2005/03/29 00:17:20 tgl Exp $
36+
* $PostgreSQL: pgsql/src/pl/plperl/plperl.c,v 1.71 2005/04/01 19:34:06 tgl Exp $
3737
*
3838
**********************************************************************/
3939

@@ -409,21 +409,16 @@ plperl_trigger_build_args(FunctionCallInfo fcinfo)
409409
* NB: copy the result if needed for any great length of time
410410
*/
411411
static TupleDesc
412-
get_function_tupdesc(Oid result_type, ReturnSetInfo *rsinfo)
412+
get_function_tupdesc(FunctionCallInfo fcinfo)
413413
{
414-
if (result_type == RECORDOID)
415-
{
416-
/* We must get the information from call context */
417-
if (!rsinfo || !IsA(rsinfo, ReturnSetInfo) ||
418-
rsinfo->expectedDesc == NULL)
419-
ereport(ERROR,
420-
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
421-
errmsg("function returning record called in context "
422-
"that cannot accept type record")));
423-
return rsinfo->expectedDesc;
424-
}
425-
else /* ordinary composite type */
426-
return lookup_rowtype_tupdesc(result_type, -1);
414+
TupleDesc result;
415+
416+
if (get_call_result_type(fcinfo, NULL, &result) != TYPEFUNC_COMPOSITE)
417+
ereport(ERROR,
418+
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
419+
errmsg("function returning record called in context "
420+
"that cannot accept type record")));
421+
return result;
427422
}
428423

429424
/**********************************************************************
@@ -897,8 +892,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
897892

898893
/* Cache a copy of the result's tupdesc and attinmeta */
899894
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
900-
tupdesc = get_function_tupdesc(prodesc->result_oid,
901-
(ReturnSetInfo *) fcinfo->resultinfo);
895+
tupdesc = get_function_tupdesc(fcinfo);
902896
tupdesc = CreateTupleDescCopy(tupdesc);
903897
funcctx->attinmeta = TupleDescGetAttInMetadata(tupdesc);
904898
MemoryContextSwitchTo(oldcontext);
@@ -1003,8 +997,7 @@ plperl_func_handler(PG_FUNCTION_ARGS)
1003997
/*
1004998
* XXX should cache the attinmeta data instead of recomputing
1005999
*/
1006-
td = get_function_tupdesc(prodesc->result_oid,
1007-
(ReturnSetInfo *) fcinfo->resultinfo);
1000+
td = get_function_tupdesc(fcinfo);
10081001
/* td = CreateTupleDescCopy(td); */
10091002
attinmeta = TupleDescGetAttInMetadata(td);
10101003

src/pl/plperl/test/test.expected

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,61 @@ SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
222222
3 | Hello | PL/Perl
223223
(3 rows)
224224

225+
CREATE OR REPLACE FUNCTION
226+
perl_out_params(f1 out integer, f2 out text, f3 out text) AS $$
227+
return {f2 => 'hello', f1 => 1, f3 => 'world'};
228+
$$ LANGUAGE plperl;
229+
SELECT perl_out_params();
230+
perl_out_params
231+
-----------------
232+
(1,hello,world)
233+
(1 row)
234+
235+
SELECT * FROM perl_out_params();
236+
f1 | f2 | f3
237+
----+-------+-------
238+
1 | hello | world
239+
(1 row)
240+
241+
SELECT (perl_out_params()).f2;
242+
f2
243+
-------
244+
hello
245+
(1 row)
246+
247+
CREATE OR REPLACE FUNCTION
248+
perl_out_params_set(out f1 integer, out f2 text, out f3 text)
249+
RETURNS SETOF record AS $$
250+
return [
251+
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
252+
{ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
253+
{ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
254+
];
255+
$$ LANGUAGE plperl;
256+
SELECT perl_out_params_set();
257+
perl_out_params_set
258+
----------------------
259+
(1,Hello,World)
260+
(2,Hello,PostgreSQL)
261+
(3,Hello,PL/Perl)
262+
(3 rows)
263+
264+
SELECT * FROM perl_out_params_set();
265+
f1 | f2 | f3
266+
----+-------+------------
267+
1 | Hello | World
268+
2 | Hello | PostgreSQL
269+
3 | Hello | PL/Perl
270+
(3 rows)
271+
272+
SELECT (perl_out_params_set()).f3;
273+
f3
274+
------------
275+
World
276+
PostgreSQL
277+
PL/Perl
278+
(3 rows)
279+
225280
CREATE TYPE footype AS (x INTEGER, y INTEGER);
226281
CREATE OR REPLACE FUNCTION foo_good() RETURNS SETOF footype AS $$
227282
return [

src/pl/plperl/test/test_queries.sql

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,29 @@ SELECT perl_record_set();
135135
SELECT * FROM perl_record_set();
136136
SELECT * FROM perl_record_set() AS (f1 integer, f2 text, f3 text);
137137

138+
CREATE OR REPLACE FUNCTION
139+
perl_out_params(f1 out integer, f2 out text, f3 out text) AS $$
140+
return {f2 => 'hello', f1 => 1, f3 => 'world'};
141+
$$ LANGUAGE plperl;
142+
143+
SELECT perl_out_params();
144+
SELECT * FROM perl_out_params();
145+
SELECT (perl_out_params()).f2;
146+
147+
CREATE OR REPLACE FUNCTION
148+
perl_out_params_set(out f1 integer, out f2 text, out f3 text)
149+
RETURNS SETOF record AS $$
150+
return [
151+
{ f1 => 1, f2 => 'Hello', f3 => 'World' },
152+
{ f1 => 2, f2 => 'Hello', f3 => 'PostgreSQL' },
153+
{ f1 => 3, f2 => 'Hello', f3 => 'PL/Perl' }
154+
];
155+
$$ LANGUAGE plperl;
156+
157+
SELECT perl_out_params_set();
158+
SELECT * FROM perl_out_params_set();
159+
SELECT (perl_out_params_set()).f3;
160+
138161
--
139162
-- Check behavior with erroneous return values
140163
--

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy