mirror of
https://github.com/postgres/postgres.git
synced 2025-12-12 02:37:31 +03:00
Support INOUT arguments in procedures
In a top-level CALL, the values of INOUT arguments will be returned as a result row. In PL/pgSQL, the values are assigned back to the input arguments. In other languages, the same convention as for return a record from a function is used. That does not require any code changes in the PL implementations. Reviewed-by: Pavel Stehule <pavel.stehule@gmail.com>
This commit is contained in:
@@ -29,6 +29,29 @@ SELECT * FROM test1;
|
||||
55
|
||||
(1 row)
|
||||
|
||||
-- output arguments
|
||||
CREATE PROCEDURE test_proc5(INOUT a text)
|
||||
LANGUAGE plpythonu
|
||||
AS $$
|
||||
return [a + '+' + a]
|
||||
$$;
|
||||
CALL test_proc5('abc');
|
||||
a
|
||||
---------
|
||||
abc+abc
|
||||
(1 row)
|
||||
|
||||
CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int)
|
||||
LANGUAGE plpythonu
|
||||
AS $$
|
||||
return (b * a, c * a)
|
||||
$$;
|
||||
CALL test_proc6(2, 3, 4);
|
||||
b | c
|
||||
---+---
|
||||
6 | 8
|
||||
(1 row)
|
||||
|
||||
DROP PROCEDURE test_proc1;
|
||||
DROP PROCEDURE test_proc2;
|
||||
DROP PROCEDURE test_proc3;
|
||||
|
||||
@@ -204,21 +204,19 @@ PLy_exec_function(FunctionCallInfo fcinfo, PLyProcedure *proc)
|
||||
* return value as a special "void datum" rather than NULL (as is the
|
||||
* case for non-void-returning functions).
|
||||
*/
|
||||
if (proc->is_procedure)
|
||||
if (proc->result.typoid == VOIDOID)
|
||||
{
|
||||
if (plrv != Py_None)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("PL/Python procedure did not return None")));
|
||||
fcinfo->isnull = false;
|
||||
rv = (Datum) 0;
|
||||
}
|
||||
else if (proc->result.typoid == VOIDOID)
|
||||
{
|
||||
if (plrv != Py_None)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("PL/Python function with return type \"void\" did not return None")));
|
||||
{
|
||||
if (proc->is_procedure)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("PL/Python procedure did not return None")));
|
||||
else
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_DATATYPE_MISMATCH),
|
||||
errmsg("PL/Python function with return type \"void\" did not return None")));
|
||||
}
|
||||
|
||||
fcinfo->isnull = false;
|
||||
rv = (Datum) 0;
|
||||
|
||||
@@ -34,6 +34,26 @@ CALL test_proc3(55);
|
||||
SELECT * FROM test1;
|
||||
|
||||
|
||||
-- output arguments
|
||||
|
||||
CREATE PROCEDURE test_proc5(INOUT a text)
|
||||
LANGUAGE plpythonu
|
||||
AS $$
|
||||
return [a + '+' + a]
|
||||
$$;
|
||||
|
||||
CALL test_proc5('abc');
|
||||
|
||||
|
||||
CREATE PROCEDURE test_proc6(a int, INOUT b int, INOUT c int)
|
||||
LANGUAGE plpythonu
|
||||
AS $$
|
||||
return (b * a, c * a)
|
||||
$$;
|
||||
|
||||
CALL test_proc6(2, 3, 4);
|
||||
|
||||
|
||||
DROP PROCEDURE test_proc1;
|
||||
DROP PROCEDURE test_proc2;
|
||||
DROP PROCEDURE test_proc3;
|
||||
|
||||
Reference in New Issue
Block a user