psql: Add \sendpipeline to send query buffers while in a pipeline
authorMichael Paquier <michael@paquier.xyz>
Tue, 18 Mar 2025 00:41:21 +0000 (09:41 +0900)
committerMichael Paquier <michael@paquier.xyz>
Tue, 18 Mar 2025 00:41:21 +0000 (09:41 +0900)
In the initial pipeline support for psql added in 41625ab8ea3d, \g was
used as the way to push extended query into an ongoing pipeline.  \gx
was blocked.

These two meta-commands have format-related options that can be applied
when fetching a query result (expanded, etc.).  As the results of a
pipeline are fetched asynchronously, not at the moment of the
meta-command execution but at the moment of a \getresults or a
\endpipeline, authorizing \g while blocking \gx leads to a confusing
implementation, making one think that psql should be smart enough to
remember the output format options defined from the time when \g or \gx
were executed.  Doing so would lead to more code complications when
retrieving a batch of results.  There is an extra argument other than
simplicity here: the output format options defined at the point of a
\getresults or a \endpipeline execution should be what affect the output
format for a batch of results.

To avoid any confusion, we have settled to the introduction of a new
meta-command called \sendpipeline, replacing \g when within a pipeline.
An advantage of this design is that it is possible to add new options
specific to pipelines when sending a query buffer, independent of \g
and \gx, should it prove to be necessary.

Most of the changes of this commit happen in the regression tests, where
\g is replaced by \sendpipeline.  More tests are added to check that \g
is not allowed.

Per discussion between the author, Daniel Vérité and me.

Author: Anthonin Bonnefoy <anthonin.bonnefoy@datadoghq.com>
Discussion: https://postgr.es/m/ad4b9f1a-f7fe-4ab8-8546-90754726d0be@manitou-mail.org

doc/src/sgml/ref/psql-ref.sgml
src/bin/psql/command.c
src/bin/psql/help.c
src/bin/psql/tab-complete.in.c
src/test/regress/expected/psql.out
src/test/regress/expected/psql_pipeline.out
src/test/regress/sql/psql.sql
src/test/regress/sql/psql_pipeline.sql

index cedccc14129f861bfb67642789e793ea545214b1..cddf6e07531db984714548f1246977c6020279c6 100644 (file)
@@ -3677,6 +3677,7 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
 
      <varlistentry id="app-psql-meta-command-pipeline">
       <term><literal>\startpipeline</literal></term>
+      <term><literal>\sendpipeline</literal></term>
       <term><literal>\syncpipeline</literal></term>
       <term><literal>\endpipeline</literal></term>
       <term><literal>\flushrequest</literal></term>
@@ -3701,10 +3702,10 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
         queries need to be sent using the meta-commands
         <literal>\bind</literal>, <literal>\bind_named</literal>,
         <literal>\close</literal> or <literal>\parse</literal>. While a
-        pipeline is ongoing, <literal>\g</literal> will append the current
-        query buffer to the pipeline. Other meta-commands like
-        <literal>\gx</literal> or <literal>\gdesc</literal> are not allowed
-        in pipeline mode.
+        pipeline is ongoing, <literal>\sendpipeline</literal> will append the
+        current query buffer to the pipeline. Other meta-commands like
+        <literal>\g</literal>, <literal>\gx</literal> or <literal>\gdesc</literal>
+        are not allowed in pipeline mode.
        </para>
 
        <para>
@@ -3738,7 +3739,7 @@ testdb=&gt; <userinput>\setenv LESS -imx4F</userinput>
         Example:
 <programlisting>
 \startpipeline
-SELECT 1 \bind \g
+SELECT 1 \bind \sendpipeline
 \flushrequest
 \getresults
 \endpipeline
index fb0b27568c52de9ca7d89d06f3cb7fe7651b8073..a87ff7e4597179ed4e72d6a8ab121a0dd2668262 100644 (file)
@@ -131,6 +131,7 @@ static backslashResult exec_command_quit(PsqlScanState scan_state, bool active_b
 static backslashResult exec_command_reset(PsqlScanState scan_state, bool active_branch,
                                          PQExpBuffer query_buf);
 static backslashResult exec_command_s(PsqlScanState scan_state, bool active_branch);
+static backslashResult exec_command_sendpipeline(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,
                                           const char *cmd);
@@ -417,6 +418,8 @@ exec_command(const char *cmd,
        status = exec_command_reset(scan_state, active_branch, query_buf);
    else if (strcmp(cmd, "s") == 0)
        status = exec_command_s(scan_state, active_branch);
+   else if (strcmp(cmd, "sendpipeline") == 0)
+       status = exec_command_sendpipeline(scan_state, active_branch);
    else if (strcmp(cmd, "set") == 0)
        status = exec_command_set(scan_state, active_branch);
    else if (strcmp(cmd, "setenv") == 0)
@@ -1734,10 +1737,9 @@ exec_command_g(PsqlScanState scan_state, bool active_branch, const char *cmd)
 
    if (status == PSQL_CMD_SKIP_LINE && active_branch)
    {
-       if (strcmp(cmd, "gx") == 0 &&
-           PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
+       if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
        {
-           pg_log_error("\\gx not allowed in pipeline mode");
+           pg_log_error("\\%s not allowed in pipeline mode", cmd);
            clean_extended_state();
            free(fname);
            return PSQL_CMD_ERROR;
@@ -2776,6 +2778,43 @@ exec_command_s(PsqlScanState scan_state, bool active_branch)
    return success ? PSQL_CMD_SKIP_LINE : PSQL_CMD_ERROR;
 }
 
+/*
+ * \sendpipeline -- send an extended query to an ongoing pipeline
+ */
+static backslashResult
+exec_command_sendpipeline(PsqlScanState scan_state, bool active_branch)
+{
+   backslashResult status = PSQL_CMD_SKIP_LINE;
+
+   if (active_branch)
+   {
+       if (PQpipelineStatus(pset.db) != PQ_PIPELINE_OFF)
+       {
+           if (pset.send_mode == PSQL_SEND_EXTENDED_QUERY_PREPARED ||
+               pset.send_mode == PSQL_SEND_EXTENDED_QUERY_PARAMS)
+           {
+               status = PSQL_CMD_SEND;
+           }
+           else
+           {
+               pg_log_error("\\sendpipeline must be used after \\bind or \\bind_named");
+               clean_extended_state();
+               return PSQL_CMD_ERROR;
+           }
+       }
+       else
+       {
+           pg_log_error("\\sendpipeline not allowed outside of pipeline mode");
+           clean_extended_state();
+           return PSQL_CMD_ERROR;
+       }
+   }
+   else
+       ignore_slash_options(scan_state);
+
+   return status;
+}
+
 /*
  * \set -- set variable
  */
index 714b8619233060555f7ba1cf7355f246ff0fcd97..e47cad24de9c2e48ce39acd98a2742c12d287716 100644 (file)
@@ -181,6 +181,7 @@ slashUsage(unsigned short int pager)
    HELP0("  \\gx [(OPTIONS)] [FILE] as \\g, but forces expanded output mode\n");
    HELP0("  \\parse STMT_NAME       create a prepared statement\n");
    HELP0("  \\q                     quit psql\n");
+   HELP0("  \\sendpipeline          send an extended query to an ongoing pipeline\n");
    HELP0("  \\startpipeline         enter pipeline mode\n");
    HELP0("  \\syncpipeline          add a synchronisation point to an ongoing pipeline\n");
    HELP0("  \\watch [[i=]SEC] [c=N] [m=MIN]\n"
index 8432be641ac066957e51568dab91d695acbd6260..9a4d993e2bc994c11539e83f8fdde2696b1e05e3 100644 (file)
@@ -1895,7 +1895,8 @@ psql_completion(const char *text, int start, int end)
        "\\parse", "\\password", "\\print", "\\prompt", "\\pset",
        "\\qecho", "\\quit",
        "\\reset",
-       "\\s", "\\set", "\\setenv", "\\sf", "\\startpipeline", "\\sv", "\\syncpipeline",
+       "\\s", "\\sendpipeline", "\\set", "\\setenv", "\\sf",
+       "\\startpipeline", "\\sv", "\\syncpipeline",
        "\\t", "\\T", "\\timing",
        "\\unset",
        "\\x",
index 6543e90de758bc53a6a293b767673c3b51a20f13..8687ffe27506128fa8c4145ee12c86c275c4436f 100644 (file)
@@ -4706,6 +4706,7 @@ invalid command \lo
    \q
    \reset
    \s arg1
+   \sendpipeline
    \set arg1 arg2 arg3 arg4 arg5 arg6 arg7
    \setenv arg1 arg2
    \sf whole_line
index 3df2415a84031468b4969364bb308084eb58a2fa..68e3c19ea05b41f7d025f5391e689ae13e8cde81 100644 (file)
@@ -4,7 +4,7 @@
 CREATE TABLE psql_pipeline(a INTEGER PRIMARY KEY, s TEXT);
 -- Single query
 \startpipeline
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -13,9 +13,9 @@ SELECT $1 \bind 'val1' \g
 
 -- Multiple queries
 \startpipeline
-SELECT $1 \bind 'val1' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1 \bind 'val1' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -35,10 +35,10 @@ SELECT $1, $2 \bind 'val2' 'val3' \g
 -- Test \flush
 \startpipeline
 \flush
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \flush
-SELECT $1, $2 \bind 'val2' 'val3' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -63,12 +63,12 @@ SELECT $1, $2 \bind 'val2' 'val3' \g
 0
 \echo :PIPELINE_RESULT_COUNT
 0
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \syncpipeline
 \syncpipeline
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \syncpipeline
-SELECT $1, $2 \bind 'val4' 'val5' \g
+SELECT $1, $2 \bind 'val4' 'val5' \sendpipeline
 \echo :PIPELINE_COMMAND_COUNT
 1
 \echo :PIPELINE_SYNC_COUNT
@@ -94,7 +94,7 @@ SELECT $1, $2 \bind 'val4' 'val5' \g
 -- \startpipeline should not have any effect if already in a pipeline.
 \startpipeline
 \startpipeline
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -103,24 +103,24 @@ SELECT $1 \bind 'val1' \g
 
 -- Convert an implicit transaction block to an explicit transaction block.
 \startpipeline
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 2 \g
-ROLLBACK \bind \g
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 2 \sendpipeline
+ROLLBACK \bind \sendpipeline
 \endpipeline
 -- Multiple explicit transactions
 \startpipeline
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-ROLLBACK \bind \g
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-COMMIT \bind \g
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+ROLLBACK \bind \sendpipeline
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+COMMIT \bind \sendpipeline
 \endpipeline
 -- COPY FROM STDIN
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -129,8 +129,8 @@ COPY psql_pipeline FROM STDIN \bind \g
 
 -- COPY FROM STDIN with \flushrequest + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \flushrequest
 \getresults
  ?column? 
@@ -142,8 +142,8 @@ message type 0x5a arrived from server while idle
 \endpipeline
 -- COPY FROM STDIN with \syncpipeline + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \syncpipeline
 \getresults
  ?column? 
@@ -154,8 +154,8 @@ COPY psql_pipeline FROM STDIN \bind \g
 \endpipeline
 -- COPY TO STDOUT
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -168,8 +168,8 @@ copy psql_pipeline TO STDOUT \bind \g
 4  test4
 -- COPY TO STDOUT with \flushrequest + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \flushrequest
 \getresults
  ?column? 
@@ -184,8 +184,8 @@ copy psql_pipeline TO STDOUT \bind \g
 \endpipeline
 -- COPY TO STDOUT with \syncpipeline + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \syncpipeline
 \getresults
  ?column? 
@@ -203,14 +203,14 @@ copy psql_pipeline TO STDOUT \bind \g
 SELECT $1 \parse ''
 SELECT $1, $2 \parse ''
 SELECT $2 \parse pipeline_1
-\bind_named '' 1 2 \g
-\bind_named pipeline_1 2 \g
+\bind_named '' 1 2 \sendpipeline
+\bind_named pipeline_1 2 \sendpipeline
 \endpipeline
 ERROR:  could not determine data type of parameter $1
 -- \getresults displays all results preceding a \flushrequest.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
 \getresults
  ?column? 
@@ -226,8 +226,8 @@ SELECT $1 \bind 2 \g
 \endpipeline
 -- \getresults displays all results preceding a \syncpipeline.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \syncpipeline
 \getresults
  ?column? 
@@ -245,7 +245,7 @@ SELECT $1 \bind 2 \g
 \startpipeline
 \getresults
 No pending results to get
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
 No pending results to get
 \flushrequest
@@ -259,9 +259,9 @@ No pending results to get
 No pending results to get
 -- \getresults only fetches results preceding a \flushrequest.
 \startpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
  ?column? 
 ----------
@@ -276,9 +276,9 @@ SELECT $1 \bind 2 \g
 
 -- \getresults only fetches results preceding a \syncpipeline.
 \startpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \syncpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
  ?column? 
 ----------
@@ -294,7 +294,7 @@ SELECT $1 \bind 2 \g
 -- Use pipeline with chunked results for both \getresults and \endpipeline.
 \startpipeline
 \set FETCH_COUNT 10
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
 \getresults
  ?column? 
@@ -302,7 +302,7 @@ SELECT $1 \bind 2 \g
  2
 (1 row)
 
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -312,9 +312,9 @@ SELECT $1 \bind 2 \g
 \unset FETCH_COUNT
 -- \getresults with specific number of requested results.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
-SELECT $1 \bind 3 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
+SELECT $1 \bind 3 \sendpipeline
 \echo :PIPELINE_SYNC_COUNT
 0
 \syncpipeline
@@ -330,7 +330,7 @@ SELECT $1 \bind 3 \g
 
 \echo :PIPELINE_RESULT_COUNT
 2
-SELECT $1 \bind 4 \g
+SELECT $1 \bind 4 \sendpipeline
 \getresults 3
  ?column? 
 ----------
@@ -354,7 +354,7 @@ SELECT $1 \bind 4 \g
 \startpipeline
 \syncpipeline
 \syncpipeline
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \flushrequest
 \getresults 2
 \getresults 1
@@ -366,9 +366,9 @@ SELECT $1 \bind 1 \g
 \endpipeline
 -- \getresults 0 should get all the results.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
-SELECT $1 \bind 3 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
+SELECT $1 \bind 3 \sendpipeline
 \syncpipeline
 \getresults 0
  ?column? 
@@ -398,7 +398,7 @@ cannot send pipeline when not in pipeline mode
 \startpipeline
 SELECT 1;
 PQsendQuery not allowed in pipeline mode
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -408,9 +408,9 @@ SELECT $1 \bind 'val1' \g
 -- After an aborted pipeline, commands after a \syncpipeline should be
 -- displayed.
 \startpipeline
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \syncpipeline
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
 ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
  ?column? 
@@ -421,23 +421,23 @@ ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
 -- For an incorrect number of parameters, the pipeline is aborted and
 -- the following queries will not be executed.
 \startpipeline
-SELECT \bind 'val1' \g
-SELECT $1 \bind 'val1' \g
+SELECT \bind 'val1' \sendpipeline
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
 ERROR:  bind message supplies 1 parameters, but prepared statement "" requires 0
 -- An explicit transaction with an error needs to be rollbacked after
 -- the pipeline.
 \startpipeline
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-ROLLBACK \bind \g
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+ROLLBACK \bind \sendpipeline
 \endpipeline
 ERROR:  duplicate key value violates unique constraint "psql_pipeline_pkey"
 DETAIL:  Key (a)=(1) already exists.
 ROLLBACK;
 -- \watch sends a simple query, something not allowed within a pipeline.
 \startpipeline
-SELECT \bind \g
+SELECT \bind \sendpipeline
 \watch 1
 PQsendQuery not allowed in pipeline mode
 
@@ -450,7 +450,7 @@ PQsendQuery not allowed in pipeline mode
 \startpipeline
 SELECT $1 \bind 1 \gdesc
 synchronous command execution functions are not allowed in pipeline mode
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -465,42 +465,63 @@ SELECT $1 as k, $2 as l \parse 'second'
 \gset not allowed in pipeline mode
 \bind_named second 1 2 \gset pref02_ \echo :pref02_i :pref02_j
 \gset not allowed in pipeline mode
-\bind_named '' 1 2 \g
+\bind_named '' 1 2 \sendpipeline
 \endpipeline
  i | j 
 ---+---
  1 | 2
 (1 row)
 
--- \gx is not allowed, pipeline should still be usable.
+-- \g and \gx are not allowed, pipeline should still be usable.
 \startpipeline
+SELECT $1 \bind 1 \g
+\g not allowed in pipeline mode
+SELECT $1 \bind 1 \g (format=unaligned tuples_only=on)
+\g not allowed in pipeline mode
 SELECT $1 \bind 1 \gx
 \gx not allowed in pipeline mode
+SELECT $1 \bind 1 \gx (format=unaligned tuples_only=on)
+\gx not allowed in pipeline mode
 \reset
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
  ?column? 
 ----------
  1
 (1 row)
 
--- \gx warning should be emitted in an aborted pipeline, with
+-- \g and \gx warnings should be emitted in an aborted pipeline, with
 -- pipeline still usable.
 \startpipeline
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \flushrequest
 \getresults
 ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
+SELECT $1 \bind 1 \g
+\g not allowed in pipeline mode
 SELECT $1 \bind 1 \gx
 \gx not allowed in pipeline mode
 \endpipeline
+-- \sendpipeline is not allowed outside of a pipeline
+\sendpipeline
+\sendpipeline not allowed outside of pipeline mode
+SELECT $1 \bind 1 \sendpipeline
+\sendpipeline not allowed outside of pipeline mode
+\reset
+-- \sendpipeline is not allowed if not preceded by \bind or \bind_named
+\startpipeline
+\sendpipeline
+\sendpipeline must be used after \bind or \bind_named
+SELECT 1 \sendpipeline
+\sendpipeline must be used after \bind or \bind_named
+\endpipeline
 -- \gexec is not allowed, pipeline should still be usable.
 \startpipeline
 SELECT 'INSERT INTO psql_pipeline(a) SELECT generate_series(1, 10)' \parse 'insert_stmt'
 \bind_named insert_stmt \gexec
 \gexec not allowed in pipeline mode
-\bind_named insert_stmt \g
-SELECT COUNT(*) FROM psql_pipeline \bind \g
+\bind_named insert_stmt \sendpipeline
+SELECT COUNT(*) FROM psql_pipeline \bind \sendpipeline
 \endpipeline
                           ?column?                          
 ------------------------------------------------------------
@@ -515,26 +536,26 @@ SELECT COUNT(*) FROM psql_pipeline \bind \g
 -- After an error, pipeline is aborted and requires \syncpipeline to be
 -- reusable.
 \startpipeline
-SELECT $1 \bind \g
-SELECT $1 \bind 1 \g
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 \flushrequest
 \getresults
 ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
 -- Pipeline is aborted.
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 -- Sync allows pipeline to recover.
 \syncpipeline
 \getresults
 Pipeline aborted, command did not run
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 \flushrequest
 \getresults
@@ -551,10 +572,10 @@ SELECT $1 \parse a
 \endpipeline
 -- In an aborted pipeline, \getresults 1 aborts commands one at a time.
 \startpipeline
-SELECT $1 \bind \g
-SELECT $1 \bind 1 \g
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \syncpipeline
 \getresults 1
 ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
@@ -569,11 +590,11 @@ Pipeline aborted, command did not run
 -- Test chunked results with an aborted pipeline.
 \startpipeline
 \set FETCH_COUNT 10
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \flushrequest
 \getresults
 ERROR:  bind message supplies 0 parameters, but prepared statement "" requires 1
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \endpipeline
 fetching results in chunked mode failed
 Pipeline aborted, command did not run
@@ -595,7 +616,7 @@ select 1;
 
 -- Error messages accumulate and are repeated.
 \startpipeline
-SELECT 1 \bind \g
+SELECT 1 \bind \sendpipeline
 SELECT 1;
 PQsendQuery not allowed in pipeline mode
 SELECT 1;
@@ -616,12 +637,12 @@ PQsendQuery not allowed in pipeline mode
 -- commit the implicit transaction block. The first command after a
 -- sync will not be seen as belonging to a pipeline.
 \startpipeline
-SET LOCAL statement_timeout='1h' \bind \g
-SHOW statement_timeout \bind \g
+SET LOCAL statement_timeout='1h' \bind \sendpipeline
+SHOW statement_timeout \bind \sendpipeline
 \syncpipeline
-SHOW statement_timeout \bind \g
-SET LOCAL statement_timeout='2h' \bind \g
-SHOW statement_timeout \bind \g
+SHOW statement_timeout \bind \sendpipeline
+SET LOCAL statement_timeout='2h' \bind \sendpipeline
+SHOW statement_timeout \bind \sendpipeline
 \endpipeline
 WARNING:  SET LOCAL can only be used in transaction blocks
  statement_timeout 
@@ -641,9 +662,9 @@ WARNING:  SET LOCAL can only be used in transaction blocks
 
 -- REINDEX CONCURRENTLY fails if not the first command in a pipeline.
 \startpipeline
-SELECT $1 \bind 1 \g
-REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+REINDEX TABLE CONCURRENTLY psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -653,8 +674,8 @@ SELECT $1 \bind 2 \g
 ERROR:  REINDEX CONCURRENTLY cannot run inside a transaction block
 -- REINDEX CONCURRENTLY works if it is the first command in a pipeline.
 \startpipeline
-REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+REINDEX TABLE CONCURRENTLY psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -663,25 +684,25 @@ SELECT $1 \bind 2 \g
 
 -- Subtransactions are not allowed in a pipeline.
 \startpipeline
-SAVEPOINT a \bind \g
-SELECT $1 \bind 1 \g
-ROLLBACK TO SAVEPOINT a \bind \g
-SELECT $1 \bind 2 \g
+SAVEPOINT a \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
+ROLLBACK TO SAVEPOINT a \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 ERROR:  SAVEPOINT can only be used in transaction blocks
 -- LOCK fails as the first command in a pipeline, as not seen in an
 -- implicit transaction block.
 \startpipeline
-LOCK psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+LOCK psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 ERROR:  LOCK TABLE can only be used in transaction blocks
 -- LOCK succeeds as it is not the first command in a pipeline,
 -- seen in an implicit transaction block.
 \startpipeline
-SELECT $1 \bind 1 \g
-LOCK psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+LOCK psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -695,12 +716,12 @@ SELECT $1 \bind 2 \g
 
 -- VACUUM works as the first command in a pipeline.
 \startpipeline
-VACUUM psql_pipeline \bind \g
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
 -- VACUUM fails when not the first command in a pipeline.
 \startpipeline
-SELECT 1 \bind \g
-VACUUM psql_pipeline \bind \g
+SELECT 1 \bind \sendpipeline
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
  ?column? 
 ----------
@@ -710,9 +731,9 @@ VACUUM psql_pipeline \bind \g
 ERROR:  VACUUM cannot run inside a transaction block
 -- VACUUM works after a \syncpipeline.
 \startpipeline
-SELECT 1 \bind \g
+SELECT 1 \bind \sendpipeline
 \syncpipeline
-VACUUM psql_pipeline \bind \g
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
  ?column? 
 ----------
index 97d1be3aac3eb0787bc501b8daca5e0f117c2ed9..1a8a83462f022bd1fba7f96c6639e753912af7f6 100644 (file)
@@ -1074,6 +1074,7 @@ select \if false \\ (bogus \else \\ 42 \endif \\ forty_two;
    \q
    \reset
    \s arg1
+   \sendpipeline
    \set arg1 arg2 arg3 arg4 arg5 arg6 arg7
    \setenv arg1 arg2
    \sf whole_line
index 6517ebb71f8defdf37c8f3491fb74d6da1dcd23e..e4d7e614af392569eee5f33913e000538bb5b775 100644 (file)
@@ -6,23 +6,23 @@ CREATE TABLE psql_pipeline(a INTEGER PRIMARY KEY, s TEXT);
 
 -- Single query
 \startpipeline
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
 
 -- Multiple queries
 \startpipeline
-SELECT $1 \bind 'val1' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1 \bind 'val1' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \endpipeline
 
 -- Test \flush
 \startpipeline
 \flush
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \flush
-SELECT $1, $2 \bind 'val2' 'val3' \g
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \endpipeline
 
 -- Send multiple syncs
@@ -30,12 +30,12 @@ SELECT $1, $2 \bind 'val2' 'val3' \g
 \echo :PIPELINE_COMMAND_COUNT
 \echo :PIPELINE_SYNC_COUNT
 \echo :PIPELINE_RESULT_COUNT
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \syncpipeline
 \syncpipeline
-SELECT $1, $2 \bind 'val2' 'val3' \g
+SELECT $1, $2 \bind 'val2' 'val3' \sendpipeline
 \syncpipeline
-SELECT $1, $2 \bind 'val4' 'val5' \g
+SELECT $1, $2 \bind 'val4' 'val5' \sendpipeline
 \echo :PIPELINE_COMMAND_COUNT
 \echo :PIPELINE_SYNC_COUNT
 \echo :PIPELINE_RESULT_COUNT
@@ -44,39 +44,39 @@ SELECT $1, $2 \bind 'val4' 'val5' \g
 -- \startpipeline should not have any effect if already in a pipeline.
 \startpipeline
 \startpipeline
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
 
 -- Convert an implicit transaction block to an explicit transaction block.
 \startpipeline
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 2 \g
-ROLLBACK \bind \g
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 2 \sendpipeline
+ROLLBACK \bind \sendpipeline
 \endpipeline
 
 -- Multiple explicit transactions
 \startpipeline
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-ROLLBACK \bind \g
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-COMMIT \bind \g
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+ROLLBACK \bind \sendpipeline
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+COMMIT \bind \sendpipeline
 \endpipeline
 
 -- COPY FROM STDIN
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \endpipeline
 2  test2
 \.
 
 -- COPY FROM STDIN with \flushrequest + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \flushrequest
 \getresults
 3  test3
@@ -85,8 +85,8 @@ COPY psql_pipeline FROM STDIN \bind \g
 
 -- COPY FROM STDIN with \syncpipeline + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-COPY psql_pipeline FROM STDIN \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+COPY psql_pipeline FROM STDIN \bind \sendpipeline
 \syncpipeline
 \getresults
 4  test4
@@ -95,22 +95,22 @@ COPY psql_pipeline FROM STDIN \bind \g
 
 -- COPY TO STDOUT
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \endpipeline
 
 -- COPY TO STDOUT with \flushrequest + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \flushrequest
 \getresults
 \endpipeline
 
 -- COPY TO STDOUT with \syncpipeline + \getresults
 \startpipeline
-SELECT $1 \bind 'val1' \g
-copy psql_pipeline TO STDOUT \bind \g
+SELECT $1 \bind 'val1' \sendpipeline
+copy psql_pipeline TO STDOUT \bind \sendpipeline
 \syncpipeline
 \getresults
 \endpipeline
@@ -120,22 +120,22 @@ copy psql_pipeline TO STDOUT \bind \g
 SELECT $1 \parse ''
 SELECT $1, $2 \parse ''
 SELECT $2 \parse pipeline_1
-\bind_named '' 1 2 \g
-\bind_named pipeline_1 2 \g
+\bind_named '' 1 2 \sendpipeline
+\bind_named pipeline_1 2 \sendpipeline
 \endpipeline
 
 -- \getresults displays all results preceding a \flushrequest.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
 \getresults
 \endpipeline
 
 -- \getresults displays all results preceding a \syncpipeline.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \syncpipeline
 \getresults
 \endpipeline
@@ -143,7 +143,7 @@ SELECT $1 \bind 2 \g
 -- \getresults immediately returns if there is no result to fetch.
 \startpipeline
 \getresults
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
 \flushrequest
 \endpipeline
@@ -151,42 +151,42 @@ SELECT $1 \bind 2 \g
 
 -- \getresults only fetches results preceding a \flushrequest.
 \startpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
 \endpipeline
 
 -- \getresults only fetches results preceding a \syncpipeline.
 \startpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \syncpipeline
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \getresults
 \endpipeline
 
 -- Use pipeline with chunked results for both \getresults and \endpipeline.
 \startpipeline
 \set FETCH_COUNT 10
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \flushrequest
 \getresults
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 \unset FETCH_COUNT
 
 -- \getresults with specific number of requested results.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
-SELECT $1 \bind 3 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
+SELECT $1 \bind 3 \sendpipeline
 \echo :PIPELINE_SYNC_COUNT
 \syncpipeline
 \echo :PIPELINE_SYNC_COUNT
 \echo :PIPELINE_RESULT_COUNT
 \getresults 1
 \echo :PIPELINE_RESULT_COUNT
-SELECT $1 \bind 4 \g
+SELECT $1 \bind 4 \sendpipeline
 \getresults 3
 \echo :PIPELINE_RESULT_COUNT
 \endpipeline
@@ -195,7 +195,7 @@ SELECT $1 \bind 4 \g
 \startpipeline
 \syncpipeline
 \syncpipeline
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \flushrequest
 \getresults 2
 \getresults 1
@@ -203,9 +203,9 @@ SELECT $1 \bind 1 \g
 
 -- \getresults 0 should get all the results.
 \startpipeline
-SELECT $1 \bind 1 \g
-SELECT $1 \bind 2 \g
-SELECT $1 \bind 3 \g
+SELECT $1 \bind 1 \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
+SELECT $1 \bind 3 \sendpipeline
 \syncpipeline
 \getresults 0
 \endpipeline
@@ -221,36 +221,36 @@ SELECT $1 \bind 3 \g
 -- pipeline usable.
 \startpipeline
 SELECT 1;
-SELECT $1 \bind 'val1' \g
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
 
 -- After an aborted pipeline, commands after a \syncpipeline should be
 -- displayed.
 \startpipeline
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \syncpipeline
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
 
 -- For an incorrect number of parameters, the pipeline is aborted and
 -- the following queries will not be executed.
 \startpipeline
-SELECT \bind 'val1' \g
-SELECT $1 \bind 'val1' \g
+SELECT \bind 'val1' \sendpipeline
+SELECT $1 \bind 'val1' \sendpipeline
 \endpipeline
 
 -- An explicit transaction with an error needs to be rollbacked after
 -- the pipeline.
 \startpipeline
-BEGIN \bind \g
-INSERT INTO psql_pipeline VALUES ($1) \bind 1 \g
-ROLLBACK \bind \g
+BEGIN \bind \sendpipeline
+INSERT INTO psql_pipeline VALUES ($1) \bind 1 \sendpipeline
+ROLLBACK \bind \sendpipeline
 \endpipeline
 ROLLBACK;
 
 -- \watch sends a simple query, something not allowed within a pipeline.
 \startpipeline
-SELECT \bind \g
+SELECT \bind \sendpipeline
 \watch 1
 \endpipeline
 
@@ -258,7 +258,7 @@ SELECT \bind \g
 -- and the pipeline should still be usable.
 \startpipeline
 SELECT $1 \bind 1 \gdesc
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
 
 -- \gset is not allowed in a pipeline, pipeline should still be usable.
@@ -267,54 +267,69 @@ SELECT $1 as i, $2 as j \parse ''
 SELECT $1 as k, $2 as l \parse 'second'
 \bind_named '' 1 2 \gset
 \bind_named second 1 2 \gset pref02_ \echo :pref02_i :pref02_j
-\bind_named '' 1 2 \g
+\bind_named '' 1 2 \sendpipeline
 \endpipeline
 
--- \gx is not allowed, pipeline should still be usable.
+-- \g and \gx are not allowed, pipeline should still be usable.
 \startpipeline
+SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \g (format=unaligned tuples_only=on)
 SELECT $1 \bind 1 \gx
+SELECT $1 \bind 1 \gx (format=unaligned tuples_only=on)
 \reset
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 \endpipeline
 
--- \gx warning should be emitted in an aborted pipeline, with
+-- \g and \gx warnings should be emitted in an aborted pipeline, with
 -- pipeline still usable.
 \startpipeline
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \flushrequest
 \getresults
+SELECT $1 \bind 1 \g
 SELECT $1 \bind 1 \gx
 \endpipeline
 
+-- \sendpipeline is not allowed outside of a pipeline
+\sendpipeline
+SELECT $1 \bind 1 \sendpipeline
+\reset
+
+-- \sendpipeline is not allowed if not preceded by \bind or \bind_named
+\startpipeline
+\sendpipeline
+SELECT 1 \sendpipeline
+\endpipeline
+
 -- \gexec is not allowed, pipeline should still be usable.
 \startpipeline
 SELECT 'INSERT INTO psql_pipeline(a) SELECT generate_series(1, 10)' \parse 'insert_stmt'
 \bind_named insert_stmt \gexec
-\bind_named insert_stmt \g
-SELECT COUNT(*) FROM psql_pipeline \bind \g
+\bind_named insert_stmt \sendpipeline
+SELECT COUNT(*) FROM psql_pipeline \bind \sendpipeline
 \endpipeline
 
 -- After an error, pipeline is aborted and requires \syncpipeline to be
 -- reusable.
 \startpipeline
-SELECT $1 \bind \g
-SELECT $1 \bind 1 \g
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 \flushrequest
 \getresults
 -- Pipeline is aborted.
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 -- Sync allows pipeline to recover.
 \syncpipeline
 \getresults
-SELECT $1 \bind 1 \g
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \close a
 \flushrequest
 \getresults
@@ -322,10 +337,10 @@ SELECT $1 \parse a
 
 -- In an aborted pipeline, \getresults 1 aborts commands one at a time.
 \startpipeline
-SELECT $1 \bind \g
-SELECT $1 \bind 1 \g
+SELECT $1 \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
 SELECT $1 \parse a
-\bind_named a 1 \g
+\bind_named a 1 \sendpipeline
 \syncpipeline
 \getresults 1
 \getresults 1
@@ -337,10 +352,10 @@ SELECT $1 \parse a
 -- Test chunked results with an aborted pipeline.
 \startpipeline
 \set FETCH_COUNT 10
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \flushrequest
 \getresults
-SELECT $1 \bind \g
+SELECT $1 \bind \sendpipeline
 \endpipeline
 \unset FETCH_COUNT
 
@@ -356,7 +371,7 @@ select 1;
 
 -- Error messages accumulate and are repeated.
 \startpipeline
-SELECT 1 \bind \g
+SELECT 1 \bind \sendpipeline
 SELECT 1;
 SELECT 1;
 \endpipeline
@@ -371,66 +386,66 @@ SELECT 1;
 -- commit the implicit transaction block. The first command after a
 -- sync will not be seen as belonging to a pipeline.
 \startpipeline
-SET LOCAL statement_timeout='1h' \bind \g
-SHOW statement_timeout \bind \g
+SET LOCAL statement_timeout='1h' \bind \sendpipeline
+SHOW statement_timeout \bind \sendpipeline
 \syncpipeline
-SHOW statement_timeout \bind \g
-SET LOCAL statement_timeout='2h' \bind \g
-SHOW statement_timeout \bind \g
+SHOW statement_timeout \bind \sendpipeline
+SET LOCAL statement_timeout='2h' \bind \sendpipeline
+SHOW statement_timeout \bind \sendpipeline
 \endpipeline
 
 -- REINDEX CONCURRENTLY fails if not the first command in a pipeline.
 \startpipeline
-SELECT $1 \bind 1 \g
-REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+REINDEX TABLE CONCURRENTLY psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 
 -- REINDEX CONCURRENTLY works if it is the first command in a pipeline.
 \startpipeline
-REINDEX TABLE CONCURRENTLY psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+REINDEX TABLE CONCURRENTLY psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 
 -- Subtransactions are not allowed in a pipeline.
 \startpipeline
-SAVEPOINT a \bind \g
-SELECT $1 \bind 1 \g
-ROLLBACK TO SAVEPOINT a \bind \g
-SELECT $1 \bind 2 \g
+SAVEPOINT a \bind \sendpipeline
+SELECT $1 \bind 1 \sendpipeline
+ROLLBACK TO SAVEPOINT a \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 
 -- LOCK fails as the first command in a pipeline, as not seen in an
 -- implicit transaction block.
 \startpipeline
-LOCK psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+LOCK psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 
 -- LOCK succeeds as it is not the first command in a pipeline,
 -- seen in an implicit transaction block.
 \startpipeline
-SELECT $1 \bind 1 \g
-LOCK psql_pipeline \bind \g
-SELECT $1 \bind 2 \g
+SELECT $1 \bind 1 \sendpipeline
+LOCK psql_pipeline \bind \sendpipeline
+SELECT $1 \bind 2 \sendpipeline
 \endpipeline
 
 -- VACUUM works as the first command in a pipeline.
 \startpipeline
-VACUUM psql_pipeline \bind \g
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
 
 -- VACUUM fails when not the first command in a pipeline.
 \startpipeline
-SELECT 1 \bind \g
-VACUUM psql_pipeline \bind \g
+SELECT 1 \bind \sendpipeline
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
 
 -- VACUUM works after a \syncpipeline.
 \startpipeline
-SELECT 1 \bind \g
+SELECT 1 \bind \sendpipeline
 \syncpipeline
-VACUUM psql_pipeline \bind \g
+VACUUM psql_pipeline \bind \sendpipeline
 \endpipeline
 
 -- Clean up