@@ -48,7 +48,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate,
4848static List * ExpandColumnRefStar (ParseState * pstate , ColumnRef * cref ,
4949 bool make_target_entry );
5050static List * ExpandAllTables (ParseState * pstate , int location );
51- static List * ExpandIndirectionStar (ParseState * pstate , A_Indirection * ind ,
51+ static Node * ExpandIndirectionStar (ParseState * pstate , A_Indirection * ind ,
5252 bool make_target_entry , ParseExprKind exprKind );
5353static List * ExpandSingleTable (ParseState * pstate , ParseNamespaceItem * nsitem ,
5454 int sublevels_up , int location ,
@@ -134,6 +134,7 @@ transformTargetList(ParseState *pstate, List *targetlist,
134134 foreach (o_target , targetlist )
135135 {
136136 ResTarget * res = (ResTarget * ) lfirst (o_target );
137+ Node * transformed = NULL ;
137138
138139 /*
139140 * Check for "something.*". Depending on the complexity of the
@@ -162,13 +163,19 @@ transformTargetList(ParseState *pstate, List *targetlist,
162163
163164 if (IsA (llast (ind -> indirection ), A_Star ))
164165 {
165- /* It is something.*, expand into multiple items */
166- p_target = list_concat (p_target ,
167- ExpandIndirectionStar (pstate ,
168- ind ,
169- true,
170- exprKind ));
171- continue ;
166+ Node * columns = ExpandIndirectionStar (pstate ,
167+ ind ,
168+ true,
169+ exprKind );
170+
171+ if (IsA (columns , List ))
172+ {
173+ /* It is something.*, expand into multiple items */
174+ p_target = list_concat (p_target , (List * ) columns );
175+ continue ;
176+ }
177+
178+ transformed = (Node * ) columns ;
172179 }
173180 }
174181 }
@@ -180,7 +187,7 @@ transformTargetList(ParseState *pstate, List *targetlist,
180187 p_target = lappend (p_target ,
181188 transformTargetEntry (pstate ,
182189 res -> val ,
183- NULL ,
190+ transformed ,
184191 exprKind ,
185192 res -> name ,
186193 false));
@@ -251,10 +258,15 @@ transformExpressionList(ParseState *pstate, List *exprlist,
251258
252259 if (IsA (llast (ind -> indirection ), A_Star ))
253260 {
254- /* It is something.*, expand into multiple items */
255- result = list_concat (result ,
256- ExpandIndirectionStar (pstate , ind ,
257- false, exprKind ));
261+ Node * cols = ExpandIndirectionStar (pstate , ind ,
262+ false, exprKind );
263+
264+ if (!cols || IsA (cols , List ))
265+ /* It is something.*, expand into multiple items */
266+ result = list_concat (result , (List * ) cols );
267+ else
268+ result = lappend (result , cols );
269+
258270 continue ;
259271 }
260272 }
@@ -1345,22 +1357,30 @@ ExpandAllTables(ParseState *pstate, int location)
13451357 * For robustness, we use a separate "make_target_entry" flag to control
13461358 * this rather than relying on exprKind.
13471359 */
1348- static List *
1360+ static Node *
13491361ExpandIndirectionStar (ParseState * pstate , A_Indirection * ind ,
13501362 bool make_target_entry , ParseExprKind exprKind )
13511363{
13521364 Node * expr ;
1365+ ParseExprKind sv_expr_kind ;
1366+ bool trailing_star_expansion = false;
1367+
1368+ /* Save and restore identity of expression type we're parsing */
1369+ Assert (exprKind != EXPR_KIND_NONE );
1370+ sv_expr_kind = pstate -> p_expr_kind ;
1371+ pstate -> p_expr_kind = exprKind ;
13531372
13541373 /* Strip off the '*' to create a reference to the rowtype object */
1355- ind = copyObject ( ind );
1356- ind -> indirection = list_truncate ( ind -> indirection ,
1357- list_length ( ind -> indirection ) - 1 ) ;
1374+ expr = transformIndirection ( pstate , ind , & trailing_star_expansion );
1375+
1376+ pstate -> p_expr_kind = sv_expr_kind ;
13581377
1359- /* And transform that */
1360- expr = transformExpr (pstate , (Node * ) ind , exprKind );
1378+ /* '*' was consumed by generic type subscripting */
1379+ if (!trailing_star_expansion )
1380+ return expr ;
13611381
13621382 /* Expand the rowtype expression into individual fields */
1363- return ExpandRowReference (pstate , expr , make_target_entry );
1383+ return ( Node * ) ExpandRowReference (pstate , expr , make_target_entry );
13641384}
13651385
13661386/*
@@ -1785,13 +1805,18 @@ FigureColnameInternal(Node *node, char **name)
17851805 char * fname = NULL ;
17861806 ListCell * l ;
17871807
1788- /* find last field name, if any, ignoring "*" and subscripts */
1808+ /*
1809+ * find last field name, if any, ignoring subscripts, and use
1810+ * '?column?' when there's a trailing '*'.
1811+ */
17891812 foreach (l , ind -> indirection )
17901813 {
17911814 Node * i = lfirst (l );
17921815
17931816 if (IsA (i , String ))
17941817 fname = strVal (i );
1818+ else if (IsA (i , A_Star ))
1819+ fname = "?column?" ;
17951820 }
17961821 if (fname )
17971822 {
0 commit comments