From 4da65a23e7d8821b8eff8075add93caef471d4f8 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 15 Dec 2008 21:35:31 +0000 Subject: Code review for CREATE OR REPLACE VIEW patch. Do things in a saner order to result in hopefully-less-confusing error messages when the new definition isn't compatible with the old; minor other cleanup. --- src/backend/commands/view.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'src/backend/commands/view.c') diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c index 23a03d28a9c..3b589d49e81 100644 --- a/src/backend/commands/view.c +++ b/src/backend/commands/view.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.108 2008/12/06 23:22:46 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/view.c,v 1.109 2008/12/15 21:35:31 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -165,6 +165,9 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) aclcheck_error(ACLCHECK_NOT_OWNER, ACL_KIND_CLASS, RelationGetRelationName(rel)); + /* Also check it's not in use already */ + CheckTableNotInUse(rel, "CREATE OR REPLACE VIEW"); + /* * Due to the namespace visibility rules for temporary objects, we * should only end up replacing a temporary view with another @@ -173,37 +176,41 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) Assert(relation->istemp == rel->rd_istemp); /* - * If new attributes have been added, we must modify the pre-existing - * view. - */ - if (list_length(attrList) > rel->rd_att->natts) { + * Create a tuple descriptor to compare against the existing view, and + * verify that the old column list is an initial prefix of the new + * column list. + */ + descriptor = BuildDescForRelation(attrList); + checkViewTupleDesc(descriptor, rel->rd_att); + + /* + * If new attributes have been added, we must add pg_attribute entries + * for them. It is convenient (although overkill) to use the ALTER + * TABLE ADD COLUMN infrastructure for this. + */ + if (list_length(attrList) > rel->rd_att->natts) + { List *atcmds = NIL; ListCell *c; int skip = rel->rd_att->natts; - foreach(c, attrList) { + foreach(c, attrList) + { AlterTableCmd *atcmd; - if (skip > 0) { - --skip; + if (skip > 0) + { + skip--; continue; } atcmd = makeNode(AlterTableCmd); atcmd->subtype = AT_AddColumnToView; - atcmd->def = lfirst(c); + atcmd->def = (Node *) lfirst(c); atcmds = lappend(atcmds, atcmd); } AlterTableInternal(viewOid, atcmds, true); } - /* - * Create a tuple descriptor to compare against the existing view, and - * verify that the old column list is an initial prefix of the new - * column list. - */ - descriptor = BuildDescForRelation(attrList); - checkViewTupleDesc(descriptor, rel->rd_att); - /* * Seems okay, so return the OID of the pre-existing view. */ @@ -238,6 +245,7 @@ DefineVirtualRelation(const RangeVar *relation, List *tlist, bool replace) * Verify that tupledesc associated with proposed new view definition * matches tupledesc of old view. This is basically a cut-down version * of equalTupleDescs(), with code added to generate specific complaints. + * Also, we allow the new tupledesc to have more columns than the old. */ static void checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc) -- cgit v1.2.3