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

Commit28184f0

Browse files
committed
Fix confusion about the return rowtype of SQL-language procedures.
There is a very ancient hack in check_sql_fn_retval that allows asingle SELECT targetlist entry of composite type to be taken assupplying all the output columns of a function returning composite.(This is grotty and fundamentally ambiguous, but it's really hardto do nested composite-returning functions without it.)As far as I know, that doesn't cause any problems in ordinaryfunctions. It's disastrous for procedures however. All proceduresthat have any output parameters are labeled with prorettype RECORD,and the CALL code expects it will get back a record with one columnper output parameter, regardless of whether any of those parametersis composite. Doing something else leads to an assertion failureor core dump.This is simple enough to fix: we just need to not apply that rulewhen considering procedures. However, that requires adding anotherargument to check_sql_fn_retval, which at least in principle might begetting called by external callers. Therefore, in the back branchesconvert check_sql_fn_retval into an ABI-preserving wrapper around anew function check_sql_fn_retval_ext.Per report from Yahor Yuzefovich. This has been broken since weimplemented procedures, so back-patch to all supported branches.Discussion:https://postgr.es/m/CABz5gWHSjj2df6uG0NRiDhZ_Uz=Y8t0FJP-_SVSsRsnrQT76Gg@mail.gmail.com
1 parentad5cd55 commit28184f0

File tree

6 files changed

+69
-18
lines changed

6 files changed

+69
-18
lines changed

‎src/backend/catalog/pg_proc.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -926,9 +926,10 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
926926

927927
(void)get_func_result_type(funcoid,&rettype,&rettupdesc);
928928

929-
(void)check_sql_fn_retval(querytree_list,
930-
rettype,rettupdesc,
931-
false,NULL);
929+
(void)check_sql_fn_retval_ext(querytree_list,
930+
rettype,rettupdesc,
931+
proc->prokind,
932+
false,NULL);
932933
}
933934

934935
error_context_stack=sqlerrcontext.previous;

‎src/backend/executor/functions.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -733,11 +733,12 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
733733
* the rowtype column into multiple columns, since we have no way to
734734
* notify the caller that it should do that.)
735735
*/
736-
fcache->returnsTuple=check_sql_fn_retval(queryTree_list,
737-
rettype,
738-
rettupdesc,
739-
false,
740-
&resulttlist);
736+
fcache->returnsTuple=check_sql_fn_retval_ext(queryTree_list,
737+
rettype,
738+
rettupdesc,
739+
procedureStruct->prokind,
740+
false,
741+
&resulttlist);
741742

742743
/*
743744
* Construct a JunkFilter we can use to coerce the returned rowtype to the
@@ -1616,6 +1617,21 @@ check_sql_fn_retval(List *queryTreeLists,
16161617
Oidrettype,TupleDescrettupdesc,
16171618
boolinsertDroppedCols,
16181619
List**resultTargetList)
1620+
{
1621+
/* Wrapper function to preserve ABI compatibility in released branches */
1622+
returncheck_sql_fn_retval_ext(queryTreeLists,
1623+
rettype,rettupdesc,
1624+
PROKIND_FUNCTION,
1625+
insertDroppedCols,
1626+
resultTargetList);
1627+
}
1628+
1629+
bool
1630+
check_sql_fn_retval_ext(List*queryTreeLists,
1631+
Oidrettype,TupleDescrettupdesc,
1632+
charprokind,
1633+
boolinsertDroppedCols,
1634+
List**resultTargetList)
16191635
{
16201636
boolis_tuple_result= false;
16211637
Query*parse;
@@ -1633,7 +1649,7 @@ check_sql_fn_retval(List *queryTreeLists,
16331649

16341650
/*
16351651
* If it's declared to return VOID, we don't care what's in the function.
1636-
* (This takes care ofthe procedure case, as well.)
1652+
* (This takes care ofprocedures with no output parameters, as well.)
16371653
*/
16381654
if (rettype==VOIDOID)
16391655
return false;
@@ -1787,8 +1803,13 @@ check_sql_fn_retval(List *queryTreeLists,
17871803
* or not the record type really matches. For the moment we rely on
17881804
* runtime type checking to catch any discrepancy, but it'd be nice to
17891805
* do better at parse time.
1806+
*
1807+
* We must *not* do this for a procedure, however. Procedures with
1808+
* output parameter(s) have rettype RECORD, and the CALL code expects
1809+
* to get results corresponding to the list of output parameters, even
1810+
* when there's just one parameter that's composite.
17901811
*/
1791-
if (tlistlen==1)
1812+
if (tlistlen==1&&prokind!=PROKIND_PROCEDURE)
17921813
{
17931814
TargetEntry*tle= (TargetEntry*)linitial(tlist);
17941815

‎src/backend/optimizer/util/clauses.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4617,9 +4617,10 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
46174617
* needed; that's probably not important, but let's be careful.
46184618
*/
46194619
querytree_list=list_make1(querytree);
4620-
if (check_sql_fn_retval(list_make1(querytree_list),
4621-
result_type,rettupdesc,
4622-
false,NULL))
4620+
if (check_sql_fn_retval_ext(list_make1(querytree_list),
4621+
result_type,rettupdesc,
4622+
funcform->prokind,
4623+
false,NULL))
46234624
gotofail;/* reject whole-tuple-result cases */
46244625

46254626
/*
@@ -5140,9 +5141,10 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
51405141
* shows it's returning a whole tuple result; otherwise what it's
51415142
* returning is a single composite column which is not what we need.
51425143
*/
5143-
if (!check_sql_fn_retval(list_make1(querytree_list),
5144-
fexpr->funcresulttype,rettupdesc,
5145-
true,NULL)&&
5144+
if (!check_sql_fn_retval_ext(list_make1(querytree_list),
5145+
fexpr->funcresulttype,rettupdesc,
5146+
funcform->prokind,
5147+
true,NULL)&&
51465148
(functypclass==TYPEFUNC_COMPOSITE||
51475149
functypclass==TYPEFUNC_COMPOSITE_DOMAIN||
51485150
functypclass==TYPEFUNC_RECORD))

‎src/include/executor/functions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ extern bool check_sql_fn_retval(List *queryTreeLists,
3636
boolinsertDroppedCols,
3737
List**resultTargetList);
3838

39+
externboolcheck_sql_fn_retval_ext(List*queryTreeLists,
40+
Oidrettype,TupleDescrettupdesc,
41+
charprokind,
42+
boolinsertDroppedCols,
43+
List**resultTargetList);
44+
3945
externDestReceiver*CreateSQLFunctionDestReceiver(void);
4046

4147
#endif/* FUNCTIONS_H */

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,19 @@ CALL ptest4a(a, b); -- error, not supported
106106
$$;
107107
ERROR: calling procedures with output arguments is not supported in SQL functions
108108
CONTEXT: SQL function "ptest4b"
109-
DROP PROCEDURE ptest4a;
109+
-- we used to get confused by a single output argument that is composite
110+
CREATE PROCEDURE ptest4c(INOUT comp int8_tbl)
111+
LANGUAGE SQL
112+
AS $$
113+
SELECT ROW(1, 2);
114+
$$;
115+
CALL ptest4c(NULL);
116+
comp
117+
-------
118+
(1,2)
119+
(1 row)
120+
121+
DROP PROCEDURE ptest4a, ptest4c;
110122
-- named and default parameters
111123
CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100)
112124
LANGUAGE SQL

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,16 @@ AS $$
6868
CALL ptest4a(a, b);-- error, not supported
6969
$$;
7070

71-
DROP PROCEDURE ptest4a;
71+
-- we used to get confused by a single output argument that is composite
72+
CREATE PROCEDURE ptest4c(INOUT comp int8_tbl)
73+
LANGUAGE SQL
74+
AS $$
75+
SELECT ROW(1,2);
76+
$$;
77+
78+
CALL ptest4c(NULL);
79+
80+
DROP PROCEDURE ptest4a, ptest4c;
7281

7382

7483
-- named and default parameters

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp