aboutsummaryrefslogtreecommitdiff
path: root/src/bin/psql/command.c
diff options
context:
space:
mode:
authorDaniel Gustafsson <dgustafsson@postgresql.org>2023-08-29 11:30:11 +0200
committerDaniel Gustafsson <dgustafsson@postgresql.org>2023-08-29 11:30:11 +0200
commitf347ec76e2a227e5c5b5065cce7adad16d58d209 (patch)
tree0d03e7a4caa335a0b9ae014299ccabbac8486c3f /src/bin/psql/command.c
parent95fff2abee66c16ca3609b3c1638cbd553730a90 (diff)
downloadpostgresql-f347ec76e2a227e5c5b5065cce7adad16d58d209.tar.gz
postgresql-f347ec76e2a227e5c5b5065cce7adad16d58d209.zip
Allow \watch queries to stop on minimum rows returned
When running a repeat query with \watch in psql, it can be helpful to be able to stop the watch process when the query no longer returns the expected amount of rows. An example would be to watch for the presence of a certain event in pg_stat_activity and stopping when the event is no longer present, or to watch an index creation and stop when the index is created. This adds a min_rows=MIN parameter to \watch which can be set to a non-negative integer, and the watch query will stop executing when it returns less than MIN rows. Author: Greg Sabino Mullane <htamfids@gmail.com> Reviewed-by: Michael Paquier <michael@paquier.xyz> Reviewed-by: Daniel Gustafsson <daniel@yesql.se> Discussion: https://postgr.es/m/CAKAnmmKStATuddYxP71L+p0DHtp9Rvjze3XRoy0Dyw67VQ45UA@mail.gmail.com
Diffstat (limited to 'src/bin/psql/command.c')
-rw-r--r--src/bin/psql/command.c32
1 files changed, 27 insertions, 5 deletions
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c
index 1300869d797..bcd8eb35387 100644
--- a/src/bin/psql/command.c
+++ b/src/bin/psql/command.c
@@ -162,7 +162,7 @@ static bool do_connect(enum trivalue reuse_previous_specification,
static bool do_edit(const char *filename_arg, PQExpBuffer query_buf,
int lineno, bool discard_on_quit, bool *edited);
static bool do_shell(const char *command);
-static bool do_watch(PQExpBuffer query_buf, double sleep, int iter);
+static bool do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows);
static bool lookup_object_oid(EditableObjectType obj_type, const char *desc,
Oid *obj_oid);
static bool get_create_object_cmd(EditableObjectType obj_type, Oid oid,
@@ -2775,13 +2775,15 @@ 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;
int iter = 0;
+ int min_rows = 0;
/*
* Parse arguments. We allow either an unlabeled interval or
* "name=value", where name is from the set ('i', 'interval', 'c',
- * 'count').
+ * 'count', 'm', 'min_rows').
*/
while (success)
{
@@ -2838,6 +2840,26 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
}
}
}
+ else if (strncmp("m=", opt, strlen("m=")) == 0 ||
+ strncmp("min_rows=", opt, strlen("min_rows=")) == 0)
+ {
+ if (have_min_rows)
+ {
+ pg_log_error("\\watch: minimum row count specified more than once");
+ success = false;
+ }
+ else
+ {
+ have_min_rows = true;
+ errno = 0;
+ min_rows = strtoint(valptr, &opt_end, 10);
+ if (min_rows <= 0 || *opt_end || errno == ERANGE)
+ {
+ pg_log_error("\\watch: incorrect minimum row count \"%s\"", valptr);
+ success = false;
+ }
+ }
+ }
else
{
pg_log_error("\\watch: unrecognized parameter \"%s\"", opt);
@@ -2874,7 +2896,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
/* If query_buf is empty, recall and execute previous query */
(void) copy_previous_query(query_buf, previous_buf);
- success = do_watch(query_buf, sleep, iter);
+ success = do_watch(query_buf, sleep, iter, min_rows);
}
/* Reset the query buffer as though for \r */
@@ -5144,7 +5166,7 @@ do_shell(const char *command)
* onto a bunch of exec_command's variables to silence stupider compilers.
*/
static bool
-do_watch(PQExpBuffer query_buf, double sleep, int iter)
+do_watch(PQExpBuffer query_buf, double sleep, int iter, int min_rows)
{
long sleep_ms = (long) (sleep * 1000);
printQueryOpt myopt = pset.popt;
@@ -5274,7 +5296,7 @@ do_watch(PQExpBuffer query_buf, double sleep, int iter)
myopt.title = title;
/* Run the query and print out the result */
- res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe);
+ res = PSQLexecWatch(query_buf->data, &myopt, pagerpipe, min_rows);
/*
* PSQLexecWatch handles the case where we can no longer repeat the