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

Commit6ee3261

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 parentfe4750e commit6ee3261

File tree

6 files changed

+36
-4
lines changed

6 files changed

+36
-4
lines changed

‎src/backend/catalog/pg_proc.c‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,7 @@ fmgr_sql_validator(PG_FUNCTION_ARGS)
959959

960960
(void)check_sql_fn_retval(querytree_list,
961961
rettype,rettupdesc,
962+
proc->prokind,
962963
false,NULL);
963964
}
964965

‎src/backend/executor/functions.c‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ init_sql_fcache(FunctionCallInfo fcinfo, Oid collation, bool lazyEvalOK)
746746
fcache->returnsTuple=check_sql_fn_retval(queryTree_list,
747747
rettype,
748748
rettupdesc,
749+
procedureStruct->prokind,
749750
false,
750751
&resulttlist);
751752

@@ -1606,6 +1607,7 @@ check_sql_fn_statements(List *queryTreeLists)
16061607
bool
16071608
check_sql_fn_retval(List*queryTreeLists,
16081609
Oidrettype,TupleDescrettupdesc,
1610+
charprokind,
16091611
boolinsertDroppedCols,
16101612
List**resultTargetList)
16111613
{
@@ -1625,7 +1627,7 @@ check_sql_fn_retval(List *queryTreeLists,
16251627

16261628
/*
16271629
* If it's declared to return VOID, we don't care what's in the function.
1628-
* (This takes care ofthe procedure case, as well.)
1630+
* (This takes care ofprocedures with no output parameters, as well.)
16291631
*/
16301632
if (rettype==VOIDOID)
16311633
return false;
@@ -1780,8 +1782,13 @@ check_sql_fn_retval(List *queryTreeLists,
17801782
* or not the record type really matches. For the moment we rely on
17811783
* runtime type checking to catch any discrepancy, but it'd be nice to
17821784
* do better at parse time.
1785+
*
1786+
* We must *not* do this for a procedure, however. Procedures with
1787+
* output parameter(s) have rettype RECORD, and the CALL code expects
1788+
* to get results corresponding to the list of output parameters, even
1789+
* when there's just one parameter that's composite.
17831790
*/
1784-
if (tlistlen==1)
1791+
if (tlistlen==1&&prokind!=PROKIND_PROCEDURE)
17851792
{
17861793
TargetEntry*tle= (TargetEntry*)linitial(tlist);
17871794

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4707,6 +4707,7 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
47074707
querytree_list=list_make1(querytree);
47084708
if (check_sql_fn_retval(list_make1(querytree_list),
47094709
result_type,rettupdesc,
4710+
funcform->prokind,
47104711
false,NULL))
47114712
gotofail;/* reject whole-tuple-result cases */
47124713

@@ -5253,6 +5254,7 @@ inline_set_returning_function(PlannerInfo *root, RangeTblEntry *rte)
52535254
*/
52545255
if (!check_sql_fn_retval(list_make1(querytree_list),
52555256
fexpr->funcresulttype,rettupdesc,
5257+
funcform->prokind,
52565258
true,NULL)&&
52575259
(functypclass==TYPEFUNC_COMPOSITE||
52585260
functypclass==TYPEFUNC_COMPOSITE_DOMAIN||

‎src/include/executor/functions.h‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ extern void check_sql_fn_statements(List *queryTreeLists);
4747

4848
externboolcheck_sql_fn_retval(List*queryTreeLists,
4949
Oidrettype,TupleDescrettupdesc,
50+
charprokind,
5051
boolinsertDroppedCols,
5152
List**resultTargetList);
5253

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

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,19 @@ CALL ptest4a(a, b); -- error, not supported
148148
$$;
149149
ERROR: calling procedures with output arguments is not supported in SQL functions
150150
CONTEXT: SQL function "ptest4b"
151-
DROP PROCEDURE ptest4a;
151+
-- we used to get confused by a single output argument that is composite
152+
CREATE PROCEDURE ptest4c(INOUT comp int8_tbl)
153+
LANGUAGE SQL
154+
AS $$
155+
SELECT ROW(1, 2);
156+
$$;
157+
CALL ptest4c(NULL);
158+
comp
159+
-------
160+
(1,2)
161+
(1 row)
162+
163+
DROP PROCEDURE ptest4a, ptest4c;
152164
-- named and default parameters
153165
CREATE OR REPLACE PROCEDURE ptest5(a int, b text, c int default 100)
154166
LANGUAGE SQL

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

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,16 @@ AS $$
9090
CALL ptest4a(a, b);-- error, not supported
9191
$$;
9292

93-
DROP PROCEDURE ptest4a;
93+
-- we used to get confused by a single output argument that is composite
94+
CREATE PROCEDURE ptest4c(INOUT comp int8_tbl)
95+
LANGUAGE SQL
96+
AS $$
97+
SELECT ROW(1,2);
98+
$$;
99+
100+
CALL ptest4c(NULL);
101+
102+
DROP PROCEDURE ptest4a, ptest4c;
94103

95104

96105
-- named and default parameters

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp