@@ -317,16 +317,23 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
317
317
<xref linkend="SQL-CREATETABLE">, plus the option <literal>NOT
318
318
VALID</literal>, which is currently only allowed for foreign key
319
319
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
323
327
enforced against subsequent inserts or updates (that is, they'll fail
324
328
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 check constraints ). But the
329
+ of foreign keys, or they'll fail unless the new row matches the
330
+ specified check condition ). But the
327
331
database will not assume that the constraint holds for all rows in
328
332
the table, until it is validated by using the <literal>VALIDATE
329
333
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.
330
337
</para>
331
338
</listitem>
332
339
</varlistentry>
@@ -396,23 +403,13 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
396
403
<term><literal>VALIDATE CONSTRAINT</literal></term>
397
404
<listitem>
398
405
<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.)
416
413
</para>
417
414
</listitem>
418
415
</varlistentry>
@@ -1079,8 +1076,8 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="PARAMETER">name</replaceable>
1079
1076
</variablelist>
1080
1077
</refsect1>
1081
1078
1082
- <refsect1>
1083
- <title>Notes</title>
1079
+ <refsect1 id="sql-altertable-notes" >
1080
+ <title id="sql-altertable-notes-title" >Notes</title>
1084
1081
1085
1082
<para>
1086
1083
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>
1126
1123
rewrites can thereby be combined into a single pass over the table.
1127
1124
</para>
1128
1125
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
+
1129
1152
<para>
1130
1153
The <literal>DROP COLUMN</literal> form does not physically remove
1131
1154
the column, but simply makes it invisible to SQL operations. Subsequent
0 commit comments