non-<literal>NaN</literal> values.
</para>
</note>
<para>
<productname>PostgreSQL</productname> also supports the SQL-standard
notations <type>float</type> and
<type>float(<replaceable>p</replaceable>)</type> for specifying
inexact numeric types. Here, <replaceable>p</replaceable> specifies
the minimum acceptable precision in <emphasis>binary</emphasis> digits.
<productname>PostgreSQL</productname> accepts
<type>float(1)</type> to <type>float(24)</type> as selecting the
<type>real</type> type, while
<type>float(25)</type> to <type>float(53)</type> select
<type>double precision</type>. Values of <replaceable>p</replaceable>
outside the allowed range draw an error.
<type>float</type> with no precision specified is taken to mean
<type>double precision</type>.
</para>
</sect2>
<sect2 id="datatype-serial">
<title>Serial Types</title>
<indexterm zone="datatype-serial">
<primary>smallserial</primary>
</indexterm>
<indexterm zone="datatype-serial">
<primary>serial</primary>
</indexterm>
<indexterm zone="datatype-serial">
<primary>bigserial</primary>
</indexterm>
<indexterm zone="datatype-serial">
<primary>serial2</primary>
</indexterm>
<indexterm zone="datatype-serial">
<primary>serial4</primary>
</indexterm>
<indexterm zone="datatype-serial">
<primary>serial8</primary>
</indexterm>
<indexterm>
<primary>auto-increment</primary>
<see>serial</see>
</indexterm>
<indexterm>
<primary>sequence</primary>
<secondary>and serial type</secondary>
</indexterm>
<note>
<para>
This section describes a PostgreSQL-specific way to create an
autoincrementing column. Another way is to use the SQL-standard
identity column feature, described at <xref linkend="ddl-identity-columns"/>.
</para>
</note>
<para>
The data types <type>smallserial</type>, <type>serial</type> and
<type>bigserial</type> are not true types, but merely
a notational convenience for creating unique identifier columns
(similar to the <literal>AUTO_INCREMENT</literal> property
supported by some other databases). In the current
implementation, specifying:
<programlisting>
CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
<replaceable class="parameter">colname</replaceable> SERIAL
);
</programlisting>
is equivalent to specifying:
<programlisting>
CREATE SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq AS integer;
CREATE TABLE <replaceable class="parameter">tablename</replaceable> (
<replaceable class="parameter">colname</replaceable> integer NOT NULL DEFAULT nextval('<replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq')
);
ALTER SEQUENCE <replaceable class="parameter">tablename</replaceable>_<replaceable class="parameter">colname</replaceable>_seq OWNED BY <replaceable class="parameter">tablename</replaceable>.<replaceable class="parameter">colname</replaceable>;
</programlisting>
Thus, we have created an integer column and arranged for its default
values to be assigned from a sequence generator. A <literal>NOT NULL</literal>
constraint is applied to ensure that a null value cannot be
inserted. (In most cases you would also want to attach a
<literal>UNIQUE</literal> or <literal>PRIMARY KEY</literal> constraint to prevent
duplicate values from being inserted by accident, but this is
not automatic.) Lastly, the sequence is marked as <quote>owned by</quote>
the column, so that it will be dropped if the column or table is dropped.
</para>
<note>
<para>
Because <type>smallserial</type>, <type>serial</type> and
<type>bigserial</type> are implemented using sequences, there