88 *
99 *
1010 * IDENTIFICATION
11- * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.132 2005/04/2521:03:25 tgl Exp $
11+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.133 2005/04/2522:02:30 tgl Exp $
1212 *
1313 *-------------------------------------------------------------------------
1414 */
@@ -204,8 +204,9 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
204204tle -> resorigcol = attnum ;
205205break ;
206206case RTE_SUBQUERY :
207+ /* Subselect-in-FROM: copy up from the subselect */
208+ if (attnum != InvalidAttrNumber )
207209{
208- /* Subselect-in-FROM: copy up from the subselect */
209210TargetEntry * ste = get_tle_by_resno (rte -> subquery -> targetList ,
210211attnum );
211212
@@ -217,8 +218,9 @@ markTargetListOrigin(ParseState *pstate, TargetEntry *tle,
217218}
218219break ;
219220case RTE_JOIN :
221+ /* Join RTE --- recursively inspect the alias variable */
222+ if (attnum != InvalidAttrNumber )
220223{
221- /* Join RTE --- recursively inspect the alias variable */
222224Var * aliasvar ;
223225
224226Assert (attnum > 0 && attnum <=list_length (rte -> joinaliasvars ));
@@ -920,17 +922,47 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
920922rte = GetRTEByRangeTablePosn (pstate ,var -> varno ,netlevelsup );
921923attnum = var -> varattno ;
922924
925+ if (attnum == InvalidAttrNumber )
926+ {
927+ /* Whole-row reference to an RTE, so expand the known fields */
928+ List * names ,
929+ * vars ;
930+ ListCell * lname ,
931+ * lvar ;
932+ int i ;
933+
934+ expandRTE (GetLevelNRangeTable (pstate ,netlevelsup ),
935+ var -> varno ,0 , false,& names ,& vars );
936+
937+ tupleDesc = CreateTemplateTupleDesc (list_length (vars ), false);
938+ i = 1 ;
939+ forboth (lname ,names ,lvar ,vars )
940+ {
941+ char * label = strVal (lfirst (lname ));
942+ Node * varnode = (Node * )lfirst (lvar );
943+
944+ TupleDescInitEntry (tupleDesc ,i ,
945+ label ,
946+ exprType (varnode ),
947+ exprTypmod (varnode ),
948+ 0 );
949+ i ++ ;
950+ }
951+ Assert (lname == NULL && lvar == NULL );/* lists same length? */
952+
953+ return tupleDesc ;
954+ }
955+
923956expr = (Node * )var ;/* default if we can't drill down */
924957
925958switch (rte -> rtekind )
926959{
927960case RTE_RELATION :
928961case RTE_SPECIAL :
929962/*
930- * This case should not occur: a whole-row Var should have the
931- * table's named rowtype, and a column of a table shouldn't have
932- * type RECORD either. Fall through and fail (most likely)
933- * at the bottom.
963+ * This case should not occur: a column of a table shouldn't have
964+ * type RECORD. Fall through and fail (most likely) at the
965+ * bottom.
934966 */
935967break ;
936968case RTE_SUBQUERY :
@@ -963,49 +995,18 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
963995}
964996break ;
965997case RTE_JOIN :
966- /* Join RTE */
967- if (attnum == InvalidAttrNumber )
968- {
969- /* Whole-row reference to join, so expand the fields */
970- List * names ,
971- * vars ;
972- ListCell * lname ,
973- * lvar ;
974- int i ;
975-
976- expandRTE (GetLevelNRangeTable (pstate ,netlevelsup ),
977- var -> varno ,0 , false,& names ,& vars );
978-
979- tupleDesc = CreateTemplateTupleDesc (list_length (vars ), false);
980- i = 1 ;
981- forboth (lname ,names ,lvar ,vars )
982- {
983- char * label = strVal (lfirst (lname ));
984- Node * varnode = (Node * )lfirst (lvar );
985-
986- TupleDescInitEntry (tupleDesc ,i ,
987- label ,
988- exprType (varnode ),
989- exprTypmod (varnode ),
990- 0 );
991- i ++ ;
992- }
993- Assert (lname == NULL && lvar == NULL );/* lists same len? */
994- return tupleDesc ;
995- }
996- /* Else recursively inspect the alias variable */
998+ /* Join RTE --- recursively inspect the alias variable */
997999Assert (attnum > 0 && attnum <=list_length (rte -> joinaliasvars ));
9981000expr = (Node * )list_nth (rte -> joinaliasvars ,attnum - 1 );
9991001if (IsA (expr ,Var ))
10001002return expandRecordVariable (pstate , (Var * )expr ,netlevelsup );
10011003/* else fall through to inspect the expression */
10021004break ;
10031005case RTE_FUNCTION :
1004- expr = rte -> funcexpr ;
1005- /* The func expr probably can't be a Var, but check */
1006- if (IsA (expr ,Var ))
1007- return expandRecordVariable (pstate , (Var * )expr ,netlevelsup );
1008- /* else fall through to inspect the expression */
1006+ /*
1007+ * We couldn't get here unless a function is declared with one
1008+ * of its result columns as RECORD, which is not allowed.
1009+ */
10091010break ;
10101011}
10111012