diff options
Diffstat (limited to 'src/backend/commands/tablecmds.c')
-rw-r--r-- | src/backend/commands/tablecmds.c | 65 |
1 files changed, 58 insertions, 7 deletions
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 89447d36782..134b217d829 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.319 2010/01/28 07:31:42 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.320 2010/01/28 23:21:11 petere Exp $ * *------------------------------------------------------------------------- */ @@ -361,6 +361,7 @@ DefineRelation(CreateStmt *stmt, char relkind) ListCell *listptr; AttrNumber attnum; static char *validnsps[] = HEAP_RELOPT_NAMESPACES; + Oid ofTypeId; /* * Truncate relname to appropriate length (probably a waste of time, as @@ -443,6 +444,11 @@ DefineRelation(CreateStmt *stmt, char relkind) (void) heap_reloptions(relkind, reloptions, true); + if (stmt->ofTypename) + ofTypeId = typenameTypeId(NULL, stmt->ofTypename, NULL); + else + ofTypeId = InvalidOid; + /* * Look up inheritance ancestors and generate relation schema, including * inherited attributes. @@ -521,6 +527,7 @@ DefineRelation(CreateStmt *stmt, char relkind) tablespaceId, InvalidOid, InvalidOid, + ofTypeId, GetUserId(), descriptor, list_concat(cookedDefaults, @@ -1230,17 +1237,46 @@ MergeAttributes(List *schema, List *supers, bool istemp, foreach(entry, schema) { ColumnDef *coldef = lfirst(entry); - ListCell *rest; + ListCell *rest = lnext(entry); + ListCell *prev = entry; + + if (coldef->typeName == NULL) + /* + * Typed table column option that does not belong to a + * column from the type. This works because the columns + * from the type come first in the list. + */ + ereport(ERROR, + (errcode(ERRCODE_UNDEFINED_COLUMN), + errmsg("column \"%s\" does not exist", + coldef->colname))); - for_each_cell(rest, lnext(entry)) + while (rest != NULL) { ColumnDef *restdef = lfirst(rest); + ListCell *next = lnext(rest); /* need to save it in case we delete it */ if (strcmp(coldef->colname, restdef->colname) == 0) - ereport(ERROR, - (errcode(ERRCODE_DUPLICATE_COLUMN), - errmsg("column \"%s\" specified more than once", - coldef->colname))); + { + if (coldef->is_from_type) + { + /* merge the column options into the column from + * the type */ + coldef->is_not_null = restdef->is_not_null; + coldef->raw_default = restdef->raw_default; + coldef->cooked_default = restdef->cooked_default; + coldef->constraints = restdef->constraints; + coldef->is_from_type = false; + list_delete_cell(schema, rest, prev); + } + else + ereport(ERROR, + (errcode(ERRCODE_DUPLICATE_COLUMN), + errmsg("column \"%s\" specified more than once", + coldef->colname))); + } + prev = rest; + rest = next; } } @@ -1921,6 +1957,11 @@ renameatt(Oid myrelid, */ targetrelation = relation_open(myrelid, AccessExclusiveLock); + if (targetrelation->rd_rel->reloftype) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot rename column of typed table"))); + /* * permissions checking. this would normally be done in utility.c, but * this particular routine is recursive. @@ -3586,6 +3627,11 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, Form_pg_type tform; Expr *defval; + if (rel->rd_rel->reloftype) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot add column to typed table"))); + attrdesc = heap_open(AttributeRelationId, RowExclusiveLock); /* @@ -4307,6 +4353,11 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName, List *children; ObjectAddress object; + if (rel->rd_rel->reloftype) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot drop column from typed table"))); + /* At top level, permission check was done in ATPrepCmd, else do it */ if (recursing) ATSimplePermissions(rel, false); |