mirror of
https://github.com/postgres/postgres.git
synced 2025-05-02 11:44:50 +03:00
Fix get_expr_result_type() to find field names for RECORD Consts.
This is a back-patch of commit d57534740 ("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 d57534740 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
This commit is contained in:
parent
f18efc6f2b
commit
59bc0dfe44
@ -7058,7 +7058,8 @@ get_name_for_var_field(Var *var, int fieldno,
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* If it's a RowExpr that was expanded from a whole-row Var, use the
|
* 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))
|
if (IsA(var, RowExpr))
|
||||||
{
|
{
|
||||||
|
@ -268,6 +268,40 @@ get_expr_result_type(Node *expr,
|
|||||||
*resultTupleDesc = BlessTupleDesc(tupdesc);
|
*resultTupleDesc = BlessTupleDesc(tupdesc);
|
||||||
return TYPEFUNC_COMPOSITE;
|
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
|
else
|
||||||
{
|
{
|
||||||
/* handle as a generic expression; no chance to resolve RECORD */
|
/* handle as a generic expression; no chance to resolve RECORD */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user