From 473165aff84506f013d5cb34187216c9c254c0b9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 15 Jul 2004 13:51:38 +0000 Subject: [PATCH] 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. --- src/backend/executor/functions.c | 35 ++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 9ddf619277..0073f8f55c 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -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; -- GitLab