]> granicus.if.org Git - postgresql/commitdiff
For a SQL function declared to return a named composite type, make
authorTom Lane <tgl@sss.pgh.pa.us>
Thu, 15 Jul 2004 13:51:38 +0000 (13:51 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Thu, 15 Jul 2004 13:51:38 +0000 (13:51 +0000)
sure the tuple datums it returns actually show that type and not RECORD.

src/backend/executor/functions.c

index 9ddf6192775777ff63f11743823c72510bae6bb4..0073f8f55c16082a2cec328ef114de8e0f86a67e 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.82 2004/06/11 01:08:42 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.83 2004/07/15 13:51:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,9 +58,10 @@ typedef struct local_es
  */
 typedef struct
 {
+       Oid                     rettype;                /* actual return type */
        int                     typlen;                 /* length of the return type */
        bool            typbyval;               /* true if return type is pass by value */
-       bool            returnsTuple;   /* true if return type is a tuple */
+       bool            returnsTuple;   /* true if returning whole tuple result */
        bool            shutdown_reg;   /* true if registered shutdown callback */
 
        ParamListInfo paramLI;          /* Param list representing current args */
@@ -167,6 +168,8 @@ init_sql_fcache(FmgrInfo *finfo)
                                                  format_type_be(procedureStruct->prorettype))));
        }
 
+       fcache->rettype = rettype;
+
        /* Now look up the actual result type */
        typeTuple = SearchSysCache(TYPEOID,
                                                           ObjectIdGetDatum(rettype),
@@ -389,20 +392,36 @@ postquel_execute(execution_state *es,
                         * Probably OK to leave them, as long as they are at the end.
                         */
                        HeapTupleHeader dtup;
+                       Oid             dtuptype;
+                       int32   dtuptypmod;
 
                        dtup = (HeapTupleHeader) palloc(tup->t_len);
                        memcpy((char *) dtup, (char *) tup->t_data, tup->t_len);
 
                        /*
-                        * For RECORD results, make sure a typmod has been assigned.
+                        * Use the declared return type if it's not RECORD; else take
+                        * the type from the computed result, making sure a typmod has
+                        * been assigned.
                         */
-                       if (tupDesc->tdtypeid == RECORDOID &&
-                               tupDesc->tdtypmod < 0)
-                               assign_record_type_typmod(tupDesc);
+                       if (fcache->rettype != RECORDOID)
+                       {
+                               /* function has a named composite return type */
+                               dtuptype = fcache->rettype;
+                               dtuptypmod = -1;
+                       }
+                       else
+                       {
+                               /* function is declared to return RECORD */
+                               if (tupDesc->tdtypeid == RECORDOID &&
+                                       tupDesc->tdtypmod < 0)
+                                       assign_record_type_typmod(tupDesc);
+                               dtuptype = tupDesc->tdtypeid;
+                               dtuptypmod = tupDesc->tdtypmod;
+                       }
 
                        HeapTupleHeaderSetDatumLength(dtup, tup->t_len);
-                       HeapTupleHeaderSetTypeId(dtup, tupDesc->tdtypeid);
-                       HeapTupleHeaderSetTypMod(dtup, tupDesc->tdtypmod);
+                       HeapTupleHeaderSetTypeId(dtup, dtuptype);
+                       HeapTupleHeaderSetTypMod(dtup, dtuptypmod);
 
                        value = PointerGetDatum(dtup);
                        fcinfo->isnull = false;