get_expr_result_type has to be prepared to pull type information
authorTom Lane <[email protected]>
Sat, 28 May 2005 05:10:47 +0000 (05:10 +0000)
committerTom Lane <[email protected]>
Sat, 28 May 2005 05:10:47 +0000 (05:10 +0000)
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.

src/backend/utils/fmgr/funcapi.c

index 300a20e94ddbd28366da2fd2ac65df79ebc3a121..01cf28754ab400022c2b02526e146cbb33a9b93a 100644 (file)
@@ -235,6 +235,36 @@ get_expr_result_type(Node *expr,
                                                                                  NULL,
                                                                                  resultTypeId,
                                                                                  resultTupleDesc);
+       else if (expr && IsA(expr, Const) &&
+                        ((Const *) expr)->consttype == RECORDOID &&
+                        !((Const *) expr)->constisnull)
+       {
+               /*
+                * Pull embedded type info from a RECORD constant.  We have to be
+                * prepared to handle this case in the wake of constant-folding of
+                * record-returning functions.
+                */
+               HeapTupleHeader td;
+               int32   typmod;
+
+               td = DatumGetHeapTupleHeader(((Const *) expr)->constvalue);
+               Assert(HeapTupleHeaderGetTypeId(td) == RECORDOID);
+               typmod = HeapTupleHeaderGetTypMod(td);
+               if (resultTypeId)
+                       *resultTypeId = RECORDOID;
+               if (typmod >= 0)
+               {
+                       if (resultTupleDesc)
+                               *resultTupleDesc = lookup_rowtype_tupdesc(RECORDOID, typmod);
+                       result = TYPEFUNC_COMPOSITE;
+               }
+               else
+               {
+                       if (resultTupleDesc)
+                               *resultTupleDesc = NULL;
+                       result = TYPEFUNC_RECORD;
+               }
+       }
        else
        {
                /* handle as a generic expression; no chance to resolve RECORD */