Skip to content

Commit cc0cac4

Browse files
committed
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.
1 parent 46573e6 commit cc0cac4

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

src/backend/optimizer/util/clauses.c

+19-2
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.236 2007/02/22 22:00:24 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.237 2007/03/06 22:45:16 tgl Exp $
1212
*
1313
* HISTORY
1414
* AUTHOR DATE MAJOR EVENT
@@ -1976,6 +1976,7 @@ eval_const_expressions_mutator(Node *node,
19761976
newrelabel->arg = (Expr *) arg;
19771977
newrelabel->resulttype = relabel->resulttype;
19781978
newrelabel->resulttypmod = relabel->resulttypmod;
1979+
newrelabel->relabelformat = relabel->relabelformat;
19791980
return (Node *) newrelabel;
19801981
}
19811982
}
@@ -2929,7 +2930,8 @@ inline_function(Oid funcid, Oid result_type, List *args,
29292930
* no rewriting was needed; that's probably not important, but let's be
29302931
* careful.
29312932
*/
2932-
(void) check_sql_fn_retval(funcid, result_type, querytree_list, NULL);
2933+
if (check_sql_fn_retval(funcid, result_type, querytree_list, NULL))
2934+
goto fail; /* reject whole-tuple-result cases */
29332935

29342936
/*
29352937
* Additional validity checks on the expression. It mustn't return a set,
@@ -3014,6 +3016,21 @@ inline_function(Oid funcid, Oid result_type, List *args,
30143016

30153017
MemoryContextDelete(mycxt);
30163018

3019+
/*
3020+
* Since check_sql_fn_retval allows binary-compatibility cases, the
3021+
* expression we now have might return some type that's only binary
3022+
* compatible with the original expression result type. To avoid
3023+
* confusing matters, insert a RelabelType in such cases.
3024+
*/
3025+
if (exprType(newexpr) != funcform->prorettype)
3026+
{
3027+
Assert(IsBinaryCoercible(exprType(newexpr), funcform->prorettype));
3028+
newexpr = (Node *) makeRelabelType((Expr *) newexpr,
3029+
funcform->prorettype,
3030+
-1,
3031+
COERCE_IMPLICIT_CAST);
3032+
}
3033+
30173034
/*
30183035
* Recursively try to simplify the modified expression. Here we must add
30193036
* the current function to the context list of active functions.

0 commit comments

Comments
 (0)