From 404247348f6328aea4206cf5252ee9dbd9794f84 Mon Sep 17 00:00:00 2001
From: Jacob Champion <jacob.champion@enterprisedb.com>
Date: Wed, 21 Jan 2026 14:31:47 -0800
Subject: [PATCH v5 1/3] doc: Expand upon protocol versions and extensions

First, split the Protocol Versions table in two, and lead with the list
of versions that are supported today. Reserved and unsupported version
numbers go into the second table.

Second, in anticipation of a new (reserved) protocol extension, document
the extension negotiation process alongside version negotiation, and add
a table to contain extension parameter registrations in the future. (I
considered splitting this in two as well, but then the first table would
be empty for a long while, which seemed silly.)

Discussion: https://postgr.es/m/DDPR5BPWH1RJ.1LWAK6QAURVAY%40jeltef.nl
---
 doc/src/sgml/protocol.sgml | 113 +++++++++++++++++++++++++++++++++----
 1 file changed, 102 insertions(+), 11 deletions(-)

diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index a2b528c481e..792ae73b369 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -189,7 +189,7 @@
   </sect2>
 
   <sect2 id="protocol-versions">
-   <title>Protocol Versions</title>
+   <title>Protocol Versions and Extensibility</title>
 
    <para>
     The current, latest version of the protocol is version 3.2. However, for
@@ -223,10 +223,12 @@
    <para>
     <xref linkend="protocol-versions-table"/> shows the currently supported
     protocol versions.
+    <xref linkend="other-protocol-versions-table"/>
+    documents protocol versions that are unsupported or otherwise reserved.
    </para>
 
    <table id="protocol-versions-table">
-    <title>Protocol Versions</title>
+    <title>Supported Protocol Versions</title>
 
     <tgroup cols="3">
      <thead>
@@ -247,6 +249,27 @@
         message was redefined to have a variable length payload.
       </entry>
       </row>
+      <row>
+      <entry>3.0</entry>
+      <entry>PostgreSQL 7.4 and later</entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
+
+   <table id="other-protocol-versions-table">
+    <title>Other Protocol Versions</title>
+
+    <tgroup cols="3">
+     <thead>
+      <row>
+       <entry>Version</entry>
+       <entry>Supported by</entry>
+       <entry>Description</entry>
+      </row>
+     </thead>
+
+     <tbody>
       <row>
       <entry>3.1</entry>
       <entry>-</entry>
@@ -257,15 +280,81 @@
       </entry>
       </row>
       <row>
-      <entry>3.0</entry>
-      <entry>PostgreSQL 7.4 and later</entry>
-      </row>
-      <row>
       <entry>2.0</entry>
       <entry>up to PostgreSQL 13</entry>
-      <entry>See previous releases of
+      <entry>Obsolete. See previous releases of
       the <productname>PostgreSQL</productname> documentation for
-      details</entry>
+      details.</entry>
+      </row>
+     </tbody>
+    </tgroup>
+   </table>
+
+   <para id="protocol-extensions">
+    Servers and clients may additionally negotiate individual extensions to the
+    protocol version in use. These are offered by the client as specially-named
+    parameters in the startup message. Servers reject any unknown or unsupported
+    extensions by sending a NegotiateProtocolVersion message containing the list
+    of rejected parameter names, at which point the client may choose whether to
+    continue with the connection. <xref linkend="protocol-extensions-table"/>
+    shows the current list of protocol extension parameters.
+   </para>
+
+   <table id="protocol-extensions-table" rowheader="firstcol">
+    <title>Protocol Extensions</title>
+
+    <tgroup cols="5">
+     <!-- For spanning, below. -->
+     <colspec colname="first" colsep="0"/>
+     <colspec colname="name" colnum="2"/>
+     <colspec colname="vals" colnum="3"/>
+     <colspec colname="support" colnum="4"/>
+     <colspec colname="last" colnum="5"/>
+
+     <!--
+       "all" spans the width of the table; it is used for the section headers.
+       "reserved" spans the Values and Supported columns, for the Reserved
+       names which define neither.
+     -->
+     <spanspec spanname="all" namest="first" nameend="last"/>
+     <spanspec spanname="reserved" namest="vals" nameend="support"/>
+
+     <thead>
+      <row>
+       <!--
+         Row header. Use namest="name" to skip to the next column.
+         XXX this causes a thin "indent" effect for the other rows
+       -->
+       <entry/>
+
+       <entry>Parameter&nbsp;Name</entry>
+       <entry>Values</entry>
+       <entry>Supported&nbsp;by</entry>
+       <entry>Description</entry>
+      </row>
+     </thead>
+
+     <tbody>
+      <row><entry spanname="all">Defined</entry></row>
+
+      <row>
+       <entry namest="last" align="center" valign="middle">
+        <emphasis>(No supported protocol extensions are currently defined.)</emphasis>
+       </entry>
+      </row>
+
+      <row><entry spanname="all">Reserved</entry></row>
+
+      <row>
+      <entry namest="name"><literal>_pq_.<replaceable>[name]</replaceable></literal></entry>
+      <entry spanname="reserved">-</entry>
+      <entry>Any other parameter names beginning with <literal>_pq_.</literal>,
+        that are not defined above, are reserved for future protocol expansion.
+        Servers <emphasis>must</emphasis> reject any that are received from a
+        client, by sending a NegotiateProtocolVersion message during the
+        <link linkend="protocol-flow-start-up">startup flow</link>, and should
+        otherwise continue the connection.
+      </entry>
       </row>
      </tbody>
     </tgroup>
@@ -295,8 +384,8 @@
     To begin a session, a frontend opens a connection to the server and sends
     a startup message.  This message includes the names of the user and of the
     database the user wants to connect to; it also identifies the particular
-    protocol version to be used.  (Optionally, the startup message can include
-    additional settings for run-time parameters.)
+    protocol version to be used.  (Optionally, the startup message can request
+    protocol extensions and include additional settings for run-time parameters.)
     The server then uses this information and
     the contents of its configuration files (such as
     <filename>pg_hba.conf</filename>) to determine
@@ -6151,7 +6240,9 @@ psql "dbname=postgres replication=database" -c "IDENTIFY_SYSTEM;"
 
          In addition to the above, other parameters may be listed.
          Parameter names beginning with <literal>_pq_.</literal> are
-         reserved for use as protocol extensions, while others are
+         reserved for use as
+         <link linkend="protocol-extensions">protocol extensions</link>,
+         while others are
          treated as run-time parameters to be set at backend start
          time.  Such settings will be applied during backend start
          (after parsing the command-line arguments if any) and will
-- 
2.34.1

