]> granicus.if.org Git - postgresql/commitdiff
Fix behavior of psql's \p to agree with \g, \w, etc.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Apr 2017 20:50:25 +0000 (16:50 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 2 Apr 2017 20:50:25 +0000 (16:50 -0400)
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
src/test/regress/expected/psql.out
src/test/regress/sql/psql.sql

index 94a3cfce9071b57d3a20182f5392e83b5577303d..494f4685758e065c03f05b409f9dd07977543864 100644 (file)
@@ -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);
index 8aa914fa95764a627c644a8fab3a5e4f1feaaf0b..d602aeef4219a7a2f088879bdbac65795a39ae28 100644 (file)
@@ -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;
index 0ae4dd84eab7dc902754c6e5878830e91d0bb088..b56a05f7f0dab8b8b8e6485b07077f4621a79304 100644 (file)
@@ -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