From eea647a8d0c68de4654ccb38f1898e5ca8be7c12 Mon Sep 17 00:00:00 2001
From: Daniel Gustafsson <dgustafsson@postgresql.org>
Date: Wed, 9 Oct 2024 14:53:48 +0200
Subject: [PATCH] Make default \watch interval configurable

The default interval which \watch waits between executing queries
was hardcoded to two seconds. This adds the variable WATCH_INTERVAL
which is used to set the default, making it configurable for the
user.
---
 doc/src/sgml/ref/psql-ref.sgml | 16 ++++++++++++++--
 src/bin/psql/command.c         |  2 +-
 src/bin/psql/help.c            |  2 ++
 src/bin/psql/settings.h        |  1 +
 src/bin/psql/startup.c         | 17 +++++++++++++++++
 src/bin/psql/variables.c       | 33 +++++++++++++++++++++++++++++++++
 src/bin/psql/variables.h       |  3 +++
 7 files changed, 71 insertions(+), 3 deletions(-)

diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml
index b825ca96a2..5b1026731f 100644
--- a/doc/src/sgml/ref/psql-ref.sgml
+++ b/doc/src/sgml/ref/psql-ref.sgml
@@ -3664,8 +3664,9 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
         Repeatedly execute the current query buffer (as <literal>\g</literal> does)
         until interrupted, or the query fails, or the execution count limit
         (if given) is reached, or the query no longer returns the minimum number
-        of rows. Wait the specified number of seconds (default 2) between executions.
-        For backwards compatibility,
+        of rows. Wait the specified number of seconds (default 2, which can be
+        changed with the variable <xref linkend="app-psql-variables-watch-interval"/>)
+        between executions.  For backwards compatibility,
         <replaceable class="parameter">seconds</replaceable> can be specified
         with or without an <literal>interval=</literal> prefix.
         Each query result is
@@ -4517,6 +4518,17 @@ bar
         </listitem>
       </varlistentry>
 
+      <varlistentry id="app-psql-variables-watch-interval">
+        <term><varname>WATCH_INTERVAL</varname></term>
+        <listitem>
+        <para>
+        This variable set the default interval which <command>\watch</command>
+        waits between executing the query.  Specifying an interval in the
+        command overrides this variable.
+        </para>
+        </listitem>
+      </varlistentry>
+
     </variablelist>
 
    </refsect3>
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 2bb8789750..cd91ca7851 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -2897,7 +2897,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
 		bool		have_sleep = false;
 		bool		have_iter = false;
 		bool		have_min_rows = false;
-		double		sleep = 2;
+		double		sleep = pset.watch_interval;
 		int			iter = 0;
 		int			min_rows = 0;
 
diff --git a/src/bin/psql/help.c b/src/bin/psql/help.c
index 19d20c5878..375c3d138f 100644
--- a/src/bin/psql/help.c
+++ b/src/bin/psql/help.c
@@ -455,6 +455,8 @@ helpVariables(unsigned short int pager)
 		  "  VERSION_NAME\n"
 		  "  VERSION_NUM\n"
 		  "    psql's version (in verbose string, short string, or numeric format)\n");
+	HELP0("  WATCH_INTERVAL\n"
+		  "    number of seconds \\watch waits beetween queries\n");
 
 	HELP0("\nDisplay settings:\n");
 	HELP0("Usage:\n");
diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h
index a22de8ef78..8a66e1c197 100644
--- a/src/bin/psql/settings.h
+++ b/src/bin/psql/settings.h
@@ -154,6 +154,7 @@ typedef struct _psqlSettings
 	int			fetch_count;
 	int			histsize;
 	int			ignoreeof;
+	double		watch_interval;
 	PSQL_ECHO	echo;
 	PSQL_ECHO_HIDDEN echo_hidden;
 	PSQL_ERROR_ROLLBACK on_error_rollback;
diff --git a/src/bin/psql/startup.c b/src/bin/psql/startup.c
index 036caaec2f..600389410d 100644
--- a/src/bin/psql/startup.c
+++ b/src/bin/psql/startup.c
@@ -939,6 +939,20 @@ histsize_hook(const char *newval)
 	return ParseVariableNum(newval, "HISTSIZE", &pset.histsize);
 }
 
+static char *
+watch_interval_substitute_hook(char *newval)
+{
+	if (newval == NULL)
+		newval = pg_strdup("2");
+	return newval;
+}
+
+static bool
+watch_interval_hook(const char *newval)
+{
+	return ParseVariableDouble(newval, "WATCH_INTERVAL", &pset.watch_interval, 0, 1000);
+}
+
 static char *
 ignoreeof_substitute_hook(char *newval)
 {
@@ -1265,4 +1279,7 @@ EstablishVariableSpace(void)
 	SetVariableHooks(pset.vars, "HIDE_TABLEAM",
 					 bool_substitute_hook,
 					 hide_tableam_hook);
+	SetVariableHooks(pset.vars, "WATCH_INTERVAL",
+					 watch_interval_substitute_hook,
+					 watch_interval_hook);
 }
diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c
index 56d70f3a10..bb8f01bf3a 100644
--- a/src/bin/psql/variables.c
+++ b/src/bin/psql/variables.c
@@ -179,6 +179,39 @@ ParseVariableNum(const char *value, const char *name, int *result)
 	}
 }
 
+bool
+ParseVariableDouble(const char *value, const char *name, double *result, double min)
+{
+	char	   *end;
+	double		dblval;
+
+	if (value == NULL)
+		value = "";
+
+	errno = 0;
+	dblval = strtod(value, &end);
+	if (errno == 0 && *end == '\0' && end != value)
+	{
+		if (dblval < min)
+		{
+			if (name)
+				pg_log_error("invalid value \"%s\" for \"%s\": must be greater than %.2f",
+							 value, name, min);
+			return false;
+		}
+		*result = dblval;
+		return true;
+
+	}
+	else
+	{
+		if (name)
+			pg_log_error("invalid value \"%s\" for \"%s\"",
+						 value, name);
+		return false;
+	}
+}
+
 /*
  * Print values of all variables.
  */
diff --git a/src/bin/psql/variables.h b/src/bin/psql/variables.h
index dca4f06dbb..f8adcbe3dd 100644
--- a/src/bin/psql/variables.h
+++ b/src/bin/psql/variables.h
@@ -81,6 +81,9 @@ bool		ParseVariableBool(const char *value, const char *name,
 bool		ParseVariableNum(const char *value, const char *name,
 							 int *result);
 
+bool		ParseVariableDouble(const char *value, const char *name,
+								double *result, double min);
+
 void		PrintVariables(VariableSpace space);
 
 bool		SetVariable(VariableSpace space, const char *name, const char *value);
-- 
2.39.3 (Apple Git-146)

