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

Commit76e6602

Browse files
committed
Improve the recently-added code for inlining set-returning functions so that
it can handle functions returning setof record. The case was left undoneoriginally, but it turns out to be simple to fix.
1 parentcbe99a9 commit76e6602

File tree

3 files changed

+70
-17
lines changed

3 files changed

+70
-17
lines changed

‎src/backend/optimizer/prep/prepjointree.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
*
1818
* IDENTIFICATION
19-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.55 2008/10/04 21:56:53 tgl Exp $
19+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.56 2008/10/09 19:27:40 tgl Exp $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -383,7 +383,7 @@ inline_set_returning_functions(PlannerInfo *root)
383383
Query*funcquery;
384384

385385
/* Check safety of expansion, and expand if possible */
386-
funcquery=inline_set_returning_function(root,rte->funcexpr);
386+
funcquery=inline_set_returning_function(root,rte);
387387
if (funcquery)
388388
{
389389
/* Successful expansion, replace the rtable entry */

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

Lines changed: 65 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.268 2008/10/04 21:56:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.269 2008/10/09 19:27:40 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHORDATEMAJOR EVENT
@@ -111,6 +111,7 @@ static Query *substitute_actual_srf_parameters(Query *expr,
111111
intnargs,List*args);
112112
staticNode*substitute_actual_srf_parameters_mutator(Node*node,
113113
substitute_actual_srf_parameters_context*context);
114+
staticbooltlist_matches_coltypelist(List*tlist,List*coltypelist);
114115

115116

116117
/*****************************************************************************
@@ -3659,17 +3660,16 @@ evaluate_expr(Expr *expr, Oid result_type, int32 result_typmod)
36593660
* inline_set_returning_function
36603661
*Attempt to "inline" a set-returning function in the FROM clause.
36613662
*
3662-
* "node" is the expression from an RTE_FUNCTION rangetable entry. If it
3663-
* represents a call of a set-returning SQL function that can safely be
3664-
* inlined, expand the function and return the substitute Query structure.
3665-
* Otherwise, return NULL.
3663+
* "rte" is an RTE_FUNCTION rangetable entry. If it represents a call of a
3664+
* set-returning SQL function that can safely be inlined, expand the function
3665+
* and return the substitute Query structure. Otherwise, return NULL.
36663666
*
36673667
* This has a good deal of similarity to inline_function(), but that's
36683668
* for the non-set-returning case, and there are enough differences to
36693669
* justify separate functions.
36703670
*/
36713671
Query*
3672-
inline_set_returning_function(PlannerInfo*root,Node*node)
3672+
inline_set_returning_function(PlannerInfo*root,RangeTblEntry*rte)
36733673
{
36743674
FuncExpr*fexpr;
36753675
HeapTuplefunc_tuple;
@@ -3686,6 +3686,8 @@ inline_set_returning_function(PlannerInfo *root, Node *node)
36863686
Query*querytree;
36873687
inti;
36883688

3689+
Assert(rte->rtekind==RTE_FUNCTION);
3690+
36893691
/*
36903692
* It doesn't make a lot of sense for a SQL SRF to refer to itself
36913693
* in its own FROM clause, since that must cause infinite recursion
@@ -3695,9 +3697,9 @@ inline_set_returning_function(PlannerInfo *root, Node *node)
36953697
check_stack_depth();
36963698

36973699
/* Fail if FROM item isn't a simple FuncExpr */
3698-
if (node==NULL|| !IsA(node,FuncExpr))
3700+
fexpr= (FuncExpr*)rte->funcexpr;
3701+
if (fexpr==NULL|| !IsA(fexpr,FuncExpr))
36993702
returnNULL;
3700-
fexpr= (FuncExpr*)node;
37013703

37023704
/*
37033705
* The function must be declared to return a set, else inlining would
@@ -3707,10 +3709,6 @@ inline_set_returning_function(PlannerInfo *root, Node *node)
37073709
if (!fexpr->funcretset)
37083710
returnNULL;
37093711

3710-
/* Fail if function returns RECORD ... we don't have enough context */
3711-
if (fexpr->funcresulttype==RECORDOID)
3712-
returnNULL;
3713-
37143712
/*
37153713
* Refuse to inline if the arguments contain any volatile functions or
37163714
* sub-selects. Volatile functions are rejected because inlining may
@@ -3837,9 +3835,20 @@ inline_set_returning_function(PlannerInfo *root, Node *node)
38373835
if (!check_sql_fn_retval(fexpr->funcid,fexpr->funcresulttype,
38383836
querytree_list,
38393837
true,NULL)&&
3840-
get_typtype(fexpr->funcresulttype)==TYPTYPE_COMPOSITE)
3838+
(get_typtype(fexpr->funcresulttype)==TYPTYPE_COMPOSITE||
3839+
fexpr->funcresulttype==RECORDOID))
38413840
gotofail;/* reject not-whole-tuple-result cases */
38423841

3842+
/*
3843+
* If it returns RECORD, we have to check against the column type list
3844+
* provided in the RTE; check_sql_fn_retval can't do that. (If no match,
3845+
* we just fail to inline, rather than complaining; see notes for
3846+
* tlist_matches_coltypelist.)
3847+
*/
3848+
if (fexpr->funcresulttype==RECORDOID&&
3849+
!tlist_matches_coltypelist(querytree->targetList,rte->funccoltypes))
3850+
gotofail;
3851+
38433852
/*
38443853
* Looks good --- substitute parameters into the query.
38453854
*/
@@ -3938,3 +3947,46 @@ substitute_actual_srf_parameters_mutator(Node *node,
39383947
substitute_actual_srf_parameters_mutator,
39393948
(void*)context);
39403949
}
3950+
3951+
/*
3952+
* Check whether a SELECT targetlist emits the specified column types,
3953+
* to see if it's safe to inline a function returning record.
3954+
*
3955+
* We insist on exact match here. The executor allows binary-coercible
3956+
* cases too, but we don't have a way to preserve the correct column types
3957+
* in the correct places if we inline the function in such a case.
3958+
*
3959+
* Note that we only check type OIDs not typmods; this agrees with what the
3960+
* executor would do at runtime, and attributing a specific typmod to a
3961+
* function result is largely wishful thinking anyway.
3962+
*/
3963+
staticbool
3964+
tlist_matches_coltypelist(List*tlist,List*coltypelist)
3965+
{
3966+
ListCell*tlistitem;
3967+
ListCell*clistitem;
3968+
3969+
clistitem=list_head(coltypelist);
3970+
foreach(tlistitem,tlist)
3971+
{
3972+
TargetEntry*tle= (TargetEntry*)lfirst(tlistitem);
3973+
Oidcoltype;
3974+
3975+
if (tle->resjunk)
3976+
continue;/* ignore junk columns */
3977+
3978+
if (clistitem==NULL)
3979+
return false;/* too many tlist items */
3980+
3981+
coltype=lfirst_oid(clistitem);
3982+
clistitem=lnext(clistitem);
3983+
3984+
if (exprType((Node*)tle->expr)!=coltype)
3985+
return false;/* column type mismatch */
3986+
}
3987+
3988+
if (clistitem!=NULL)
3989+
return false;/* too few tlist items */
3990+
3991+
return true;
3992+
}

‎src/include/optimizer/clauses.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.94 2008/08/25 22:42:34 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/optimizer/clauses.h,v 1.95 2008/10/09 19:27:40 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -77,6 +77,7 @@ extern Node *eval_const_expressions(PlannerInfo *root, Node *node);
7777

7878
externNode*estimate_expression_value(PlannerInfo*root,Node*node);
7979

80-
externQuery*inline_set_returning_function(PlannerInfo*root,Node*node);
80+
externQuery*inline_set_returning_function(PlannerInfo*root,
81+
RangeTblEntry*rte);
8182

8283
#endif/* CLAUSES_H */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp