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=> <userinput>INSERT INTO my_table VALUES (:'content');</userinput> </varlistentry> <varlistentry> + <term><literal>%r</literal></term> + <listitem> + <para> + Recovery status: & ("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; +}