Skip to content

Commit 6d9ee03

Browse files
committed
get_expr_result_type has to be prepared to pull type information
from a RECORD Const node, because that's what it may be faced with after constant-folding of a function returning RECORD. Per example from Michael Fuhr.
1 parent 70f3204 commit 6d9ee03

File tree

1 file changed

+31
-1
lines changed

1 file changed

+31
-1
lines changed

src/backend/utils/fmgr/funcapi.c

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Copyright (c) 2002-2005, PostgreSQL Global Development Group
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.21 2005/04/25 20:59:44 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.22 2005/05/28 05:10:47 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -235,6 +235,36 @@ get_expr_result_type(Node *expr,
235235
NULL,
236236
resultTypeId,
237237
resultTupleDesc);
238+
else if (expr && IsA(expr, Const) &&
239+
((Const *) expr)->consttype == RECORDOID &&
240+
!((Const *) expr)->constisnull)
241+
{
242+
/*
243+
* Pull embedded type info from a RECORD constant. We have to be
244+
* prepared to handle this case in the wake of constant-folding of
245+
* record-returning functions.
246+
*/
247+
HeapTupleHeader td;
248+
int32 typmod;
249+
250+
td = DatumGetHeapTupleHeader(((Const *) expr)->constvalue);
251+
Assert(HeapTupleHeaderGetTypeId(td) == RECORDOID);
252+
typmod = HeapTupleHeaderGetTypMod(td);
253+
if (resultTypeId)
254+
*resultTypeId = RECORDOID;
255+
if (typmod >= 0)
256+
{
257+
if (resultTupleDesc)
258+
*resultTupleDesc = lookup_rowtype_tupdesc(RECORDOID, typmod);
259+
result = TYPEFUNC_COMPOSITE;
260+
}
261+
else
262+
{
263+
if (resultTupleDesc)
264+
*resultTupleDesc = NULL;
265+
result = TYPEFUNC_RECORD;
266+
}
267+
}
238268
else
239269
{
240270
/* handle as a generic expression; no chance to resolve RECORD */

0 commit comments

Comments
 (0)