修复打开proc_outparam_override后,视图依赖package.function,执行查询时返回结果不正确的问题

This commit is contained in:
wangfeihuo
2024-08-31 19:22:34 +08:00
parent 770625fb5a
commit bd3c185fde
6 changed files with 89 additions and 7 deletions

View File

@ -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++) {

View File

@ -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<retType>(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);

View File

@ -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;

View File

@ -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_ */

View File

@ -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;

View File

@ -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;