Hi

Attached patch adds an "%r" substitution for psql prompts to show
recovery status. Specifically it displays an "&" (ampersand) if
the server is in recovery, otherwise nothing, e.g.:

    postgres=&# SELECT foo;

Why is this useful? Because I find myself messing about with replication
clusters a lot, and it would be nice to have an at-a-glance confirmation
whether I'm connected to a standby or not.

Why an ampersand? Because it's not used for any other prompts, and
it can be used as a mnemonic: "and" -> "st'and'by" (clutching at
straws a bit there I admit, but best I could come up with).

Note this substitution sends a "pg_is_in_recovery()" query to the server
each time it's encountered; unless there's something I'm overlooking I
think that's the only reliable way to determine current recovery status.
A possible alternative would be only to check the status each time a new
database connection is made, but that wouldn't catch the case where the
server has been promoted.

Will submit to next commitfest.


Regards

Ian Barwick

--
 Ian Barwick                   http://www.2ndQuadrant.com/
 PostgreSQL Development, 24x7 Support, Training & Services
diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index fce7e3a..dfef268 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -4104,6 +4104,17 @@ testdb=&gt; <userinput>INSERT INTO my_table VALUES (:'content');</userinput>
       </varlistentry>
 
       <varlistentry>
+        <term><literal>%r</literal></term>
+        <listitem>
+        <para>
+        Recovery status: &amp; ("st<emphasis>and</emphasis>by") if in recovery, otherwise empty.
+        Note this prompt substitution sends a <literal><function>pg_is_in_recovery()</function></literal>
+        query to the server each time it is encountered.
+        </para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
         <term><literal>%</literal><replaceable class="parameter">digits</replaceable></term>
         <listitem>
         <para>
diff --git a/src/bin/psql/prompt.c b/src/bin/psql/prompt.c
index 913b23e..90586eb 100644
--- a/src/bin/psql/prompt.c
+++ b/src/bin/psql/prompt.c
@@ -22,6 +22,7 @@
 #include "prompt.h"
 #include "settings.h"
 
+static bool is_in_recovery(void);
 
 /*--------------------------
  * get_prompt
@@ -46,6 +47,7 @@
  *		in prompt3 nothing
  * %x - transaction status: empty, *, !, ? (unknown or no connection)
  * %l - The line number inside the current statement, starting from 1.
+ * %r - recovery status: & ("st'and'by") if in recovery, otherwise empty
  * %? - the error code of the last query (not yet implemented)
  * %% - a percent sign
  *
@@ -313,6 +315,11 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 #endif							/* USE_READLINE */
 					break;
 
+				case 'r':
+					if (is_in_recovery())
+						buf[0] = '&';
+					break;
+
 				default:
 					buf[0] = *p;
 					buf[1] = '\0';
@@ -336,3 +343,26 @@ get_prompt(promptStatus_t status, ConditionalStack cstack)
 
 	return destination;
 }
+
+
+bool
+is_in_recovery(void)
+{
+	PGresult   *res;
+	bool        server_is_in_recovery = false;
+
+	if (!pset.db)
+		return false;
+
+	res = PSQLexec("SELECT pg_catalog.pg_is_in_recovery()");
+
+	if (!res)
+		return false;
+
+	if (strcmp(PQgetvalue(res, 0, 0), "t") == 0)
+		server_is_in_recovery = true;
+
+	PQclear(res);
+
+	return server_is_in_recovery;
+}

Reply via email to