mirror of
https://github.com/postgres/postgres.git
synced 2025-08-24 09:27:52 +03:00
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
This commit is contained in:
@@ -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 -
|
||||
|
Reference in New Issue
Block a user