aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/functions.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2004-07-15 13:51:38 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2004-07-15 13:51:38 +0000
commit473165aff84506f013d5cb34187216c9c254c0b9 (patch)
treed6d30324f951323341ae089508e136b9dbb47846 /src/backend/executor/functions.c
parent93a1fce5ccd23a19b681c9804b63bc3c5423933f (diff)
downloadpostgresql-473165aff84506f013d5cb34187216c9c254c0b9.tar.gz
postgresql-473165aff84506f013d5cb34187216c9c254c0b9.zip
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.
Diffstat (limited to 'src/backend/executor/functions.c')
-rw-r--r--src/backend/executor/functions.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 9ddf6192775..0073f8f55c1 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;