|
8 | 8 | *
|
9 | 9 | *
|
10 | 10 | * 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 $ |
12 | 12 | *
|
13 | 13 | *-------------------------------------------------------------------------
|
14 | 14 | */
|
@@ -58,9 +58,10 @@ typedef struct local_es
|
58 | 58 | */
|
59 | 59 | typedefstruct
|
60 | 60 | {
|
| 61 | +Oidrettype;/* actual return type */ |
61 | 62 | inttyplen;/* length of the return type */
|
62 | 63 | booltypbyval;/* true if return type is pass by value */
|
63 |
| -boolreturnsTuple;/* true ifreturn type is atuple */ |
| 64 | +boolreturnsTuple;/* true ifreturning wholetuple result */ |
64 | 65 | boolshutdown_reg;/* true if registered shutdown callback */
|
65 | 66 |
|
66 | 67 | ParamListInfoparamLI;/* Param list representing current args */
|
@@ -167,6 +168,8 @@ init_sql_fcache(FmgrInfo *finfo)
|
167 | 168 | format_type_be(procedureStruct->prorettype))));
|
168 | 169 | }
|
169 | 170 |
|
| 171 | +fcache->rettype=rettype; |
| 172 | + |
170 | 173 | /* Now look up the actual result type */
|
171 | 174 | typeTuple=SearchSysCache(TYPEOID,
|
172 | 175 | ObjectIdGetDatum(rettype),
|
@@ -389,20 +392,36 @@ postquel_execute(execution_state *es,
|
389 | 392 | * Probably OK to leave them, as long as they are at the end.
|
390 | 393 | */
|
391 | 394 | HeapTupleHeaderdtup;
|
| 395 | +Oiddtuptype; |
| 396 | +int32dtuptypmod; |
392 | 397 |
|
393 | 398 | dtup= (HeapTupleHeader)palloc(tup->t_len);
|
394 | 399 | memcpy((char*)dtup, (char*)tup->t_data,tup->t_len);
|
395 | 400 |
|
396 | 401 | /*
|
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. |
398 | 405 | */
|
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 | +} |
402 | 421 |
|
403 | 422 | HeapTupleHeaderSetDatumLength(dtup,tup->t_len);
|
404 |
| -HeapTupleHeaderSetTypeId(dtup,tupDesc->tdtypeid); |
405 |
| -HeapTupleHeaderSetTypMod(dtup,tupDesc->tdtypmod); |
| 423 | +HeapTupleHeaderSetTypeId(dtup,dtuptype); |
| 424 | +HeapTupleHeaderSetTypMod(dtup,dtuptypmod); |
406 | 425 |
|
407 | 426 | value=PointerGetDatum(dtup);
|
408 | 427 | fcinfo->isnull= false;
|
|