From 7de0149b2b69a133ef8762cce67a16ed2defd087 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Fri, 1 Dec 2023 12:55:56 +0900
Subject: [PATCH v8 6/7] Sequence access methods - core documentation

---
 doc/src/sgml/config.sgml                   | 16 +++++
 doc/src/sgml/filelist.sgml                 |  1 +
 doc/src/sgml/postgres.sgml                 |  1 +
 doc/src/sgml/ref/create_access_method.sgml | 15 ++--
 doc/src/sgml/ref/create_sequence.sgml      | 12 ++++
 doc/src/sgml/sequenceam.sgml               | 80 ++++++++++++++++++++++
 6 files changed, 119 insertions(+), 6 deletions(-)
 create mode 100644 doc/src/sgml/sequenceam.sgml

diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 12feac6087..651caa7491 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -8993,6 +8993,22 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
       </listitem>
      </varlistentry>
 
+     <varlistentry id="guc-default-sequence-access-method" xreflabel="default_sequence_access_method">
+      <term><varname>default_sequence_access_method</varname> (<type>string</type>)
+      <indexterm>
+       <primary><varname>default_sequence_access_method</varname> configuration parameter</primary>
+      </indexterm>
+      </term>
+      <listitem>
+       <para>
+        This parameter specifies the default sequence access method to use when
+        creating sequences if the <command>CREATE SEQUENCE</command>
+        command does not explicitly specify an access method. The default is
+        <literal>local</literal>.
+       </para>
+      </listitem>
+     </varlistentry>
+
      <varlistentry id="guc-default-tablespace" xreflabel="default_tablespace">
       <term><varname>default_tablespace</varname> (<type>string</type>)
       <indexterm>
diff --git a/doc/src/sgml/filelist.sgml b/doc/src/sgml/filelist.sgml
index a7ff5f8264..07aa3f18c7 100644
--- a/doc/src/sgml/filelist.sgml
+++ b/doc/src/sgml/filelist.sgml
@@ -95,6 +95,7 @@
 <!ENTITY planstats    SYSTEM "planstats.sgml">
 <!ENTITY tableam    SYSTEM "tableam.sgml">
 <!ENTITY indexam    SYSTEM "indexam.sgml">
+<!ENTITY sequenceam SYSTEM "sequenceam.sgml">
 <!ENTITY nls        SYSTEM "nls.sgml">
 <!ENTITY plhandler  SYSTEM "plhandler.sgml">
 <!ENTITY fdwhandler SYSTEM "fdwhandler.sgml">
diff --git a/doc/src/sgml/postgres.sgml b/doc/src/sgml/postgres.sgml
index ec9f90e283..6b82f4c7fc 100644
--- a/doc/src/sgml/postgres.sgml
+++ b/doc/src/sgml/postgres.sgml
@@ -256,6 +256,7 @@ break is not needed in a wider output rendering.
   &geqo;
   &tableam;
   &indexam;
+  &sequenceam;
   &wal-for-extensions;
   &indextypes;
   &storage;
diff --git a/doc/src/sgml/ref/create_access_method.sgml b/doc/src/sgml/ref/create_access_method.sgml
index dae43dbaed..3067dc4d4d 100644
--- a/doc/src/sgml/ref/create_access_method.sgml
+++ b/doc/src/sgml/ref/create_access_method.sgml
@@ -61,8 +61,8 @@ CREATE ACCESS METHOD <replaceable class="parameter">name</replaceable>
     <listitem>
      <para>
       This clause specifies the type of access method to define.
-      Only <literal>TABLE</literal> and <literal>INDEX</literal>
-      are supported at present.
+      Only <literal>TABLE</literal>, <literal>SEQUENCE</literal> and
+      <literal>INDEX</literal> are supported at present.
      </para>
     </listitem>
    </varlistentry>
@@ -77,12 +77,15 @@ CREATE ACCESS METHOD <replaceable class="parameter">name</replaceable>
       declared to take a single argument of type <type>internal</type>,
       and its return type depends on the type of access method;
       for <literal>TABLE</literal> access methods, it must
-      be <type>table_am_handler</type> and for <literal>INDEX</literal>
-      access methods, it must be <type>index_am_handler</type>.
+      be <type>table_am_handler</type>; for <literal>INDEX</literal>
+      access methods, it must be <type>index_am_handler</type>;
+      for <literal>SEQUENCE</literal>, it must be
+      <type>sequence_am_handler</type>;
       The C-level API that the handler function must implement varies
       depending on the type of access method. The table access method API
-      is described in <xref linkend="tableam"/> and the index access method
-      API is described in <xref linkend="indexam"/>.
+      is described in <xref linkend="tableam"/>, the index access method
+      API is described in <xref linkend="indexam"/> and the sequence access
+      method is described in <xref linkend="sequenceam"/>.
      </para>
     </listitem>
    </varlistentry>
diff --git a/doc/src/sgml/ref/create_sequence.sgml b/doc/src/sgml/ref/create_sequence.sgml
index 1e283f13d1..52c6096e4b 100644
--- a/doc/src/sgml/ref/create_sequence.sgml
+++ b/doc/src/sgml/ref/create_sequence.sgml
@@ -29,6 +29,7 @@ CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] <replaceab
     [ START [ WITH ] <replaceable class="parameter">start</replaceable> ]
     [ CACHE <replaceable class="parameter">cache</replaceable> ]
     [ OWNED BY { <replaceable class="parameter">table_name</replaceable>.<replaceable class="parameter">column_name</replaceable> | NONE } ]
+    [ USING <replaceable class="parameter">access_method</replaceable> ]
 </synopsis>
  </refsynopsisdiv>
 
@@ -263,6 +264,17 @@ SELECT * FROM <replaceable>name</replaceable>;
      </para>
     </listitem>
    </varlistentry>
+
+   <varlistentry>
+    <term><literal>USING</literal> <replaceable class="parameter">access_method</replaceable></term>
+    <listitem>
+     <para>
+      The <literal>USING</literal> option specifies which sequence access
+      method will be used when generating the sequence numbers. The default
+      is <literal>local</literal>.
+     </para>
+    </listitem>
+   </varlistentry>
   </variablelist>
  </refsect1>
 
diff --git a/doc/src/sgml/sequenceam.sgml b/doc/src/sgml/sequenceam.sgml
new file mode 100644
index 0000000000..a96170bfac
--- /dev/null
+++ b/doc/src/sgml/sequenceam.sgml
@@ -0,0 +1,80 @@
+<!-- doc/src/sgml/sequenceam.sgml -->
+
+<chapter id="sequenceam">
+ <title>Sequence Access Method Interface Definition</title>
+
+ <indexterm>
+  <primary>Sequence Access Method</primary>
+ </indexterm>
+ <indexterm>
+  <primary>sequenceam</primary>
+  <secondary>Sequence Access Method</secondary>
+ </indexterm>
+
+ <para>
+  This chapter explains the interface between the core
+  <productname>PostgreSQL</productname> system and <firstterm>sequence access
+  methods</firstterm>, which manage the operations around sequences . The core
+  system knows little about these access methods beyond what is specified here,
+  so it is possible to develop entirely new access method types by writing
+  add-on code.
+ </para>
+
+ <para>
+  Each sequence access method is described by a row in the
+  <link linkend="catalog-pg-am"><structname>pg_am</structname></link> system
+  catalog. The <structname>pg_am</structname> entry specifies a name and a
+  <firstterm>handler function</firstterm> for the sequence access method.  These
+  entries can be created and deleted using the
+  <xref linkend="sql-create-access-method"/> and
+  <xref linkend="sql-drop-access-method"/> SQL commands.
+ </para>
+
+ <para>
+  A sequence access method handler function must be declared to accept a single
+  argument of type <type>internal</type> and to return the pseudo-type
+  <type>sequence_am_handler</type>.  The argument is a dummy value that simply
+  serves to prevent handler functions from being called directly from SQL commands.
+
+  The result of the function must be a pointer to a struct of type
+  <structname>SequenceAmRoutine</structname>, which contains everything that the
+  core code needs to know to make use of the sequence access method. The return
+  value needs to be of server lifetime, which is typically achieved by
+  defining it as a <literal>static const</literal> variable in global
+  scope. The <structname>SequenceAmRoutine</structname> struct, also called the
+  access method's <firstterm>API struct</firstterm>, defines the behavior of
+  the access method using callbacks. These callbacks are pointers to plain C
+  functions and are not visible or callable at the SQL level. All the
+  callbacks and their behavior is defined in the
+  <structname>SequenceAmRoutine</structname> structure (with comments inside
+  the struct defining the requirements for callbacks). Most callbacks have
+  wrapper functions, which are documented from the point of view of a user
+  (rather than an implementor) of the sequence access method.  For details,
+  please refer to the <ulink url="https://git.postgresql.org/gitweb/?p=postgresql.git;a=blob;f=src/include/access/sequenceam.h;hb=HEAD">
+   <filename>src/include/access/sequenceam.h</filename></ulink> file.
+ </para>
+
+ <para>
+  Currently, the way a sequence access method stores data is fairly
+  unconstrained, and it is possible to use a predefined
+  <link linkend="tableam">Table Access Method</link> to store sequence
+  data.
+ </para>
+
+ <para>
+  For crash safety, a sequence access method can use
+  <link linkend="wal"><acronym>WAL</acronym></link>, or a custom
+  implementation.
+  If <acronym>WAL</acronym> is chosen, either
+  <link linkend="generic-wal">Generic WAL Records</link> can be used, or a
+  <link linkend="custom-rmgr">Custom WAL Resource Manager</link> can be
+  implemented.
+ </para>
+
+ <para>
+  Any developer of a new <literal>sequence access method</literal> can refer to
+  the existing <literal>local</literal> implementation present in
+  <filename>src/backend/access/sequence/local.c</filename> for details of
+  its implementation.
+ </para>
+</chapter>
-- 
2.45.2

