Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit e30e3fd

Browse files
committed
Fix use of uninitialized variable in inline_function().
Commit e717a9a introduced a code path that bypassed the call of get_expr_result_type, which is not good because we need its rettupdesc result to pass to check_sql_fn_retval. We'd failed to notice right away because the code path in which check_sql_fn_retval uses that argument is fairly hard to reach in this context. It's not impossible though, and in any case inline_function would have no business assuming that check_sql_fn_retval doesn't need that value. To fix, move get_expr_result_type out of the if-block, which in turn requires moving the construction of the dummy FuncExpr out of it. Per report from Ranier Vilela. (I'm bemused by the lack of any compiler complaints...) Discussion: https://postgr.es/m/CAEudQAqBqQpQ3HruWAGU_7WaMJ7tntpk0T8k_dVtNB46DqdBgw@mail.gmail.com
1 parent 5e0b1ae commit e30e3fd

File tree

1 file changed

+22
-22
lines changed

1 file changed

+22
-22
lines changed

src/backend/optimizer/util/clauses.c

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4317,6 +4317,22 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
43174317
ALLOCSET_DEFAULT_SIZES);
43184318
oldcxt = MemoryContextSwitchTo(mycxt);
43194319

4320+
/*
4321+
* We need a dummy FuncExpr node containing the already-simplified
4322+
* arguments. (In some cases we don't really need it, but building it is
4323+
* cheap enough that it's not worth contortions to avoid.)
4324+
*/
4325+
fexpr = makeNode(FuncExpr);
4326+
fexpr->funcid = funcid;
4327+
fexpr->funcresulttype = result_type;
4328+
fexpr->funcretset = false;
4329+
fexpr->funcvariadic = funcvariadic;
4330+
fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
4331+
fexpr->funccollid = result_collid; /* doesn't matter */
4332+
fexpr->inputcollid = input_collid;
4333+
fexpr->args = args;
4334+
fexpr->location = -1;
4335+
43204336
/* Fetch the function body */
43214337
tmp = SysCacheGetAttr(PROCOID,
43224338
func_tuple,
@@ -4359,32 +4375,11 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
43594375
}
43604376
else
43614377
{
4362-
/*
4363-
* Set up to handle parameters while parsing the function body. We
4364-
* need a dummy FuncExpr node containing the already-simplified
4365-
* arguments to pass to prepare_sql_fn_parse_info. (In some cases we
4366-
* don't really need that, but for simplicity we always build it.)
4367-
*/
4368-
fexpr = makeNode(FuncExpr);
4369-
fexpr->funcid = funcid;
4370-
fexpr->funcresulttype = result_type;
4371-
fexpr->funcretset = false;
4372-
fexpr->funcvariadic = funcvariadic;
4373-
fexpr->funcformat = COERCE_EXPLICIT_CALL; /* doesn't matter */
4374-
fexpr->funccollid = result_collid; /* doesn't matter */
4375-
fexpr->inputcollid = input_collid;
4376-
fexpr->args = args;
4377-
fexpr->location = -1;
4378-
4378+
/* Set up to handle parameters while parsing the function body. */
43794379
pinfo = prepare_sql_fn_parse_info(func_tuple,
43804380
(Node *) fexpr,
43814381
input_collid);
43824382

4383-
/* fexpr also provides a convenient way to resolve a composite result */
4384-
(void) get_expr_result_type((Node *) fexpr,
4385-
NULL,
4386-
&rettupdesc);
4387-
43884383
/*
43894384
* We just do parsing and parse analysis, not rewriting, because
43904385
* rewriting will not affect table-free-SELECT-only queries, which is
@@ -4434,6 +4429,11 @@ inline_function(Oid funcid, Oid result_type, Oid result_collid,
44344429
list_length(querytree->targetList) != 1)
44354430
goto fail;
44364431

4432+
/* If the function result is composite, resolve it */
4433+
(void) get_expr_result_type((Node *) fexpr,
4434+
NULL,
4435+
&rettupdesc);
4436+
44374437
/*
44384438
* Make sure the function (still) returns what it's declared to. This
44394439
* will raise an error if wrong, but that's okay since the function would

0 commit comments

Comments
 (0)