Skip to content

Commit 83b72ee

Browse files
committed
ParseComplexProjection should make use of expandRecordVariable so that
it can handle cases like (foo.x).y where foo is a subquery and x is a function-returning-RECORD RTE in that subquery.
1 parent 12a323b commit 83b72ee

File tree

3 files changed

+20
-10
lines changed

3 files changed

+20
-10
lines changed

src/backend/parser/parse_func.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.179 2005/04/23 22:09:58 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.180 2005/05/31 01:03:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -25,6 +25,7 @@
2525
#include "parser/parse_expr.h"
2626
#include "parser/parse_func.h"
2727
#include "parser/parse_relation.h"
28+
#include "parser/parse_target.h"
2829
#include "parser/parse_type.h"
2930
#include "utils/builtins.h"
3031
#include "utils/fmgroids.h"
@@ -957,6 +958,9 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
957958
* function. A bonus is that we avoid generating an unnecessary
958959
* FieldSelect; our result can omit the whole-row Var and just be a
959960
* Var for the selected field.
961+
*
962+
* This case could be handled by expandRecordVariable, but it's
963+
* more efficient to do it this way when possible.
960964
*/
961965
if (IsA(first_arg, Var) &&
962966
((Var *) first_arg)->varattno == InvalidAttrNumber)
@@ -971,12 +975,18 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
971975
}
972976

973977
/*
974-
* Else do it the hard way. Note that if the arg is of RECORD type,
975-
* and isn't resolvable as a function with OUT params, we will never
976-
* be able to recognize a column name here.
978+
* Else do it the hard way with get_expr_result_type().
979+
*
980+
* If it's a Var of type RECORD, we have to work even harder: we have
981+
* to find what the Var refers to, and pass that to get_expr_result_type.
982+
* That task is handled by expandRecordVariable().
977983
*/
978-
if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
984+
if (IsA(first_arg, Var) &&
985+
((Var *) first_arg)->vartype == RECORDOID)
986+
tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
987+
else if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
979988
return NULL; /* unresolvable RECORD type */
989+
Assert(tupdesc);
980990

981991
for (i = 0; i < tupdesc->natts; i++)
982992
{

src/backend/parser/parse_target.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.133 2005/04/25 22:02:30 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.134 2005/05/31 01:03:23 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -44,8 +44,6 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
4444
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
4545
static List *ExpandAllTables(ParseState *pstate);
4646
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
47-
static TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
48-
int levelsup);
4947
static int FigureColnameInternal(Node *node, char **name);
5048

5149

@@ -905,7 +903,7 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
905903
*
906904
* levelsup is an extra offset to interpret the Var's varlevelsup correctly.
907905
*/
908-
static TupleDesc
906+
TupleDesc
909907
expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
910908
{
911909
TupleDesc tupleDesc;

src/include/parser/parse_target.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.35 2004/12/31 22:03:38 pgsql Exp $
10+
* $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.36 2005/05/31 01:03:23 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -27,6 +27,8 @@ extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
2727
List *indirection);
2828
extern List *checkInsertTargets(ParseState *pstate, List *cols,
2929
List **attrnos);
30+
extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
31+
int levelsup);
3032
extern char *FigureColname(Node *node);
3133

3234
#endif /* PARSE_TARGET_H */

0 commit comments

Comments
 (0)