1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

ALTER TABLE DROP COLUMN works. Patch by Christopher Kings-Lynne,

code review by Tom Lane.  Remaining issues: functions that take or
return tuple types are likely to break if one drops (or adds!)
a column in the table defining the type.  Need to think about what
to do here.

Along the way: some code review for recent COPY changes; mark system
columns attnotnull = true where appropriate, per discussion a month ago.
This commit is contained in:
Tom Lane
2002-08-02 18:15:10 +00:00
parent 5e6528adf7
commit 38bb77a5d1
44 changed files with 1823 additions and 891 deletions

View File

@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.81 2002/07/24 19:11:09 petere Exp $
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.82 2002/08/02 18:15:05 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -327,9 +327,9 @@ checkretval(Oid rettype, List *queryTreeList)
Oid typerelid;
Oid restype;
Relation reln;
Oid relid;
int relnatts;
int i;
int relnatts; /* physical number of columns in rel */
int rellogcols; /* # of nondeleted columns in rel */
int colindex; /* physical column index */
/* guard against empty function body; OK only if no return type */
if (queryTreeList == NIL)
@@ -404,42 +404,55 @@ checkretval(Oid rettype, List *queryTreeList)
/*
* By here, the procedure returns a tuple or set of tuples. This part
* of the typechecking is a hack. We look up the relation that is the
* declared return type, and be sure that attributes 1 .. n in the
* target list match the declared types.
* declared return type, and scan the non-deleted attributes to ensure
* that they match the datatypes of the non-resjunk columns.
*/
reln = heap_open(typerelid, AccessShareLock);
relid = reln->rd_id;
relnatts = reln->rd_rel->relnatts;
rellogcols = 0; /* we'll count nondeleted cols as we go */
colindex = 0;
if (tlistlen != relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), relnatts);
/* expect attributes 1 .. n in order */
i = 0;
foreach(tlistitem, tlist)
{
TargetEntry *tle = (TargetEntry *) lfirst(tlistitem);
Form_pg_attribute attr;
Oid tletype;
Oid atttype;
if (tle->resdom->resjunk)
continue;
do {
colindex++;
if (colindex > relnatts)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), rellogcols);
attr = reln->rd_att->attrs[colindex - 1];
} while (attr->attisdropped);
rellogcols++;
tletype = exprType(tle->expr);
atttype = reln->rd_att->attrs[i]->atttypid;
atttype = attr->atttypid;
if (!IsBinaryCompatible(tletype, atttype))
elog(ERROR, "function declared to return %s returns %s instead of %s at column %d",
format_type_be(rettype),
format_type_be(tletype),
format_type_be(atttype),
i + 1);
i++;
rellogcols);
}
/* this shouldn't happen, but let's just check... */
if (i != relnatts)
for (;;)
{
colindex++;
if (colindex > relnatts)
break;
if (!reln->rd_att->attrs[colindex - 1]->attisdropped)
rellogcols++;
}
if (tlistlen != rellogcols)
elog(ERROR, "function declared to return %s does not SELECT the right number of columns (%d)",
format_type_be(rettype), relnatts);
format_type_be(rettype), rellogcols);
heap_close(reln, AccessShareLock);
}