Commit 5dbc5da1 authored by Tom Lane's avatar Tom Lane

Fix behavior of psql's \p to agree with \g, \w, etc.

In commit e984ef58 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
parent 130ae4a5
...@@ -106,7 +106,7 @@ static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_bra ...@@ -106,7 +106,7 @@ static backslashResult exec_command_lo(PsqlScanState scan_state, bool active_bra
const char *cmd); const char *cmd);
static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch); static backslashResult exec_command_out(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_print(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_password(PsqlScanState scan_state, bool active_branch);
static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch, static backslashResult exec_command_prompt(PsqlScanState scan_state, bool active_branch,
const char *cmd); const char *cmd);
...@@ -362,7 +362,8 @@ exec_command(const char *cmd, ...@@ -362,7 +362,8 @@ exec_command(const char *cmd,
else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0) else if (strcmp(cmd, "o") == 0 || strcmp(cmd, "out") == 0)
status = exec_command_out(scan_state, active_branch); status = exec_command_out(scan_state, active_branch);
else if (strcmp(cmd, "p") == 0 || strcmp(cmd, "print") == 0) 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) else if (strcmp(cmd, "password") == 0)
status = exec_command_password(scan_state, active_branch); status = exec_command_password(scan_state, active_branch);
else if (strcmp(cmd, "prompt") == 0) else if (strcmp(cmd, "prompt") == 0)
...@@ -955,7 +956,7 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch, ...@@ -955,7 +956,7 @@ exec_command_edit(PsqlScanState scan_state, bool active_branch,
if (fname) if (fname)
canonicalize_path(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); copy_previous_query(query_buf, previous_buf);
if (do_edit(fname, query_buf, lineno, NULL)) if (do_edit(fname, query_buf, lineno, NULL))
...@@ -1827,12 +1828,19 @@ exec_command_out(PsqlScanState scan_state, bool active_branch) ...@@ -1827,12 +1828,19 @@ exec_command_out(PsqlScanState scan_state, bool active_branch)
*/ */
static backslashResult static backslashResult
exec_command_print(PsqlScanState scan_state, bool active_branch, exec_command_print(PsqlScanState scan_state, bool active_branch,
PQExpBuffer query_buf) PQExpBuffer query_buf, PQExpBuffer previous_buf)
{ {
if (active_branch) 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) if (query_buf && query_buf->len > 0)
puts(query_buf->data); puts(query_buf->data);
else if (previous_buf && previous_buf->len > 0)
puts(previous_buf->data);
else if (!pset.quiet) else if (!pset.quiet)
puts(_("Query buffer is empty.")); puts(_("Query buffer is empty."));
fflush(stdout); fflush(stdout);
...@@ -2549,9 +2557,14 @@ exec_command_write(PsqlScanState scan_state, bool active_branch, ...@@ -2549,9 +2557,14 @@ exec_command_write(PsqlScanState scan_state, bool active_branch,
{ {
int result; 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) if (query_buf && query_buf->len > 0)
fprintf(fd, "%s\n", query_buf->data); fprintf(fd, "%s\n", query_buf->data);
/* Applies to previous query if current buffer is empty */
else if (previous_buf && previous_buf->len > 0) else if (previous_buf && previous_buf->len > 0)
fprintf(fd, "%s\n", previous_buf->data); fprintf(fd, "%s\n", previous_buf->data);
...@@ -2602,7 +2615,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch, ...@@ -2602,7 +2615,7 @@ exec_command_watch(PsqlScanState scan_state, bool active_branch,
free(opt); 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); copy_previous_query(query_buf, previous_buf);
success = do_watch(query_buf, sleep); success = do_watch(query_buf, sleep);
......
...@@ -2932,3 +2932,35 @@ NOTICE: foo ...@@ -2932,3 +2932,35 @@ NOTICE: foo
CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE CONTEXT: PL/pgSQL function inline_code_block line 3 at RAISE
ERROR: bar ERROR: bar
CONTEXT: PL/pgSQL function inline_code_block line 4 at RAISE 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;
...@@ -548,3 +548,15 @@ begin ...@@ -548,3 +548,15 @@ begin
raise notice 'foo'; raise notice 'foo';
raise exception 'bar'; raise exception 'bar';
end $$; 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
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment