Skip to content

Commit 473165a

Browse files
committed
For a SQL function declared to return a named composite type, make
sure the tuple datums it returns actually show that type and not RECORD.
1 parent 93a1fce commit 473165a

File tree

1 file changed

+27
-8
lines changed

1 file changed

+27
-8
lines changed

src/backend/executor/functions.c

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.82 2004/06/11 01:08:42 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/functions.c,v 1.83 2004/07/15 13:51:38 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -58,9 +58,10 @@ typedef struct local_es
5858
*/
5959
typedef struct
6060
{
61+
Oid rettype; /* actual return type */
6162
int typlen; /* length of the return type */
6263
bool typbyval; /* true if return type is pass by value */
63-
bool returnsTuple; /* true if return type is a tuple */
64+
bool returnsTuple; /* true if returning whole tuple result */
6465
bool shutdown_reg; /* true if registered shutdown callback */
6566

6667
ParamListInfo paramLI; /* Param list representing current args */
@@ -167,6 +168,8 @@ init_sql_fcache(FmgrInfo *finfo)
167168
format_type_be(procedureStruct->prorettype))));
168169
}
169170

171+
fcache->rettype = rettype;
172+
170173
/* Now look up the actual result type */
171174
typeTuple = SearchSysCache(TYPEOID,
172175
ObjectIdGetDatum(rettype),
@@ -389,20 +392,36 @@ postquel_execute(execution_state *es,
389392
* Probably OK to leave them, as long as they are at the end.
390393
*/
391394
HeapTupleHeader dtup;
395+
Oid dtuptype;
396+
int32 dtuptypmod;
392397

393398
dtup = (HeapTupleHeader) palloc(tup->t_len);
394399
memcpy((char *) dtup, (char *) tup->t_data, tup->t_len);
395400

396401
/*
397-
* For RECORD results, make sure a typmod has been assigned.
402+
* Use the declared return type if it's not RECORD; else take
403+
* the type from the computed result, making sure a typmod has
404+
* been assigned.
398405
*/
399-
if (tupDesc->tdtypeid == RECORDOID &&
400-
tupDesc->tdtypmod < 0)
401-
assign_record_type_typmod(tupDesc);
406+
if (fcache->rettype != RECORDOID)
407+
{
408+
/* function has a named composite return type */
409+
dtuptype = fcache->rettype;
410+
dtuptypmod = -1;
411+
}
412+
else
413+
{
414+
/* function is declared to return RECORD */
415+
if (tupDesc->tdtypeid == RECORDOID &&
416+
tupDesc->tdtypmod < 0)
417+
assign_record_type_typmod(tupDesc);
418+
dtuptype = tupDesc->tdtypeid;
419+
dtuptypmod = tupDesc->tdtypmod;
420+
}
402421

403422
HeapTupleHeaderSetDatumLength(dtup, tup->t_len);
404-
HeapTupleHeaderSetTypeId(dtup, tupDesc->tdtypeid);
405-
HeapTupleHeaderSetTypMod(dtup, tupDesc->tdtypmod);
423+
HeapTupleHeaderSetTypeId(dtup, dtuptype);
424+
HeapTupleHeaderSetTypMod(dtup, dtuptypmod);
406425

407426
value = PointerGetDatum(dtup);
408427
fcinfo->isnull = false;

0 commit comments

Comments
 (0)