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 ([email protected])
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers