Skip to content

Commit 8a15b41

Browse files
committed
Fix get_expr_result_type() to find field names for RECORD Consts.
This is a back-patch of commit d575347 ("Fix EXPLAIN of SEARCH BREADTH FIRST with a constant initial value") into pre-v14 branches. At the time I'd thought it was not needed in branches that lack the SEARCH/CYCLE feature, but that was just a failure of imagination. It's possible to demonstrate "record type has not been registered" failures in older branches too, during deparsing of views that contain references to fields of composite constants. Back-patch only the code changes, as the test cases added by d575347 all require SEARCH/CYCLE syntax. A suitable test case will be added in the upcoming fix for bug #18077. Discussion: https://postgr.es/m/17644-3bd1f3036d6d7a16@postgresql.org Discussion: https://postgr.es/m/3607145.1694803130@sss.pgh.pa.us
1 parent 2f02d4a commit 8a15b41

File tree

2 files changed

+36
-1
lines changed

2 files changed

+36
-1
lines changed

src/backend/utils/adt/ruleutils.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7018,7 +7018,8 @@ get_name_for_var_field(Var *var, int fieldno,
70187018

70197019
/*
70207020
* If it's a RowExpr that was expanded from a whole-row Var, use the
7021-
* column names attached to it.
7021+
* column names attached to it. (We could let get_expr_result_tupdesc()
7022+
* handle this, but it's much cheaper to just pull out the name we need.)
70227023
*/
70237024
if (IsA(var, RowExpr))
70247025
{

src/backend/utils/fmgr/funcapi.c

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,40 @@ get_expr_result_type(Node *expr,
268268
*resultTupleDesc = BlessTupleDesc(tupdesc);
269269
return TYPEFUNC_COMPOSITE;
270270
}
271+
else if (expr && IsA(expr, Const) &&
272+
((Const *) expr)->consttype == RECORDOID &&
273+
!((Const *) expr)->constisnull)
274+
{
275+
/*
276+
* When EXPLAIN'ing some queries with SEARCH/CYCLE clauses, we may
277+
* need to resolve field names of a RECORD-type Const. The datum
278+
* should contain a typmod that will tell us that.
279+
*/
280+
HeapTupleHeader rec;
281+
Oid tupType;
282+
int32 tupTypmod;
283+
284+
rec = DatumGetHeapTupleHeader(((Const *) expr)->constvalue);
285+
tupType = HeapTupleHeaderGetTypeId(rec);
286+
tupTypmod = HeapTupleHeaderGetTypMod(rec);
287+
if (resultTypeId)
288+
*resultTypeId = tupType;
289+
if (tupType != RECORDOID || tupTypmod >= 0)
290+
{
291+
/* Should be able to look it up */
292+
if (resultTupleDesc)
293+
*resultTupleDesc = lookup_rowtype_tupdesc_copy(tupType,
294+
tupTypmod);
295+
return TYPEFUNC_COMPOSITE;
296+
}
297+
else
298+
{
299+
/* This shouldn't really happen ... */
300+
if (resultTupleDesc)
301+
*resultTupleDesc = NULL;
302+
return TYPEFUNC_RECORD;
303+
}
304+
}
271305
else
272306
{
273307
/* handle as a generic expression; no chance to resolve RECORD */

0 commit comments

Comments
 (0)