diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 1293545947e..62d9917ca36 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -3015,17 +3015,34 @@ MergeAttributes(List *schema, List *supers, char relpersistence, coldef->is_not_null |= restdef->is_not_null; /* - * As above, reject generated columns in partitions that - * are not generated in the parent. + * Check for conflicts related to generated columns. + * + * Same rules as above: generated-ness has to match the + * parent, but the contents of the generation expression + * can be different. */ - if (restdef->generated && !coldef->generated) - ereport(ERROR, - (errcode(ERRCODE_INVALID_COLUMN_DEFINITION), - errmsg("child column \"%s\" specifies generation expression", - restdef->colname), - errhint("A child table column cannot be generated unless its parent column is."))); - /* Other way around should have been dealt with above */ - Assert(!(coldef->generated && !restdef->generated)); + if (coldef->generated) + { + if (restdef->raw_default && !restdef->generated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_DEFINITION), + errmsg("column \"%s\" inherits from generated column but specifies default", + restdef->colname))); + if (restdef->identity) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_DEFINITION), + errmsg("column \"%s\" inherits from generated column but specifies identity", + restdef->colname))); + } + else + { + if (restdef->generated) + ereport(ERROR, + (errcode(ERRCODE_INVALID_COLUMN_DEFINITION), + errmsg("child column \"%s\" specifies generation expression", + restdef->colname), + errhint("A child table column cannot be generated unless its parent column is."))); + } /* * Override the parent's default value for this column diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out index 11940c851f2..702774d6444 100644 --- a/src/test/regress/expected/generated.out +++ b/src/test/regress/expected/generated.out @@ -730,10 +730,26 @@ CREATE TABLE gtest_child PARTITION OF gtest_parent CREATE TABLE gtest_child2 PARTITION OF gtest_parent ( f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 22) STORED -- overrides gen expr ) FOR VALUES FROM ('2016-08-01') TO ('2016-09-01'); +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 DEFAULT 42 -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); +ERROR: column "f3" inherits from generated column but specifies default +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); +ERROR: identity columns are not supported on partitions CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint); ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error ERROR: column "f3" in child table must be a generated column DROP TABLE gtest_child3; +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint DEFAULT 42); +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error +ERROR: column "f3" in child table must be a generated column +DROP TABLE gtest_child3; +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS IDENTITY); +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error +ERROR: column "f3" in child table must be a generated column +DROP TABLE gtest_child3; CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 33) STORED); ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); \d gtest_child diff --git a/src/test/regress/sql/generated.sql b/src/test/regress/sql/generated.sql index 87ec8421162..36f6bff3483 100644 --- a/src/test/regress/sql/generated.sql +++ b/src/test/regress/sql/generated.sql @@ -390,9 +390,21 @@ CREATE TABLE gtest_child PARTITION OF gtest_parent CREATE TABLE gtest_child2 PARTITION OF gtest_parent ( f3 WITH OPTIONS GENERATED ALWAYS AS (f2 * 22) STORED -- overrides gen expr ) FOR VALUES FROM ('2016-08-01') TO ('2016-09-01'); +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 DEFAULT 42 -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); +CREATE TABLE gtest_child3 PARTITION OF gtest_parent ( + f3 WITH OPTIONS GENERATED ALWAYS AS IDENTITY -- error +) FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint); ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error DROP TABLE gtest_child3; +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint DEFAULT 42); +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error +DROP TABLE gtest_child3; +CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS IDENTITY); +ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); -- error +DROP TABLE gtest_child3; CREATE TABLE gtest_child3 (f1 date NOT NULL, f2 bigint, f3 bigint GENERATED ALWAYS AS (f2 * 33) STORED); ALTER TABLE gtest_parent ATTACH PARTITION gtest_child3 FOR VALUES FROM ('2016-09-01') TO ('2016-10-01'); \d gtest_child