Hello,
ParseVariableDouble() in src/bin/psql/variables.c is asymmetric in how
it handles the [min, max] bounds it documents. The lower-bound branch
correctly returns false, but the upper-bound branch logs the error and
then falls through to assign *result and return true. The function's
contract ("the value must be within the range [min,max] in order to be
considered valid"; "if unsuccessful, *result isn't clobbered") is
broken on the upper-bound path.
The only caller today is watch_interval_hook, so the user-visible
effect is that an out-of-range WATCH_INTERVAL is reported as invalid
yet still assigned.
Reproducer:
$ psql
# \set WATCH_INTERVAL 99999999
invalid value "99999999" for variable "WATCH_INTERVAL": must be less than
1000000.00
# \echo :WATCH_INTERVAL
99999999
The error is printed, but the variable is set anyway.
Regards,
Sven Klemm
From dde5e00fe368a323b685e154896ef2905f91176e Mon Sep 17 00:00:00 2001
From: Sven Klemm <[email protected]>
Date: Fri, 8 May 2026 17:24:51 +0200
Subject: [PATCH] psql: Make ParseVariableDouble reject values above max
When the parsed value exceeded max, ParseVariableDouble logged the
"must be less than" error but then fell through to assign *result and
return true, contradicting both its docstring (caller's *result is
left untouched on failure) and the documented [min,max] contract. The
lower-bound branch already returns false; mirror that behavior on the
upper bound.
---
src/bin/psql/variables.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/bin/psql/variables.c b/src/bin/psql/variables.c
index f2a28bc9820..8060f2959cc 100644
--- a/src/bin/psql/variables.c
+++ b/src/bin/psql/variables.c
@@ -224,6 +224,7 @@ ParseVariableDouble(const char *value, const char *name, double *result, double
if (name)
pg_log_error("invalid value \"%s\" for variable \"%s\": must be less than %.2f",
value, name, max);
+ return false;
}
*result = dblval;
return true;
--
2.54.0