diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index daa80ec4aa..8e5e3296df 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -15157,8 +15157,9 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu */ /* - * Cannot have expressions containing whole-row references or - * system column references. + * Cannot have expressions containing whole-row references, + * system column references, or anonymous and self-referencing + * records. */ pull_varattnos(expr, 1, &expr_attrs); if (bms_is_member(0 - FirstLowInvalidHeapAttributeNumber, @@ -15175,6 +15176,13 @@ ComputePartitionAttrs(ParseState *pstate, Relation rel, List *partParams, AttrNu errmsg("partition key expressions cannot contain system column references"))); } + if (atttype == RECORDOID || + (type_is_rowtype(atttype) && atttype == rel->rd_rel->reltype)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TABLE_DEFINITION), + errmsg("partition key cannot be of anonymous or self-referencing composite type"), + parser_errposition(pstate, pelem->location))); + /* * Generated columns cannot work: They are computed after * BEFORE triggers, but partition routing is done before all diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index f63016871c..9fd772d4f8 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -402,6 +402,28 @@ CREATE TABLE partitioned ( ERROR: cannot use system column "xmin" in partition key LINE 3: ) PARTITION BY RANGE (xmin); ^ +-- cannot use anonymous or self-referencing records +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (((a, b))); +ERROR: partition key cannot be of anonymous or self-referencing composite type +LINE 4: ) PARTITION BY RANGE (((a, b))); + ^ +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((row(a, b))); +ERROR: partition key cannot be of anonymous or self-referencing composite type +LINE 4: ) PARTITION BY RANGE ((row(a, b))); + ^ +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((row(a, b)::partitioned)); +ERROR: partition key cannot be of anonymous or self-referencing composite type +LINE 4: ) PARTITION BY RANGE ((row(a, b)::partitioned)); + ^ -- functions in key must be immutable CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; CREATE TABLE partitioned ( diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index e835b65ac4..abf4d6e093 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -384,6 +384,20 @@ CREATE TABLE partitioned ( a int ) PARTITION BY RANGE (xmin); +-- cannot use anonymous or self-referencing records +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE (((a, b))); +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((row(a, b))); +CREATE TABLE partitioned ( + a int, + b int +) PARTITION BY RANGE ((row(a, b)::partitioned)); + -- functions in key must be immutable CREATE FUNCTION immut_func (a int) RETURNS int AS $$ SELECT a + random()::int; $$ LANGUAGE SQL; CREATE TABLE partitioned (