]> granicus.if.org Git - postgresql/commitdiff
get_expr_result_type has to be prepared to pull type information
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 28 May 2005 05:10:47 +0000 (05:10 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
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 3310c9b026afdf8b8250e13d9a8e3d30be1f57f0..3ecb59eec8eada76e6398edf15a64f8b67588a95 100644 (file)
@@ -7,7 +7,7 @@
  * Copyright (c) 2002-2005, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.21 2005/04/25 20:59:44 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/fmgr/funcapi.c,v 1.22 2005/05/28 05:10:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -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 */