aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/parser/analyze.c109
1 files changed, 66 insertions, 43 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 4a8175e0cad..582747a23f4 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.350 2006/09/18 00:52:14 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/parser/analyze.c,v 1.351 2006/09/18 16:04:04 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -2093,14 +2093,6 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
/* transform targetlist */
qry->targetList = transformTargetList(pstate, stmt->targetList);
- /* handle any SELECT INTO/CREATE TABLE AS spec */
- qry->into = stmt->into;
- if (stmt->intoColNames)
- applyColumnNames(qry->targetList, stmt->intoColNames);
- qry->intoOptions = copyObject(stmt->intoOptions);
- qry->intoOnCommit = stmt->intoOnCommit;
- qry->intoTableSpaceName = stmt->intoTableSpaceName;
-
/* mark column origins */
markTargetListOrigins(pstate, qry->targetList);
@@ -2137,6 +2129,17 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
qry->limitCount = transformLimitClause(pstate, stmt->limitCount,
"LIMIT");
+ /* handle any SELECT INTO/CREATE TABLE AS spec */
+ if (stmt->into)
+ {
+ qry->into = stmt->into;
+ if (stmt->intoColNames)
+ applyColumnNames(qry->targetList, stmt->intoColNames);
+ qry->intoOptions = copyObject(stmt->intoOptions);
+ qry->intoOnCommit = stmt->intoOnCommit;
+ qry->intoTableSpaceName = stmt->intoTableSpaceName;
+ }
+
qry->rtable = pstate->p_rtable;
qry->jointree = makeFromExpr(pstate->p_joinlist, qual);
@@ -2271,6 +2274,7 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
rtr->rtindex = list_length(pstate->p_rtable);
Assert(rte == rt_fetch(rtr->rtindex, pstate->p_rtable));
pstate->p_joinlist = lappend(pstate->p_joinlist, rtr);
+ pstate->p_varnamespace = lappend(pstate->p_varnamespace, rte);
/*
* Generate a targetlist as though expanding "*"
@@ -2278,14 +2282,6 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
Assert(pstate->p_next_resno == 1);
qry->targetList = expandRelAttrs(pstate, rte, rtr->rtindex, 0);
- /* handle any CREATE TABLE AS spec */
- qry->into = stmt->into;
- if (stmt->intoColNames)
- applyColumnNames(qry->targetList, stmt->intoColNames);
- qry->intoOptions = copyObject(stmt->intoOptions);
- qry->intoOnCommit = stmt->intoOnCommit;
- qry->intoTableSpaceName = stmt->intoTableSpaceName;
-
/*
* The grammar allows attaching ORDER BY, LIMIT, and FOR UPDATE
* to a VALUES, so cope.
@@ -2305,6 +2301,17 @@ transformValuesClause(ParseState *pstate, SelectStmt *stmt)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("SELECT FOR UPDATE/SHARE cannot be applied to VALUES")));
+ /* handle any CREATE TABLE AS spec */
+ if (stmt->into)
+ {
+ qry->into = stmt->into;
+ if (stmt->intoColNames)
+ applyColumnNames(qry->targetList, stmt->intoColNames);
+ qry->intoOptions = copyObject(stmt->intoOptions);
+ qry->intoOnCommit = stmt->intoOnCommit;
+ qry->intoTableSpaceName = stmt->intoTableSpaceName;
+ }
+
/*
* There mustn't have been any table references in the expressions,
* else strange things would happen, like Cartesian products of
@@ -2360,7 +2367,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
int leftmostRTI;
Query *leftmostQuery;
SetOperationStmt *sostmt;
- List *intoColNames;
+ List *intoColNames = NIL;
List *sortClause;
Node *limitOffset;
Node *limitCount;
@@ -2391,11 +2398,14 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
leftmostSelect = leftmostSelect->larg;
Assert(leftmostSelect && IsA(leftmostSelect, SelectStmt) &&
leftmostSelect->larg == NULL);
- qry->into = leftmostSelect->into;
- intoColNames = leftmostSelect->intoColNames;
- qry->intoOptions = copyObject(leftmostSelect->intoOptions);
- qry->intoOnCommit = leftmostSelect->intoOnCommit;
- qry->intoTableSpaceName = leftmostSelect->intoTableSpaceName;
+ if (leftmostSelect->into)
+ {
+ qry->into = leftmostSelect->into;
+ intoColNames = leftmostSelect->intoColNames;
+ qry->intoOptions = copyObject(leftmostSelect->intoOptions);
+ qry->intoOnCommit = leftmostSelect->intoOnCommit;
+ qry->intoTableSpaceName = leftmostSelect->intoTableSpaceName;
+ }
/* clear this to prevent complaints in transformSetOperationTree() */
leftmostSelect->into = NULL;
@@ -2482,19 +2492,6 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
}
/*
- * Handle SELECT INTO/CREATE TABLE AS.
- *
- * Any column names from CREATE TABLE AS need to be attached to both the
- * top level and the leftmost subquery. We do not do this earlier because
- * we do *not* want the targetnames list to be affected.
- */
- if (intoColNames)
- {
- applyColumnNames(qry->targetList, intoColNames);
- applyColumnNames(leftmostQuery->targetList, intoColNames);
- }
-
- /*
* As a first step towards supporting sort clauses that are expressions
* using the output columns, generate a varnamespace entry that makes the
* output columns visible. A Join RTE node is handy for this, since we
@@ -2547,6 +2544,19 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
qry->limitCount = transformLimitClause(pstate, limitCount,
"LIMIT");
+ /*
+ * Handle SELECT INTO/CREATE TABLE AS.
+ *
+ * Any column names from CREATE TABLE AS need to be attached to both the
+ * top level and the leftmost subquery. We do not do this earlier because
+ * we do *not* want sortClause processing to be affected.
+ */
+ if (intoColNames)
+ {
+ applyColumnNames(qry->targetList, intoColNames);
+ applyColumnNames(leftmostQuery->targetList, intoColNames);
+ }
+
qry->rtable = pstate->p_rtable;
qry->jointree = makeFromExpr(pstate->p_joinlist, NULL);
@@ -2788,19 +2798,32 @@ applyColumnNames(List *dst, List *src)
ListCell *dst_item;
ListCell *src_item;
- if (list_length(src) > list_length(dst))
- ereport(ERROR,
- (errcode(ERRCODE_SYNTAX_ERROR),
- errmsg("CREATE TABLE AS specifies too many column names")));
+ src_item = list_head(src);
- forboth(dst_item, dst, src_item, src)
+ foreach(dst_item, dst)
{
TargetEntry *d = (TargetEntry *) lfirst(dst_item);
- ColumnDef *s = (ColumnDef *) lfirst(src_item);
+ ColumnDef *s;
+
+ /* junk targets don't count */
+ if (d->resjunk)
+ continue;
+
+ /* fewer ColumnDefs than target entries is OK */
+ if (src_item == NULL)
+ break;
+
+ s = (ColumnDef *) lfirst(src_item);
+ src_item = lnext(src_item);
- Assert(!d->resjunk);
d->resname = pstrdup(s->colname);
}
+
+ /* more ColumnDefs than target entries is not OK */
+ if (src_item != NULL)
+ ereport(ERROR,
+ (errcode(ERRCODE_SYNTAX_ERROR),
+ errmsg("CREATE TABLE AS specifies too many column names")));
}