v2-0001-Prevent-psql-haning-in-watch-with-submillisecond-.patch

application/octet-stream

Filename: v2-0001-Prevent-psql-haning-in-watch-with-submillisecond-.patch
Type: application/octet-stream
Part: 0
Message: Re: \watch 0 or \watch 0.00001 doesn't do what I want

Patch

Format: format-patch
Series: patch v2-0001
Subject: Prevent psql haning in \watch with submillisecond interval
File+
src/bin/psql/command.c 8 3
src/bin/psql/t/001_basic.pl 4 0
From a74d8bd8589881e701b2e95b521f1208a9c3c580 Mon Sep 17 00:00:00 2001
From: Andrey Borodin <amborodin@acm.org>
Date: Thu, 10 Oct 2024 10:43:54 +0500
Subject: [PATCH v2] Prevent psql haning in \watch with submillisecond interval

---
 src/bin/psql/command.c      | 11 ++++++++---
 src/bin/psql/t/001_basic.pl |  4 ++++
 2 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 2bb87897505..328d78c73f9 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -5359,6 +5359,10 @@ do_shell(const char *command)
  *
  * We break this out of exec_command to avoid having to plaster "volatile"
  * onto a bunch of exec_command's variables to silence stupider compilers.
+ *
+ * "sleep" is the amount of time to sleep during each loop, measured in
+ * seconds.  The internals of this function should use "sleep_ms" for
+ * precise sleep time calculations.
  */
 static bool
 do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
@@ -5484,10 +5488,10 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
 
 		if (user_title)
 			snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
-					 user_title, timebuf, sleep);
+					 user_title, timebuf, sleep_ms / 1000.0);
 		else
 			snprintf(title, title_len, _("%s (every %gs)\n"),
-					 timebuf, sleep);
+					 timebuf, sleep_ms / 1000.0);
 		myopt.title = title;
 
 		/* Run the query and print out the result */
@@ -5508,7 +5512,8 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
 		if (pagerpipe && ferror(pagerpipe))
 			break;
 
-		if (sleep == 0)
+		/* Tight loop, no wait needed */
+		if (sleep_ms == 0)
 			continue;
 
 #ifdef WIN32
diff --git a/src/bin/psql/t/001_basic.pl b/src/bin/psql/t/001_basic.pl
index 5f2f4541af0..dedaf18e44f 100644
--- a/src/bin/psql/t/001_basic.pl
+++ b/src/bin/psql/t/001_basic.pl
@@ -355,6 +355,10 @@ psql_like(
 psql_like($node, sprintf('SELECT 1 \watch c=3 i=%g', 0.01),
 	qr/1\n1\n1/, '\watch with 3 iterations');
 
+# Sub-millisecond wait should not hang
+psql_like($node, sprintf('SELECT 1 \watch c=3 i=%g', 0.0001),
+	qr/1\n1\n1/, '\watch with 3 iterations');
+
 # Check \watch minimum row count
 psql_fails_like(
 	$node,
-- 
2.42.0