From 354acecf442baabada83b0f7cd6b1b850ba712c5 Mon Sep 17 00:00:00 2001 From: Daniel Gustafsson Date: Wed, 9 Oct 2024 14:53:48 +0200 Subject: [PATCH v3] 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 | 52 ++++++++++++++++++++++++++++++++++ src/bin/psql/variables.h | 3 ++ 7 files changed, 90 insertions(+), 3 deletions(-) diff --git a/doc/src/sgml/ref/psql-ref.sgml b/doc/src/sgml/ref/psql-ref.sgml index e42073ed748..57bfa340460 100644 --- a/doc/src/sgml/ref/psql-ref.sgml +++ b/doc/src/sgml/ref/psql-ref.sgml @@ -3665,8 +3665,9 @@ testdb=> \setenv LESS -imx4F Repeatedly execute the current query buffer (as \g 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 ) + between executions. For backwards compatibility, seconds can be specified with or without an interval= prefix. Each query result is @@ -4518,6 +4519,17 @@ bar + + WATCH_INTERVAL + + + This variable sets the default interval which \watch + waits between executing the query. Specifying an interval in the + command overrides this variable. + + + + diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 1f3cbb11f7c..78930dc061b 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -2894,7 +2894,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 02fe5d151e0..76a30b7b708 100644 --- a/src/bin/psql/help.c +++ b/src/bin/psql/help.c @@ -452,6 +452,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 between queries\n"); HELP0("\nDisplay settings:\n"); HELP0("Usage:\n"); diff --git a/src/bin/psql/settings.h b/src/bin/psql/settings.h index a22de8ef78e..8a66e1c197f 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 036caaec2ff..276afa3f248 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); +} + 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 56d70f3a109..0283a2b3c7d 100644 --- a/src/bin/psql/variables.c +++ b/src/bin/psql/variables.c @@ -179,6 +179,58 @@ 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; + + /* + * Empty-string input has historically been treated differently by strtod + * on various platforms, so handle that by specifically checking for it. + */ + if ((value == NULL) || (*value == '\0')) + { + if (name) + pg_log_error("invalid input syntax for \"%s\"", name); + return false; + } + + 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 at least %.2f", + value, name, min); + return false; + } + *result = dblval; + return true; + } + + /* + * Cater for platforms which treat values which aren't zero, but that are + * too close to zero to have full precision, by checking for zero or real + * out-of-range values. + */ + else if ((errno = ERANGE) && + (dblval == 0.0 || dblval >= HUGE_VAL || dblval <= -HUGE_VAL)) + { + if (name) + pg_log_error("\"%s\" is out of range for \"%s\"", value, name); + return false; + } + 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 dca4f06dbbb..f8adcbe3dd5 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)