@@ -317,16 +317,23 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
317317 <xref linkend="SQL-CREATETABLE">, plus the option <literal>NOT
318318 VALID</literal>, which is currently only allowed for foreign key
319319 and CHECK constraints.
320- If the constraint is marked <literal>NOT VALID</literal>, the
321- potentially-lengthy initial check to verify that all rows in the table
322- satisfy the constraint is skipped. The constraint will still be
320+ </para>
321+
322+ <para>
323+ Normally, this form will cause a scan of the table to verify that all
324+ existing rows in the table satisfy the new constraint. But if
325+ the <literal>NOT VALID</literal> option is used, this
326+ potentially-lengthy scan is skipped. The constraint will still be
323327 enforced against subsequent inserts or updates (that is, they'll fail
324328 unless there is a matching row in the referenced table, in the case
325- of foreign keys; and they'll fail unless the new row matches the
326- specified checkconstraints ). But the
329+ of foreign keys, or they'll fail unless the new row matches the
330+ specified checkcondition ). But the
327331 database will not assume that the constraint holds for all rows in
328332 the table, until it is validated by using the <literal>VALIDATE
329333 CONSTRAINT</literal> option.
334+ See <xref linkend="sql-altertable-notes"
335+ endterm="sql-altertable-notes-title"> below for more information
336+ about using the <literal>NOT VALID</literal> option.
330337 </para>
331338 </listitem>
332339 </varlistentry>
@@ -396,23 +403,13 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
396403 <term><literal>VALIDATE CONSTRAINT</literal></term>
397404 <listitem>
398405 <para>
399- This form validates a foreign key or check constraint that was previously created
400- as <literal>NOT VALID</literal>, by scanning the table to ensure there
401- are no rows for which the constraint is not satisfied.
402- Nothing happens if the constraint is already marked valid.
403- </para>
404- <para>
405- Validation can be a long process on larger tables. The value of separating
406- validation from initial creation is that you can defer validation to less
407- busy times, or can be used to give additional time to correct pre-existing
408- errors while preventing new errors. Note also that validation on its own
409- does not prevent normal write commands against the table while it runs.
410- </para>
411- <para>
412- Validation acquires only a <literal>SHARE UPDATE EXCLUSIVE</literal> lock
413- on the table being altered. If the constraint is a foreign key then
414- a <literal>ROW SHARE</literal> lock is also required on
415- the table referenced by the constraint.
406+ This form validates a foreign key or check constraint that was
407+ previously created as <literal>NOT VALID</literal>, by scanning the
408+ table to ensure there are no rows for which the constraint is not
409+ satisfied. Nothing happens if the constraint is already marked valid.
410+ (See <xref linkend="sql-altertable-notes"
411+ endterm="sql-altertable-notes-title"> below for an explanation of the
412+ usefulness of this command.)
416413 </para>
417414 </listitem>
418415 </varlistentry>
@@ -1079,8 +1076,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
10791076 </variablelist>
10801077 </refsect1>
10811078
1082- <refsect1>
1083- <title>Notes</title>
1079+ <refsect1 id="sql-altertable-notes" >
1080+ <title id="sql-altertable-notes-title" >Notes</title>
10841081
10851082 <para>
10861083 The key word <literal>COLUMN</literal> is noise and can be omitted.
@@ -1126,6 +1123,32 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
11261123 rewrites can thereby be combined into a single pass over the table.
11271124 </para>
11281125
1126+ <para>
1127+ Scanning a large table to verify a new foreign key or check constraint
1128+ can take a long time, and other updates to the table are locked out
1129+ until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
1130+ committed. The main purpose of the <literal>NOT VALID</literal>
1131+ constraint option is to reduce the impact of adding a constraint on
1132+ concurrent updates. With <literal>NOT VALID</literal>,
1133+ the <command>ADD CONSTRAINT</command> command does not scan the table
1134+ and can be committed immediately. After that, a <literal>VALIDATE
1135+ CONSTRAINT</literal> command can be issued to verify that existing rows
1136+ satisfy the constraint. The validation step does not need to lock out
1137+ concurrent updates, since it knows that other transactions will be
1138+ enforcing the constraint for rows that they insert or update; only
1139+ pre-existing rows need to be checked. Hence, validation acquires only
1140+ a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
1141+ altered. (If the constraint is a foreign key then a <literal>ROW
1142+ SHARE</literal> lock is also required on the table referenced by the
1143+ constraint.) In addition to improving concurrency, it can be useful to
1144+ use <literal>NOT VALID</literal> and <literal>VALIDATE
1145+ CONSTRAINT</literal> in cases where the table is known to contain
1146+ pre-existing violations. Once the constraint is in place, no new
1147+ violations can be inserted, and the existing problems can be corrected
1148+ at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
1149+ succeeds.
1150+ </para>
1151+
11291152 <para>
11301153 The <literal>DROP COLUMN</literal> form does not physically remove
11311154 the column, but simply makes it invisible to SQL operations. Subsequent