From b73bab3819514da14df93c8a14c51d7840d9335c Mon Sep 17 00:00:00 2001
From: Jim Jones <jim.jones@uni-muenster.de>
Date: Tue, 27 Jan 2026 15:27:13 +0100
Subject: [PATCH v9] Add %i prompt escape to indicate hot standby status

This patch introduces a new prompt escape %i for psql, which shows
whether the connected server is operating in hot standby mode. It
expands to standby if the server reports in_hot_standby = on, and
primary otherwise.

This is useful for distinguishing standby servers from primary ones
at a glance, especially when working with multiple connections in
replicated environments where libpq's multi-host connection strings
are used.

Author: Jim Jones <jim.jones@uni-muenster.de>
Reviewed-by: Fujii Masao <masao.fujii@gmail.com>
Reviewed-by: Greg Sabino Mullane <htamfids@gmail.com>
Reviewed-by: Srinath Reddy Sadipiralla <srinath2133@gmail.com>
Reviewed-by: Nathan Bossart <nathandbossart@gmail.com>
Reviewed-by: Chao Li <li.evan.chao@gmail.com>
Reviewed-by: Andreas Karlsson <andreas@proxel.se>
Discussion: https://www.postgresql.org/message-id/flat/016f6738-f9a9-4e98-bb5a-e1e4b9591d46@uni-muenster.de
---
 doc/src/sgml/ref/psql-ref.sgml | 16 ++++++++++++++++
 src/bin/psql/prompt.c          | 18 +++++++++++++++++-
 2 files changed, 33 insertions(+), 1 deletion(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index e464e3b13d..e27bba9c88 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -5075,6 +5075,22 @@ testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
         </listitem>
       </varlistentry>
 
+      <varlistentry id="app-psql-prompting-i">
+        <term><literal>%i</literal></term>
+        <listitem>
+        <para>
+        Indicates whether the server is in hot standby mode.
+        The value is shown as <literal>standby</literal> if the server reports
+        <xref linkend="guc-in-hot-standby"/> as <literal>on</literal>,
+        and <literal>primary</literal> otherwise.
+        This can be useful when connecting to multiple hosts to quickly identify
+        if the connected server is currently in recovery mode.
+        A value of <literal>?</literal> is shown when connected to a server
+        running <productname>PostgreSQL</productname> 13 or older.
+        </para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry id="app-psql-prompting-x">
         <term><literal>%x</literal></term>
         <listitem>
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 44eae59641..7aae217fb2 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -44,6 +44,8 @@
  *			or a ! if session is not connected to a database;
  *		in prompt2 -, *, ', or ";
  *		in prompt3 nothing
+ * %i - "standby" or "primary" depending on the server's in_hot_standby
+ *      status, or "?" if unavailable (empty if unknown)
  * %x - transaction status: empty, *, !, ? (unknown or no connection)
  * %l - The line number inside the current statement, starting from 1.
  * %? - the error code of the last query (not yet implemented)
@@ -258,7 +260,21 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 							break;
 					}
 					break;
-
+				case 'i':
+					if (pset.db)
+					{
+						const char *hs = PQparameterStatus(pset.db, "in_hot_standby");
+						if (hs)
+						{
+							if (strcmp(hs, "on") == 0)
+								strlcpy(buf, "standby", sizeof(buf));
+							else
+								strlcpy(buf, "primary", sizeof(buf));
+						}
+						else
+							buf[0] = '?';
+					}
+					break;
 				case 'x':
 					if (!pset.db)
 						buf[0] = '?';
-- 
2.43.0

