aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_target.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r--src/backend/parser/parse_target.c72
1 files changed, 50 insertions, 22 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 86670d26794..859de3b10c6 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.143 2006/06/16 18:42:22 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/parse_target.c,v 1.144 2006/06/26 17:24:41 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -42,9 +42,7 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
ListCell *indirection,
Node *rhs,
int location);
-static List *ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref);
static List *ExpandAllTables(ParseState *pstate);
-static List *ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind);
static int FigureColnameInternal(Node *node, char **name);
@@ -117,7 +115,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
{
/* It is something.*, expand into multiple items */
p_target = list_concat(p_target,
- ExpandColumnRefStar(pstate, cref));
+ ExpandColumnRefStar(pstate, cref,
+ true));
continue;
}
}
@@ -131,7 +130,8 @@ transformTargetList(ParseState *pstate, List *targetlist)
{
/* It is something.*, expand into multiple items */
p_target = list_concat(p_target,
- ExpandIndirectionStar(pstate, ind));
+ ExpandIndirectionStar(pstate, ind,
+ true));
continue;
}
}
@@ -696,13 +696,16 @@ checkInsertTargets(ParseState *pstate, List *cols, List **attrnos)
/*
* ExpandColumnRefStar()
- * Turns foo.* (in the target list) into a list of targetlist entries.
+ * Transforms foo.* into a list of expressions or targetlist entries.
*
* This handles the case where '*' appears as the last or only name in a
- * ColumnRef.
+ * ColumnRef. The code is shared between the case of foo.* at the top level
+ * in a SELECT target list (where we want TargetEntry nodes in the result)
+ * and foo.* in a ROW() construct (where we want just bare expressions).
*/
-static List *
-ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
+List *
+ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref,
+ bool targetlist)
{
List *fields = cref->fields;
int numnames = list_length(fields);
@@ -713,7 +716,12 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
* Target item is a bare '*', expand all tables
*
* (e.g., SELECT * FROM emp, dept)
+ *
+ * Since the grammar only accepts bare '*' at top level of SELECT,
+ * we need not handle the targetlist==false case here.
*/
+ Assert(targetlist);
+
return ExpandAllTables(pstate);
}
else
@@ -775,13 +783,22 @@ ExpandColumnRefStar(ParseState *pstate, ColumnRef *cref)
rtindex = RTERangeTablePosn(pstate, rte, &sublevels_up);
- return expandRelAttrs(pstate, rte, rtindex, sublevels_up);
+ if (targetlist)
+ return expandRelAttrs(pstate, rte, rtindex, sublevels_up);
+ else
+ {
+ List *vars;
+
+ expandRTE(rte, rtindex, sublevels_up, false,
+ NULL, &vars);
+ return vars;
+ }
}
}
/*
* ExpandAllTables()
- * Turns '*' (in the target list) into a list of targetlist entries.
+ * Transforms '*' (in the target list) into a list of targetlist entries.
*
* tlist entries are generated for each relation appearing in the query's
* varnamespace. We do not consider relnamespace because that would include
@@ -814,18 +831,22 @@ ExpandAllTables(ParseState *pstate)
/*
* ExpandIndirectionStar()
- * Turns foo.* (in the target list) into a list of targetlist entries.
+ * Transforms foo.* into a list of expressions or targetlist entries.
*
* This handles the case where '*' appears as the last item in A_Indirection.
+ * The code is shared between the case of foo.* at the top level in a SELECT
+ * target list (where we want TargetEntry nodes in the result) and foo.* in
+ * a ROW() construct (where we want just bare expressions).
*/
-static List *
-ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
+List *
+ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind,
+ bool targetlist)
{
+ List *result = NIL;
Node *expr;
TupleDesc tupleDesc;
int numAttrs;
int i;
- List *te_list = NIL;
/* Strip off the '*' to create a reference to the rowtype object */
ind = copyObject(ind);
@@ -860,7 +881,6 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
{
Form_pg_attribute att = tupleDesc->attrs[i];
Node *fieldnode;
- TargetEntry *te;
if (att->attisdropped)
continue;
@@ -893,14 +913,22 @@ ExpandIndirectionStar(ParseState *pstate, A_Indirection *ind)
fieldnode = (Node *) fselect;
}
- te = makeTargetEntry((Expr *) fieldnode,
- (AttrNumber) pstate->p_next_resno++,
- pstrdup(NameStr(att->attname)),
- false);
- te_list = lappend(te_list, te);
+ if (targetlist)
+ {
+ /* add TargetEntry decoration */
+ TargetEntry *te;
+
+ te = makeTargetEntry((Expr *) fieldnode,
+ (AttrNumber) pstate->p_next_resno++,
+ pstrdup(NameStr(att->attname)),
+ false);
+ result = lappend(result, te);
+ }
+ else
+ result = lappend(result, fieldnode);
}
- return te_list;
+ return result;
}
/*