Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit00beecf

Browse files
committed
psql: add an optional execution-count limit to \watch.
\watch can now be told to stop after N executions of the query.With the idea that we might want to add more options to \watchin future, this patch generalizes the command's syntax to a listof name=value options, with the interval allowed to omit the namefor backwards compatibility.Andrey Borodin, reviewed by Kyotaro Horiguchi, Nathan Bossart,Michael Paquier, Yugo Nagata, and myselfDiscussion:https://postgr.es/m/CAAhFRxiZ2-n_L1ErMm9AZjgmUK=qS6VHb+0SaMn8sqqbhF7How@mail.gmail.com
1 parent2820adf commit00beecf

File tree

6 files changed

+135
-32
lines changed

6 files changed

+135
-32
lines changed

‎doc/src/sgml/ref/psql-ref.sgml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3551,12 +3551,16 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
35513551

35523552

35533553
<varlistentry id="app-psql-meta-command-watch">
3554-
<term><literal>\watch [ <replaceable class="parameter">seconds</replaceable> ]</literal></term>
3554+
<term><literal>\watch [i[nterval]=<replaceable class="parameter">seconds</replaceable> ] [ c[ount]=<replaceable class="parameter">times</replaceable> ] [<replaceable class="parameter">seconds</replaceable> ]</literal></term>
35553555
<listitem>
35563556
<para>
35573557
Repeatedly execute the current query buffer (as <literal>\g</literal> does)
3558-
until interrupted or the query fails. Wait the specified number of
3559-
seconds (default 2) between executions. Each query result is
3558+
until interrupted, or the query fails, or the execution count limit
3559+
(if given) is reached. Wait the specified number of
3560+
seconds (default 2) between executions. For backwards compatibility,
3561+
<replaceable class="parameter">seconds</replaceable> can be specified
3562+
with or without an <literal>interval=</literal> prefix.
3563+
Each query result is
35603564
displayed with a header that includes the <literal>\pset title</literal>
35613565
string (if any), the time as of query start, and the delay interval.
35623566
</para>

‎src/bin/psql/command.c

Lines changed: 100 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ static bool do_connect(enum trivalue reuse_previous_specification,
162162
staticbooldo_edit(constchar*filename_arg,PQExpBufferquery_buf,
163163
intlineno,booldiscard_on_quit,bool*edited);
164164
staticbooldo_shell(constchar*command);
165-
staticbooldo_watch(PQExpBufferquery_buf,doublesleep);
165+
staticbooldo_watch(PQExpBufferquery_buf,doublesleep,intiter);
166166
staticboollookup_object_oid(EditableObjectTypeobj_type,constchar*desc,
167167
Oid*obj_oid);
168168
staticboolget_create_object_cmd(EditableObjectTypeobj_type,Oidoid,
@@ -2759,7 +2759,8 @@ exec_command_write(PsqlScanState scan_state, bool active_branch,
27592759
}
27602760

27612761
/*
2762-
* \watch -- execute a query every N seconds
2762+
* \watch -- execute a query every N seconds.
2763+
* Optionally, stop after M iterations.
27632764
*/
27642765
staticbackslashResult
27652766
exec_command_watch(PsqlScanStatescan_state,boolactive_branch,
@@ -2769,32 +2770,109 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
27692770

27702771
if (active_branch)
27712772
{
2772-
char*opt=psql_scan_slash_option(scan_state,
2773-
OT_NORMAL,NULL, true);
2773+
boolhave_sleep= false;
2774+
boolhave_iter= false;
27742775
doublesleep=2;
2776+
intiter=0;
27752777

2776-
/* Convert optional sleep-length argument */
2777-
if (opt)
2778+
/*
2779+
* Parse arguments. We allow either an unlabeled interval or
2780+
* "name=value", where name is from the set ('i', 'interval', 'c',
2781+
* 'count').
2782+
*/
2783+
while (success)
27782784
{
2785+
char*opt=psql_scan_slash_option(scan_state,
2786+
OT_NORMAL,NULL, true);
2787+
char*valptr;
27792788
char*opt_end;
27802789

2781-
errno=0;
2782-
sleep=strtod(opt,&opt_end);
2783-
if (sleep<0||*opt_end||errno==ERANGE)
2790+
if (!opt)
2791+
break;/* no more arguments */
2792+
2793+
valptr=strchr(opt,'=');
2794+
if (valptr)
27842795
{
2785-
pg_log_error("\\watch: incorrect interval value '%s'",opt);
2786-
free(opt);
2787-
resetPQExpBuffer(query_buf);
2788-
psql_scan_reset(scan_state);
2789-
returnPSQL_CMD_ERROR;
2796+
/* Labeled argument */
2797+
valptr++;
2798+
if (strncmp("i=",opt,strlen("i="))==0||
2799+
strncmp("interval=",opt,strlen("interval="))==0)
2800+
{
2801+
if (have_sleep)
2802+
{
2803+
pg_log_error("\\watch: interval value is specified more than once");
2804+
success= false;
2805+
}
2806+
else
2807+
{
2808+
have_sleep= true;
2809+
errno=0;
2810+
sleep=strtod(valptr,&opt_end);
2811+
if (sleep<0||*opt_end||errno==ERANGE)
2812+
{
2813+
pg_log_error("\\watch: incorrect interval value \"%s\"",valptr);
2814+
success= false;
2815+
}
2816+
}
2817+
}
2818+
elseif (strncmp("c=",opt,strlen("c="))==0||
2819+
strncmp("count=",opt,strlen("count="))==0)
2820+
{
2821+
if (have_iter)
2822+
{
2823+
pg_log_error("\\watch: iteration count is specified more than once");
2824+
success= false;
2825+
}
2826+
else
2827+
{
2828+
have_iter= true;
2829+
errno=0;
2830+
iter=strtoint(valptr,&opt_end,10);
2831+
if (iter <=0||*opt_end||errno==ERANGE)
2832+
{
2833+
pg_log_error("\\watch: incorrect iteration count \"%s\"",valptr);
2834+
success= false;
2835+
}
2836+
}
2837+
}
2838+
else
2839+
{
2840+
pg_log_error("\\watch: unrecognized parameter \"%s\"",opt);
2841+
success= false;
2842+
}
2843+
}
2844+
else
2845+
{
2846+
/* Unlabeled argument: take it as interval */
2847+
if (have_sleep)
2848+
{
2849+
pg_log_error("\\watch: interval value is specified more than once");
2850+
success= false;
2851+
}
2852+
else
2853+
{
2854+
have_sleep= true;
2855+
errno=0;
2856+
sleep=strtod(opt,&opt_end);
2857+
if (sleep<0||*opt_end||errno==ERANGE)
2858+
{
2859+
pg_log_error("\\watch: incorrect interval value \"%s\"",opt);
2860+
success= false;
2861+
}
2862+
}
27902863
}
2864+
27912865
free(opt);
27922866
}
27932867

2794-
/* If query_buf is empty, recall and execute previous query */
2795-
(void)copy_previous_query(query_buf,previous_buf);
2868+
/* If we parsed arguments successfully, do the command */
2869+
if (success)
2870+
{
2871+
/* If query_buf is empty, recall and execute previous query */
2872+
(void)copy_previous_query(query_buf,previous_buf);
27962873

2797-
success=do_watch(query_buf,sleep);
2874+
success=do_watch(query_buf,sleep,iter);
2875+
}
27982876

27992877
/* Reset the query buffer as though for \r */
28002878
resetPQExpBuffer(query_buf);
@@ -5071,7 +5149,7 @@ do_shell(const char *command)
50715149
* onto a bunch of exec_command's variables to silence stupider compilers.
50725150
*/
50735151
staticbool
5074-
do_watch(PQExpBufferquery_buf,doublesleep)
5152+
do_watch(PQExpBufferquery_buf,doublesleep,intiter)
50755153
{
50765154
longsleep_ms= (long) (sleep*1000);
50775155
printQueryOptmyopt=pset.popt;
@@ -5204,6 +5282,10 @@ do_watch(PQExpBuffer query_buf, double sleep)
52045282
if (res <=0)
52055283
break;
52065284

5285+
/* If we have iteration count, check that it's not exceeded yet */
5286+
if (iter&& (--iter <=0))
5287+
break;
5288+
52075289
if (pagerpipe&&ferror(pagerpipe))
52085290
break;
52095291

‎src/bin/psql/help.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ slashUsage(unsigned short int pager)
200200
HELP0(" \\gset [PREFIX] execute query and store result in psql variables\n");
201201
HELP0(" \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n");
202202
HELP0(" \\q quit psql\n");
203-
HELP0(" \\watch [SEC]execute query every SEC seconds\n");
203+
HELP0(" \\watch [[i=]SEC][c=N]execute query every SEC seconds, up to N times\n");
204204
HELP0("\n");
205205

206206
HELP0("Help\n");

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

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -350,21 +350,38 @@ sub psql_fails_like
350350
'\copy from with DEFAULT'
351351
);
352352

353+
# Check \watch
354+
psql_like(
355+
$node,
356+
'SELECT 1 \watch c=3 i=0.01',
357+
qr/1\n1\n1/,
358+
'\watch with 3 iterations');
359+
353360
# Check \watch errors
354361
psql_fails_like(
355362
$node,
356-
'SELECT 1;\watch -10',
357-
qr/incorrect interval value'-10'/,
363+
'SELECT 1\watch -10',
364+
qr/incorrect interval value"-10"/,
358365
'\watch, negative interval');
359366
psql_fails_like(
360367
$node,
361-
'SELECT 1;\watch 10ab',
362-
qr/incorrect interval value '10ab'/,
363-
'\watch incorrect interval');
368+
'SELECT 1 \watch 10ab',
369+
qr/incorrect interval value "10ab"/,
370+
'\watch, incorrect interval');
371+
psql_fails_like(
372+
$node,
373+
'SELECT 1 \watch 10e400',
374+
qr/incorrect interval value "10e400"/,
375+
'\watch, out-of-range interval');
376+
psql_fails_like(
377+
$node,
378+
'SELECT 1 \watch 1 1',
379+
qr/interval value is specified more than once/,
380+
'\watch, interval value is specified more than once');
364381
psql_fails_like(
365382
$node,
366-
'SELECT 1;\watch10e400',
367-
qr/incorrect interval value '10e400'/,
368-
'\watch out-of-range interval');
383+
'SELECT 1\watchc=1 c=1',
384+
qr/iteration count is specified more than once/,
385+
'\watch, iteration count is specified more than once');
369386

370387
done_testing();

‎src/test/regress/expected/psql.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4536,7 +4536,7 @@ invalid command \lo
45364536
\timing arg1
45374537
\unset arg1
45384538
\w arg1
4539-
\watch arg1
4539+
\watch arg1 arg2
45404540
\x arg1
45414541
-- \else here is eaten as part of OT_FILEPIPE argument
45424542
\w |/no/such/file \else

‎src/test/regress/sql/psql.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,7 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two;
10221022
\timing arg1
10231023
\unset arg1
10241024
\w arg1
1025-
\watch arg1
1025+
\watch arg1 arg2
10261026
\x arg1
10271027
-- \else here is eaten as part of OT_FILEPIPE argument
10281028
\w |/no/such/file \else

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp