Re: Correct handling of blank/commented lines in PSQL interactive-mode history

Поиск
Список
Период
Сортировка
От Tom Lane
Тема Re: Correct handling of blank/commented lines in PSQL interactive-mode history
Дата
Msg-id 1433553.1638219388@sss.pgh.pa.us
обсуждение исходный текст
Ответ на Re: Correct handling of blank/commented lines in PSQL interactive-mode history  (Tom Lane <tgl@sss.pgh.pa.us>)
Ответы Re: Correct handling of blank/commented lines in PSQL interactive-mode history  (Greg Nancarrow <gregn4422@gmail.com>)
Re: Correct handling of blank/commented lines in PSQL interactive-mode history  (Alvaro Herrera <alvherre@alvh.no-ip.org>)
Список pgsql-hackers
After some further hackery, here's a set of patches that I think
might be acceptable.  They're actually fairly independent, although
they touch different aspects of the same behavior.

0001 gets rid of psqlscan.l's habit of suppressing dash-dash comments,
but only once we have collected some non-whitespace query input.
The upshot of this is that dash-dash comments will get sent to the
server as long as they are within the query proper, that is after the
first non-whitespace token and before the ending semicolon.  Comments
that are between queries are still suppressed, because not doing that
seems to result in far too much behavioral change.  As it stands,
though, there are just a few regression test result changes.

0002 is a simplified version of Greg's patch.  I think we only need
to look at the state of the query_buf to see if any input has been
collected in order to determine if we are within or between queries.
I'd originally thought this'd need to be a lot more complicated,
but as long as psqlscan.l continues to drop pre-query comments,
this seems to be enough.

0003 is the same patch I posted before to adjust M-# behavior.

            regards, tom lane

diff --git a/contrib/pg_stat_statements/expected/pg_stat_statements.out
b/contrib/pg_stat_statements/expected/pg_stat_statements.out
index b52d187722..e0abe34bb6 100644
--- a/contrib/pg_stat_statements/expected/pg_stat_statements.out
+++ b/contrib/pg_stat_statements/expected/pg_stat_statements.out
@@ -101,7 +101,7 @@ SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
 ------------------------------------------------------------------------------+-------+------
  PREPARE pgss_test (int) AS SELECT $1, $2 LIMIT $3                            |     1 |    1
  SELECT $1                                                                   +|     4 |    4
-                                                                             +|       |
+   -- multiline                                                              +|       |
    AS "text"                                                                  |       |
  SELECT $1 + $2                                                               |     2 |    2
  SELECT $1 + $2 + $3 AS "add"                                                 |     3 |    3
diff --git a/src/fe_utils/psqlscan.l b/src/fe_utils/psqlscan.l
index 0fab48a382..325b440a12 100644
--- a/src/fe_utils/psqlscan.l
+++ b/src/fe_utils/psqlscan.l
@@ -376,12 +376,11 @@ other            .
                     /*
                      * Note that the whitespace rule includes both true
                      * whitespace and single-line ("--" style) comments.
-                     * We suppress whitespace at the start of the query
-                     * buffer.  We also suppress all single-line comments,
-                     * which is pretty dubious but is the historical
-                     * behavior.
+                     * We suppress whitespace until we have collected some
+                     * non-whitespace data.  (This interacts with some
+                     * decisions in MainLoop(); see there for details.)
                      */
-                    if (!(output_buf->len == 0 || yytext[0] == '-'))
+                    if (output_buf->len > 0)
                         ECHO;
                 }

diff --git a/src/test/regress/expected/aggregates.out b/src/test/regress/expected/aggregates.out
index 5949996ebc..be5fa5727d 100644
--- a/src/test/regress/expected/aggregates.out
+++ b/src/test/regress/expected/aggregates.out
@@ -1905,14 +1905,14 @@ from generate_series(1,5) x,
      (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
 group by p order by p;
 ERROR:  sum is not an ordered-set aggregate, so it cannot have WITHIN GROUP
-LINE 1: select p, sum() within group (order by x::float8)
+LINE 1: select p, sum() within group (order by x::float8)  -- error
                   ^
 select p, percentile_cont(p,p)  -- error
 from generate_series(1,5) x,
      (values (0::float8),(0.1),(0.25),(0.4),(0.5),(0.6),(0.75),(0.9),(1)) v(p)
 group by p order by p;
 ERROR:  WITHIN GROUP is required for ordered-set aggregate percentile_cont
-LINE 1: select p, percentile_cont(p,p)
+LINE 1: select p, percentile_cont(p,p)  -- error
                   ^
 select percentile_cont(0.5) within group (order by b) from aggtest;
  percentile_cont
diff --git a/src/test/regress/expected/generated.out b/src/test/regress/expected/generated.out
index c2e5676196..cb9373227d 100644
--- a/src/test/regress/expected/generated.out
+++ b/src/test/regress/expected/generated.out
@@ -928,7 +928,7 @@ CREATE TRIGGER gtest2a BEFORE INSERT OR UPDATE ON gtest26
   WHEN (NEW.b < 0)  -- error
   EXECUTE PROCEDURE gtest_trigger_func();
 ERROR:  BEFORE trigger's WHEN condition cannot reference NEW generated columns
-LINE 3:   WHEN (NEW.b < 0)
+LINE 3:   WHEN (NEW.b < 0)  -- error
                 ^
 DETAIL:  Column "b" is a generated column.
 CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26
@@ -936,7 +936,7 @@ CREATE TRIGGER gtest2b BEFORE INSERT OR UPDATE ON gtest26
   WHEN (NEW.* IS NOT NULL)  -- error
   EXECUTE PROCEDURE gtest_trigger_func();
 ERROR:  BEFORE trigger's WHEN condition cannot reference NEW generated columns
-LINE 3:   WHEN (NEW.* IS NOT NULL)
+LINE 3:   WHEN (NEW.* IS NOT NULL)  -- error
                 ^
 DETAIL:  A whole-row reference is used and the table contains generated columns.
 CREATE TRIGGER gtest2 BEFORE INSERT ON gtest26
diff --git a/src/test/regress/expected/with.out b/src/test/regress/expected/with.out
index a3a2e383e3..75e61460d9 100644
--- a/src/test/regress/expected/with.out
+++ b/src/test/regress/expected/with.out
@@ -2100,7 +2100,7 @@ WITH outermost(x) AS (
 )
 SELECT * FROM outermost ORDER BY 1;
 ERROR:  relation "outermost" does not exist
-LINE 4:          SELECT * FROM outermost
+LINE 4:          SELECT * FROM outermost  -- fail
                                ^
 DETAIL:  There is a WITH item named "outermost", but it cannot be referenced from this part of the query.
 HINT:  Use WITH RECURSIVE, or re-order the WITH items to remove forward references.
@@ -2124,7 +2124,7 @@ WITH RECURSIVE outermost(x) AS (
 )
 SELECT * FROM outermost ORDER BY 1;
 ERROR:  recursive reference to query "outermost" must not appear within a subquery
-LINE 2:   WITH innermost as (SELECT 2 FROM outermost)
+LINE 2:   WITH innermost as (SELECT 2 FROM outermost) -- fail
                                            ^
 --
 -- This test will fail with the old implementation of PARAM_EXEC parameter
diff --git a/src/bin/psql/mainloop.c b/src/bin/psql/mainloop.c
index e49ed02293..3b7b4ad4a2 100644
--- a/src/bin/psql/mainloop.c
+++ b/src/bin/psql/mainloop.c
@@ -564,9 +564,20 @@ MainLoop(FILE *source)
                 break;
         }
 
-        /* Add line to pending history if we didn't execute anything yet */
-        if (pset.cur_cmd_interactive && !line_saved_in_history)
-            pg_append_history(line, history_buf);
+        /*
+         * Add line to pending history if we didn't do so already.  Then, if
+         * the query buffer is still empty, flush out any unsent history
+         * entry.  This means that empty lines (containing only whitespace and
+         * perhaps a dash-dash comment) that precede a query will be recorded
+         * as separate history entries, not as part of that query.
+         */
+        if (pset.cur_cmd_interactive)
+        {
+            if (!line_saved_in_history)
+                pg_append_history(line, history_buf);
+            if (query_buf->len == 0)
+                pg_send_history(history_buf);
+        }
 
         psql_scan_finish(scan_state);
         free(line);
diff --git a/src/bin/psql/input.c b/src/bin/psql/input.c
index f926bc98dc..1dcd95a7b9 100644
--- a/src/bin/psql/input.c
+++ b/src/bin/psql/input.c
@@ -353,8 +353,13 @@ initializeInput(int flags)
 
         useReadline = true;
 
-        /* these two things must be done in this order: */
+        /* set appropriate values for Readline's global variables */
         initialize_readline();
+
+        /* set comment-begin to a useful value for SQL */
+        (void) rl_variable_bind("comment-begin", "-- ");
+
+        /* this reads ~/.inputrc, so do it after rl_variable_bind */
         rl_initialize();
 
         useHistory = true;

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Daniel Gustafsson
Дата:
Сообщение: Re: improve CREATE EXTENSION error message
Следующее
От: Tom Lane
Дата:
Сообщение: Re: improve CREATE EXTENSION error message