@@ -358,27 +358,36 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
358358 <xref linkend="sql-createtable"/>, plus the option <literal>NOT
359359 VALID</literal>, which is currently only allowed for foreign key
360360 and CHECK constraints.
361- If the constraint is marked <literal>NOT VALID</literal>, the
362- potentially-lengthy initial check to verify that all rows in the table
363- satisfy the constraint is skipped. The constraint will still be
361+ </para>
362+
363+ <para>
364+ Normally, this form will cause a scan of the table to verify that all
365+ existing rows in the table satisfy the new constraint. But if
366+ the <literal>NOT VALID</literal> option is used, this
367+ potentially-lengthy scan is skipped. The constraint will still be
364368 enforced against subsequent inserts or updates (that is, they'll fail
365369 unless there is a matching row in the referenced table, in the case
366- of foreign keys; and they'll fail unless the new row matches the
367- specified check constraints ). But the
370+ of foreign keys, or they'll fail unless the new row matches the
371+ specified check condition ). But the
368372 database will not assume that the constraint holds for all rows in
369373 the table, until it is validated by using the <literal>VALIDATE
370- CONSTRAINT</literal> option. Foreign key constraints on partitioned
371- tables may not be declared <literal>NOT VALID</literal> at present.
374+ CONSTRAINT</literal> option.
375+ See <xref linkend="sql-altertable-notes"
376+ endterm="sql-altertable-notes-title"/> below for more information
377+ about using the <literal>NOT VALID</literal> option.
372378 </para>
373379
374380 <para>
375- The addition of a foreign key constraint requires a
376- <literal>SHARE ROW EXCLUSIVE</literal> lock on the referenced table.
381+ Addition of a foreign key constraint requires a
382+ <literal>SHARE ROW EXCLUSIVE</literal> lock on the referenced table,
383+ in addition to the lock on the table receiving the constraint.
377384 </para>
378385
379386 <para>
380387 Additional restrictions apply when unique or primary key constraints
381- are added to partitioned tables; see <xref linkend="sql-createtable" />.
388+ are added to partitioned tables; see <xref linkend="sql-createtable"/>.
389+ Also, foreign key constraints on partitioned
390+ tables may not be declared <literal>NOT VALID</literal> at present.
382391 </para>
383392
384393 </listitem>
@@ -453,23 +462,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
453462 <term><literal>VALIDATE CONSTRAINT</literal></term>
454463 <listitem>
455464 <para>
456- This form validates a foreign key or check constraint that was previously created
457- as <literal>NOT VALID</literal>, by scanning the table to ensure there
458- are no rows for which the constraint is not satisfied.
459- Nothing happens if the constraint is already marked valid.
460- </para>
461- <para>
462- Validation can be a long process on larger tables. The value of separating
463- validation from initial creation is that you can defer validation to less
464- busy times, or can be used to give additional time to correct pre-existing
465- errors while preventing new errors. Note also that validation on its own
466- does not prevent normal write commands against the table while it runs.
467- </para>
468- <para>
469- Validation acquires only a <literal>SHARE UPDATE EXCLUSIVE</literal> lock
470- on the table being altered. If the constraint is a foreign key then
471- a <literal>ROW SHARE</literal> lock is also required on
472- the table referenced by the constraint.
465+ This form validates a foreign key or check constraint that was
466+ previously created as <literal>NOT VALID</literal>, by scanning the
467+ table to ensure there are no rows for which the constraint is not
468+ satisfied. Nothing happens if the constraint is already marked valid.
469+ (See <xref linkend="sql-altertable-notes"
470+ endterm="sql-altertable-notes-title"/> below for an explanation of the
471+ usefulness of this command.)
473472 </para>
474473 </listitem>
475474 </varlistentry>
@@ -1153,8 +1152,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
11531152 </variablelist>
11541153 </refsect1>
11551154
1156- <refsect1>
1157- <title>Notes</title>
1155+ <refsect1 id="sql-altertable-notes" >
1156+ <title id="sql-altertable-notes-title" >Notes</title>
11581157
11591158 <para>
11601159 The key word <literal>COLUMN</literal> is noise and can be omitted.
@@ -1199,6 +1198,32 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
11991198 rewrites can thereby be combined into a single pass over the table.
12001199 </para>
12011200
1201+ <para>
1202+ Scanning a large table to verify a new foreign key or check constraint
1203+ can take a long time, and other updates to the table are locked out
1204+ until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
1205+ committed. The main purpose of the <literal>NOT VALID</literal>
1206+ constraint option is to reduce the impact of adding a constraint on
1207+ concurrent updates. With <literal>NOT VALID</literal>,
1208+ the <command>ADD CONSTRAINT</command> command does not scan the table
1209+ and can be committed immediately. After that, a <literal>VALIDATE
1210+ CONSTRAINT</literal> command can be issued to verify that existing rows
1211+ satisfy the constraint. The validation step does not need to lock out
1212+ concurrent updates, since it knows that other transactions will be
1213+ enforcing the constraint for rows that they insert or update; only
1214+ pre-existing rows need to be checked. Hence, validation acquires only
1215+ a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
1216+ altered. (If the constraint is a foreign key then a <literal>ROW
1217+ SHARE</literal> lock is also required on the table referenced by the
1218+ constraint.) In addition to improving concurrency, it can be useful to
1219+ use <literal>NOT VALID</literal> and <literal>VALIDATE
1220+ CONSTRAINT</literal> in cases where the table is known to contain
1221+ pre-existing violations. Once the constraint is in place, no new
1222+ violations can be inserted, and the existing problems can be corrected
1223+ at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
1224+ succeeds.
1225+ </para>
1226+
12021227 <para>
12031228 The <literal>DROP COLUMN</literal> form does not physically remove
12041229 the column, but simply makes it invisible to SQL operations. Subsequent
0 commit comments