/*
* If it's a RowExpr that was expanded from a whole-row Var, use the
- * column names attached to it.
+ * column names attached to it. (We could let get_expr_result_tupdesc()
+ * handle this, but it's much cheaper to just pull out the name we need.)
*/
if (IsA(var, RowExpr))
{
*resultTupleDesc = BlessTupleDesc(tupdesc);
return TYPEFUNC_COMPOSITE;
}
+ else if (expr && IsA(expr, Const) &&
+ ((Const *) expr)->consttype == RECORDOID &&
+ !((Const *) expr)->constisnull)
+ {
+ /*
+ * When EXPLAIN'ing some queries with SEARCH/CYCLE clauses, we may
+ * need to resolve field names of a RECORD-type Const. The datum
+ * should contain a typmod that will tell us that.
+ */
+ HeapTupleHeader rec;
+ Oid tupType;
+ int32 tupTypmod;
+
+ rec = DatumGetHeapTupleHeader(((Const *) expr)->constvalue);
+ tupType = HeapTupleHeaderGetTypeId(rec);
+ tupTypmod = HeapTupleHeaderGetTypMod(rec);
+ if (resultTypeId)
+ *resultTypeId = tupType;
+ if (tupType != RECORDOID || tupTypmod >= 0)
+ {
+ /* Should be able to look it up */
+ if (resultTupleDesc)
+ *resultTupleDesc = lookup_rowtype_tupdesc_copy(tupType,
+ tupTypmod);
+ return TYPEFUNC_COMPOSITE;
+ }
+ else
+ {
+ /* This shouldn't really happen ... */
+ if (resultTupleDesc)
+ *resultTupleDesc = NULL;
+ return TYPEFUNC_RECORD;
+ }
+ }
else
{
/* handle as a generic expression; no chance to resolve RECORD */