mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-21 08:29:39 +08:00
Fix oversight in original coding of inline_function(): since
check_sql_fn_retval allows binary-compatibility cases, the expression extracted from an inline-able SQL function might have a type that is only binary-compatible with the declared function result type. To avoid possibly changing the semantics of the expression, we should insert a RelabelType node in such cases. This has only been shown to have bad consequences in recent 8.1 and up releases, but I suspect there may be failure cases in the older branches too, so patch it all the way back. Per bug #3116 from Greg Mullane. Along the way, fix an omission in eval_const_expressions_mutator: it failed to copy the relabelformat field when processing a RelabelType. No known observable failures from this, but it definitely isn't intended behavior.
This commit is contained in:
parent
3530283dae
commit
cafbf1e1cc
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.223.2.1 2007/02/02 00:03:17 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.223.2.2 2007/03/06 22:45:23 tgl Exp $
|
||||
*
|
||||
* HISTORY
|
||||
* AUTHOR DATE MAJOR EVENT
|
||||
@ -1842,6 +1842,7 @@ eval_const_expressions_mutator(Node *node,
|
||||
newrelabel->arg = (Expr *) arg;
|
||||
newrelabel->resulttype = relabel->resulttype;
|
||||
newrelabel->resulttypmod = relabel->resulttypmod;
|
||||
newrelabel->relabelformat = relabel->relabelformat;
|
||||
return (Node *) newrelabel;
|
||||
}
|
||||
}
|
||||
@ -2795,7 +2796,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
* no rewriting was needed; that's probably not important, but let's be
|
||||
* careful.
|
||||
*/
|
||||
(void) check_sql_fn_retval(funcid, result_type, querytree_list, NULL);
|
||||
if (check_sql_fn_retval(funcid, result_type, querytree_list, NULL))
|
||||
goto fail; /* reject whole-tuple-result cases */
|
||||
|
||||
/*
|
||||
* Additional validity checks on the expression. It mustn't return a set,
|
||||
@ -2880,6 +2882,21 @@ inline_function(Oid funcid, Oid result_type, List *args,
|
||||
|
||||
MemoryContextDelete(mycxt);
|
||||
|
||||
/*
|
||||
* Since check_sql_fn_retval allows binary-compatibility cases, the
|
||||
* expression we now have might return some type that's only binary
|
||||
* compatible with the original expression result type. To avoid
|
||||
* confusing matters, insert a RelabelType in such cases.
|
||||
*/
|
||||
if (exprType(newexpr) != funcform->prorettype)
|
||||
{
|
||||
Assert(IsBinaryCoercible(exprType(newexpr), funcform->prorettype));
|
||||
newexpr = (Node *) makeRelabelType((Expr *) newexpr,
|
||||
funcform->prorettype,
|
||||
-1,
|
||||
COERCE_IMPLICIT_CAST);
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively try to simplify the modified expression. Here we must add
|
||||
* the current function to the context list of active functions.
|
||||
|
Loading…
Reference in New Issue
Block a user