1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-03 20:02:46 +03:00

Change the rules for inherited CHECK constraints to be essentially the same

as those for inherited columns; that is, it's no longer allowed for a child
table to not have a check constraint matching one that exists on a parent.
This satisfies the principle of least surprise (rows selected from the parent
will always appear to meet its check constraints) and eliminates some
longstanding bogosity in pg_dump, which formerly had to guess about whether
check constraints were really inherited or not.

The implementation involves adding conislocal and coninhcount columns to
pg_constraint (paralleling attislocal and attinhcount in pg_attribute)
and refactoring various ALTER TABLE actions to be more like those for
columns.

Alex Hunsaker, Nikhil Sontakke, Tom Lane
This commit is contained in:
Tom Lane
2008-05-09 23:32:05 +00:00
parent f8df836ae3
commit cd902b331d
25 changed files with 1391 additions and 575 deletions

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.165 2008/04/14 17:05:32 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/catalogs.sgml,v 2.166 2008/05/09 23:32:03 tgl Exp $ -->
<!--
Documentation of the system catalogs, directed toward PostgreSQL developers
-->
@ -1907,6 +1907,26 @@
<entry>Foreign key match type</entry>
</row>
<row>
<entry><structfield>conislocal</structfield></entry>
<entry><type>bool</type></entry>
<entry></entry>
<entry>
This constraint is defined locally in the relation. Note that a
constraint can be locally defined and inherited simultaneously
</entry>
</row>
<row>
<entry><structfield>coninhcount</structfield></entry>
<entry><type>int4</type></entry>
<entry></entry>
<entry>
The number of direct ancestors this constraint has. A constraint with
a nonzero number of ancestors cannot be dropped nor renamed
</entry>
</row>
<row>
<entry><structfield>conkey</structfield></entry>
<entry><type>int2[]</type></entry>

View File

@ -1,4 +1,4 @@
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.81 2008/01/13 17:58:54 tgl Exp $ -->
<!-- $PostgreSQL: pgsql/doc/src/sgml/ddl.sgml,v 1.82 2008/05/09 23:32:03 tgl Exp $ -->
<chapter id="ddl">
<title>Data Definition</title>
@ -2107,7 +2107,8 @@ VALUES ('New York', NULL, NULL, 'NY');
<para>
A parent table cannot be dropped while any of its children remain. Neither
can columns of child tables be dropped or altered if they are inherited
can columns or check constraints of child tables be dropped or altered
if they are inherited
from any parent tables. If you wish to remove a table and all of its
descendants, one easy way is to drop the parent table with the
<literal>CASCADE</literal> option.
@ -2117,7 +2118,7 @@ VALUES ('New York', NULL, NULL, 'NY');
<xref linkend="sql-altertable" endterm="sql-altertable-title"> will
propagate any changes in column data definitions and check
constraints down the inheritance hierarchy. Again, dropping
columns or constraints on parent tables is only possible when using
columns that are depended on by other tables is only possible when using
the <literal>CASCADE</literal> option. <command>ALTER
TABLE</command> follows the same rules for duplicate column merging
and rejection that apply during <command>CREATE TABLE</command>.

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.98 2007/11/28 15:42:31 petere Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/alter_table.sgml,v 1.99 2008/05/09 23:32:03 tgl Exp $
PostgreSQL documentation
-->
@ -713,7 +713,8 @@ ALTER TABLE table ALTER COLUMN anycol TYPE anytype;
The <literal>TRIGGER</>, <literal>CLUSTER</>, <literal>OWNER</>,
and <literal>TABLESPACE</> actions never recurse to descendant tables;
that is, they always act as though <literal>ONLY</> were specified.
Adding a constraint can recurse only for <literal>CHECK</> constraints.
Adding a constraint can recurse only for <literal>CHECK</> constraints,
and is required to do so for such constraints.
</para>
<para>
@ -804,7 +805,7 @@ ALTER TABLE distributors ALTER COLUMN street DROP NOT NULL;
</para>
<para>
To add a check constraint to a table:
To add a check constraint to a table and all its children:
<programlisting>
ALTER TABLE distributors ADD CONSTRAINT zipchk CHECK (char_length(zipcode) = 5);
</programlisting>
@ -817,6 +818,14 @@ ALTER TABLE distributors DROP CONSTRAINT zipchk;
</programlisting>
</para>
<para>
To remove a check constraint from a table only:
<programlisting>
ALTER TABLE ONLY distributors DROP CONSTRAINT zipchk;
</programlisting>
(The check constraint remains in place for any child tables.)
</para>
<para>
To add a foreign key constraint to a table:
<programlisting>

View File

@ -1,5 +1,5 @@
<!--
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.109 2007/07/17 05:02:00 neilc Exp $
$PostgreSQL: pgsql/doc/src/sgml/ref/create_table.sgml,v 1.110 2008/05/09 23:32:04 tgl Exp $
PostgreSQL documentation
-->
@ -210,16 +210,25 @@ and <replaceable class="PARAMETER">table_constraint</replaceable> is:
the new table. If the column name list of the new table
contains a column name that is also inherited, the data type must
likewise match the inherited column(s), and the column
definitions are merged into one. However, inherited and new
column declarations of the same name need not specify identical
constraints: all constraints provided from any declaration are
merged together and all are applied to the new table. If the
definitions are merged into one. If the
new table explicitly specifies a default value for the column,
this default overrides any defaults from inherited declarations
of the column. Otherwise, any parents that specify default
values for the column must all specify the same default, or an
error will be reported.
</para>
<para>
<literal>CHECK</> constraints are merged in essentially the same way as
columns: if multiple parent tables and/or the new table definition
contain identically-named <literal>CHECK</> constraints, these
constraints must all have the same check expression, or an error will be
reported. Constraints having the same name and expression will
be merged into one copy. Notice that an unnamed <literal>CHECK</>
constraint in the new table will never be merged, since a unique name
will always be chosen for it.
</para>
<!--
<para>
<productname>PostgreSQL</> automatically allows the