@@ -266,16 +266,23 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
266
266
<xref linkend="SQL-CREATETABLE">, plus the option <literal>NOT
267
267
VALID</literal>, which is currently only allowed for foreign key
268
268
and CHECK constraints.
269
- If the constraint is marked <literal>NOT VALID</literal>, the
270
- potentially-lengthy initial check to verify that all rows in the table
271
- satisfy the constraint is skipped. The constraint will still be
269
+ </para>
270
+
271
+ <para>
272
+ Normally, this form will cause a scan of the table to verify that all
273
+ existing rows in the table satisfy the new constraint. But if
274
+ the <literal>NOT VALID</literal> option is used, this
275
+ potentially-lengthy scan is skipped. The constraint will still be
272
276
enforced against subsequent inserts or updates (that is, they'll fail
273
277
unless there is a matching row in the referenced table, in the case
274
- of foreign keys; and they'll fail unless the new row matches the
275
- specified check constraints ). But the
278
+ of foreign keys, or they'll fail unless the new row matches the
279
+ specified check condition ). But the
276
280
database will not assume that the constraint holds for all rows in
277
281
the table, until it is validated by using the <literal>VALIDATE
278
282
CONSTRAINT</literal> option.
283
+ See <xref linkend="sql-altertable-notes"
284
+ endterm="sql-altertable-notes-title"> below for more information
285
+ about using the <literal>NOT VALID</literal> option.
279
286
</para>
280
287
</listitem>
281
288
</varlistentry>
@@ -345,23 +352,13 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
345
352
<term><literal>VALIDATE CONSTRAINT</literal></term>
346
353
<listitem>
347
354
<para>
348
- This form validates a foreign key or check constraint that was previously created
349
- as <literal>NOT VALID</literal>, by scanning the table to ensure there
350
- are no rows for which the constraint is not satisfied.
351
- Nothing happens if the constraint is already marked valid.
352
- </para>
353
- <para>
354
- Validation can be a long process on larger tables. The value of separating
355
- validation from initial creation is that you can defer validation to less
356
- busy times, or can be used to give additional time to correct pre-existing
357
- errors while preventing new errors. Note also that validation on its own
358
- does not prevent normal write commands against the table while it runs.
359
- </para>
360
- <para>
361
- Validation acquires only a <literal>SHARE UPDATE EXCLUSIVE</literal> lock
362
- on the table being altered. If the constraint is a foreign key then
363
- a <literal>ROW SHARE</literal> lock is also required on
364
- the table referenced by the constraint.
355
+ This form validates a foreign key or check constraint that was
356
+ previously created as <literal>NOT VALID</literal>, by scanning the
357
+ table to ensure there are no rows for which the constraint is not
358
+ satisfied. Nothing happens if the constraint is already marked valid.
359
+ (See <xref linkend="sql-altertable-notes"
360
+ endterm="sql-altertable-notes-title"> below for an explanation of the
361
+ usefulness of this command.)
365
362
</para>
366
363
</listitem>
367
364
</varlistentry>
@@ -883,8 +880,8 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
883
880
</variablelist>
884
881
</refsect1>
885
882
886
- <refsect1>
887
- <title>Notes</title>
883
+ <refsect1 id="sql-altertable-notes" >
884
+ <title id="sql-altertable-notes-title" >Notes</title>
888
885
889
886
<para>
890
887
The key word <literal>COLUMN</literal> is noise and can be omitted.
@@ -925,6 +922,32 @@ ALTER TABLE ALL IN TABLESPACE <replaceable class="PARAMETER">name</replaceable>
925
922
rewrites can thereby be combined into a single pass over the table.
926
923
</para>
927
924
925
+ <para>
926
+ Scanning a large table to verify a new foreign key or check constraint
927
+ can take a long time, and other updates to the table are locked out
928
+ until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
929
+ committed. The main purpose of the <literal>NOT VALID</literal>
930
+ constraint option is to reduce the impact of adding a constraint on
931
+ concurrent updates. With <literal>NOT VALID</literal>,
932
+ the <command>ADD CONSTRAINT</command> command does not scan the table
933
+ and can be committed immediately. After that, a <literal>VALIDATE
934
+ CONSTRAINT</literal> command can be issued to verify that existing rows
935
+ satisfy the constraint. The validation step does not need to lock out
936
+ concurrent updates, since it knows that other transactions will be
937
+ enforcing the constraint for rows that they insert or update; only
938
+ pre-existing rows need to be checked. Hence, validation acquires only
939
+ a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
940
+ altered. (If the constraint is a foreign key then a <literal>ROW
941
+ SHARE</literal> lock is also required on the table referenced by the
942
+ constraint.) In addition to improving concurrency, it can be useful to
943
+ use <literal>NOT VALID</literal> and <literal>VALIDATE
944
+ CONSTRAINT</literal> in cases where the table is known to contain
945
+ pre-existing violations. Once the constraint is in place, no new
946
+ violations can be inserted, and the existing problems can be corrected
947
+ at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
948
+ succeeds.
949
+ </para>
950
+
928
951
<para>
929
952
The <literal>DROP COLUMN</literal> form does not physically remove
930
953
the column, but simply makes it invisible to SQL operations. Subsequent
0 commit comments