Fix a thinko in my patch of a couple months ago for bug #3116: it did the

wrong thing when inlining polymorphic SQL functions, because it was using the
function's declared return type where it should have used the actual result
type of the current call.  In 8.1 and 8.2 this causes obvious failures even if
you don't have assertions turned on; in 8.0 and 7.4 it would only be a problem
if the inlined expression were used as an input to a function that did
run-time type determination on its inputs.  Add a regression test, since this
is evidently an under-tested area.
This commit is contained in:
Tom Lane 2007-05-01 18:53:52 +00:00
parent c432061963
commit b4349519c1
3 changed files with 55 additions and 4 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.243 2007/04/30 00:14:54 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/util/clauses.c,v 1.244 2007/05/01 18:53:51 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@ -3063,11 +3063,11 @@ inline_function(Oid funcid, Oid result_type, List *args,
* compatible with the original expression result type. To avoid
* confusing matters, insert a RelabelType in such cases.
*/
if (exprType(newexpr) != funcform->prorettype)
if (exprType(newexpr) != result_type)
{
Assert(IsBinaryCoercible(exprType(newexpr), funcform->prorettype));
Assert(IsBinaryCoercible(exprType(newexpr), result_type));
newexpr = (Node *) makeRelabelType((Expr *) newexpr,
funcform->prorettype,
result_type,
-1,
COERCE_IMPLICIT_CAST);
}

View File

@ -542,3 +542,38 @@ select mysum2(f1, f1 + 1) from t;
38
(1 row)
-- test inlining of polymorphic SQL functions
create function bleat(int) returns int as $$
begin
raise notice 'bleat %', $1;
return $1;
end$$ language plpgsql;
create function sql_if(bool, anyelement, anyelement) returns anyelement as $$
select case when $1 then $2 else $3 end $$ language sql;
-- Note this would fail with integer overflow, never mind wrong bleat() output,
-- if the CASE expression were not successfully inlined
select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl;
NOTICE: bleat 1
NOTICE: bleat 123456
NOTICE: bleat -123455
NOTICE: bleat 2147483647
NOTICE: bleat -2147483646
f1 | sql_if
-------------+-------------
0 | 1
123456 | 123456
-123456 | -123455
2147483647 | 2147483647
-2147483647 | -2147483646
(5 rows)
select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;
q2 | sql_if
-------------------+-------------------
456 | 456
4567890123456789 | 4567890123456789
123 | 123
4567890123456789 | 4567890123456789
-4567890123456789 | -4567890123456788
(5 rows)

View File

@ -374,3 +374,19 @@ select f3, myaggn08b(f1) from t group by f3;
select f3, myaggn09a(f1) from t group by f3;
select f3, myaggn10a(f1) from t group by f3;
select mysum2(f1, f1 + 1) from t;
-- test inlining of polymorphic SQL functions
create function bleat(int) returns int as $$
begin
raise notice 'bleat %', $1;
return $1;
end$$ language plpgsql;
create function sql_if(bool, anyelement, anyelement) returns anyelement as $$
select case when $1 then $2 else $3 end $$ language sql;
-- Note this would fail with integer overflow, never mind wrong bleat() output,
-- if the CASE expression were not successfully inlined
select f1, sql_if(f1 > 0, bleat(f1), bleat(f1 + 1)) from int4_tbl;
select q2, sql_if(q2 > 0, q2, q2 + 1) from int8_tbl;