]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix oversight in original coding of inline_function(): since
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Mar 2007 22:45:41 +0000 (22:45 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 6 Mar 2007 22:45:41 +0000 (22:45 +0000)
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.

src/backend/optimizer/util/clauses.c

index ca1f1623bd02332fa03f84cfd4b875017ea895fc..0725cd921849717a43852571644f45da9a51b1b2 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.5 2007/02/02 00:04:02 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.154.2.6 2007/03/06 22:45:41 tgl Exp $
  *
  * HISTORY
  *       AUTHOR                        DATE                    MAJOR EVENT
@@ -31,6 +31,7 @@
 #include "optimizer/var.h"
 #include "parser/analyze.h"
 #include "parser/parse_clause.h"
+#include "parser/parse_coerce.h"
 #include "parser/parse_expr.h"
 #include "tcop/tcopprot.h"
 #include "utils/acl.h"
@@ -1414,6 +1415,7 @@ eval_const_expressions_mutator(Node *node, List *active_fns)
                        newrelabel->arg = (Expr *) arg;
                        newrelabel->resulttype = relabel->resulttype;
                        newrelabel->resulttypmod = relabel->resulttypmod;
+                       newrelabel->relabelformat = relabel->relabelformat;
                        return (Node *) newrelabel;
                }
        }
@@ -1979,6 +1981,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.