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
This commit is contained in:
Robert Haas 2017-02-19 21:29:27 +05:30
parent 0414b26bac
commit a3dc8e495b
5 changed files with 44 additions and 47 deletions

View File

@ -2861,14 +2861,6 @@ VALUES ('Albany', NULL, NULL, 'NY');
</para> </para>
</listitem> </listitem>
<listitem>
<para>
If the partitioned table specified <literal>WITH OIDS</literal> then
each partition must also specify <literal>WITH OIDS</literal>. Oids
are not automatically inherited by partitions.
</para>
</listitem>
<listitem> <listitem>
<para> <para>
One cannot drop a <literal>NOT NULL</literal> constraint on a One cannot drop a <literal>NOT NULL</literal> constraint on a

View File

@ -300,14 +300,18 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
</note> </note>
<para> <para>
A partition cannot have columns other than those inherited from the A partition must have the same column names and types as the partitioned
parent. If the parent is specified <literal>WITH OIDS</literal> then table to which it belongs. If the parent is specified <literal>WITH
the partitions must also explicitly specify <literal>WITH OIDS</literal>. OIDS</literal> then all partitions must have OIDs; the parent's OID
Defaults and constraints can optionally be specified for each of the column will be inherited by all partitions just like any other column.
inherited columns. One can also specify table constraints in addition Modifications to the column names or types of a partitioned table, or
to those inherited from the parent. If a check constraint with the name the addition or removal of an OID column, will automatically propagate
matching one of the parent's constraint is specified, it is merged with to all partitions. <literal>CHECK</> constraints will be inherited
the latter, provided the specified condition is same. automatically by every partition, but an individual partition may specify
additional <literal>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.
</para> </para>
<para> <para>
@ -318,15 +322,11 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
</para> </para>
<para> <para>
A partition must have the same column names and types as the table of Operations such as TRUNCATE which normally affect a table and all of its
which it is a partition. Therefore, modifications to the column names inheritance children will cascade to all partitions, but may also be
or types of the partitioned table will automatically propagate to all performed on an individual partition. Note that dropping a partition
children, as will operations such as TRUNCATE which normally affect a with <literal>DROP TABLE</literal> requires taking an <literal>ACCESS
table and all of its inheritance children. It is also possible to EXCLUSIVE</literal> lock on the parent table.
TRUNCATE a partition individually, just as for an inheritance child.
Note that dropping a partition with <literal>DROP TABLE</literal>
requires taking an <literal>ACCESS EXCLUSIVE</literal> lock on the
parent table.
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>

View File

@ -634,19 +634,14 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
relkind == RELKIND_PARTITIONED_TABLE)); relkind == RELKIND_PARTITIONED_TABLE));
descriptor->tdhasoid = (localHasOids || parentOidCount > 0); descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
if (stmt->partbound) /*
{ * If a partitioned table doesn't have the system OID column, then none
/* If the parent has OIDs, partitions must have them too. */ * of its partitions should have it.
if (parentOidCount > 0 && !localHasOids) */
ereport(ERROR, if (stmt->partbound && parentOidCount == 0 && localHasOids)
(errcode(ERRCODE_WRONG_OBJECT_TYPE), ereport(ERROR,
errmsg("cannot create table without OIDs as partition of table with OIDs"))); (errcode(ERRCODE_WRONG_OBJECT_TYPE),
/* If the parent doesn't, partitions must not have them. */ errmsg("cannot create table with OIDs as partition of table without OIDs")));
if (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 * Find columns with default values and prepare for insertion of the

View File

@ -524,16 +524,24 @@ DROP TABLE temp_parted;
CREATE TABLE no_oids_parted ( CREATE TABLE no_oids_parted (
a int a int
) PARTITION BY RANGE (a) WITHOUT OIDS; ) 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 ERROR: cannot create table with OIDs as partition of table without OIDs
DROP TABLE no_oids_parted; 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 ( CREATE TABLE oids_parted (
a int a int
) PARTITION BY RANGE (a) WITH OIDS; ) PARTITION BY RANGE (a) WITH OIDS;
CREATE TABLE fail_part PARTITION OF oids_parted FOR VALUES FROM (1) TO (10 ) WITHOUT OIDS; CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS;
ERROR: cannot create table without OIDs as partition of table with OIDs \d+ part_forced_oids
DROP TABLE oids_parted; 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 -- check for partition bound overlap and other invalid specifications
CREATE TABLE list_parted2 ( CREATE TABLE list_parted2 (
a varchar a varchar

View File

@ -493,15 +493,17 @@ DROP TABLE temp_parted;
CREATE TABLE no_oids_parted ( CREATE TABLE no_oids_parted (
a int a int
) PARTITION BY RANGE (a) WITHOUT OIDS; ) 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; 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 ( CREATE TABLE oids_parted (
a int a int
) PARTITION BY RANGE (a) WITH OIDS; ) PARTITION BY RANGE (a) WITH OIDS;
CREATE TABLE fail_part PARTITION OF oids_parted FOR VALUES FROM (1) TO (10 ) WITHOUT OIDS; CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS;
DROP TABLE oids_parted; \d+ part_forced_oids
DROP TABLE oids_parted, part_forced_oids;
-- check for partition bound overlap and other invalid specifications -- check for partition bound overlap and other invalid specifications