//Description: postgres 函数和程序的返回值研究
//Create Date: 2020-02-12 17:46:30
//Author: channy
[toc]
procedure没有returnType
create function f_test_12(a int, out b int, out c int) returns record as $$
begin
raise notice 'begin f';
a = 9;
b = a + 3;
c = a * 3;
raise notice 'c = %', c;
return;
end $$
language plpgsql;
create procedure p_test_12() as $$
declare
ret res_test_12;
x int = 14;
begin
raise notice 'begin p';
ret = f_test_12(x);
raise notice '%', ret;
end $$
language plpgsql;
backend/commands/functioncmds.c
305 if (fp->mode != FUNC_PARAM_IN && fp->mode != FUNC_PARAM_VARIADIC)
306 {
307 //if (objtype == OBJECT_PROCEDURE)
308 // *requiredResultType = RECORDOID;
309 //else if (outCount == 0) /* save first output param's type */
310 // *requiredResultType = toid;
311 outCount++;
312 }
432 if (outCount > 0 || varCount > 0)
433 {
434 *allParameterTypes = construct_array(allTypes, parameterCount, OIDOID,
435 sizeof(Oid), true, 'i');
436 *parameterModes = construct_array(paramModes, parameterCount, CHAROID,
437 1, true, 'c');
438 //if (outCount > 1)
439 // *requiredResultType = RECORDOID;
440 /* otherwise we set requiredResultType correctly above */
441 }
pl/plpgsql/src/pl_gram.y
3256 else if (plpgsql_curr_compile->out_param_varno >= 0)
3257 {
3258 int tok = yylex();
3259
3260 if (tok == T_DATUM && plpgsql_peek() == ';' &&
3261 (yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_VAR ||
3262 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_PROMISE ||
3263 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_ROW ||
3264 yylval.wdatum.datum->dtype == PLPGSQL_DTYPE_REC))
3265 {
3266 new->retvarno = yylval.wdatum.datum->dno;
3267
3268 tok = yylex();
3269 Assert(tok == ';');
3270 }
3271 else
3272 {
3273 plpgsql_push_back_token(tok);
3274 new->expr = read_sql_expression(';', ";");
3275 }
3276
3277 //if (yylex() != ';')
3278 // ereport(ERROR,
3279 // (errcode(ERRCODE_DATATYPE_MISMATCH),
3280 // errmsg("RETURN cannot have a parameter in function with OUT parameters "),
3281 // parser_errposition(yylloc)));
3282 //new->retvarno = plpgsql_curr_compile->out_param_varno;
3283 }
function一定要有返回值(return或out)
create function f_test_12(a int, b varchar) returns void as $$
begin
raise notice 'begin f';
a = 9;
b = 'x';
raise notice 'a = %', b;
end $$
language plpgsql;
create function f_test_12(a int, b varchar) as $$
begin
raise notice 'begin f';
a = 9;
b = 'x';
raise notice 'a = %', b;
--return;
end $$
language plpgsql;
ERROR: function result type must be specified
create function f_test_12(a int, b varchar) returns int as $$
begin
raise notice 'begin f';
a = 9;
b = 'x';
raise notice 'a = %', b;
return 8;
end $$
language plpgsql;
create function f_test_12(a int, out b int) as $$
begin
raise notice 'begin f';
a = 9;
b = a + 3;
raise notice 'a = %', a;
return;
end $$
language plpgsql;
CREATE FUNCTION
postgres=# select f_test_12(2);
NOTICE: begin f
NOTICE: a = 9
f_test_12
-----------
12
(1 row)
postgres=# create function f_test_12(a int, out b int) returns int as $$
begin
raise notice 'begin f';
a = 9;
b = a + 3;
raise notice 'a = %', a;
return;
end $$
language plpgsql;
CREATE FUNCTION
postgres=# select f_test_12(5);
NOTICE: begin f
NOTICE: a = 9
f_test_12
-----------
12
(1 row)
postgres=# create function f_test_12(a int, out b int, out c int) returns record as $$
begin
raise notice 'begin f';
a = 9;
b = a + 3;
c = a * 3;
raise notice 'c = %', c;
return;
end $$
language plpgsql;
CREATE FUNCTION
postgres=# select f_test_12(3);
NOTICE: begin f
NOTICE: c = 27
f_test_12
-----------
(12,27)
(1 row)
create function f_test_12(a int, out b int) returns varchar as $$
begin
raise notice 'begin f';
a = 9;
b = a + 3;
raise notice 'a = %', a;
return;
end $$
language plpgsql;