--- /dev/null
+<!-- doc/src/sgml/seqam.sgml -->
+
+<chapter id="seqam">
+ <title>Sequence Access Method Interface Definition</title>
+
+ <para>
+ This chapter describes the interface for writing sequence access methods.
+ </para>
+
+ <para>
+ The sequence access method defines behavior of a sequence which is using it.
+ Mainly how the new values are generated. Each sequence can have different
+ access method in order to behave in a way that makes most sense in the
+ application context.
+ </para>
+
+ <para>
+ All sequence access method share same storage. The storage API is provided
+ by <productname>PostgreSQL</> backend.
+ </para>
+
+ <sect1 id="seqam-catalog">
+ <title>Catalog Entries for Sequence Access Method</title>
+
+ <para>
+ Each sequence access method is described by a row in the
+ <structname>pg_seqam</structname> system catalog (see
+ <xref linkend="catalog-pg-seqam">). The contents of a
+ <structname>pg_seqam</structname> row is the name of the access method
+ and are references to
+ <link linkend="catalog-pg-proc"><structname>pg_proc</structname></link>
+ entries that identify the functions provided by the access method.
+ functions supplied by the access method.
+ </para>
+ </sect1>
+
+ <sect1 id="seqam-functions">
+ <title>Sequence Access Method Functions</title>
+
+ <para>
+ The functions defining the sequence access method API are:
+ </para>
+
+ <para>
+<programlisting>
+void
+seqam_init (Oid seqrelid, List *seqparams, bytea *reloptions,
+ Datum *value, bool *nulls);
+</programlisting>
+ Initialize sequence. This function is called both for new sequence
+ initilization and for reinitialization when the sequence access method
+ has been changed by <command>ALTER SEQUENCE</>. The <literal>seqrelid</>
+ is set InvalidOid if new sequence is being initialized, otherwise it points
+ to <link linkend="catalog-pg-class"><structname>pg_class</structname></link>
+ tuple representing the existing sequence.
+ The <literal>seqparams</> is list of <structname>DefElem</>s as passed to
+ the <command>CREATE SEQUENCE</> or <command>ALTER SEQUENCE</> statements.
+ <literal>reloptions</> contains parsed reloptions passed to the
+ <command>CREATE SEQUENCE</> or <command>ALTER SEQUENCE</> statements.
+ The <literal>values</> and <literal>nulls</> describe new tuple for the
+ <structname>pg_sequence</structname> tuple which this function can update
+ as needed.
+ </para>
+
+ <para>
+<programlisting>
+bytea *
+seqam_reloptions (ArrayType *reloptions, bool validate);
+</programlisting>
+ Parse and validate the reloptions array for an sequence.
+ <parameter>reloptions</> is a <type>text</> array containing entries of the
+ form <replaceable>name</><literal>=</><replaceable>value</>.
+ The function should construct a <type>bytea</> value, which will be then sent
+ to the <function>seqam_init</> and stored in the catalog.
+ When <parameter>validate</> is true, the function should report a suitable
+ error message if any of the options are unrecognized or have invalid
+ values; when <parameter>validate</> is false, invalid entries should be
+ silently ignored. (<parameter>validate</> is false when loading options
+ already stored in <structname>pg_catalog</>; an invalid entry could only
+ be found if the access method has changed its rules for options, and in
+ that case ignoring obsolete entries is appropriate.)
+ It is OK to return NULL if default behavior is wanted.
+ </para>
+
+ <para>
+<programlisting>
+int64
+seqam_alloc (Relation seqrel, SequenceHandle *seqh, int64 nrequested,
+ int64 *last);
+</programlisting>
+ Allocate new sequence value(s). The <literal>nrequested</> specifies how
+ many new values should be allocated by this call. Return value is the next
+ allocated value and <literal>last</> should be set to last allocated value.
+ </para>
+
+ <para>
+<programlisting>
+bool
+seqam_setval Relation seqrel, SequenceHandle *seqh, int64 new_value)
+</programlisting>
+ Set the current sequence value the the <literal>new_value</>.
+ </para>
+
+ <para>
+<programlisting>
+int
+seqam_get_state (Relation seqrel, SequenceHandle *seqh, char ***keys,
+ char ***values);
+</programlisting>
+ Dump the current state of the sequence. Return value is number of elements
+ in the output arrays <literal>keys</> and <literal>values</> which in turn
+ define the key/value pairs of the current state description. This interface
+ is mainly used by <command>pg_dump</command>.
+ </para>
+
+ <para>
+<programlisting>
+void
+seqam_set_state (Relation seqrel, SequenceHandle *seqh, char **keys,
+ char **values, int count)
+</programlisting>
+ Restore state of the sequence based on the key/value pairs defined in
+ the <literal>keys</> and <literal>values</> parameters. The
+ <literal>count</> specifies length of the forementioned arrays.
+ This interface is mainly used by <command>pg_dump</command>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="seqam-storage">
+ <title>Sequence Access Method Storage API</title>
+
+ <para>
+ To store the current state of the sequence backend provides following
+ functions which the sequence access method can use:
+ </para>
+
+ <para>
+<programlisting>
+void
+sequence_open(Oid seqrelid, SequenceHandle *seqh);
+</programlisting>
+ Open sequence with given <literal>seqrelid</>. The <literal>seqh</> is
+ output parameter which will be set to the sequence handle.
+ </para>
+
+ <para>
+<programlisting>
+void
+sequence_close (SequenceHandle *seqh);
+</programlisting>
+ Release and close the opened sequence.
+ </para>
+
+ <para>
+<programlisting>
+HeapTuple
+sequence_read_tuple (SequenceHandle *seqh);
+</programlisting>
+ Reads and locks the sequence tuple for processing by the access method.
+ </para>
+
+ <para>
+<programlisting>
+void
+sequence_save_tuple(SequenceHandle *seqh, HeapTuple newtup,
+ bool do_wal);
+</programlisting>
+ Save the modified sequence tuple. Note that the <literal>newtup</> can be
+ <symbol>NULL</> if the sequence tuple was modified inline.
+ </para>
+
+ <para>
+<programlisting>
+void
+sequence_release_tuple(SequenceHandle *seqh);
+</programlisting>
+ Release the tuple read and locked by <function>sequence_read_tuple</>.
+ </para>
+
+ </sect1>
+
+ <sect1 id="seqam-utility">
+ <title>Sequence Access Method Utility Functions</title>
+
+ <para>
+ Additional utility functions which can be useful when writing sequence
+ access methods:
+ </para>
+
+ <para>
+<programlisting>
+bool
+sequence_needs_wal(SequenceHandle *seqh);
+</programlisting>
+ Returns <literal>true</> if the sequence tuple was last saved before last
+ checkpoint. This can be help when deciding what to set <literal>do_wal</>
+ to when calling <function>sequence_save_tuple</>.
+ </para>
+
+ <para>
+<programlisting>
+int64
+sequence_increment(Relation seqrel, int64 *value, int64 incnum,
+ int64 minv, int64 maxv, int64 incby,
+ bool is_cycled, bool report_errors);
+</programlisting>
+ Helper function to increment value of a sequence, correctly handling
+ sequence options like min value, max value, increment value and cycling of
+ the sequence value. The <literal>value</> is pointer to current value which
+ should be incremented, <literal>incnum</> specifies how much should the
+ value be incremented, the rest of the options should be set to values
+ specified by the sequence's <structname>pg_sequence</structname> tuple.
+ Returns by how much was the value increased.
+ </para>
+
+ <para>
+<programlisting>
+void
+sequence_check_range (int64 value, int64 min_value,
+ int64 max_value);
+</programlisting>
+ Checks if the <literal>value</> is between <literal>min_value</>
+ and <literal>max_value</> and raises standard error message if it's not.
+ </para>
+
+ <para>
+<programlisting>
+int64
+sequence_get_restart_value(List *options, int64 default_value,
+ bool *found);
+</programlisting>
+ Given the list of <structname>DefElm</> <literal>options</> get the restart
+ value for a sequence. If it was not specified in the <literal>options</>
+ list the <literal>default_value</> will be returned and <literal>found</>
+ will be set to <literal>false</>.
+ </para>
+
+ </sect1>
+
+</chapter>