]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix a thinko in my patch of a couple months ago for bug #3116: it did the
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 May 2007 18:54:24 +0000 (18:54 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 1 May 2007 18:54:24 +0000 (18:54 +0000)
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.

src/backend/optimizer/util/clauses.c
src/test/regress/expected/polymorphism.out
src/test/regress/sql/polymorphism.sql

index 0725cd921849717a43852571644f45da9a51b1b2..6683e417ca5c3f533f6744c11e70460fe1f2e006 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.6 2007/03/06 22:45:41 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.7 2007/05/01 18:54:24 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -1987,11 +1987,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);
        }
index 55687467a0d25751442b1251cfb3263ebbabdb8c..651ae0baacb9120c413883aaccd00da2953f8e2a 100644 (file)
@@ -530,3 +530,38 @@ select f3, myaggn10a(f1) from t group by f3;
  a  | {1,2,3}
 (3 rows)
 
+-- 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)
+
index 5175f9f93d1c1f7a99c8b637f5a593dce41209b5..d3a5cd1c132e39a90766836c3457782582c3e0ea 100644 (file)
@@ -365,3 +365,19 @@ select f3, myaggn08a(f1) from t group by f3;
 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;
+
+-- 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;