Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04db0fd

Browse files
committed
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.
1 parent b7b8692 commit 04db0fd

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

src/backend/parser/parse_utilcmd.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,6 +825,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
825825
TupleDesc tupdesc;
826826
int i;
827827
Oid ofTypeId;
828+
bool typeOk = false;
828829

829830
AssertArg(ofTypename);
830831

@@ -833,7 +834,21 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
833834
ofTypeId = HeapTupleGetOid(tuple);
834835
ofTypename->typeOid = ofTypeId; /* cached for later */
835836

836-
if (typ->typtype != TYPTYPE_COMPOSITE)
837+
if (typ->typtype == TYPTYPE_COMPOSITE)
838+
{
839+
Relation typeRelation;
840+
841+
Assert(OidIsValid(typ->typrelid));
842+
typeRelation = relation_open(typ->typrelid, AccessShareLock);
843+
typeOk = (typeRelation->rd_rel->relkind == RELKIND_COMPOSITE_TYPE);
844+
/*
845+
* Close the parent rel, but keep our AccessShareLock on it until xact
846+
* commit. That will prevent someone else from deleting or ALTERing
847+
* the type before the typed table creation commits.
848+
*/
849+
relation_close(typeRelation, NoLock);
850+
}
851+
if (!typeOk)
837852
ereport(ERROR,
838853
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
839854
errmsg("type %s is not a composite type",

src/test/regress/expected/typed_table.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ DETAIL: drop cascades to table persons
9191
drop cascades to function get_all_persons()
9292
drop cascades to table persons2
9393
drop cascades to table persons3
94+
CREATE TABLE persons5 OF stuff; -- only CREATE TYPE AS types may be used
95+
ERROR: type stuff is not a composite type
9496
DROP TABLE stuff;
9597
-- implicit casting
9698
CREATE TYPE person_type AS (id int, name text);

src/test/regress/sql/typed_table.sql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@ CREATE TABLE persons4 OF person_type (
4646
DROP TYPE person_type RESTRICT;
4747
DROP TYPE person_type CASCADE;
4848

49+
CREATE TABLE persons5 OF stuff; -- only CREATE TYPE AS types may be used
50+
4951
DROP TABLE stuff;
5052

5153

0 commit comments

Comments
 (0)