<literal>USING</literal> clause does not change the column
contents and the old type is either binary coercible to the new type
or an unconstrained domain over the new type, a table rewrite is not
needed. However, indexes will still be rebuilt unless the system
can verify that the new index would be logically equivalent to the
existing one. For example, if the collation for a column has been
changed, an index rebuild is required because the new sort
order might be different. However, in the absence of a collation
change, a column can be changed from <type>text</type> to
<type>varchar</type> (or vice versa) without rebuilding the indexes
because these data types sort identically.
</para>
<para>
Table and/or index
rebuilds may take a significant amount of time for a large table,
and will temporarily require as much as double the disk space.
</para>
<para>
Adding an enforced <literal>CHECK</literal> or <literal>NOT NULL</literal>
constraint requires scanning the table to verify that existing rows meet the
constraint, but does not require a table rewrite. If a <literal>CHECK</literal>
constraint is added as <literal>NOT ENFORCED</literal>, the validation will
not be performed.
</para>
<para>
Similarly, when attaching a new partition it may be scanned to verify that
existing rows meet the partition constraint.
</para>
<para>
The main reason for providing the option to specify multiple changes
in a single <command>ALTER TABLE</command> is that multiple table scans or
rewrites can thereby be combined into a single pass over the table.
</para>
<para>
Scanning a large table to verify a new foreign key or check constraint
can take a long time, and other updates to the table are locked out
until the <command>ALTER TABLE ADD CONSTRAINT</command> command is
committed. The main purpose of the <literal>NOT VALID</literal>
constraint option is to reduce the impact of adding a constraint on
concurrent updates. With <literal>NOT VALID</literal>,
the <command>ADD CONSTRAINT</command> command does not scan the table
and can be committed immediately. After that, a <literal>VALIDATE
CONSTRAINT</literal> command can be issued to verify that existing rows
satisfy the constraint. The validation step does not need to lock out
concurrent updates, since it knows that other transactions will be
enforcing the constraint for rows that they insert or update; only
pre-existing rows need to be checked. Hence, validation acquires only
a <literal>SHARE UPDATE EXCLUSIVE</literal> lock on the table being
altered. (If the constraint is a foreign key then a <literal>ROW
SHARE</literal> lock is also required on the table referenced by the
constraint.) In addition to improving concurrency, it can be useful to
use <literal>NOT VALID</literal> and <literal>VALIDATE
CONSTRAINT</literal> in cases where the table is known to contain
pre-existing violations. Once the constraint is in place, no new
violations can be inserted, and the existing problems can be corrected
at leisure until <literal>VALIDATE CONSTRAINT</literal> finally
succeeds.
</para>
<para>
The <literal>DROP COLUMN</literal> form does not physically remove
the column, but simply makes it invisible to SQL operations. Subsequent
insert and update operations in the table will store a null value for the
column. Thus, dropping a column is quick but it will not immediately
reduce the on-disk size of your table, as the space occupied
by the dropped column is not reclaimed. The space will be
reclaimed over time as existing rows are updated.
</para>
<para>
To force immediate reclamation of space occupied by a dropped column,
you can execute one of the forms of <command>ALTER TABLE</command> that
performs a rewrite of the whole table. This