Hi, I've noticed two issues with the query buffer post-commit e984ef5 (Support \if ... \elif ... \else ... \endif in psql scripting):
1. \p ignores the "previous buffer". Example: postgres=# select 1; ?column? ---------- 1 (1 row) postgres=# \p Query buffer is empty. That doesn't match the pre-commit behavior, and is not consistent with \e or \w 2. \r keeps the "previous buffer". I think it should clear it. Example: postgres=# select 1; ?column? ---------- 1 (1 row) postgres=# select 2 \r Query buffer reset (cleared). postgres=# \w /tmp/buffer postgres=# \! cat /tmp/buffer select 1; I suggest the attached fix, with a few new regression tests. Best regards, -- Daniel Vérité PostgreSQL-powered mailer: http://www.manitou-mail.org Twitter: @DanielVerite
diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 94a3cfc..6554268 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -106,14 +106,14 @@ static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_bra const char *cmd); static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf); + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_password(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, const char *cmd); static backslashResult exec_command_pset(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf); + PQExpBuffer query_buf, PQExpBuffer previous_buf); static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_set(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_setenv(PsqlScanState scan_state, bool active_branch, @@ -192,8 +192,8 @@ static void checkWin32Codepage(void); * execution of the backslash command (for example, \r clears it). * * previous_buf contains the query most recently sent to the server - * (empty if none yet). This should not be modified here, but some - * commands copy its content into query_buf. + * (empty if none yet). This should not be modified here (except by + * \r), but some commands copy its content into query_buf. * * query_buf and previous_buf will be NULL when executing a "-c" * command-line option. @@ -362,7 +362,8 @@ exec_command(const char *cmd, else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) status = exec_command_out(scan_state, active_branch); else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0) - status = exec_command_print(scan_state, active_branch, query_buf); + status = exec_command_print(scan_state, active_branch, + query_buf, previous_buf); else if (strcmp(cmd, "password") == 0) status = exec_command_password(scan_state, active_branch); else if (strcmp(cmd, "prompt") == 0) @@ -372,7 +373,8 @@ exec_command(const char *cmd, else if (strcmp(cmd, "q") == 0 || strcmp(cmd, "quit") == 0) status = exec_command_quit(scan_state, active_branch); else if (strcmp(cmd, "r") == 0 || strcmp(cmd, "reset") == 0) - status = exec_command_reset(scan_state, active_branch, query_buf); + status = exec_command_reset(scan_state, active_branch, + query_buf, previous_buf); else if (strcmp(cmd, "s") == 0) status = exec_command_s(scan_state, active_branch); else if (strcmp(cmd, "set") == 0) @@ -1827,12 +1829,15 @@ exec_command_out(PsqlScanState scan_state, bool active_branch) */ static backslashResult exec_command_print(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf) + PQExpBuffer query_buf, PQExpBuffer previous_buf) { if (active_branch) { if (query_buf && query_buf->len > 0) puts(query_buf->data); + /* Applies to previous query if current buffer is empty */ + else if (previous_buf && previous_buf->len > 0) + puts(previous_buf->data); else if (!pset.quiet) puts(_("Query buffer is empty.")); fflush(stdout); @@ -2056,10 +2061,11 @@ exec_command_quit(PsqlScanState scan_state, bool active_branch) */ static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch, - PQExpBuffer query_buf) + PQExpBuffer query_buf, PQExpBuffer previous_buf) { if (active_branch) { + resetPQExpBuffer(previous_buf); resetPQExpBuffer(query_buf); psql_scan_reset(scan_state); if (!pset.quiet) diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 8aa914f..f1c516a 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -2932,3 +2932,30 @@ NOTICE: foo CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE ERROR: bar CONTEXT: PL/pgSQL function inline_code_block line 4 at RAISE +-- test printing and clearing the query buffer +SELECT 1; + ?column? +---------- + 1 +(1 row) + +\p +SELECT 1; +SELECT 2 \r +\p +SELECT 3 \p +SELECT 3 +UNION SELECT 4 \p +SELECT 3 +UNION SELECT 4 +UNION SELECT 5 +ORDER BY 1; + ?column? +---------- + 3 + 4 + 5 +(3 rows) + +\r +\p diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 0ae4dd8..b56a05f 100644 --- a/src/test/regress/sql/psql.sql +++ b/src/test/regress/sql/psql.sql @@ -548,3 +548,15 @@ begin raise notice 'foo'; raise exception 'bar'; end $$; + +-- test printing and clearing the query buffer +SELECT 1; +\p +SELECT 2 \r +\p +SELECT 3 \p +UNION SELECT 4 \p +UNION SELECT 5 +ORDER BY 1; +\r +\p
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers