From 553e3827a5f353e2ba8e40b5f4fb01478fe5b97a Mon Sep 17 00:00:00 2001 From: Fujii Masao Date: Wed, 19 Aug 2026 13:06:15 +0900 Subject: [PATCH v1] psql: Do not let invalid \getresults affect the next query In pipeline mode, an invalid \getresults argument could previously affect the next SQL command in the same pipeline. For example, after reporting an error for \getresults -1, psql could treat the following SQL command as a request to read pending pipeline results instead of sending it to the server, making the command appear to be skipped or causing missing results. This happened because psql marked \getresults as a request to read pipeline results before validating its optional argument. When validation failed, psql reported the error without running the normal cleanup path that clears the request. Fix this by validating the \getresults argument before marking the command as a request to read pipeline results. After an invalid argument, psql now reports the error and sends the following SQL command normally. Backpatch to v18, where psql pipeline meta-commands were introduced. --- src/bin/psql/command.c | 9 +++++---- src/test/regress/expected/psql_pipeline.out | 21 +++++++++++++++++++++ src/test/regress/sql/psql_pipeline.sql | 11 +++++++++++ 3 files changed, 37 insertions(+), 4 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 7a3e88ea5c3..1008a46f048 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -1934,10 +1934,8 @@ exec_command_getresults(PsqlScanState scan_state, bool active_branch) if (active_branch) { char *opt; - int num_results; + int num_results = 0; - pset.send_mode = PSQL_SEND_GET_RESULTS; - status = PSQL_CMD_SEND; opt = psql_scan_slash_option(scan_state, OT_NORMAL, NULL, false); pset.requested_results = 0; @@ -1950,8 +1948,11 @@ exec_command_getresults(PsqlScanState scan_state, bool active_branch) pg_log_error("\\getresults: invalid number of requested results"); return PSQL_CMD_ERROR; } - pset.requested_results = num_results; } + + pset.requested_results = num_results; + pset.send_mode = PSQL_SEND_GET_RESULTS; + status = PSQL_CMD_SEND; } else ignore_slash_options(scan_state); diff --git a/src/test/regress/expected/psql_pipeline.out b/src/test/regress/expected/psql_pipeline.out index a931d63cafe..6fc5aea49d9 100644 --- a/src/test/regress/expected/psql_pipeline.out +++ b/src/test/regress/expected/psql_pipeline.out @@ -627,6 +627,27 @@ Pipeline aborted, command did not run \startpipeline \getresults -1 \getresults: invalid number of requested results +\endpipeline +-- After an invalid \getresults argument, the next SQL command in the +-- pipeline should still be sent and returned normally. +\startpipeline +SELECT 1; +\flushrequest +\getresults -1 +\getresults: invalid number of requested results +SELECT 99; +\flushrequest +\getresults + ?column? +---------- + 1 +(1 row) + + ?column? +---------- + 99 +(1 row) + \endpipeline -- \getresults when there is no result should not impact the next -- query executed. diff --git a/src/test/regress/sql/psql_pipeline.sql b/src/test/regress/sql/psql_pipeline.sql index 468ef1d090b..b6bd917c90b 100644 --- a/src/test/regress/sql/psql_pipeline.sql +++ b/src/test/regress/sql/psql_pipeline.sql @@ -354,6 +354,17 @@ SELECT $1 \bind \sendpipeline \getresults -1 \endpipeline +-- After an invalid \getresults argument, the next SQL command in the +-- pipeline should still be sent and returned normally. +\startpipeline +SELECT 1; +\flushrequest +\getresults -1 +SELECT 99; +\flushrequest +\getresults +\endpipeline + -- \getresults when there is no result should not impact the next -- query executed. \getresults 1 -- 2.55.0