Skip to content

Commit 8a61708

Browse files
committed
psql: Fix \watch when using interval values less than 1ms
Attempting to use an interval of time less than 1ms would cause \watch to hang. This was confusing, so let's change the logic so as an interval lower than 1ms behaves the same as 0. Comments are added to mention that the internals of do_watch() had better rely on "sleep_ms", the interval value in milliseconds. While on it, this commit adds a test to check the behavior of interval values less than 1ms. \watch hanging for interval values less than 1ms existed before 6f9ee74, that has changed the code to support an interval value of 0. Reported-by: Heikki Linnakangas Author: Andrey M. Borodin, Michael Paquier Discussion: https://postgr.es/m/88445e0e-3156-4b9d-afae-9a1a7b1631f6@iki.fi Backpatch-through: 16
1 parent 54889ea commit 8a61708

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

src/bin/psql/command.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5231,6 +5231,10 @@ do_shell(const char *command)
52315231
*
52325232
* We break this out of exec_command to avoid having to plaster "volatile"
52335233
* onto a bunch of exec_command's variables to silence stupider compilers.
5234+
*
5235+
* "sleep" is the amount of time to sleep during each loop, measured in
5236+
* seconds. The internals of this function should use "sleep_ms" for
5237+
* precise sleep time calculations.
52345238
*/
52355239
static bool
52365240
do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
@@ -5356,10 +5360,10 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
53565360

53575361
if (user_title)
53585362
snprintf(title, title_len, _("%s\t%s (every %gs)\n"),
5359-
user_title, timebuf, sleep);
5363+
user_title, timebuf, sleep_ms / 1000.0);
53605364
else
53615365
snprintf(title, title_len, _("%s (every %gs)\n"),
5362-
timebuf, sleep);
5366+
timebuf, sleep_ms / 1000.0);
53635367
myopt.title = title;
53645368

53655369
/* Run the query and print out the result */
@@ -5380,7 +5384,8 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
53805384
if (pagerpipe && ferror(pagerpipe))
53815385
break;
53825386

5383-
if (sleep == 0)
5387+
/* Tight loop, no wait needed */
5388+
if (sleep_ms == 0)
53845389
continue;
53855390

53865391
#ifdef WIN32

src/bin/psql/t/001_basic.pl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -352,8 +352,14 @@ sub psql_fails_like
352352

353353
# Check \watch
354354
# Note: the interval value is parsed with locale-aware strtod()
355-
psql_like($node, sprintf('SELECT 1 \watch c=3 i=%g', 0.01),
356-
qr/1\n1\n1/, '\watch with 3 iterations');
355+
psql_like(
356+
$node, sprintf('SELECT 1 \watch c=3 i=%g', 0.01),
357+
qr/1\n1\n1/, '\watch with 3 iterations, interval of 0.01');
358+
359+
# Sub-millisecond wait works, equivalent to 0.
360+
psql_like(
361+
$node, sprintf('SELECT 1 \watch c=3 i=%g', 0.0001),
362+
qr/1\n1\n1/, '\watch with 3 iterations, interval of 0.0001');
357363

358364
# Check \watch minimum row count
359365
psql_fails_like(

0 commit comments

Comments
 (0)