Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit525bd16

Browse files
committed
Fix handling of polymorphic output arguments for procedures.
Most of the infrastructure for procedure arguments was alreadyokay with polymorphic output arguments, but it turns out thatCallStmtResultDesc() was a few bricks shy of a load here. It thoughtall it needed to do was call build_function_result_tupdesc_t, butthat function specifically disclaims responsibility for resolvingpolymorphic arguments. Failing to handle that doesn't seem to bea problem for CALL in plpgsql, but CALL from plain SQL would geterrors like "cannot display a value of type anyelement", or evencrash outright.In v14 and later we can simply examine the exposed types of theCallStmt.outargs nodes to get the right type OIDs. But it's a lotmore complicated to fix in v12/v13, because those versions don'thave CallStmt.outargs, nor do they do expand_function_argumentsuntil ExecuteCallStmt runs. We have to duplicatively runexpand_function_arguments, and then re-determine which elementsof the args list are output arguments.Per bug #18463 from Drew Kimball. Back-patch to all supportedversions, since it's busted in all of them.Discussion:https://postgr.es/m/18463-f8cd77e12564d8a2@postgresql.org
1 parentc871423 commit525bd16

File tree

5 files changed

+144
-0
lines changed

5 files changed

+144
-0
lines changed

‎src/backend/commands/functioncmds.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@
5656
#include"executor/functions.h"
5757
#include"funcapi.h"
5858
#include"miscadmin.h"
59+
#include"nodes/nodeFuncs.h"
5960
#include"optimizer/optimizer.h"
6061
#include"parser/analyze.h"
6162
#include"parser/parse_coerce.h"
@@ -2391,5 +2392,32 @@ CallStmtResultDesc(CallStmt *stmt)
23912392

23922393
ReleaseSysCache(tuple);
23932394

2395+
/*
2396+
* The result of build_function_result_tupdesc_t has the right column
2397+
* names, but it just has the declared output argument types, which is the
2398+
* wrong thing in polymorphic cases. Get the correct types by examining
2399+
* stmt->outargs. We intentionally keep the atttypmod as -1 and the
2400+
* attcollation as the type's default, since that's always the appropriate
2401+
* thing for function outputs; there's no point in considering any
2402+
* additional info available from outargs. Note that tupdesc is null if
2403+
* there are no outargs.
2404+
*/
2405+
if (tupdesc)
2406+
{
2407+
Assert(tupdesc->natts==list_length(stmt->outargs));
2408+
for (inti=0;i<tupdesc->natts;i++)
2409+
{
2410+
Form_pg_attributeatt=TupleDescAttr(tupdesc,i);
2411+
Node*outarg= (Node*)list_nth(stmt->outargs,i);
2412+
2413+
TupleDescInitEntry(tupdesc,
2414+
i+1,
2415+
NameStr(att->attname),
2416+
exprType(outarg),
2417+
-1,
2418+
0);
2419+
}
2420+
}
2421+
23942422
returntupdesc;
23952423
}

‎src/pl/plpgsql/src/expected/plpgsql_call.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -397,6 +397,40 @@ END
397397
$$;
398398
NOTICE: a: <NULL>, b: {30,7}
399399
NOTICE: _a: 37, _b: 30, _c: 7
400+
-- polymorphic OUT arguments
401+
CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray)
402+
LANGUAGE plpgsql
403+
AS $$
404+
BEGIN
405+
RAISE NOTICE 'a: %', a;
406+
b := a;
407+
c := array[a];
408+
END;
409+
$$;
410+
DO $$
411+
DECLARE _a int; _b int; _c int[];
412+
BEGIN
413+
_a := 10;
414+
CALL test_proc12(_a, _b, _c);
415+
RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;
416+
END
417+
$$;
418+
NOTICE: a: 10
419+
NOTICE: _a: 10, _b: 10, _c: {10}
420+
DO $$
421+
DECLARE _a int; _b int; _c text[];
422+
BEGIN
423+
_a := 10;
424+
CALL test_proc12(_a, _b, _c); -- error
425+
RAISE NOTICE '_a: %, _b: %, _c: %', _a, _b, _c;
426+
END
427+
$$;
428+
ERROR: procedure test_proc12(integer, integer, text[]) does not exist
429+
LINE 1: CALL test_proc12(_a, _b, _c)
430+
^
431+
HINT: No procedure matches the given name and argument types. You might need to add explicit type casts.
432+
QUERY: CALL test_proc12(_a, _b, _c)
433+
CONTEXT: PL/pgSQL function inline_code_block line 5 at CALL
400434
-- transition variable assignment
401435
TRUNCATE test1;
402436
CREATE FUNCTION triggerfunc1() RETURNS trigger

‎src/pl/plpgsql/src/sql/plpgsql_call.sql

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,36 @@ BEGIN
363363
END
364364
$$;
365365

366+
-- polymorphic OUT arguments
367+
368+
CREATE PROCEDURE test_proc12(a anyelement, OUT b anyelement, OUT c anyarray)
369+
LANGUAGE plpgsql
370+
AS $$
371+
BEGIN
372+
RAISE NOTICE'a: %', a;
373+
b := a;
374+
c := array[a];
375+
END;
376+
$$;
377+
378+
DO $$
379+
DECLARE _aint; _bint; _cint[];
380+
BEGIN
381+
_a :=10;
382+
CALL test_proc12(_a, _b, _c);
383+
RAISE NOTICE'_a: %, _b: %, _c: %', _a, _b, _c;
384+
END
385+
$$;
386+
387+
DO $$
388+
DECLARE _aint; _bint; _ctext[];
389+
BEGIN
390+
_a :=10;
391+
CALL test_proc12(_a, _b, _c);-- error
392+
RAISE NOTICE'_a: %, _b: %, _c: %', _a, _b, _c;
393+
END
394+
$$;
395+
366396

367397
-- transition variable assignment
368398

‎src/test/regress/expected/create_procedure.out

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,40 @@ AS $$
193193
SELECT NULL::int;
194194
$$;
195195
CALL ptest6(1, 2);
196+
CREATE PROCEDURE ptest6a(inout a anyelement, out b anyelement)
197+
LANGUAGE SQL
198+
AS $$
199+
SELECT $1, $1;
200+
$$;
201+
CALL ptest6a(1, null);
202+
a | b
203+
---+---
204+
1 | 1
205+
(1 row)
206+
207+
CALL ptest6a(1.1, null);
208+
a | b
209+
-----+-----
210+
1.1 | 1.1
211+
(1 row)
212+
213+
CREATE PROCEDURE ptest6b(a anyelement, out b anyelement, out c anyarray)
214+
LANGUAGE SQL
215+
AS $$
216+
SELECT $1, array[$1];
217+
$$;
218+
CALL ptest6b(1, null, null);
219+
b | c
220+
---+-----
221+
1 | {1}
222+
(1 row)
223+
224+
CALL ptest6b(1.1, null, null);
225+
b | c
226+
-----+-------
227+
1.1 | {1.1}
228+
(1 row)
229+
196230
-- collation assignment
197231
CREATE PROCEDURE ptest7(a text, b text)
198232
LANGUAGE SQL

‎src/test/regress/sql/create_procedure.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,24 @@ $$;
131131

132132
CALL ptest6(1,2);
133133

134+
CREATE PROCEDURE ptest6a(inout a anyelement, out b anyelement)
135+
LANGUAGE SQL
136+
AS $$
137+
SELECT $1, $1;
138+
$$;
139+
140+
CALL ptest6a(1,null);
141+
CALL ptest6a(1.1,null);
142+
143+
CREATE PROCEDURE ptest6b(a anyelement, out b anyelement, out c anyarray)
144+
LANGUAGE SQL
145+
AS $$
146+
SELECT $1, array[$1];
147+
$$;
148+
149+
CALL ptest6b(1,null,null);
150+
CALL ptest6b(1.1,null,null);
151+
134152

135153
-- collation assignment
136154

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp