提交 473165af 编写于 作者: T Tom Lane

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.
上级 93a1fce5
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 ...@@ -58,9 +58,10 @@ typedef struct local_es
*/ */
typedef struct typedef struct
{ {
Oid rettype; /* actual return type */
int typlen; /* length of the return type */ int typlen; /* length of the return type */
bool typbyval; /* true if return type is pass by value */ 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 */ bool shutdown_reg; /* true if registered shutdown callback */
ParamListInfo paramLI; /* Param list representing current args */ ParamListInfo paramLI; /* Param list representing current args */
...@@ -167,6 +168,8 @@ init_sql_fcache(FmgrInfo *finfo) ...@@ -167,6 +168,8 @@ init_sql_fcache(FmgrInfo *finfo)
format_type_be(procedureStruct->prorettype)))); format_type_be(procedureStruct->prorettype))));
} }
fcache->rettype = rettype;
/* Now look up the actual result type */ /* Now look up the actual result type */
typeTuple = SearchSysCache(TYPEOID, typeTuple = SearchSysCache(TYPEOID,
ObjectIdGetDatum(rettype), ObjectIdGetDatum(rettype),
...@@ -389,20 +392,36 @@ postquel_execute(execution_state *es, ...@@ -389,20 +392,36 @@ postquel_execute(execution_state *es,
* Probably OK to leave them, as long as they are at the end. * Probably OK to leave them, as long as they are at the end.
*/ */
HeapTupleHeader dtup; HeapTupleHeader dtup;
Oid dtuptype;
int32 dtuptypmod;
dtup = (HeapTupleHeader) palloc(tup->t_len); dtup = (HeapTupleHeader) palloc(tup->t_len);
memcpy((char *) dtup, (char *) tup->t_data, 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 && if (fcache->rettype != RECORDOID)
tupDesc->tdtypmod < 0) {
assign_record_type_typmod(tupDesc); /* 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); HeapTupleHeaderSetDatumLength(dtup, tup->t_len);
HeapTupleHeaderSetTypeId(dtup, tupDesc->tdtypeid); HeapTupleHeaderSetTypeId(dtup, dtuptype);
HeapTupleHeaderSetTypMod(dtup, tupDesc->tdtypmod); HeapTupleHeaderSetTypMod(dtup, dtuptypmod);
value = PointerGetDatum(dtup); value = PointerGetDatum(dtup);
fcinfo->isnull = false; fcinfo->isnull = false;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册