From 5dbc5da1187c1ddb6e091047194d364337ebf232 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sun, 2 Apr 2017 16:50:25 -0400 Subject: [PATCH] Fix behavior of psql's \p to agree with \g, \w, etc. MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In commit e984ef586 I (tgl) simplified the behavior of \p to just print the current query buffer; but Daniel Vérité points out that this made it inconsistent with the behavior of \g and \w. It should print the same thing \g would execute. Fix that, and improve related comments. Daniel Vérité Discussion: https://postgr.es/m/9b4ea968-753f-4b5f-b46c-d7d3bf7c8f90@manitou-mail.org --- src/bin/psql/command.c | 25 +++++++++++++++++------ src/test/regress/expected/psql.out | 32 ++++++++++++++++++++++++++++++ src/test/regress/sql/psql.sql | 12 +++++++++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/src/bin/psql/command.c b/src/bin/psql/command.c index 94a3cfce90..494f468575 100644 --- a/src/bin/psql/command.c +++ b/src/bin/psql/command.c @@ -106,7 +106,7 @@ 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); @@ -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) @@ -955,7 +956,7 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch, if (fname) canonicalize_path(fname); - /* Applies to previous query if current buffer is empty */ + /* If query_buf is empty, recall previous query for editing */ copy_previous_query(query_buf, previous_buf); if (do_edit(fname, query_buf, lineno, NULL)) @@ -1827,12 +1828,19 @@ 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) { + /* + * We want to print the same thing \g would execute, but not to change + * the query buffer state; so we can't use copy_previous_query(). + * Also, beware of possibility that buffer pointers are NULL. + */ if (query_buf && query_buf->len > 0) puts(query_buf->data); + else if (previous_buf && previous_buf->len > 0) + puts(previous_buf->data); else if (!pset.quiet) puts(_("Query buffer is empty.")); fflush(stdout); @@ -2549,9 +2557,14 @@ exec_command_write(PsqlScanState scan_state, bool active_branch, { int result; + /* + * We want to print the same thing \g would execute, but not to + * change the query buffer state; so we can't use + * copy_previous_query(). Also, beware of possibility that buffer + * pointers are NULL. + */ if (query_buf && query_buf->len > 0) fprintf(fd, "%s\n", query_buf->data); - /* Applies to previous query if current buffer is empty */ else if (previous_buf && previous_buf->len > 0) fprintf(fd, "%s\n", previous_buf->data); @@ -2602,7 +2615,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch, free(opt); } - /* Applies to previous query if current buffer is empty */ + /* If query_buf is empty, recall and execute previous query */ copy_previous_query(query_buf, previous_buf); success = do_watch(query_buf, sleep); diff --git a/src/test/regress/expected/psql.out b/src/test/regress/expected/psql.out index 8aa914fa95..d602aeef42 100644 --- a/src/test/regress/expected/psql.out +++ b/src/test/regress/expected/psql.out @@ -2932,3 +2932,35 @@ 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 1; +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 +SELECT 3 +UNION SELECT 4 +UNION SELECT 5 +ORDER BY 1; diff --git a/src/test/regress/sql/psql.sql b/src/test/regress/sql/psql.sql index 0ae4dd84ea..b56a05f7f0 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 -- 2.40.0