]> granicus.if.org Git - postgresql/commitdiff
ParseComplexProjection should make use of expandRecordVariable so that
authorTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2005 01:03:23 +0000 (01:03 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Tue, 31 May 2005 01:03:23 +0000 (01:03 +0000)
it can handle cases like (foo.x).y where foo is a subquery and x is
a function-returning-RECORD RTE in that subquery.

src/backend/parser/parse_func.c
src/backend/parser/parse_target.c
src/include/parser/parse_target.h

index 002e15a9fa203c6c566e768133f7480d713f94a8..e585e6df716b31a89595a58ec1c8ff01a51ca07b 100644 (file)
@@ -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++)
        {
index ee523be03e1098e627407a7c2719841ea64863a6..12acfb830290186afd4d31c2a65e4e0fe91c62cb 100644 (file)
@@ -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;
index 30abd52c1a02c6b33f1960acce750a4fda950b3e..35c2a41baf04e918e81dbc2319b0ad54da8e2cbd 100644 (file)
@@ -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 */