aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2001-11-05 05:00:14 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2001-11-05 05:00:14 +0000
commit5251e7b3d07da28b48ec5c7930c8b57b554fd27a (patch)
tree6b0f24e3c8722839d2fc549d052995d2d4e3b763 /src
parentd556920a982c29810c2afaf64ca4840713a424c1 (diff)
downloadpostgresql-5251e7b3d07da28b48ec5c7930c8b57b554fd27a.tar.gz
postgresql-5251e7b3d07da28b48ec5c7930c8b57b554fd27a.zip
CREATE TABLE foo (x,y,z) AS SELECT ... can't apply target column names
to the target list in gram.y; it must wait till after expansion of the target list in analyze.c. Per bug report 4-Nov: lx=# CREATE TABLE abc (a char, b char, c char); CREATE lx=# CREATE TABLE xyz (x, y, z) AS SELECT * FROM abc; ERROR: CREATE TABLE/AS SELECT has mismatched column count
Diffstat (limited to 'src')
-rw-r--r--src/backend/nodes/copyfuncs.c3
-rw-r--r--src/backend/nodes/equalfuncs.c4
-rw-r--r--src/backend/parser/analyze.c36
-rw-r--r--src/backend/parser/gram.y31
-rw-r--r--src/include/nodes/parsenodes.h3
5 files changed, 45 insertions, 32 deletions
diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c
index 620054380a4..6977a6081de 100644
--- a/src/backend/nodes/copyfuncs.c
+++ b/src/backend/nodes/copyfuncs.c
@@ -15,7 +15,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.159 2001/10/25 05:49:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.160 2001/11/05 05:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -1835,6 +1835,7 @@ _copySelectStmt(SelectStmt *from)
if (from->into)
newnode->into = pstrdup(from->into);
newnode->istemp = from->istemp;
+ Node_Copy(from, newnode, intoColNames);
Node_Copy(from, newnode, targetList);
Node_Copy(from, newnode, fromClause);
Node_Copy(from, newnode, whereClause);
diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c
index 0a48a194df3..538a773e31b 100644
--- a/src/backend/nodes/equalfuncs.c
+++ b/src/backend/nodes/equalfuncs.c
@@ -20,7 +20,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.107 2001/10/25 05:49:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.108 2001/11/05 05:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -681,6 +681,8 @@ _equalSelectStmt(SelectStmt *a, SelectStmt *b)
return false;
if (a->istemp != b->istemp)
return false;
+ if (!equal(a->intoColNames, b->intoColNames))
+ return false;
if (!equal(a->targetList, b->targetList))
return false;
if (!equal(a->fromClause, b->fromClause))
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c
index 0d833079e4a..40e9700f024 100644
--- a/src/backend/parser/analyze.c
+++ b/src/backend/parser/analyze.c
@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.209 2001/11/04 03:08:11 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/analyze.c,v 1.210 2001/11/05 05:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -88,6 +88,7 @@ static void transformFKConstraints(ParseState *pstate,
CreateStmtContext *cxt);
static Node *transformTypeRefs(ParseState *pstate, Node *stmt);
+static void applyColumnNames(List *dst, List *src);
static void transformTypeRefsList(ParseState *pstate, List *l);
static void transformTypeRef(ParseState *pstate, TypeName *tn);
static List *getSetColTypes(ParseState *pstate, Node *node);
@@ -1942,9 +1943,13 @@ transformSelectStmt(ParseState *pstate, SelectStmt *stmt)
/* process the FROM clause */
transformFromClause(pstate, stmt->fromClause);
- /* transform targetlist and WHERE */
+ /* transform targetlist */
qry->targetList = transformTargetList(pstate, stmt->targetList);
+ if (stmt->intoColNames)
+ applyColumnNames(qry->targetList, stmt->intoColNames);
+
+ /* transform WHERE */
qual = transformWhereClause(pstate, stmt->whereClause);
/*
@@ -2003,6 +2008,7 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
SetOperationStmt *sostmt;
char *into;
bool istemp;
+ List *intoColNames;
char *portalname;
bool binary;
List *sortClause;
@@ -2031,12 +2037,14 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
leftmostSelect->larg == NULL);
into = leftmostSelect->into;
istemp = leftmostSelect->istemp;
+ intoColNames = leftmostSelect->intoColNames;
portalname = stmt->portalname;
binary = stmt->binary;
/* clear them to prevent complaints in transformSetOperationTree() */
leftmostSelect->into = NULL;
leftmostSelect->istemp = false;
+ leftmostSelect->intoColNames = NIL;
stmt->portalname = NULL;
stmt->binary = false;
@@ -2149,6 +2157,9 @@ transformSetOperationStmt(ParseState *pstate, SelectStmt *stmt)
qry->isBinary = FALSE;
}
+ if (intoColNames)
+ applyColumnNames(qry->targetList, intoColNames);
+
/*
* As a first step towards supporting sort clauses that are
* expressions using the output columns, generate a namespace entry
@@ -2377,6 +2388,27 @@ getSetColTypes(ParseState *pstate, Node *node)
}
}
+/* Attach column names from a ColumnDef list to a TargetEntry list */
+static void
+applyColumnNames(List *dst, List *src)
+{
+ if (length(src) > length(dst))
+ elog(ERROR,"CREATE TABLE AS specifies too many column names");
+
+ while (src != NIL && dst != NIL)
+ {
+ TargetEntry *d = (TargetEntry *) lfirst(dst);
+ ColumnDef *s = (ColumnDef *) lfirst(src);
+
+ Assert(d->resdom && !d->resdom->resjunk);
+
+ d->resdom->resname = pstrdup(s->colname);
+
+ dst = lnext(dst);
+ src = lnext(src);
+ }
+}
+
/*
* transformUpdateStmt -
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index c97c9da509e..63465c91686 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.271 2001/10/31 04:49:43 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.272 2001/11/05 05:00:14 tgl Exp $
*
* HISTORY
* AUTHOR DATE MAJOR EVENT
@@ -86,7 +86,6 @@ static Node *makeTypeCast(Node *arg, TypeName *typename);
static Node *makeStringConst(char *str, TypeName *typename);
static Node *makeFloatConst(char *str);
static Node *makeRowExpr(char *opr, List *largs, List *rargs);
-static void mapTargetColumns(List *source, List *target);
static SelectStmt *findLeftmostSelect(SelectStmt *node);
static void insertSelectOptions(SelectStmt *stmt,
List *sortClause, List *forUpdate,
@@ -1611,11 +1610,10 @@ CreateAsStmt: CREATE OptTemp TABLE relation_name OptCreateAs AS SelectStmt
*/
SelectStmt *n = findLeftmostSelect((SelectStmt *) $7);
if (n->into != NULL)
- elog(ERROR,"CREATE TABLE / AS SELECT may not specify INTO");
+ elog(ERROR,"CREATE TABLE AS may not specify INTO");
n->istemp = $2;
n->into = $4;
- if ($5 != NIL)
- mapTargetColumns($5, n->targetList);
+ n->intoColNames = $5;
$$ = $7;
}
;
@@ -3552,6 +3550,7 @@ simple_select: SELECT opt_distinct target_list
n->targetList = $3;
n->istemp = (bool) ((Value *) lfirst($4))->val.ival;
n->into = (char *) lnext($4);
+ n->intoColNames = NIL;
n->fromClause = $5;
n->whereClause = $6;
n->groupClause = $7;
@@ -6106,28 +6105,6 @@ makeRowExpr(char *opr, List *largs, List *rargs)
return expr;
}
-static void
-mapTargetColumns(List *src, List *dst)
-{
- ColumnDef *s;
- ResTarget *d;
-
- if (length(src) != length(dst))
- elog(ERROR,"CREATE TABLE / AS SELECT has mismatched column count");
-
- while ((src != NIL) && (dst != NIL))
- {
- s = (ColumnDef *)lfirst(src);
- d = (ResTarget *)lfirst(dst);
-
- d->name = s->colname;
-
- src = lnext(src);
- dst = lnext(dst);
- }
-} /* mapTargetColumns() */
-
-
/* findLeftmostSelect()
* Find the leftmost component SelectStmt in a set-operation parsetree.
*/
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 1abd7ba365a..892177c920c 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $Id: parsenodes.h,v 1.149 2001/10/28 06:26:07 momjian Exp $
+ * $Id: parsenodes.h,v 1.150 2001/11/05 05:00:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -881,6 +881,7 @@ typedef struct SelectStmt
* DISTINCT) */
char *into; /* name of table (for select into table) */
bool istemp; /* into is a temp table? */
+ List *intoColNames; /* column names for into table */
List *targetList; /* the target list (of ResTarget) */
List *fromClause; /* the FROM clause */
Node *whereClause; /* WHERE qualification */