linkend="maintenance"/> for details. It is
unwise, however, to depend on the uniqueness of transaction IDs
over the long term (more than one billion transactions).
</para>
<para>
Command identifiers are also 32-bit quantities. This creates a hard limit
of 2<superscript>32</superscript> (4 billion) <acronym>SQL</acronym> commands
within a single transaction. In practice this limit is not a
problem — note that the limit is on the number of
<acronym>SQL</acronym> commands, not the number of rows processed.
Also, only commands that actually modify the database contents will
consume a command identifier.
</para>
</sect1>
<sect1 id="ddl-alter">
<title>Modifying Tables</title>
<indexterm zone="ddl-alter">
<primary>table</primary>
<secondary>modifying</secondary>
</indexterm>
<para>
When you create a table and you realize that you made a mistake, or
the requirements of the application change, you can drop the
table and create it again. But this is not a convenient option if
the table is already filled with data, or if the table is
referenced by other database objects (for instance a foreign key
constraint). Therefore <productname>PostgreSQL</productname>
provides a family of commands to make modifications to existing
tables. Note that this is conceptually distinct from altering
the data contained in the table: here we are interested in altering
the definition, or structure, of the table.
</para>
<para>
You can:
<itemizedlist spacing="compact">
<listitem>
<para>Add columns</para>
</listitem>
<listitem>
<para>Remove columns</para>
</listitem>
<listitem>
<para>Add constraints</para>
</listitem>
<listitem>
<para>Remove constraints</para>
</listitem>
<listitem>
<para>Change default values</para>
</listitem>
<listitem>
<para>Change column data types</para>
</listitem>
<listitem>
<para>Rename columns</para>
</listitem>
<listitem>
<para>Rename tables</para>
</listitem>
</itemizedlist>
All these actions are performed using the
<xref linkend="sql-altertable"/>
command, whose reference page contains details beyond those given
here.
</para>
<sect2 id="ddl-alter-adding-a-column">
<title>Adding a Column</title>
<indexterm>
<primary>column</primary>
<secondary>adding</secondary>
</indexterm>
<para>
To add a column, use a command like:
<programlisting>
ALTER TABLE products ADD COLUMN description text;
</programlisting>
The new column is initially filled with whatever default
value is given (null if you don't specify a <literal>DEFAULT</literal> clause).
</para>
<tip>
<para>
Adding a column with a constant default value does not require each row of
the table to be updated when the <command>ALTER TABLE</command> statement
is executed. Instead, the default value will be returned the next time
the row is accessed, and applied when the table is rewritten, making
the <command>ALTER TABLE</command> very fast even on large tables.
</para>
<para>
If the default value is volatile (e.g., <function>clock_timestamp()</function>)
each row will need to be updated with the value calculated at the time
<command>ALTER TABLE</command> is executed. To avoid a potentially
lengthy update operation, particularly if you intend to fill the column
with mostly nondefault values anyway, it may be preferable to add the
column with no default, insert the correct values using
<command>UPDATE</command>, and then add any desired default as described
below.
</para>
</tip>
<para>
You can also define constraints on the column at the same time,
using the usual syntax:
<programlisting>
ALTER TABLE products ADD COLUMN description text CHECK (description <> '');
</programlisting>
In fact all the options that