@@ -358,27 +358,36 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
358
358
<xref linkend="sql-createtable"/>, plus the option <literal>NOT
359
359
VALID</literal>, which is currently only allowed for foreign key
360
360
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
364
368
enforced against subsequent inserts or updates (that is, they'll fail
365
369
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
368
372
database will not assume that the constraint holds for all rows in
369
373
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.
372
378
</para>
373
379
374
380
<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.
377
384
</para>
378
385
379
386
<para>
380
387
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.
382
391
</para>
383
392
384
393
</listitem>
@@ -453,23 +462,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
453
462
<term><literal>VALIDATE CONSTRAINT</literal></term>
454
463
<listitem>
455
464
<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.)
473
472
</para>
474
473
</listitem>
475
474
</varlistentry>
@@ -1153,8 +1152,8 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
1153
1152
</variablelist>
1154
1153
</refsect1>
1155
1154
1156
- <refsect1>
1157
- <title>Notes</title>
1155
+ <refsect1 id="sql-altertable-notes" >
1156
+ <title id="sql-altertable-notes-title" >Notes</title>
1158
1157
1159
1158
<para>
1160
1159
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
1199
1198
rewrites can thereby be combined into a single pass over the table.
1200
1199
</para>
1201
1200
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
+
1202
1227
<para>
1203
1228
The <literal>DROP COLUMN</literal> form does not physically remove
1204
1229
the column, but simply makes it invisible to SQL operations. Subsequent
0 commit comments