Commit 42d5e34e authored by Tom Lane's avatar Tom Lane

Repair mishandling of PRIMARY KEY declaration that references an

inherited column, per bug report from Elphick 12/15/00.
parent a626b78c
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: analyze.c,v 1.172 2000/12/07 01:12:08 tgl Exp $
* $Id: analyze.c,v 1.173 2000/12/18 01:37:56 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -945,9 +945,10 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
index->withClause = NIL;
index->whereClause = NULL;
foreach(keys, constraint->keys)
foreach (keys, constraint->keys)
{
int found=0;
bool found = false;
key = (Ident *) lfirst(keys);
Assert(IsA(key, Ident));
column = NULL;
......@@ -956,26 +957,58 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
column = lfirst(columns);
Assert(IsA(column, ColumnDef));
if (strcmp(column->colname, key->name) == 0)
{
found = true;
break;
}
}
if (found)
{
/* found column in the new table; force it to be NOT NULL */
if (constraint->contype == CONSTR_PRIMARY)
column->is_not_null = TRUE;
}
if (columns == NIL) { /* try inherited tables */
else
{
/* try inherited tables */
List *inhRelnames = stmt->inhRelnames;
List *inher;
List *inhRelnames=stmt->inhRelnames;
Relation rel;
foreach (inher, inhRelnames) {
int count=0;
Value *inh=lfirst(inher);
if (inh->type!=T_String) {
elog(ERROR, "inherited table name list returns a non-string");
}
rel=heap_openr(inh->val.str, AccessShareLock);
foreach (inher, inhRelnames)
{
Value *inh = lfirst(inher);
Relation rel;
int count;
Assert(IsA(inh, String));
rel = heap_openr(inh->val.str, AccessShareLock);
if (rel->rd_rel->relkind != RELKIND_RELATION)
elog(ERROR, "inherited table \"%s\" is not a relation",
inh->val.str);
for (; count<rel->rd_att->natts; count++) {
char *name=NameStr(rel->rd_att->attrs[count]->attname);
if (strcmp(key->name, name) == 0) {
found=1;
inh->val.str);
for (count = 0; count < rel->rd_att->natts; count++)
{
Form_pg_attribute inhattr = rel->rd_att->attrs[count];
char *inhname = NameStr(inhattr->attname);
if (strcmp(key->name, inhname) == 0)
{
found = true;
/*
* If the column is inherited, we currently have
* no easy way to force it to be NOT NULL.
* Only way I can see to fix this would be to
* convert the inherited-column info to ColumnDef
* nodes before we reach this point, and then
* create the table from those nodes rather than
* referencing the parent tables later. That
* would likely be cleaner, but too much work
* to contemplate right now. Instead, raise an
* error if the inherited column won't be NOT NULL.
* (Would a NOTICE be more reasonable?)
*/
if (! inhattr->attnotnull)
elog(ERROR, "inherited attribute \"%s\" cannot be a PRIMARY KEY because it is not marked NOT NULL",
inhname);
break;
}
}
......@@ -984,16 +1017,11 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
break;
}
}
else {
found=1;
}
if (!found)
elog(ERROR, "CREATE TABLE: column '%s' named in key does not exist",
elog(ERROR, "CREATE TABLE: column \"%s\" named in key does not exist",
key->name);
if (constraint->contype == CONSTR_PRIMARY)
column->is_not_null = TRUE;
iparam = makeNode(IndexElem);
iparam->name = pstrdup(key->name);
iparam->args = NIL;
......@@ -1001,7 +1029,8 @@ transformCreateStmt(ParseState *pstate, CreateStmt *stmt)
index->indexParams = lappend(index->indexParams, iparam);
if (index->idxname == NULL)
index->idxname = CreateIndexName(stmt->relname, iparam->name, "key", ilist);
index->idxname = CreateIndexName(stmt->relname, iparam->name,
"key", ilist);
}
if (index->idxname == NULL) /* should not happen */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment