diff options
author | Robert Haas <rhaas@postgresql.org> | 2011-04-18 10:13:34 -0400 |
---|---|---|
committer | Robert Haas <rhaas@postgresql.org> | 2011-04-18 10:19:46 -0400 |
commit | 04db0fdbfa9382730bb65f94bca2cd8063a3456a (patch) | |
tree | fa66be340f38b1cd5507732828e59aef0744a293 /src/backend/parser/parse_utilcmd.c | |
parent | b7b86924c6da46c774e1ab5d524a6bc4f72627ab (diff) | |
download | postgresql-04db0fdbfa9382730bb65f94bca2cd8063a3456a.tar.gz postgresql-04db0fdbfa9382730bb65f94bca2cd8063a3456a.zip |
Only allow typed tables to hang off composite types, not e.g. tables.
This also ensures that we take a relation lock on the composite type when
creating a typed table, which is necessary to prevent the composite type
and the typed table from getting out of step in the face of concurrent
DDL.
Noah Misch, with some changes.
Diffstat (limited to 'src/backend/parser/parse_utilcmd.c')
-rw-r--r-- | src/backend/parser/parse_utilcmd.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c index eba890bf88d..4f1bb34dae0 100644 --- a/src/backend/parser/parse_utilcmd.c +++ b/src/backend/parser/parse_utilcmd.c @@ -825,6 +825,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) TupleDesc tupdesc; int i; Oid ofTypeId; + bool typeOk = false; AssertArg(ofTypename); @@ -833,7 +834,21 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename) ofTypeId = HeapTupleGetOid(tuple); ofTypename->typeOid = ofTypeId; /* cached for later */ - if (typ->typtype != TYPTYPE_COMPOSITE) + if (typ->typtype == TYPTYPE_COMPOSITE) + { + Relation typeRelation; + + Assert(OidIsValid(typ->typrelid)); + typeRelation = relation_open(typ->typrelid, AccessShareLock); + typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE); + /* + * Close the parent rel, but keep our AccessShareLock on it until xact + * commit. That will prevent someone else from deleting or ALTERing + * the type before the typed table creation commits. + */ + relation_close(typeRelation, NoLock); + } + if (!typeOk) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("type %s is not a composite type", |