diff --git a/src/gausskernel/runtime/executor/execQual.cpp b/src/gausskernel/runtime/executor/execQual.cpp index f7ace8757..3b3594d28 100644 --- a/src/gausskernel/runtime/executor/execQual.cpp +++ b/src/gausskernel/runtime/executor/execQual.cpp @@ -2199,14 +2199,8 @@ static void tupledesc_match(TupleDesc dst_tupdesc, TupleDesc src_tupdesc) } } -void set_result_for_plpgsql_language_function_with_outparam(FuncExprState *fcache, Datum *result, bool *isNull) +void set_result_for_plpgsql_language_function_with_outparam(Datum *result, bool *isNull) { - if (!IsA(fcache->xprstate.expr, FuncExpr)) { - return; - } - if (!fcache->is_plpgsql_func_with_outparam) { - return; - } HeapTupleHeader td = DatumGetHeapTupleHeader(*result); TupleDesc tupdesc; PG_TRY(); @@ -2237,6 +2231,18 @@ void set_result_for_plpgsql_language_function_with_outparam(FuncExprState *fcach pfree(nulls); } +void set_result_for_plpgsql_language_function_with_outparam(FuncExprState *fcache, Datum *result, bool *isNull) +{ + if (!IsA(fcache->xprstate.expr, FuncExpr)) { + return; + } + if (!fcache->is_plpgsql_func_with_outparam) { + return; + } + return set_result_for_plpgsql_language_function_with_outparam(result, isNull); +} + + bool ExecSetArgIsByValue(FunctionCallInfo fcinfo) { for (int i = 0; i < fcinfo->nargs; i++) { diff --git a/src/gausskernel/runtime/vecexecutor/vecexpression.cpp b/src/gausskernel/runtime/vecexecutor/vecexpression.cpp index c803c8f4c..1b8197347 100644 --- a/src/gausskernel/runtime/vecexecutor/vecexpression.cpp +++ b/src/gausskernel/runtime/vecexecutor/vecexpression.cpp @@ -1800,6 +1800,14 @@ static ScalarVector* GenericFunctionT(PG_FUNCTION_ARGS) if (!fenced) { rowcinfo->isnull = false; result = RowFunction(rowcinfo); + + if (fcinfo->is_plpgsql_language_function_with_outparam) { + bool is_null = false; + set_result_for_plpgsql_language_function_with_outparam(&result, &is_null); + if (is_null == true) { + rowcinfo->isnull = true; + } + } if (rowcinfo->isnull == false) { presult[i] = ScalarVector::DatumToScalarT(result, false); SET_NOTNULL(presultFlag[i]); @@ -2090,6 +2098,10 @@ static ScalarVector* ExecMakeVecFunctionResult( fcinfo->nargs += EXTRA_NARGS; fcinfo->isnull = false; + if (IsA(fcache->xprstate.expr, FuncExpr) && is_function_with_plpgsql_language_and_outparam(fcache->func.fn_oid)) { + fcinfo->is_plpgsql_language_function_with_outparam = true; + } + result = VecFunctionCallInvoke(fcinfo); fcinfo->nargs -= EXTRA_NARGS; pgstat_end_function_usage(&fcusage, true); diff --git a/src/include/fmgr.h b/src/include/fmgr.h index cb0d2e30a..127b5d36d 100644 --- a/src/include/fmgr.h +++ b/src/include/fmgr.h @@ -170,6 +170,7 @@ typedef struct FunctionCallInfoData { UDFInfoType udfInfo; StartWithFuncEvalInfo swinfo; CoercionContext ccontext; + bool is_plpgsql_language_function_with_outparam; FunctionCallInfoData() { @@ -185,6 +186,7 @@ typedef struct FunctionCallInfoData { isnull = false; can_ignore = false; ccontext = COERCION_UNKNOWN; + is_plpgsql_language_function_with_outparam = false; } } FunctionCallInfoData; diff --git a/src/include/vecexecutor/vecexpression.h b/src/include/vecexecutor/vecexpression.h index 19cad8aea..1a66fb0a1 100644 --- a/src/include/vecexecutor/vecexpression.h +++ b/src/include/vecexecutor/vecexpression.h @@ -34,4 +34,7 @@ GenericArgExtract ChooseExtractFun(Oid Dtype, Oid fn_oid = 0); +extern void set_result_for_plpgsql_language_function_with_outparam(Datum *result, bool *isNull); + + #endif /* VECEXPRESSION_H_ */ diff --git a/src/test/regress/expected/out_param_func_overload.out b/src/test/regress/expected/out_param_func_overload.out index 8c76cecb5..dd1512266 100644 --- a/src/test/regress/expected/out_param_func_overload.out +++ b/src/test/regress/expected/out_param_func_overload.out @@ -293,6 +293,40 @@ drop package pkg_type; NOTICE: drop cascades to 2 other objects DETAIL: drop cascades to function out_param_func_overload.func(integer) drop cascades to function out_param_func_overload.func2(integer) +CREATE OR REPLACE PACKAGE pac_test_1 AS +FUNCTION f_test_1(para1 in out int, para2 in out int, para3 in out int) RETURN int; +END pac_test_1; +/ +CREATE OR REPLACE PACKAGE BODY pac_test_1 AS +FUNCTION f_test_1(para1 in out int, para2 in out int, para3 in out int) +RETURN int IS +BEGIN +RETURN 1; +END; +END pac_test_1; +/ +create table t1(c1 int,c2 text) with (ORIENTATION=COLUMN);; +insert into t1 select a,a || 'test' from generate_series(1,10) as a; +create view v1 as select c1,c2,pac_test_1.f_test_1(c1,c1,c1) from t1; +select * from v1; + c1 | c2 | f_test_1 +----+--------+---------- + 1 | 1test | 1 + 2 | 2test | 1 + 3 | 3test | 1 + 4 | 4test | 1 + 5 | 5test | 1 + 6 | 6test | 1 + 7 | 7test | 1 + 8 | 8test | 1 + 9 | 9test | 1 + 10 | 10test | 1 +(10 rows) + +drop view v1; +drop package pac_test_1; +NOTICE: drop cascades to function out_param_func_overload.f_test_1(integer,integer,integer) +drop table t1; --clean reset behavior_compat_options; drop schema out_param_func_overload cascade; diff --git a/src/test/regress/sql/out_param_func_overload.sql b/src/test/regress/sql/out_param_func_overload.sql index 06e448031..1710d96db 100644 --- a/src/test/regress/sql/out_param_func_overload.sql +++ b/src/test/regress/sql/out_param_func_overload.sql @@ -238,6 +238,31 @@ END; drop package pkg_type; +CREATE OR REPLACE PACKAGE pac_test_1 AS +FUNCTION f_test_1(para1 in out int, para2 in out int, para3 in out int) RETURN int; +END pac_test_1; +/ + +CREATE OR REPLACE PACKAGE BODY pac_test_1 AS +FUNCTION f_test_1(para1 in out int, para2 in out int, para3 in out int) +RETURN int IS +BEGIN +RETURN 1; +END; +END pac_test_1; +/ + +create table t1(c1 int,c2 text) with (ORIENTATION=COLUMN);; +insert into t1 select a,a || 'test' from generate_series(1,10) as a; + +create view v1 as select c1,c2,pac_test_1.f_test_1(c1,c1,c1) from t1; +select * from v1; + +drop view v1; +drop package pac_test_1; +drop table t1; + + --clean reset behavior_compat_options;