From a3dc8e495b4967fe07086a700d115c89f4f0add0 Mon Sep 17 00:00:00 2001 From: Robert Haas Date: Sun, 19 Feb 2017 21:29:27 +0530 Subject: [PATCH] Make partitions automatically inherit OIDs. Previously, if the parent was specified as WITH OIDS, each child also had to be explicitly specified as WITH OIDS. Amit Langote, per a report from Simon Riggs. Some additional work on the documentation changes by me. Discussion: http://postgr.es/m/CANP8+jJBpWocfKrbJcaf3iBt9E3U=WPE_NC8YE6rye+YJ1sYnQ@mail.gmail.com --- doc/src/sgml/ddl.sgml | 8 ----- doc/src/sgml/ref/create_table.sgml | 34 +++++++++++----------- src/backend/commands/tablecmds.c | 21 +++++-------- src/test/regress/expected/create_table.out | 18 ++++++++---- src/test/regress/sql/create_table.sql | 10 ++++--- 5 files changed, 44 insertions(+), 47 deletions(-) diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml index f909242e4c..5779eac43d 100644 --- a/doc/src/sgml/ddl.sgml +++ b/doc/src/sgml/ddl.sgml @@ -2861,14 +2861,6 @@ VALUES ('Albany', NULL, NULL, 'NY'); - - - If the partitioned table specified WITH OIDS then - each partition must also specify WITH OIDS. Oids - are not automatically inherited by partitions. - - - One cannot drop a NOT NULL constraint on a diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml index 41c08bba74..bb081ff86f 100644 --- a/doc/src/sgml/ref/create_table.sgml +++ b/doc/src/sgml/ref/create_table.sgml @@ -300,14 +300,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI - A partition cannot have columns other than those inherited from the - parent. If the parent is specified WITH OIDS then - the partitions must also explicitly specify WITH OIDS. - Defaults and constraints can optionally be specified for each of the - inherited columns. One can also specify table constraints in addition - to those inherited from the parent. If a check constraint with the name - matching one of the parent's constraint is specified, it is merged with - the latter, provided the specified condition is same. + A partition must have the same column names and types as the partitioned + table to which it belongs. If the parent is specified WITH + OIDS then all partitions must have OIDs; the parent's OID + column will be inherited by all partitions just like any other column. + Modifications to the column names or types of a partitioned table, or + the addition or removal of an OID column, will automatically propagate + to all partitions. CHECK constraints will be inherited + automatically by every partition, but an individual partition may specify + additional CHECK constraints; additional constraints with + the same name and condition as in the parent will be merged with the + parent constraint. Defaults may be specified separately for each + partition. @@ -318,15 +322,11 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI - A partition must have the same column names and types as the table of - which it is a partition. Therefore, modifications to the column names - or types of the partitioned table will automatically propagate to all - children, as will operations such as TRUNCATE which normally affect a - table and all of its inheritance children. It is also possible to - TRUNCATE a partition individually, just as for an inheritance child. - Note that dropping a partition with DROP TABLE - requires taking an ACCESS EXCLUSIVE lock on the - parent table. + Operations such as TRUNCATE which normally affect a table and all of its + inheritance children will cascade to all partitions, but may also be + performed on an individual partition. Note that dropping a partition + with DROP TABLE requires taking an ACCESS + EXCLUSIVE lock on the parent table. diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index f33aa70da6..3cea220421 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -634,19 +634,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId, relkind == RELKIND_PARTITIONED_TABLE)); descriptor->tdhasoid = (localHasOids || parentOidCount > 0); - if (stmt->partbound) - { - /* If the parent has OIDs, partitions must have them too. */ - if (parentOidCount > 0 && !localHasOids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create table without OIDs as partition of table with OIDs"))); - /* If the parent doesn't, partitions must not have them. */ - if (parentOidCount == 0 && localHasOids) - ereport(ERROR, - (errcode(ERRCODE_WRONG_OBJECT_TYPE), - errmsg("cannot create table with OIDs as partition of table without OIDs"))); - } + /* + * If a partitioned table doesn't have the system OID column, then none + * of its partitions should have it. + */ + if (stmt->partbound && parentOidCount == 0 && localHasOids) + ereport(ERROR, + (errcode(ERRCODE_WRONG_OBJECT_TYPE), + errmsg("cannot create table with OIDs as partition of table without OIDs"))); /* * Find columns with default values and prepare for insertion of the diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out index fc92cd92dd..20eb3d35f9 100644 --- a/src/test/regress/expected/create_table.out +++ b/src/test/regress/expected/create_table.out @@ -524,16 +524,24 @@ DROP TABLE temp_parted; CREATE TABLE no_oids_parted ( a int ) PARTITION BY RANGE (a) WITHOUT OIDS; -CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10 )WITH OIDS; +CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS; ERROR: cannot create table with OIDs as partition of table without OIDs DROP TABLE no_oids_parted; --- likewise, the reverse if also true +-- If the partitioned table has oids, then the partition must have them. +-- If the WITHOUT OIDS option is specified for partition, it is overridden. CREATE TABLE oids_parted ( a int ) PARTITION BY RANGE (a) WITH OIDS; -CREATE TABLE fail_part PARTITION OF oids_parted FOR VALUES FROM (1) TO (10 ) WITHOUT OIDS; -ERROR: cannot create table without OIDs as partition of table with OIDs -DROP TABLE oids_parted; +CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS; +\d+ part_forced_oids + Table "public.part_forced_oids" + Column | Type | Collation | Nullable | Default | Storage | Stats target | Description +--------+---------+-----------+----------+---------+---------+--------------+------------- + a | integer | | not null | | plain | | +Partition of: oids_parted FOR VALUES FROM (1) TO (10) +Has OIDs: yes + +DROP TABLE oids_parted, part_forced_oids; -- check for partition bound overlap and other invalid specifications CREATE TABLE list_parted2 ( a varchar diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql index 5f25c436ee..f41dd71475 100644 --- a/src/test/regress/sql/create_table.sql +++ b/src/test/regress/sql/create_table.sql @@ -493,15 +493,17 @@ DROP TABLE temp_parted; CREATE TABLE no_oids_parted ( a int ) PARTITION BY RANGE (a) WITHOUT OIDS; -CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10 )WITH OIDS; +CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS; DROP TABLE no_oids_parted; --- likewise, the reverse if also true +-- If the partitioned table has oids, then the partition must have them. +-- If the WITHOUT OIDS option is specified for partition, it is overridden. CREATE TABLE oids_parted ( a int ) PARTITION BY RANGE (a) WITH OIDS; -CREATE TABLE fail_part PARTITION OF oids_parted FOR VALUES FROM (1) TO (10 ) WITHOUT OIDS; -DROP TABLE oids_parted; +CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS; +\d+ part_forced_oids +DROP TABLE oids_parted, part_forced_oids; -- check for partition bound overlap and other invalid specifications