Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit2f02d4a

Browse files
committed
Allow extracting fields from a ROW() expression in more cases.
Teach get_expr_result_type() to manufacture a tuple descriptor directlyfrom a RowExpr node. If the RowExpr has type RECORD, this is the onlyway to get a tupdesc for its result, since even if the rowtype has beenblessed, we don't have its typmod available at this point. (If theRowExpr has some named composite type, we continue to let the existingcode handle it, since the RowExpr might well not have the correct columnnames embedded in it.)This fixes assorted corner cases illustrated by the added regressiontests.This is a back-patch of the v13-era commit8b7a0f1 into previousbranches. At the time I'd judged it not important enough to back-patch,but the upcoming fix for bug #18077 includes a test case that dependson this working correctly; and8b7a0f1 has now aged long enough tohave good confidence that it won't break anything.Discussion:https://postgr.es/m/10872.1572202006@sss.pgh.pa.usDiscussion:https://postgr.es/m/3607145.1694803130@sss.pgh.pa.us
1 parent50d44c1 commit2f02d4a

File tree

3 files changed

+80
-0
lines changed

3 files changed

+80
-0
lines changed

‎src/backend/utils/fmgr/funcapi.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,38 @@ get_expr_result_type(Node *expr,
236236
NULL,
237237
resultTypeId,
238238
resultTupleDesc);
239+
elseif (expr&&IsA(expr,RowExpr)&&
240+
((RowExpr*)expr)->row_typeid==RECORDOID)
241+
{
242+
/* We can resolve the record type by generating the tupdesc directly */
243+
RowExpr*rexpr= (RowExpr*)expr;
244+
TupleDesctupdesc;
245+
AttrNumberi=1;
246+
ListCell*lcc,
247+
*lcn;
248+
249+
tupdesc=CreateTemplateTupleDesc(list_length(rexpr->args));
250+
Assert(list_length(rexpr->args)==list_length(rexpr->colnames));
251+
forboth(lcc,rexpr->args,lcn,rexpr->colnames)
252+
{
253+
Node*col= (Node*)lfirst(lcc);
254+
char*colname=strVal(lfirst(lcn));
255+
256+
TupleDescInitEntry(tupdesc,i,
257+
colname,
258+
exprType(col),
259+
exprTypmod(col),
260+
0);
261+
TupleDescInitEntryCollation(tupdesc,i,
262+
exprCollation(col));
263+
i++;
264+
}
265+
if (resultTypeId)
266+
*resultTypeId=rexpr->row_typeid;
267+
if (resultTupleDesc)
268+
*resultTupleDesc=BlessTupleDesc(tupdesc);
269+
returnTYPEFUNC_COMPOSITE;
270+
}
239271
else
240272
{
241273
/* handle as a generic expression; no chance to resolve RECORD */

‎src/test/regress/expected/rowtypes.out

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,45 @@ where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)');
445445
4567890123456789 | 123
446446
(2 rows)
447447

448+
-- Check ability to select columns from an anonymous rowtype
449+
select (row(1, 2.0)).f1;
450+
f1
451+
----
452+
1
453+
(1 row)
454+
455+
select (row(1, 2.0)).f2;
456+
f2
457+
-----
458+
2.0
459+
(1 row)
460+
461+
select (row(1, 2.0)).nosuch; -- fail
462+
ERROR: could not identify column "nosuch" in record data type
463+
LINE 1: select (row(1, 2.0)).nosuch;
464+
^
465+
select (row(1, 2.0)).*;
466+
f1 | f2
467+
----+-----
468+
1 | 2.0
469+
(1 row)
470+
471+
select (r).f1 from (select row(1, 2.0) as r) ss;
472+
f1
473+
----
474+
1
475+
(1 row)
476+
477+
select (r).f3 from (select row(1, 2.0) as r) ss; -- fail
478+
ERROR: could not identify column "f3" in record data type
479+
LINE 1: select (r).f3 from (select row(1, 2.0) as r) ss;
480+
^
481+
select (r).* from (select row(1, 2.0) as r) ss;
482+
f1 | f2
483+
----+-----
484+
1 | 2.0
485+
(1 row)
486+
448487
-- Check some corner cases involving empty rowtypes
449488
select ROW();
450489
row

‎src/test/regress/sql/rowtypes.sql

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,15 @@ where i8 in (row(123,456)::int8_tbl, '(4567890123456789,123)');
176176
select*from int8_tbl i8
177177
where i8in (row(123,456)::int8_tbl,'(4567890123456789,123)');
178178

179+
-- Check ability to select columns from an anonymous rowtype
180+
select (row(1,2.0)).f1;
181+
select (row(1,2.0)).f2;
182+
select (row(1,2.0)).nosuch;-- fail
183+
select (row(1,2.0)).*;
184+
select (r).f1from (select row(1,2.0)as r) ss;
185+
select (r).f3from (select row(1,2.0)as r) ss;-- fail
186+
select (r).*from (select row(1,2.0)as r) ss;
187+
179188
-- Check some corner cases involving empty rowtypes
180189
select ROW();
181190
select ROW() ISNULL;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp