<!--

Les sources et discussions pour ces sujets sont :

* Add psql backslash commands to allowing issuance of pipeline queries (Anthonin
Bonnefoy) § § §

  - The new commands are \startpipeline, \syncpipeline, \sendpipeline,
    \endpipeline, \flushrequest, \flush, and \getresults.
  - https://postgr.es/c/41625ab8e
    https://postgr.es/m/CAO6_XqroE7JuMEm1sWz55rp9fAYX2JwmcP_3m_v51vnOFdsLiQ@mail.gmail.com
  - https://postgr.es/c/17caf6644
    https://postgr.es/m/ad4b9f1a-f7fe-4ab8-8546-90754726d0be@manitou-mail.org
  - https://postgr.es/c/2cce0fe44
    https://postgr.es/m/d67b9c19-d009-4a50-8020-1a0ea92366a1@manitou-mail.org

* Allow adding pipeline status to the psql prompt and add related state variables
(Anthonin Bonnefoy) §

  - The new prompt character is "%P" and the new psql
    variables are PIPELINE_SYNC_COUNT, PIPELINE_COMMAND_COUNT, and
    PIPELINE_RESULT_COUNT.
  - https://postgr.es/c/3ce357584
    https://postgr.es/m/CAO6_XqroE7JuMEm1sWz55rp9fAYX2JwmcP_3m_v51vnOFdsLiQ@mail.gmail.com

-->

<div class="slide-content">

  * Nouvelles métas commandes :
    - `\startpipeline`, `\endpipeline`, `\syncpipeline`, `\flush`,
      `\flushrequest`, `\getresults` et `\sendpipeline`
  * Nouvelles variables :
    - `PIPELINE_SYNC_COUNT`, `PIPELINE_COMMAND_COUNT`, `PIPELINE_RESULT_COUNT`
  * Statut du pipeline dans le prompt avec `%P` ( `on`, `off`, `abort`)
  * Principalement destinés aux tests de non régression
  * Permet de convertir un script en mode pipeline

</div>

<div class="notes">

Le mode pipeline permet d'envoyer un ensemble de commandes de manière groupée
à PostgreSQL et de récupérer le résultat ensuite. Cela permet de diminuer le
nombre d'allers-retours entre client et serveur en regroupant les messages
envoyés, ce qui est particulièrement intéressant quand il y a une forte latence
entre le serveur de base de données et le serveur d'application.

Les métacommandes suivantes permettent d'utiliser le mode pipeline du
protocole de communication directement dans `psql` :

* `\startpipeline` : démarre un pipeline. Toutes les requêtes préparées ou les
  requêtes terminées par un `;` (elles sont en fait transformées en requêtes
  préparées) sont ajoutées dans une queue jusqu'à ce que le pipeline soit
  terminé ou synchonisé ;
* `\endpipeline` : termine un pipeline. Cette commande envoie toutes les
  commandes au serveur, les réponses sont ensuite traitées par `psql` ;
* `\syncpipeline` : place une demande de synchronisation dans la queue sans
  envoyer les commandes de la queue au serveur ;
* `\flush` et `\flushrequest` : force le backend à envoyer les données en
  attente dans son buffer d'envoi. Chaque commande utilise une portion du code
  de PostgreSQL différente ;
* `\getresults` : lit les résultat du pipeline. Il est possible de contrôler
  le nombre de résultats à lire, `0` signifiant que l'on souhaite tout récupérer ;
* `\sendpipeline` : cette commande remplace `\g` et `\gx` pour les pipelines.

Ces métacommandes permettent de tester le protocole de communication étendu de
PostgreSQL directement via `psql`. Elles vont permettre d'améliorer les tests de non
régression.

Dans un patch différent, trois compteurs ont été ajoutés pour suivre le statut
d'un pipeline :

  - `PIPELINE_SYNC_COUNT` : nombre de commandes sync dans la queue ;
  - `PIPELINE_COMMAND_COUNT` : nombre de commandes dans la queue ;
  - `PIPELINE_RESULT_COUNT` : nombre de rapports lisibles avec la commande `\getresult`.

Voici un exemple d’utilisation de ces fonctionnalités :

```sql
psql << '_END_SCRIPT_'
\set pipeline_info '\\echo sync: :PIPELINE_SYNC_COUNT, cmd: :PIPELINE_COMMAND_COUNT, result: :PIPELINE_RESULT_COUNT'

\startpipeline

-- La commande fonctionne avec des requêtes non préparées. Elles seront
-- transformées en requêtes préparées de manière transparente.
DROP TABLE IF EXISTS test_psql;
CREATE TABLE test_psql(i int);
:pipeline_info
\syncpipeline

-- ... des requêtes préparée non nommées
INSERT INTO test_psql(i)
SELECT generate_series($1::bigint, $2::bigint) \bind 1 10 \sendpipeline

-- ... et nommées
INSERT INTO test_psql(i)
SELECT generate_series($1::bigint, $2::bigint) \parse myinsert
\bind_named 'myinsert' 11 20 \sendpipeline
\bind_named 'myinsert' 21 30 \sendpipeline
\close 'myinsert'
:pipeline_info
\syncpipeline

SELECT * FROM test_psql;

:pipeline_info
\flushrequest
:pipeline_info
\getresults
:pipeline_info
\endpipeline
_END_SCRIPT_
```

Résultat :

```default
sync: 0, cmd: 2, result: 0
sync: 1, cmd: 5, result: 2
sync: 2, cmd: 1, result: 7
sync: 2, cmd: 0, result: 8

DROP TABLE
CREATE TABLE
INSERT 0 10

INSERT 0 10
INSERT 0 10

 i
----
  1
...
 30
(30 rows)

sync: 0, cmd: 0, result: 0
```

Pour finir, la variable de prompt `%P` a été ajoutée pour donner des
informations sur l'état du pipeline parmi `on`, `off`, `abort`.

Avec cette définition de prompt :

```default
\set PROMPT1 'pipeline: %P (%:PIPELINE_SYNC_COUNT:, %:PIPELINE_COMMAND_COUNT:, %:PIPELINE_RESULT_COUNT:)%#%x '
```

nous obtenons le prompt suivant, avec un statut à `off` :

```default
pipeline: off (0, 0, 0)# \startpipeline
```

Le démarrage du mode pipeline passe le statut à `on` :

```default
pipeline: on (0, 0, 0)# SELECT failure;
pipeline: on (0, 1, 0)#* \flushrequest
```

... et une erreur le passe à `abort` :

```default
pipeline: on (0, 0, 1)#* \getresults
ERROR:  column "failure" does not exist
LINE 1: SELECT failure;
pipeline: abort (0, 0, 0)#
```

</div>
