aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-05-31 01:03:23 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-05-31 01:03:23 +0000
commit83b72ee286764e20c3f1c8c418780bab50ff6c29 (patch)
tree3b245169d7a3826510d8cd55c8c7ab749c520e02 /src
parent12a323b7a8d430e9bddae7c0155239d7a5790afc (diff)
downloadpostgresql-83b72ee286764e20c3f1c8c418780bab50ff6c29.tar.gz
postgresql-83b72ee286764e20c3f1c8c418780bab50ff6c29.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/parse_func.c20
-rw-r--r--src/backend/parser/parse_target.c6
-rw-r--r--src/include/parser/parse_target.h4
3 files changed, 20 insertions, 10 deletions
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 002e15a9fa2..e585e6df716 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.179 2005/04/23 22:09:58 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_func.c,v 1.180 2005/05/31 01:03:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -25,6 +25,7 @@
#include "parser/parse_expr.h"
#include "parser/parse_func.h"
#include "parser/parse_relation.h"
+#include "parser/parse_target.h"
#include "parser/parse_type.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
@@ -957,6 +958,9 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
* function. A bonus is that we avoid generating an unnecessary
* FieldSelect; our result can omit the whole-row Var and just be a
* Var for the selected field.
+ *
+ * This case could be handled by expandRecordVariable, but it's
+ * more efficient to do it this way when possible.
*/
if (IsA(first_arg, Var) &&
((Var *) first_arg)->varattno == InvalidAttrNumber)
@@ -971,12 +975,18 @@ ParseComplexProjection(ParseState *pstate, char *funcname, Node *first_arg)
}
/*
- * Else do it the hard way. Note that if the arg is of RECORD type,
- * and isn't resolvable as a function with OUT params, we will never
- * be able to recognize a column name here.
+ * Else do it the hard way with get_expr_result_type().
+ *
+ * If it's a Var of type RECORD, we have to work even harder: we have
+ * to find what the Var refers to, and pass that to get_expr_result_type.
+ * That task is handled by expandRecordVariable().
*/
- if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ if (IsA(first_arg, Var) &&
+ ((Var *) first_arg)->vartype == RECORDOID)
+ tupdesc = expandRecordVariable(pstate, (Var *) first_arg, 0);
+ else if (get_expr_result_type(first_arg, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
return NULL; /* unresolvable RECORD type */
+ Assert(tupdesc);
for (i = 0; i < tupdesc->natts; i++)
{
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index ee523be03e1..12acfb83029 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.133 2005/04/25 22:02:30 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.134 2005/05/31 01:03:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,8 +44,6 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
static List *ExpandAllTables(ParseState *pstate);
static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
-static TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
- int levelsup);
static int FigureColnameInternal(Node *node, char **name);
@@ -905,7 +903,7 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
*
* levelsup is an extra offset to interpret the Var's varlevelsup correctly.
*/
-static TupleDesc
+TupleDesc
expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
{
TupleDesc tupleDesc;
diff --git a/src/include/parser/parse_target.h b/src/include/parser/parse_target.h
index 30abd52c1a0..35c2a41baf0 100644
--- a/src/include/parser/parse_target.h
+++ b/src/include/parser/parse_target.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.35 2004/12/31 22:03:38 pgsql Exp $
+ * $PostgreSQL: pgsql/src/include/parser/parse_target.h,v 1.36 2005/05/31 01:03:23 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -27,6 +27,8 @@ extern void updateTargetListEntry(ParseState *pstate, TargetEntry *tle,
List *indirection);
extern List *checkInsertTargets(ParseState *pstate, List *cols,
List **attrnos);
+extern TupleDesc expandRecordVariable(ParseState *pstate, Var *var,
+ int levelsup);
extern char *FigureColname(Node *node);
#endif /* PARSE_TARGET_H */