<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Blog Loxodata</title>
    <link>http://www.loxodata.com/post/</link>
    <description>Contenu récent au sujet de PostgreSQL sur le blog de Loxodata</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>fr-FR</language>
    <image>
      <url>https://www.loxodata.com/images/logos/logo.png</url>
      <title>Loxodata</title>
      <link>https://www.loxodata.com/post/</link>
      <width>32</width>
      <height>32</height>
      <description>Contenu récent au sujet de PostgreSQL sur le blog de Loxodata</description>
    </image>
    
    <copyright>© 2010-2026 LOXODATA</copyright>
    <lastBuildDate>Mon, 08 Jun 2026 14:00:00 +0200</lastBuildDate>
    <atom:link href="/post/" rel="self" type="application/rss+xml" />
    
    <item>
      <title>PostgreSQL 19 bêta 1</title>
      <link>http://www.loxodata.com/post/postgresql-19-beta1/</link>
      <pubDate>Mon, 08 Jun 2026 14:00:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/postgresql-19-beta1/</guid>
      <description>&lt;h1 id=&#34;postgresql-19-bêta-1-publiée&#34;&gt;PostgreSQL 19 Bêta 1 publiée&lt;/h1&gt;
&lt;p&gt;Le PostgreSQL Global Development Group annonce la disponibilité de la
première bêta de PostgreSQL 19 en &lt;a href=&#34;https://www.postgresql.org/download/&#34;&gt;téléchargement&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cette publication contient un aperçu des fonctionnalités qui seront
disponibles dans la version finale de PostgreSQL 19, bien que des
modifications puissent intervenir pendant la période bêta.&lt;/p&gt;
&lt;p&gt;Vous pouvez trouver des informations sur toutes les fonctionnalités et
les changements de PostgreSQL 19 dans les &lt;a href=&#34;https://www.postgresql.org/docs/19/release-19.html&#34;&gt;notes de version&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans l&amp;rsquo;esprit de la communauté open source PostgreSQL, nous vous
encourageons fortement à tester les nouvelles fonctionnalités de
PostgreSQL 19 dans vos systèmes afin de nous aider à éliminer les
bogues et autres problèmes. Bien que nous ne vous conseillons pas de
faire fonctionner cette publication bêta 1 dans vos environnements de
production, nous vous encourageons à trouver des moyens de faire
fonctionner votre charge applicative typique avec cette publication
bêta.&lt;/p&gt;
&lt;p&gt;Vos tests et vos commentaires aideront la communauté à s&amp;rsquo;assurer que
PostgreSQL 19 respecte nos standards de stabilité et de fiabilité
pour continuer à en faire la base de données relationnelle open-source la plus avancée du
monde. Vous pouvez également vous renseigner sur notre &lt;a href=&#34;https://www.postgresql.org/developer/beta/&#34;&gt;processus de
beta testing&lt;/a&gt; et comment y
contribuer.&lt;/p&gt;
&lt;h2 id=&#34;principales-fonctionnalités-de-postgresql-19&#34;&gt;Principales fonctionnalités de PostgreSQL 19&lt;/h2&gt;
&lt;p&gt;Vous trouverez ci-dessous les principales fonctionnalités planifiées
pour PostgreSQL 19. Cette liste n&amp;rsquo;est pas exhaustive : pour la liste
complète des fonctionnalités, se référer à la &lt;a href=&#34;https://www.postgresql.org/docs/19/release-19.html&#34;&gt;note de publication&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;performance&#34;&gt;Performance&lt;/h3&gt;
&lt;p&gt;PostgreSQL capitalise sur le sous-système d&amp;rsquo;I/O asynchrone introduit
dans PostgreSQL 18. Dans cette publication, &lt;code&gt;io_method=worker&lt;/code&gt;
augmente automatiquement le nombre de processus d&amp;rsquo;I/O, en se basant
sur les nouveaux paramètres &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-resource.html#GUC-IO-MIN-WORKERS&#34;&gt;&lt;code&gt;io_min_workers&lt;/code&gt;&lt;/a&gt;
et &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-resource.html#GUC-IO-MAX-WORKERS&#34;&gt;&lt;code&gt;io_max_worker&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Cette publication introduit aussi l&amp;rsquo;extension &lt;a href=&#34;https://www.postgresql.org/docs/19/pgplanadvice.html&#34;&gt;&lt;code&gt;pg_plan_advice&lt;/code&gt;&lt;/a&gt;, qui
permet aux utilisateurs de contrôler et stabiliser les décisions du
planner, accompagné de &lt;a href=&#34;https://www.postgresql.org/docs/19/pgplanadvice.html&#34;&gt;&lt;code&gt;pg_stash_advice&lt;/code&gt;&lt;/a&gt; pour appliquer
automatiquement les choix en utilisant les identifiants de requête.&lt;/p&gt;
&lt;p&gt;Cette publication apporte des améliorations à &lt;code&gt;VACUUM&lt;/code&gt; et aux opérations
de maintenance. Autovacuum peut maintenant utiliser de la
parallélisation, qui peut être configurée avec le nouveau paramètre
&lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-autovacuum.html#GUC-AUTOVACUUM-MAX-PARALLEL-WORKERS&#34;&gt;&lt;code&gt;autovacuum_max_parallel_workers&lt;/code&gt;&lt;/a&gt;,
et un nouveau système de notation
aide à prioriser les tables à traiter par &lt;code&gt;VACUUM&lt;/code&gt;. De plus, PostgreSQL
19 améliore &lt;code&gt;VACUUM&lt;/code&gt; avec une nouvelle stratégie réduisant
automatiquement la quantité de travail en marquant les pages comme
visibles tant qu&amp;rsquo;elles sont requêtées.&lt;/p&gt;
&lt;p&gt;Enfin, cette publication ajoute
la commande &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-repack.html&#34;&gt;&lt;code&gt;REPACK&lt;/code&gt;&lt;/a&gt; et son option non bloquante &lt;code&gt;CONCURRENTLY&lt;/code&gt;, ce qui
permet de reconstruire des tables avec moins de surcharge
opérationnelle.&lt;/p&gt;
&lt;p&gt;PostgreSQL double les performances des &lt;code&gt;INSERT&lt;/code&gt;
lorsque des vérifications de &lt;a href=&#34;https://www.postgresql.org/docs/19/ddl-constraints.html#DDL-CONSTRAINTS-FK&#34;&gt;clés étrangères&lt;/a&gt;
interviennent.&lt;/p&gt;
&lt;p&gt;De plus,
cette publication améliore plusieurs aires de la planification et de
l&amp;rsquo;exécuteur de requêtes, incluant des optimisations sur les anti-join,
une utilisation plus large des tris incrémentaux, une &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-query.html#GUC-ENABLE-EAGER-AGGREGATE&#34;&gt;agrégation anticipée&lt;/a&gt;
qui accélère le traitement des lignes, des lectures plus
rapides à partir du stockage pendant les lectures séquentielles
parallélisées, et une simplification de &lt;a href=&#34;https://www.postgresql.org/docs/19/functions-comparison.html&#34;&gt;&lt;code&gt;IS DISTINCT FROM&lt;/code&gt;&lt;/a&gt;
et &lt;a href=&#34;https://www.postgresql.org/docs/19/functions-comparison.html&#34;&gt;&lt;code&gt;IS NOT DISTINCT FROM&lt;/code&gt;&lt;/a&gt;
vers les opérateurs &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt; et &lt;code&gt;=&lt;/code&gt; lorsque les données en entrées ne peuvent
pas être &lt;code&gt;NULL&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Il y a aussi des améliorations de la montée en charge de
&lt;a href=&#34;https://www.postgresql.org/docs/19/sql-listen.html&#34;&gt;&lt;code&gt;LISTEN&lt;/code&gt;&lt;/a&gt;&lt;code&gt;/&lt;/code&gt;&lt;a href=&#34;https://www.postgresql.org/docs/19/sql-notify.html&#34;&gt;&lt;code&gt;NOTIFY&lt;/code&gt;&lt;/a&gt;
impactant les charges multi-channel.&lt;/p&gt;
&lt;h3 id=&#34;expérience-développeur&#34;&gt;Expérience développeur&lt;/h3&gt;
&lt;p&gt;PostgreSQL 19 introduit le support de &lt;a href=&#34;https://www.postgresql.org/docs/19/ddl-property-graphs.html&#34;&gt;SQL/PGQ&lt;/a&gt;,
permettant aux
utilisateurs d&amp;rsquo;exécuter des « Property Graph Queries » en utilisant la
syntaxe SQL standard.&lt;/p&gt;
&lt;p&gt;Cette publication étend aussi les possibilités
des requêtes temporelles avec le support de la clause &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-update.html&#34;&gt;&lt;code&gt;FOR PORTION OF&lt;/code&gt;&lt;/a&gt;
pour les commandes &lt;code&gt;UPDATE&lt;/code&gt; et &lt;code&gt;DELETE&lt;/code&gt;, complétant le support des
contraintes temporelles ajoutées dans PostgreSQL 18.&lt;/p&gt;
&lt;p&gt;Cette publication
ajoute aussi les commandes &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-altertable.html&#34;&gt;&lt;code&gt;ALTER TABLE ... MERGE PARTITIONS&lt;/code&gt;&lt;/a&gt;
et &lt;code&gt;ALTER TABLE ... SPLIT PARTITIONS&lt;/code&gt; pour faciliter la réorganisation à
la volée des tables partitionnées.&lt;/p&gt;
&lt;p&gt;Il y a aussi maintenant le support
des lignes retournées en conflit pendant une opération « upsert »
utilisant la commande &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-insert.html#SQL-ON-CONFLICT&#34;&gt;&lt;code&gt;INSERT ... ON CONFLICT DO SELECT ... RETURNING&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PostgreSQL 19 introduit la nouvelle syntaxe &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-select.html#SQL-GROUPBY&#34;&gt;&lt;code&gt;GROUP BY ALL&lt;/code&gt;&lt;/a&gt;,
facilitant l&amp;rsquo;ajout de toutes les colonnes non agrégées et non issues d&amp;rsquo;une
fonction fenêtrée au regroupement.&lt;/p&gt;
&lt;p&gt;Cette publication
étend les capacités de traitement des chaines de caractères dans
&lt;a href=&#34;https://www.postgresql.org/docs/19/functions-json.html#FUNCTIONS-SQLJSON-PATH&#34;&gt;JSONPATH&lt;/a&gt; avec l&amp;rsquo;ajout des fonctions &lt;code&gt;lower()&lt;/code&gt;, &lt;code&gt;upper()&lt;/code&gt;, &lt;code&gt;initcap()&lt;/code&gt;,
&lt;code&gt;replace()&lt;/code&gt;, &lt;code&gt;split_part()&lt;/code&gt; et la famille de fonctions &lt;code&gt;trim()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;PostgreSQL facilite l&amp;rsquo;adoption de motifs de requêtes
« read-your-writes » lorsqu&amp;rsquo;on travaille avec des réplicas en utilisant
la commande &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-wait-for.html&#34;&gt;&lt;code&gt;WAIT FOR LSN&lt;/code&gt;&lt;/a&gt;. Ceci permet à une session d&amp;rsquo;attendre un
changement lié au rejeu d&amp;rsquo;une position spécifique du log (LSN)
sur le replica avant d&amp;rsquo;exécuter une requête &lt;code&gt;SELECT&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;PostgreSQL 19 ajoute aussi de nouvelles fonctions SQL pour récupérer
les &lt;a href=&#34;https://www.postgresql.org/docs/19/functions-info.html#FUNCTIONS-GET-OBJECT-DDL&#34;&gt;commandes DDL&lt;/a&gt;
nécessaires pour recréer des rôles, tablespaces et
bases de données, simplifiant l&amp;rsquo;écriture de scripts et de tâches de
migration.&lt;/p&gt;
&lt;p&gt;De plus, la fonction &lt;a href=&#34;https://www.postgresql.org/docs/19/functions-math.html#FUNCTIONS-MATH-RANDOM-TABLE&#34;&gt;&lt;code&gt;random()&lt;/code&gt;&lt;/a&gt;
fonctionne maintenant avec
des dates et des horodatages, et le langage &lt;a href=&#34;https://www.postgresql.org/docs/19/plpython-event-trigger.html&#34;&gt;PL/Python&lt;/a&gt;
supporte désormais les déclencheurs sur événement (« events triggers »).&lt;/p&gt;
&lt;h3 id=&#34;fonctionnalité-liées-à-la-sécurité&#34;&gt;Fonctionnalité liées à la sécurité&lt;/h3&gt;
&lt;p&gt;PostgreSQL ajoute le support côté serveur de « Server Name Indication »
(SNI) à travers un nouveau fichier de configuration :
&lt;a href=&#34;https://www.postgresql.org/docs/19/ssl-tcp.html#SSL-SNI&#34;&gt;&lt;code&gt;pg_hosts.conf&lt;/code&gt;&lt;/a&gt;,
permettant à un serveur PostgreSQL de présenter
différents certificats TLS basés sur le nom demandé par le client.&lt;/p&gt;
&lt;p&gt;Il y
a aussi un nouveau paramètre &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-connection.html#GUC-PASSWORD-EXPIRATION-WARNING-THRESHOLD&#34;&gt;&lt;code&gt;password_expiration_warning_threshold&lt;/code&gt;&lt;/a&gt;,
par défaut à 7 jours, avertissant l&amp;rsquo;utilisateur d&amp;rsquo;une prochaine
expiration du mot de passe.&lt;/p&gt;
&lt;p&gt;À la suite des efforts pour la dépréciation de l&amp;rsquo;&lt;a href=&#34;https://www.postgresql.org/docs/19/auth-password.html&#34;&gt;authentification &lt;code&gt;md5&lt;/code&gt;&lt;/a&gt;,
cette publication émet un avertissement au client après une
authentification md5 réussie. Ceci est contrôlable à travers le
nouveau paramètre &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-connection.html#GUC-MD5-PASSWORD-WARNINGS&#34;&gt;&lt;code&gt;md5_password_warnings&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;supervision-et-observabilité&#34;&gt;Supervision et observabilité&lt;/h3&gt;
&lt;p&gt;PostgreSQL introduit une nouvelle vue &lt;a href=&#34;https://www.postgresql.org/docs/19/monitoring-stats.html#MONITORING-PG-STAT-LOCK-VIEW&#34;&gt;&lt;code&gt;pg_stat_lock&lt;/code&gt;&lt;/a&gt;,
qui rapporte des statistiques par type de verrous, et une vue
&lt;a href=&#34;https://www.postgresql.org/docs/19/monitoring-stats.html#MONITORING-PG-STAT-RECOVERY-VIEW&#34;&gt;&lt;code&gt;pg_stat_recovery&lt;/code&gt;&lt;/a&gt;
fournissant une visibilité détaillée sur l&amp;rsquo;état des opérations de
récupération.&lt;/p&gt;
&lt;p&gt;Une colonne &lt;code&gt;stats_reset&lt;/code&gt; est maintenant disponible dans
différentes vues statistiques montrant le moment de la remise à zéro
des compteurs.&lt;/p&gt;
&lt;p&gt;Les vues &lt;a href=&#34;https://www.postgresql.org/docs/19/progress-reporting.html#VACUUM-PROGRESS-REPORTING&#34;&gt;&lt;code&gt;pg_stat_progress_vacuum&lt;/code&gt;&lt;/a&gt; et
&lt;a href=&#34;https://www.postgresql.org/docs/19/progress-reporting.html#ANALYZE-PROGRESS-REPORTING&#34;&gt;&lt;code&gt;pg_stat_progress_analyze&lt;/code&gt;&lt;/a&gt;
incluent maintenant une colonne
&lt;code&gt;started_by&lt;/code&gt; rapportant l&amp;rsquo;initiateur de l&amp;rsquo;opération, et la vue
&lt;code&gt;pg_stat_progress_vacuum&lt;/code&gt; a aussi une colonne &lt;code&gt;mode&lt;/code&gt; montrant comment
le VACUUM est opéré.&lt;/p&gt;
&lt;p&gt;Cette publication permet aussi au niveau de &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-logging.html#GUC-LOG-MIN-MESSAGES&#34;&gt;&lt;code&gt;log_min_messages&lt;/code&gt;&lt;/a&gt;
d&amp;rsquo;être spécifié par type de processus, donnant aux opérateurs un
contrôle fin sur chaque partie du système de traces.&lt;/p&gt;
&lt;p&gt;De plus, les
quantités d&amp;rsquo;octets de l&amp;rsquo;écriture de pages pleines (FPW) dans les
journaux de transactions (WAL) sont maintenant rapportées dans les
messages de traces de &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-vacuum.html&#34;&gt;&lt;code&gt;VACUUM&lt;/code&gt;&lt;/a&gt;
et &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-analyze.html&#34;&gt;&lt;code&gt;ANALYZE&lt;/code&gt;&lt;/a&gt;, aidant à l&amp;rsquo;identification
des opérations de maintenance produisant de grandes quantités de
WAL.&lt;/p&gt;
&lt;p&gt;De plus, &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-explain.html&#34;&gt;&lt;code&gt;EXPLAIN ANALYZE&lt;/code&gt;&lt;/a&gt;
supporte maintenant la visualisation
des statistiques des I/O asynchrones à travers son option &lt;code&gt;IO&lt;/code&gt;,
fournissant une meilleure visibilité sur la manière qu&amp;rsquo;ont les requêtes
d&amp;rsquo;utiliser le sous-système d&amp;rsquo;I/O asynchrone.&lt;/p&gt;
&lt;h3 id=&#34;réplication-logique-et-requêtes-fédérées&#34;&gt;Réplication logique et requêtes fédérées&lt;/h3&gt;
&lt;p&gt;Dans PostgreSQL 19, la replication logique réplique maintenant les
valeurs des séquences, simplifiant les tâches de mise à jour. De plus,
la nouvelle syntaxe &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-createpublication.html&#34;&gt;&lt;code&gt;CREATE PUBLICATION ... EXCEPT&lt;/code&gt;&lt;/a&gt;
vous permet de publier toutes les tables d&amp;rsquo;une base de données, à l&amp;rsquo;exception d&amp;rsquo;un
sous-ensemble spécifique, tandis que &lt;a href=&#34;https://www.postgresql.org/docs/19/sql-createsubscription.html&#34;&gt;&lt;code&gt;CREATE SUBSCRIPTION ... SERVER&lt;/code&gt;&lt;/a&gt;
permet à un abonnement d&amp;rsquo;utiliser en serveur étranger (&lt;code&gt;FOREIGN SERVER&lt;/code&gt;), simplifiant la gestion des accès.&lt;/p&gt;
&lt;p&gt;PostgreSQL 19 rend possible l&amp;rsquo;activation de la réplication logique
sans redémarrage du serveur. La réplication logique peut maintenant
être activée à la demande même lorsque le paramètre &lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-wal.html#GUC-WAL-LEVEL&#34;&gt;&lt;code&gt;wal_level&lt;/code&gt;&lt;/a&gt;
est positionné à &lt;code&gt;replica&lt;/code&gt;, et le nouveau paramètre en lecture seule
&lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-preset.html#GUC-EFFECTIVE-WAL-LEVEL&#34;&gt;&lt;code&gt;effective_wal_level&lt;/code&gt;&lt;/a&gt;
indique quel est le niveau réel. Ceci réduit le
besoin d&amp;rsquo;activer en avance un niveau de WAL trop élevé lorsque le
besoin n&amp;rsquo;est qu&amp;rsquo;occasionnel, et évite la rupture de l&amp;rsquo;activité.&lt;/p&gt;
&lt;p&gt;Le pilote de données étrangères de PostgreSQL, &lt;a href=&#34;https://www.postgresql.org/docs/19/postgres-fdw.html&#34;&gt;&lt;code&gt;postgres_fdw&lt;/code&gt;&lt;/a&gt;,
utilisé pour de la fédération de requête, inclut plusieurs améliorations de
performance, dont le « push down » d&amp;rsquo;opérations sur les tableaux vers
le serveur distant, et en récupérant et utilisant les statistiques des
tables étrangères pour une meilleure planification locale.&lt;/p&gt;
&lt;h3 id=&#34;autres-points-importants&#34;&gt;Autres points importants&lt;/h3&gt;
&lt;p&gt;La période bêta de PostgreSQL a un mode &lt;a href=&#34;https://wiki.postgresql.org/wiki/Grease&#34;&gt;« grease »&lt;/a&gt; temporaire pour
tenter d&amp;rsquo;identifier des problèmes de compatibilité du protocole dans
l&amp;rsquo;écosystème. Cette page du wiki contient les informations sur le
fonctionnement de la campagne :
&lt;a href=&#34;https://wiki.postgresql.org/wiki/Grease&#34;&gt;https://wiki.postgresql.org/wiki/Grease&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;PostgreSQL 19 permet l&amp;rsquo;activation et la désactivation des
&lt;a href=&#34;https://www.postgresql.org/docs/19/checksums.html&#34;&gt;sommes de contrôle&lt;/a&gt;
à la volée, sans nécessiter un redémarrage ou une réinitialisation.&lt;/p&gt;
&lt;p&gt;Il y a plusieurs changements importants qui méritent une attention
particulière dans PostgreSQL 19. La compilation &lt;a href=&#34;https://www.postgresql.org/docs/19/jit.html&#34;&gt;Just-in-time (JIT)&lt;/a&gt; est
maintenant désactivée par défaut. La valeur par défaut du paramètre
&lt;a href=&#34;https://www.postgresql.org/docs/19/runtime-config-client.html#GUC-DEFAULT-TOAST-COMPRESSION&#34;&gt;&lt;code&gt;default_toast_compression&lt;/code&gt;&lt;/a&gt;
est maintenant &lt;code&gt;lz4&lt;/code&gt;, amenant de
meilleures performances de compression et décompression par défaut. Le
support de l&amp;rsquo;authentification RADIUS est supprimé. De plus, la
commande &lt;a href=&#34;https://www.postgresql.org/docs/19/app-vacuumdb.html&#34;&gt;&lt;code&gt;vacuumdb --analyze-only&lt;/code&gt;&lt;/a&gt;
analyse par défaut les tables partitionnées.&lt;/p&gt;
&lt;h2 id=&#34;fonctionnalités-supplémentaires&#34;&gt;Fonctionnalités supplémentaires&lt;/h2&gt;
&lt;p&gt;De nombreuses autres fonctionnalités et améliorations ont été ajoutées
à PostgreSQL. En fonction des cas d&amp;rsquo;usage, leur importance peut
paraître plus ou moins grande que celles mentionnées ci-dessus. Vous
pouvez consulter les &lt;a href=&#34;https://www.postgresql.org/docs/devel/release-19.html&#34;&gt;notes de publications&lt;/a&gt;
pour une liste complète des nouveautés et changements :
&lt;a href=&#34;https://www.postgresql.org/docs/19/release-19.html&#34;&gt;https://www.postgresql.org/docs/19/release-19.html&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;tests-pour-le-débogage-et-la-compatibilité&#34;&gt;Tests pour le débogage et la compatibilité&lt;/h2&gt;
&lt;p&gt;La stabilité de chaque publication de PostgreSQL dépend de vous, la
communauté. En testant la version à venir avec votre charge et vos outils de
tests, vous pourrez nous aider à trouver les bogues et régressions avant la
publication de PostgreSQL 19.&lt;/p&gt;
&lt;p&gt;Étant donné qu&amp;rsquo;il s&amp;rsquo;agit d&amp;rsquo;une version bêta, des changements mineurs dans le
comportement de la base de données, des détails et des APIs sont toujours
possibles. Vos retours et tests aideront à déterminer les ajustements finaux
des nouvelles fonctionnalités.&lt;/p&gt;
&lt;p&gt;La qualité des tests aide à déterminer le moment de la publication
finale.&lt;/p&gt;
&lt;p&gt;Une liste des &lt;a href=&#34;https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items&#34;&gt;problèmes ouverts&lt;/a&gt;
est publiquement disponible dans le wiki de PostgreSQL. Vous pouvez
&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;rapporter des bogues&lt;/a&gt;
en utilisant le formulaire présent sur le site web de PostgreSQL :
&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;https://www.postgresql.org/account/submitbug/&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;planning-bêta&#34;&gt;Planning Bêta&lt;/h2&gt;
&lt;p&gt;Il s&amp;rsquo;agit de la première publication bêta de la version 19. Le projet
PostgreSQL publiera autant de bêtas que cela est nécessaire pour tester. Celles-ci
seront suivies par une ou plusieurs publications de versions candidates,
jusqu&amp;rsquo;à la publication de la version finale vers septembre/octobre 2026.&lt;/p&gt;
&lt;p&gt;Pour plus d&amp;rsquo;information,
veuillez consulter la page &lt;a href=&#34;https://www.postgresql.org/developer/beta/&#34;&gt;Beta Testing&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;liens&#34;&gt;Liens&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/download/&#34;&gt;Téléchargement&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/developer/beta/&#34;&gt;Information sur le Bêta Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/docs/19/release-19.html&#34;&gt;Notes de publication de PostgreSQL 19 Bêta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://wiki.postgresql.org/wiki/PostgreSQL_19_Open_Items&#34;&gt;Problèmes connus de PostgreSQL 19&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;Soumettre un bogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/about/donate/&#34;&gt;Faire un don&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Crédits photo : Carlos Gonzalez&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Retour sur le PG Day France 2026</title>
      <link>http://www.loxodata.com/post/feedback-pgdayfr-2026/</link>
      <pubDate>Mon, 08 Jun 2026 09:00:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/feedback-pgdayfr-2026/</guid>
      <description>&lt;h1 id=&#34;retour-sur-les-journées-du-pg-day-france-2026&#34;&gt;Retour sur les journées du PG Day France 2026&lt;/h1&gt;
&lt;p&gt;Le dernier PG Day France s&amp;rsquo;est tenu les 3 et 4 juin 2026 à Toulouse, chez MétéoFrance.
C&amp;rsquo;est la deuxième fois que MétéoFrance héberge l&amp;rsquo;évènement.&lt;/p&gt;
&lt;p&gt;Et c&amp;rsquo;est la troisième fois que le PGDay se tient à Toulouse. Le premier était
aussi le premier organisé par PostgreSQLFr (et surtout par Jean-Christophe), en
2008.&lt;/p&gt;
&lt;p&gt;LOXODATA, sponsor GOLD sur cette édition, proposait un atelier sur PgBouncer lors
de la première journée dédiée aux ateliers techniques (il y avait quatre ateliers en tout).&lt;/p&gt;
&lt;p&gt;Philippe Viegas et Jean-Christophe Arnu ont animé un atelier PgBouncer, complètement répétable dans
un environnement de test basé sur docker. Vous pouvez ainsi télécharger
le &lt;a href=&#34;https://gitlab.com/loxo-trainings/2026-pgdayfr-pgbouncer/-/raw/main/2026-pgdayfr-pgbouncer-workshop.pdf&#34;&gt;support de l&amp;rsquo;atelier&lt;/a&gt;
et rejouer les exercices en allant sur le
&lt;a href=&#34;https://gitlab.com/loxo-trainings/2026-pgdayfr-pgbouncer&#34;&gt;repository du projet gitlab de LOXODATA&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le soir du premier jour, une soirée communautaire était offerte aux participants au
restaurant Monsieur Georges, en centre ville. Un moment très agréable et idéal pour
échanger sur PostgreSQL ou tout autre sujet avec les membres de la communauté.&lt;/p&gt;
&lt;p&gt;Le lendemain, la journée des conférences battait son plein avec pas moins de six présentations
et cinq lightning talks (juste après la pause méridienne).&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://www.loxodata.com/images/post/pgdayfr-2026/pgdayfr-2026-amphi.jpg&#34; alt=&#34;Accueil&#34;&gt;&lt;/p&gt;
&lt;p&gt;Le programme est disponible sur le site du PG Day France &lt;a href=&#34;https://pgday.fr/programme&#34;&gt;ici&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;les-conférences&#34;&gt;Les conférences&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Frédéric Delacourt (DataBene) nous a proposé un rappel des différents niveaux d&amp;rsquo;isolation
de PostgreSQL, qui restent parfois méconnus.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Wilfried Roset (OVHCloud) nous a partagé son retour d&amp;rsquo;expérience sur la mise en place d&amp;rsquo;un serveur MCP
afin d&amp;rsquo;assurer la revue de PR de ses développeurs lors de changement de schémas de base de données.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Haritabh Gupta (Supabase) nous a présenté les travaux entrepris sur Multigres afin d&amp;rsquo;assurer à ce proxy une pleine
compatibilité avec PostgreSQL.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Luigi Nardi (DBTune) nous a démontré son approche sur le &lt;em&gt;workload fingerprint&lt;/em&gt; afin d&amp;rsquo;avancer sur
l&amp;rsquo;optimisation autonome de PostgreSQL.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Franck Pachot (Microsoft) s&amp;rsquo;est lancé dans un retour d&amp;rsquo;expérience autour du modèle Domain-Driven Design et
la place de l&amp;rsquo;administrateur de base de données PostgreSQL dans cette approche.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Vincent Mercier (Amazon) a refermé le train des conférences avec une présentation du partionnement natif dans PostgreSQL et
de différents outils facilitant ce partionnement, notamment dans un environnement automatisé.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;équipe organisatrice a remercié tous les participants et speakers, ces derniers se sont vus remettre
des douceurs toulousaines (merci Jean-Christophe).&lt;/p&gt;
&lt;p&gt;LOXODATA tient à féliciter l&amp;rsquo;équipe en charge de l&amp;rsquo;organisation de l&amp;rsquo;évènement, en particulier
Xavier Simon de MétéoFrance, pour le succès de cette édition 2026. Pas
moins de 95 participants étaient inscrits !&lt;/p&gt;
&lt;p&gt;Crédit logo: Sylvain Beorchia&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostgreSQL 18.4 et autres correctifs</title>
      <link>http://www.loxodata.com/post/postgresql-18-4/</link>
      <pubDate>Mon, 01 Jun 2026 09:00:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/postgresql-18-4/</guid>
      <description>&lt;p&gt;Le PGDG (PostgreSQL Global Development Group) a publié une mise à jour
de toutes les versions supportées de PostgreSQL, incluant 18.3, 17.9,
16.13, 15.17 et 14.22.&lt;/p&gt;
&lt;p&gt;Pour la liste complète des changements, se référer à la section &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes
de publication&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;notification-de-la-fin-de-vie-de-postgresql-14&#34;&gt;Notification de la fin de vie de PostgreSQL 14&lt;/h1&gt;
&lt;p&gt;PostgreSQL ne recevra plus de correctif dès le 12 novembre 2026. Si
vous utilisez PostgreSQL dans un environnement de production, nous
vous suggérons de planifier une mise à jour vers une version supportée
et mise à jour de PostgreSQL. Pour plus de détails, se référer à la
&lt;a href=&#34;https://www.postgresql.org/support/versioning/&#34;&gt;Politique de version&lt;/a&gt;.&lt;/p&gt;
&lt;h1 id=&#34;problème-de-sécurité&#34;&gt;Problème de sécurité&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6472/&#34;&gt;CVE-2026-6472&lt;/a&gt; :
exécution de fonctions SQL arbitraires en utilisant &lt;code&gt;CREATE TYPE&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 5.4 MEDIUM (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;absence d&amp;rsquo;autorisation lors de la création d&amp;rsquo;un type (&lt;code&gt;CREATE TYPE&lt;/code&gt;)
dans PostgreSQL permet à un créateur d&amp;rsquo;objet de détourner d&amp;rsquo;autres
requêtes utilisant &lt;code&gt;search_path&lt;/code&gt; pour trouver des types définis par
l&amp;rsquo;utilisateur, y compris les types définis par extension. Autrement
dit, la victime peut exécuter des fonctions SQL arbitraires choisies
par l&amp;rsquo;attaquant. Toutes les versions précédant les versions 18.4,
17.10, 16.14, 15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Jelte Fennema-Nio d&amp;rsquo;avoir reporté ce
problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6473/&#34;&gt;CVE-2026-6473&lt;/a&gt; :
exécution de code arbitraire avec les privilèges de l&amp;rsquo;utilisateur du
système d&amp;rsquo;exploitation exécutant la base de données.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 8.8 HIGH (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;Une vulnérabilité de dépassement de capacité d&amp;rsquo;entier présente dans
plusieurs fonctionnalités du serveur PostgreSQL permet à un
utilisateur de base de données non privilégié de provoquer un
sous-dimensionnement de l&amp;rsquo;allocation mémoire et une écriture hors
limites. Ceci peut entraîner l&amp;rsquo;exécution de code arbitraire avec les
privilèges de l&amp;rsquo;utilisateur du système d&amp;rsquo;exploitation exécutant la
base de données. Toutes les versions précédant les versions 18.4,
17.10, 16.14, 15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Anemone, A1ex, Xint Code, Jihe Wang,
Jingzhou Fu, Pavel Kohout, Petr Simecek, &lt;a href=&#34;https://www.aisle.com&#34;&gt;www.aisle.com&lt;/a&gt;, Bruce Dang of
Calif.io, et Sven Klemm d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6474/&#34;&gt;CVE-2026-6474&lt;/a&gt; :
lecture de portions de mémoire du serveur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 4.3 MEDIUM (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;Une faille de sécurité dans la fonction &lt;code&gt;timeofday()&lt;/code&gt; de PostgreSQL,
utilisant un format de chaîne externe, permet à un attaquant de
récupérer des portions de la mémoire du serveur grâce à des fuseaux
horaires spécialement conçus. Toutes les versions précédant les
versions 18.4, 17.10, 16.14, 15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Xint Code d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6475/&#34;&gt;CVE-2026-6475&lt;/a&gt; :
écrasement de fichiers sans lien avec l’origine choisie par le
superutilisateur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 8.8 HIGH (client)&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;utilisation de liens symboliques avec les commandes &lt;code&gt;pg_basebackup&lt;/code&gt;
(format simple) et &lt;code&gt;pg_rewind&lt;/code&gt; de PostgreSQL permet à un
superutilisateur d&amp;rsquo;origine d&amp;rsquo;écraser des fichiers locaux, comme
&lt;code&gt;/var/lib/postgres/.bashrc&lt;/code&gt;, et de détourner ainsi le compte
système. Le démarrage du serveur après ces commandes implique toujours
une confiance implicite accordée à ce superutilisateur, du fait de
fonctionnalités telles que &lt;code&gt;shared_preload_libraries&lt;/code&gt;. Par conséquent,
cette attaque n&amp;rsquo;a d&amp;rsquo;incidence concrète que si une action est
entreprise entre l&amp;rsquo;exécution de ces commandes et le démarrage du
serveur, comme le déplacement des fichiers vers une autre machine
virtuelle ou la création d&amp;rsquo;un instantané de cette dernière. Toutes les
versions précédant les versions 18.4, 17.10, 16.14, 15.18, et 14.23
sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Valery Gubanov, XlabAI Team of Tencent
Xuanwu Lab, Atuin Automated Vulnerability Discovery Engine, Zhanpeng
Liu, Guannan Wang, et Guancheng Li d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6476/&#34;&gt;CVE-2026-6476&lt;/a&gt; :
&lt;code&gt;pg_createsubscriber&lt;/code&gt; est vulnérable aux injections SQL via le nom
de l&amp;rsquo;abonnement.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 7.2 HIGH (client)&lt;/p&gt;
&lt;p&gt;Une injection SQL dans la fonction &lt;code&gt;pg_createsubscriber&lt;/code&gt; de PostgreSQL
permet à un attaquant disposant des droits &lt;code&gt;pg_create_subscription&lt;/code&gt;
d&amp;rsquo;exécuter des requêtes SQL arbitraires en tant que
superutilisateur. L&amp;rsquo;attaque est exploitée lors de la prochaine
exécution de &lt;code&gt;pg_createsubscriber&lt;/code&gt;. Toutes les versions précédant les
versions 18.4, 17.10 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Yu Kunpeng d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6477/&#34;&gt;CVE-2026-6477&lt;/a&gt; :
les fonctions &lt;code&gt;lo_*&lt;/code&gt; de la bibliothèque &lt;code&gt;libpq&lt;/code&gt; de PostgreSQL
permettent au superutilisateur du serveur d&amp;rsquo;écraser la mémoire de la
pile du client.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 8.8 HIGH (client)&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;utilisation de la fonction intrinsèquement dangereuse &lt;code&gt;PQfn(..., result_is_int=0, ...)&lt;/code&gt; dans les fonctions &lt;code&gt;lo_export()&lt;/code&gt;, &lt;code&gt;lo_read()&lt;/code&gt;,
&lt;code&gt;lo_lseek64()&lt;/code&gt; et &lt;code&gt;lo_tell64()&lt;/code&gt; de la bibliothèque PostgreSQL permet à
l&amp;rsquo;administrateur du serveur d&amp;rsquo;écraser la mémoire tampon de la pile du
client avec une réponse de taille arbitraire. À l&amp;rsquo;instar de &lt;code&gt;gets()&lt;/code&gt;,
&lt;code&gt;PQfn(..., result_is_int=0, ...)&lt;/code&gt; stocke des données de longueur
arbitraire, déterminée par le serveur, dans une mémoire tampon de
taille indéterminée. Étant donné que les commandes &lt;code&gt;lo_export&lt;/code&gt; de &lt;code&gt;psql&lt;/code&gt;
et &lt;code&gt;pg_dump&lt;/code&gt; appellent toutes deux &lt;code&gt;lo_read()&lt;/code&gt;, l&amp;rsquo;administrateur du
serveur peut écraser la mémoire de la pile de &lt;code&gt;pg_dump&lt;/code&gt; ou de
&lt;code&gt;psql&lt;/code&gt;. Toutes les versions précédant les versions 18.4, 17.10, 16.14,
15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Yu Kunpeng d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6478/&#34;&gt;CVE-2026-6478&lt;/a&gt; :
PostgreSQL divulgue les mots de passe hachés MD5 via un canal de
synchronisation caché.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 6.5 MEDIUM (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;Une faille de sécurité dans la comparaison des mots de passe hachés
MD5 lors de l&amp;rsquo;authentification PostgreSQL permet à un attaquant de
récupérer les identifiants utilisateur nécessaires à
l&amp;rsquo;authentification. Ceci n&amp;rsquo;affecte pas les mots de passe
scram-sha-256, utilisés par défaut dans toutes les versions prises en
charge. Cependant, certaines bases de données actuelles peuvent
contenir des mots de passe hachés MD5 provenant de mises à niveau
depuis PostgreSQL 13 ou une version antérieure. Toutes les versions
précédant les versions 18.4, 17.10, 16.14, 15.18, et 14.23 sont
concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Joe Conway d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6479/&#34;&gt;CVE-2026-6479&lt;/a&gt; :
L&amp;rsquo;initialisation SSL/GSS de PostgreSQL provoque un déni de service
via une récursion non contrôlée.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 7.5 HIGH (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;Une récursion incontrôlée dans la négociation SSL et GSS de PostgreSQL
permet à un attaquant capable de se connecter à un socket AF_UNIX de
PostgreSQL d&amp;rsquo;obtenir un déni de service soutenu. Si SSL et GSS sont
désactivés, un attaquant peut réaliser la même opération en accédant à
une socket TCP de PostgreSQL. Toutes les versions précédant les
versions 18.4, 17.10, 16.14, 15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Calif.io en collaboration avec Claude
and Anthropic Research d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6575/&#34;&gt;CVE-2026-6575&lt;/a&gt; :
la fonction &lt;code&gt;pg_restore_attribute_stats&lt;/code&gt; de PostgreSQL accepte des
valeurs qui entraînent une lecture au-delà de la fin du tableau de
statistiques lors de la planification de la requête.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 4.3 MEDIUM (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;La fonction &lt;code&gt;pg_restore_attribute_stats()&lt;/code&gt; de PostgreSQL présente une
vulnérabilité de lecture au-delà du buffer. En effet, elle accepte des
valeurs de tableau de longueur non concordante, ce qui provoque une
lecture au-delà de la fin d&amp;rsquo;un tableau lors de la planification de la
requête. Ceci permet à un responsable de table d&amp;rsquo;inférer des valeurs
en mémoire au-delà de cette fin de tableau. Les versions 18 précédant
la version 18.4 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Jeroen Gui d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6637/&#34;&gt;CVE-2026-6637&lt;/a&gt; :
refint permet le dépassement de tampon de pile et l&amp;rsquo;injection SQL.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS:8.8 HIGH (module contrib)&lt;/p&gt;
&lt;p&gt;Une vulnérabilité de type dépassement de tampon de pile dans le module
« refint » de PostgreSQL permet à un utilisateur de base de données
non privilégié d&amp;rsquo;exécuter du code arbitraire avec les privilèges de
l&amp;rsquo;utilisateur du système d&amp;rsquo;exploitation exécutant la base de
données. Une attaque distincte est possible si l&amp;rsquo;application déclare
une colonne contrôlée par l&amp;rsquo;utilisateur comme clé primaire en cascade
« refint » et autorise les mises à jour de cette colonne par
l&amp;rsquo;utilisateur. Dans ce cas, une injection SQL permet au fournisseur de
valeur de mise à jour de la clé primaire d&amp;rsquo;exécuter du code SQL
arbitraire avec les privilèges de l&amp;rsquo;utilisateur de la base de données
effectuant la mise à jour. Toutes les versions précédant les versions
18.4, 17.10, 16.14, 15.18, et 14.23 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Nikolay Samokhvalov d&amp;rsquo;avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-6638/&#34;&gt;CVE-2026-6638&lt;/a&gt; :
&lt;code&gt;REFRESH PUBLICATION&lt;/code&gt; est vulnérable aux injections SQL via le nom
de la table.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Score CVSS: 3.7 LOW (serveur PostgreSQL)&lt;/p&gt;
&lt;p&gt;Une injection SQL dans la réplication logique PostgreSQL (commande
&lt;code&gt;ALTER SUBSCRIPTION ... REFRESH PUBLICATION&lt;/code&gt;) permet au créateur d&amp;rsquo;une
table abonnée d&amp;rsquo;exécuter des requêtes SQL arbitraires avec les
identifiants de publication de l&amp;rsquo;abonnement. L&amp;rsquo;attaque prend effet
lors de la prochaine mise à jour (&lt;code&gt;REFRESH PUBLICATION&lt;/code&gt;). Les versions
16, 17 et 18 précédant les versions 18.4, 17.10, 16.14 sont
concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Pavel Kohout, Aisle Research d&amp;rsquo;avoir
reporté ce problème.&lt;/p&gt;
&lt;h2 id=&#34;corrections-de-bogues-et-améliorations&#34;&gt;Corrections de bogues et améliorations&lt;/h2&gt;
&lt;p&gt;Cette publication corrige plus de 60 bogues reportés ces derniers
mois. Les problèmes listés ci-dessous concernent PostgreSQL. Certains
d&amp;rsquo;entre eux peuvent aussi concerner d&amp;rsquo;autres versions de PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;correction du fait que des requêtes pourraient retourner des
résultats incorrects lors de l&amp;rsquo;utilisation d&amp;rsquo;une collation
non-déterministe avec un index unique ;&lt;/li&gt;
&lt;li&gt;correction de la perte de défferabilité d&amp;rsquo;un déclencheur de clé
étrangère. Préalablement à ce correctif, une clé étrangère définie
en tant que &lt;code&gt;DEFERRABLE INITIALLY DEFERRED&lt;/code&gt; se serait comportée
comme &lt;code&gt;NOT DEFERRABLE&lt;/code&gt; après avoir été définie &lt;code&gt;NOT ENFORCED&lt;/code&gt; puis
&lt;code&gt;ENFORCED&lt;/code&gt;. Si vous avez une clé étrangère avec ce problème, après
l&amp;rsquo;installation de cette mise à jour, vous pouvez corriger cela en
passant l&amp;rsquo;état à &lt;code&gt;NOT ENFORCED&lt;/code&gt; puis à nouveau &lt;code&gt;ENFORCED&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;amélioration de la capacité du planner d&amp;rsquo;appliquer l&amp;rsquo;élagage des
partitions à plus de cas ;&lt;/li&gt;
&lt;li&gt;correction de la suppression des self-join afin de prendre en compte
les colonnes booléennes, par exemple &lt;code&gt;ON t1.boolcol&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;correction de plusieurs problèmes concernant les colonnes générées
virtuelles, incluant le fait que &lt;code&gt;INSERT ... ON CONFLICT&lt;/code&gt; fonctionne
lorsque &lt;code&gt;EXCLUDED&lt;/code&gt; référence une colonne générée virtuelle ;&lt;/li&gt;
&lt;li&gt;reporte une erreur de sérialisation lorsque &lt;code&gt;MERGE&lt;/code&gt; rencontre une
ligne mise à jour simultanément dans les modes d&amp;rsquo;isolation
« repeatable read » ou « serializable » ;&lt;/li&gt;
&lt;li&gt;correction de la commande &lt;code&gt;CREATE TABLE ... LIKE ... INCLUDING STATISTICS&lt;/code&gt; pour les cas où la table source a eu une ou plusieurs
colonnes supprimées ;&lt;/li&gt;
&lt;li&gt;correction de &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; pour permettre les domaines ;&lt;/li&gt;
&lt;li&gt;désactive la construction d&amp;rsquo;un type composite avec lui-même via un
type multirange ;&lt;/li&gt;
&lt;li&gt;correction de résultats parfois incorrects lorsque
&lt;code&gt;array_agg(anyarray)&lt;/code&gt; est exécuté en parallèle ;&lt;/li&gt;
&lt;li&gt;prévention de la fragmentation lors de la restauration d&amp;rsquo;une
sauvegarde incrémentale ;&lt;/li&gt;
&lt;li&gt;prévention du blocage de la promotion d&amp;rsquo;une instance secondaire à
cause d&amp;rsquo;un processus de synchronisation de slot de réplication
logique bloqué ;&lt;/li&gt;
&lt;li&gt;correction de la colonne &lt;code&gt;pid&lt;/code&gt; de la vue système &lt;code&gt;pg_aios&lt;/code&gt; pour
afficher NULL à la place de 0 lorsqu&amp;rsquo;une entrée n&amp;rsquo;est pas
propriétaire du processus ;&lt;/li&gt;
&lt;li&gt;correction de cas où la vue &lt;code&gt;pg_stat_replication&lt;/code&gt; montre un lag NULL
quand bien même la réplication est active ;&lt;/li&gt;
&lt;li&gt;affichage correcte d’alias de variables d&amp;rsquo;un &lt;code&gt;JOIN&lt;/code&gt; lorsqu&amp;rsquo;elles
sont utilisées dans un &lt;code&gt;GROUP BY&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;en cas d&amp;rsquo;échec du processus de démarrage, arrête proprement les
autres processus enfants avant d&amp;rsquo;arrêter le postmaster ;&lt;/li&gt;
&lt;li&gt;correction d&amp;rsquo;une erreur d&amp;rsquo;exécution concurrente pouvant entraîner
une boucle d&amp;rsquo;arrêt-démarrage lorsqu’une instance secondaire suit
les journaux de log (WAL) dans une instance primaire d&amp;rsquo;une version
mineure plus ancienne ;&lt;/li&gt;
&lt;li&gt;prévient l&amp;rsquo;attente infinie de l&amp;rsquo;arrêt d&amp;rsquo;un processus walsender
lorsque la réplication logique est active ;&lt;/li&gt;
&lt;li&gt;s&amp;rsquo;assure que l&amp;rsquo;écriture de la FSM persiste pendant une
restauration. Ceci pourrait avoir des conséquences sur les
performances sur une instance secondaire après une promotion ;&lt;/li&gt;
&lt;li&gt;corrections de bogues lors de la décompression de sauvegardes et
dans le code de lecture des fichiers Tar utilisé par &lt;code&gt;pg_basebackup&lt;/code&gt;
et &lt;code&gt;pg_verifybackup&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;rétabli le fait que &lt;code&gt;pg_dumpall&lt;/code&gt; n&amp;rsquo;évite pas les droits de rôle de
«&lt;em&gt;grantor&lt;/em&gt;» suspendu, comme avant PostgreSQL 16. Émission d&amp;rsquo;un
message d&amp;rsquo;avertissement à propos du «&lt;em&gt;grantor&lt;/em&gt;» manquant si le
serveur est pls récent que PostgreSQL 16 ;&lt;/li&gt;
&lt;li&gt;correction de &lt;code&gt;pg_upgrade&lt;/code&gt; pour utiliser la version correcte du
protocole lors de la connexion à de plus vieux serveurs ;&lt;/li&gt;
&lt;li&gt;correction de la sorte de &lt;code&gt;pg_overexplain&lt;/code&gt; lors de l&amp;rsquo;utilisation de
l&amp;rsquo;option &lt;code&gt;RANGE_TABLE&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;correction d&amp;rsquo;une défaillance de &lt;code&gt;postgres_fdw&lt;/code&gt; à cause d&amp;rsquo;un
nettoyage prématuré d&amp;rsquo;une connexion en échec.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cette publication met aussi à jour les fichiers de données des fuseaux
horaires à la publication 2026b, dans laquelle la Colombie-Britannique
(America/Vancouver) sera toute l&amp;rsquo;année à UTC-07 (dans les faits, DST)
à partir de novembre 2026. Cette publication prend en compte le fait
que leur abréviation de fuseau sera MST à partir de ce moment
(quoique ça pourrait changer). Il y a aussi une correction
historique pour la Moldavie, qui a utilisé l&amp;rsquo;heure EU DST en
transition depuis 2022.&lt;/p&gt;
&lt;h2 id=&#34;mise-à-jour&#34;&gt;Mise à jour&lt;/h2&gt;
&lt;p&gt;Toutes les publications de mises à jour de PostgreSQL sont
cumulatives. Comme pour les autres mises à jour mineures, il n&amp;rsquo;est pas
nécessaire d&amp;rsquo;extraire et de recharger les bases de données ni
d&amp;rsquo;utiliser &lt;code&gt;pg_upgrade&lt;/code&gt; pour appliquer cette mise à jour ; il suffit
simplement d&amp;rsquo;arrêter PostgreSQL et de mettre à jour les binaires.&lt;/p&gt;
&lt;p&gt;Les utilisateurs ayant sauté une ou plusieurs mises à jour peuvent
avoir besoin d&amp;rsquo;étapes additionnelles après la mise à jour.  Les notes
de publication des versions précédentes fournissent les détails.&lt;/p&gt;
&lt;p&gt;Pour plus de détails, se référer à la &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;note de publication de
versions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;liens&#34;&gt;Liens&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/download/&#34;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/&#34;&gt;Page sur la sécurité&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/versioning/&#34;&gt;Politique de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;Soumettre un bogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/about/donate/&#34;&gt;Faire un don&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vous avez des corrections ou suggestions sur cette annonce de
publication, merci de les envoyer à la mailing liste publique
&lt;a href=&#34;https://www.postgresql.org/list/&#34;&gt;pgsql-www@lists.postgresql.org&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Meetup du 7 avril 2026 PostgreSQL à Toulouse </title>
      <link>http://www.loxodata.com/post/meetup-toulouse-2026-04/</link>
      <pubDate>Thu, 09 Apr 2026 11:01:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/meetup-toulouse-2026-04/</guid>
      <description>&lt;h2 id=&#34;meetup-update-meetup-set-locationpictarine-where-grouptlspug&#34;&gt;Meetup &lt;code&gt;UPDATE meetup SET location=&#39;Pictarine&#39; WHERE group=&#39;TLSPUG&#39;;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Après un &lt;a href=&#34;../meetup-toulouse-2025-10&#34;&gt;redémarrage réussi&lt;/a&gt; des meetups sur
Toulouse et une confirmation au mois de janvier chez Météo-France pour
une seconde session, c&amp;rsquo;est chez Pictarine que s&amp;rsquo;est déroulé le
troisième meetup de la série. Nous tenons à remercier Pictarine pour
son accueil (lieu, boisson et nourriture) toujours aussi amical et
agréable dans des locaux « au top » (c&amp;rsquo;est le qualificatif que j&amp;rsquo;ai le
plus entendu dans la soirée pour les décrire). LOXODATA a également
agrémenté la soirée d&amp;rsquo;œufs en chocolat.&lt;/p&gt;
&lt;p&gt;Plusieurs nouvelles sur ce groupe d&amp;rsquo;ailleurs, la première est que
Toulouse PostgreSQL User Group a été &lt;a href=&#34;https://www.postgresql.org/community/user-groups/&#34;&gt;officiellement reconnu par la
communauté&lt;/a&gt; et
bénéficie donc de la force de communication du &lt;a href=&#34;https://www.postgresql.org/about/events/&#34;&gt;site
officiel&lt;/a&gt;. La seconde est
que le groupe a dépassé la centaine d&amp;rsquo;abonnés sur le site meetup, ce
qui est très encourageant. D&amp;rsquo;ailleurs, le rendez-vous a regroupé
environ 25 personnes, ce qui n&amp;rsquo;est pas si mal pour une troisième
session!&lt;/p&gt;
&lt;p&gt;Les personnes venues à ce meetup ont pu assister à deux conférences de
30 minutes :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mohamed Nossirat nous a présenté la façon la plus rapide de charger
des données dans PostgreSQL avec Python. Il a notamment considéré
qu&amp;rsquo;il n&amp;rsquo;avait pas la main sur les données et a décrit son
cheminement pour effectuer les chargements à la fois de manière
rapide et également en consommant le moins de mémoire possible. Un
pari gagné grâce aux itérateurs et à psycopg2.&lt;/li&gt;
&lt;li&gt;Pierre Fersing a ensuite présenté son retour d&amp;rsquo;expérience pour le
choix d&amp;rsquo;un opérateur PostgreSQL dans Kubernetes, pour les besoins de
Bleemeo. Sa présentation a abordé les concepts fondamentaux de
Kubernetes, les différents opérateurs testés et pour quelles raisons
certains n&amp;rsquo;ont pas été retenus face à CNPG qui s&amp;rsquo;est avéré être la
préférence. Pierre nous a ensuite montré quelques exemples
d&amp;rsquo;utilisation de CNPG au travers de manifest qu&amp;rsquo;il a agrémenté de
conseils.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Enfin, je suis intervenu pour présenter les nouvelles autour de
PostgreSQL et de son écosystème, dans une présentation qui se voulait
courte&amp;hellip; mais qui ne l&amp;rsquo;a pas été. Le support peut d&amp;rsquo;ailleurs être
téléchargé &lt;a href=&#34;http://www.loxodata.com/downloads/slides/2026-04-07-meetup-tls-whats-new.pdf&#34;&gt;ici
même&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;La prochaine session de meetup PostgreSQL Toulouse devrait se dérouler
dans le courant du mois de septembre et les organisateurs (dont je
fais partie) &lt;a href=&#34;https://sessionize.com/tls-pug-session/&#34;&gt;n&amp;rsquo;attendent plus que vos propositions de
conférences&lt;/a&gt; ou de lieu.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Retour sur le pgDay Paris 2026</title>
      <link>http://www.loxodata.com/post/pgday-paris-2026/</link>
      <pubDate>Tue, 07 Apr 2026 14:45:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/pgday-paris-2026/</guid>
      <description>&lt;p&gt;Le 26 mars 2026 s&amp;rsquo;est tenue la 10e édition du pgDay Paris, après les 10 ans en 2025. Cette édition
s&amp;rsquo;est déroulée, comme à son habitude, au sein de l&amp;rsquo;espace Saint Martin, dans le 3e arrondissement de
Paris.&lt;/p&gt;
&lt;p&gt;LOXODATA était, comme chaque année depuis le début, sponsor « partner » de l&amp;rsquo;évènement.
Nous avions un stand, et nous avons pu échanger avec les visiteurs qui ont pris le temps de venir
nous rencontrer.&lt;/p&gt;
&lt;p&gt;Cette année encore, 2 salles de conférences étaient dédiées à l&amp;rsquo;événement.
La seconde était majoritairement attribuée à des conférences faites par des sponsors. Par rapport à
2025, les créneaux étaient de 45 minutes au lieu de 20 pour les sponsors, ce qui a permis des
conférences plus étoffées techniquement.&lt;/p&gt;
&lt;p&gt;Le programme complet est sur le site du &lt;a href=&#34;https://www.postgresql.eu/events/pgdayparis2026/schedule&#34;&gt;pgDay Paris 2026&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;les-conférences&#34;&gt;Les conférences&lt;/h2&gt;
&lt;p&gt;Le programme de la journée de conférences comportait douze sessions en anglais, dont quatre étaient
réservées aux sponsors, dans la seconde salle. Une seule autre conférence a eu lieu dans cette salle,
les autres étaient programmées dans l&amp;rsquo;auditorium. Comme les années précédentes, une captation
vidéo a eu lieu, mais uniquement dans l&amp;rsquo;auditorium.&lt;/p&gt;
&lt;p&gt;Après l&amp;rsquo;accueil des participants, Boriss Mejías a pris le micro pour nous rappeler la disparition
tragique de Simon Riggs il y a 2 ans, et des valeurs qu&amp;rsquo;il portait et affectionnait.&lt;/p&gt;
&lt;p&gt;Ce fut ensuite le moment de la keynote.&lt;/p&gt;
&lt;h3 id=&#34;a-framework-for-self-driving-databases&#34;&gt;A framework for self-driving databases&lt;/h3&gt;
&lt;p&gt;Luigi Nardi et Marc Linster nous ont parlé de bases de données autonomes en partant sur une
analogie : les taxis autonomes de San-Francisco. Au fil de ce déroulement, leurs arguments pointent
ce qui leur semble nécessaire selon eux pour avoir une base de données qu&amp;rsquo;on qualifierait
d&amp;rsquo;autonome. Il ne s&amp;rsquo;agit pas de tout confier à un agent, mais de se limiter aux opérations
courantes, avec des limites connues, tout comme les taxis se contentent de conduire dans des
conditions météo précises.&lt;/p&gt;
&lt;p&gt;Ils concluent sur les évolutions qui leur semblent importantes pour aller dans cette direction dans
la communauté, avec des outils et extensions, mais aussi en ajoutant des fonctionnalités dans le
code de PostgreSQL pour faciliter la mise en place de cette gestion autonome.&lt;/p&gt;
&lt;h3 id=&#34;from-crisis-to-control-detect-and-fix-corruptions&#34;&gt;From Crisis to Control: Detect and Fix Corruptions&lt;/h3&gt;
&lt;p&gt;Dans la seconde salle, Derk van Veen nous a fait part de difficultés de corruption auxquelles il a
eu à faire face. Pour cela, il a dû rentrer plus en détails dans le stockage des données et du TOAST,
à l&amp;rsquo;aide d&amp;rsquo;extensions comme pageinspect, pg_visibility ou pg_surgery. Ce voyage pas vraiment trivial
dans les entrailles de PostgreSQL lui a permis de résoudre certains problèmes, et de mitiger la portée
de certains autres, permettant de débloquer le vacuum et de permettre à nouveau l&amp;rsquo;accès aux
données. Tout cela résultait d&amp;rsquo;une montée de version majeure ayant eu lieu quelques années plus tôt,
et qui s&amp;rsquo;écartait des meilleures pratiques.&lt;/p&gt;
&lt;h3 id=&#34;postgresqlorg-the-hidden-parts&#34;&gt;postgresql.org: The hidden parts&lt;/h3&gt;
&lt;p&gt;Dans cette présentation, Magnus Hagander, qui participe à la core team, nous précise qu&amp;rsquo;il participe
aussi à l&amp;rsquo;équipe infrastructure de la communauté. Cette équipe très importante gère les outils en
ligne de la communauté et nécessite des personnes de confiance. Il nous décrit par quelques chiffres
le nombre de personnes qui font partie de cette équipe, avec une liste des services et le nombre de
machines et d&amp;rsquo;hébergements associés. Personne n&amp;rsquo;étant dédié à l&amp;rsquo;infra, des choix sur la simplicité et
le long terme sont régulièrement faits et permettent de continuer à faire fonctionner les services.
Ces outils ne sont pas toujours récents ni à la mode, mais ils sont toujours fonctionnels et
maintenus, et l&amp;rsquo;infrastructure continue de bien fonctionner, et ce malgré l&amp;rsquo;augmentation massive de
trafic repérée depuis la venue des bots IA.&lt;/p&gt;
&lt;h3 id=&#34;database-optimization-and-reducing-global-digital-pollution&#34;&gt;Database optimization and reducing global digital pollution&lt;/h3&gt;
&lt;p&gt;Dans la seconde salle, la conférence animée par Catherine Bouxin a mis en avant l&amp;rsquo;impact écologique
souvent sous-estimé du numérique, en particulier celui des bases de données.
Elle a expliqué que la croissance massive du streaming vidéo notamment, entraîne une explosion de la
consommation énergétique des data centers.
L&amp;rsquo;importance d&amp;rsquo;optimiser ses bases de données (index, partitionnement, stockage) permet non
seulement d&amp;rsquo;améliorer les performances et de réduire les coûts, mais aussi de limiter l&amp;rsquo;empreinte
carbone.&lt;/p&gt;
&lt;p&gt;Au-delà de la technique, des actions simples ont été évoquées comme adopter un hébergement
écoresponsable, limiter la qualité du streaming ou éviter les sauvegardes inutiles.
Enfin, elle a insisté sur l&amp;rsquo;importance d&amp;rsquo;une approche globale, incluant audits, bonnes pratiques de
« green coding » et collaboration avec des experts, pour répondre aux enjeux environnementaux à venir.&lt;/p&gt;
&lt;h3 id=&#34;operational-hazards-of-managing-postgresql-dbs-over-100tb&#34;&gt;Operational hazards of managing PostgreSQL DBs over 100TB&lt;/h3&gt;
&lt;p&gt;Teresa Lopes nous a parlé de cas peu communs de grosses bases de données qui dépassent les 100 To.
Elle a commencé par rappeler que la taille n&amp;rsquo;est pas le seul problème, le nombre de transactions est
aussi un facteur important, surtout dans ce genre de contexte. Elle a abordé quelques solutions
qu&amp;rsquo;elle a pu mettre en place avec succès. En particulier, elle a abordé la gestion des lectures et
écritures, les vacuums, les sauvegardes et restaurations, le partitionnement, et la gestion des
performances des requêtes.
Elle nous a également averti que la conférence n&amp;rsquo;avait pas pour vocation de nous donner une recette
miracle. Chaque cas est différent, mais se poser des questions assez tôt permet de limiter les
risques.&lt;/p&gt;
&lt;h3 id=&#34;creating-a-dungeon-master-with-postgres-and-mcp&#34;&gt;Creating a “Dungeon Master” with Postgres and MCP&lt;/h3&gt;
&lt;p&gt;La conférence de Matt Cornillon proposait une approche mêlant PostgreSQL et intelligence artificielle.
L&amp;rsquo;idée était de montrer comment un agent IA peut gérer une partie de jeu de rôle, en interagissant
avec une base de données, pour maintenir l&amp;rsquo;état du jeu et répondre aux actions des joueurs.
La conférence a introduit le concept de MCP (Model Context Protocol) pour connecter une base
PostgreSQL à un agent IA, ainsi que la notion de « skills », plus centrée sur l&amp;rsquo;agent et ses capacités.
Une réflexion a été portée sur les skills et la sécurité, dans l&amp;rsquo;objectif d&amp;rsquo;éviter les
« hallucinations » de l&amp;rsquo;agent ainsi que l&amp;rsquo;exécution de requêtes dangereuses.
Enfin, Matt a souligné les atouts de PostgreSQL pour ce type d&amp;rsquo;usage, comme la robustesse, la légèreté,
ou l&amp;rsquo;écosystème riche.&lt;/p&gt;
&lt;h3 id=&#34;synchronisation-of-logical-replication-slots&#34;&gt;Synchronisation of logical replication slots&lt;/h3&gt;
&lt;p&gt;Dans la seconde salle, Sébastien Lardière de LOXODATA présentait, quant à lui, une fonctionnalité
introduite avec PostgreSQL 17 : la synchronisation des slots de réplication logique.
Il s&amp;rsquo;agit de continuer à utiliser la réplication logique lorsqu&amp;rsquo;un réplica n&amp;rsquo;est plus disponible et
qu&amp;rsquo;il a été décidé de promouvoir un standby physique.&lt;/p&gt;
&lt;p&gt;PostgreSQL permet de réaliser cette opération, mais un patch en cours est sur le point de permettre
la gestion des changements de primaires de manière plus simple, à l’instar de ce qui est pratiqué
pour la réplication physique.&lt;/p&gt;
&lt;h3 id=&#34;customizing-the-wordle-game-experience-with-postgresql&#34;&gt;Customizing the Wordle Game Experience with PostgreSQL&lt;/h3&gt;
&lt;p&gt;Dans cette conférence plus étoffée que son ligntning talk de l&amp;rsquo;année passée, Pavlo Golub a montré
comment PostgreSQL peut être utilisé pour personnaliser l&amp;rsquo;expérience du jeu Wordle.
L&amp;rsquo;idée principale était de recréer et enrichir le jeu directement en base de données, en gérant les
listes de mots, les règles de validation et les mécanismes de scoring.
Grâce à des fonctionnalités comme la recherche textuelle et le « fuzzy matching », il devient
possible de proposer des variantes, comme la recherche des mots similaires.
Enfin, les participants ont pu jouer contre l’IA Gemini, avec une victoire pour la salle et une pour l’IA.&lt;/p&gt;
&lt;p&gt;Cette conférence illustrait bien le potentiel de PostgreSQL comme plateforme flexible pour créer des
expériences ludiques et complètes.&lt;/p&gt;
&lt;h3 id=&#34;postgres-therapy-session-what-the-elephant-can-learn-from-its-rivals&#34;&gt;Postgres Therapy Session: What the Elephant Can Learn from Its Rivals.&lt;/h3&gt;
&lt;p&gt;Pour cette dernière conférence, Mayuresh Suresh Bagayatkar nous parle de fonctionnalités qui
existent dans d&amp;rsquo;autres systèmes de bases de données, ou comme il l&amp;rsquo;indique en titre politiquement
incorrect « que pourrions-nous voler aux autres bases de données ? ». Une courte description de
plusieurs fonctionnalités est faite, suivi pour certaines des raisons pour lesquelles elle ne sont pas dans postgres.
Pour les fonctionnalités qui pourraient apporter des améliorations, quelques idées sont présentées
sur les possibilités de les ajouter.&lt;/p&gt;
&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;Cette année, on a pu sentir le virage de l&amp;rsquo;IA arriver dans les conférences, tant dans les sujets sur
l&amp;rsquo;utilisation des agents par exemple, que sur la forme, avec un certain nombre d&amp;rsquo;illustrations
fabriquées par ces outils.&lt;/p&gt;
&lt;p&gt;Sur le contenu, les fondamentaux continuent, avec des sujets originaux.
Enfin, c&amp;rsquo;est bien entendu le côté humain qui est le plus intéressant sur ce genre d&amp;rsquo;évènement. Bien
que le nombre de participants soit inférieur à l&amp;rsquo;année dernière, les échanges étaient tout de même
intéressants lors des pauses.&lt;/p&gt;
&lt;p&gt;Nous espérons que l&amp;rsquo;année prochaine, l&amp;rsquo;évènement aura de nouveau lieu, et que le public sera de
retour, plus nombreux dans l&amp;rsquo;auditorium.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostgreSQL 18.3 et autres correctifs</title>
      <link>http://www.loxodata.com/post/postgresql-18-3/</link>
      <pubDate>Fri, 27 Feb 2026 11:00:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/postgresql-18-3/</guid>
      <description>&lt;p&gt;Le PGDG (PostgreSQL Global Development Group) a publié une mise à jour
de toutes les versions supportées de PostgreSQL, incluant 18.3, 17.9, 16.13, 15.17 et 14.22.&lt;/p&gt;
&lt;p&gt;Cette publication hors cycle corrige des &lt;a href=&#34;https://www.postgresql.org/about/news/out-of-cycle-release-scheduled-for-february-26-2026-3241/&#34;&gt;régressions&lt;/a&gt; relevées depuis la dernière publication de la 18.2 du &lt;a href=&#34;https://www.postgresql.org/about/news/postgresql-182-178-1612-1516-and-1421-released-3235/&#34;&gt;12 février 2026&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour la liste complète des changements, se référer à la section &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes
de publication&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;corrections-de-bogues-et-améliorations&#34;&gt;Corrections de bogues et améliorations&lt;/h2&gt;
&lt;p&gt;Cette mise à jour corrige plusieurs bogues ayant été signalés après
la dernière publication. Les problèmes ci-dessous concernent
PostgreSQL 18. Certains de ces problèmes peuvent aussi concerner
d&amp;rsquo;autres versions de PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;correction d&amp;rsquo;une anomalie où un standby est stoppé sur une erreur de type &lt;code&gt;could not access status of transaction&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correction d&amp;rsquo;une erreur sur la fonction &lt;a href=&#34;https://www.postgresql.org/docs/current/functions-string.html#id-1.5.8.10.5.2.2.17.1.1.1&#34;&gt;&lt;code&gt;substring()&lt;/code&gt;&lt;/a&gt; qui remonte l&amp;rsquo;erreur &lt;code&gt;invalid byte sequence for encoding&lt;/code&gt; sur des valeurs de texte non ASCII si la source de cette valeur est une colonne, et introduit par la correction &lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2006/&#34;&gt;CVE-2026-2006&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;correction de la fonction &lt;code&gt;strict_word_similarity&lt;/code&gt; dans &lt;a href=&#34;https://www.postgresql.org/docs/current/pgtrgm.html&#34;&gt;&lt;code&gt;pg_trgm&lt;/code&gt;&lt;/a&gt; qui peut entraîner des résultats incorrects ou des plantages. Cela est dû à une omission dans la correction de &lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2007/&#34;&gt;CVE-2026-2007&lt;/a&gt;;&lt;/li&gt;
&lt;li&gt;correction de la volatilité des fonctions &lt;code&gt;json_strip_nulls()&lt;/code&gt; et &lt;code&gt;jsonb_strip_nulls()&lt;/code&gt; afin qu&amp;rsquo;elles soient immutables, comme dans les versions précédentes, ce qui permet de les utiliser dans les index. Si vous avez déjà effectué une mise à niveau vers PostgreSQL 18.0 à 18.2, consultez les étapes supplémentaires dans la section « Mise à jour »;&lt;/li&gt;
&lt;li&gt;correction des tests &lt;code&gt;NOT NULL&lt;/code&gt; dans la sous-requête &lt;code&gt;LATERAL UNION ALL&lt;/code&gt; qui peuvent entraîner des résultats de requête erronés;&lt;/li&gt;
&lt;li&gt;éviter que les contraintes &lt;code&gt;NOT NULL&lt;/code&gt; ne génèrent des conflits de noms avec les contraintes écrites par l&amp;rsquo;utilisateur;&lt;/li&gt;
&lt;li&gt;correction de &lt;code&gt;pg_stat_get_backend_wait_event()&lt;/code&gt; et &lt;code&gt;pg_stat_get_backend_wait_event_type()&lt;/code&gt; pour qu&amp;rsquo;elles rapportent les valeurs des processus auxiliaires, comme &lt;code&gt;pg_stat_activity&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correction de la conversion d&amp;rsquo;une variable de type composite en un type de domaine lors du renvoi de sa valeur à partir d&amp;rsquo;une fonction PL/pgSQL;&lt;/li&gt;
&lt;li&gt;correction de la fonction d&amp;rsquo;entrée binaire &lt;a href=&#34;https://www.postgresql.org/docs/current/hstore.html&#34;&gt;&lt;code&gt;hstore&lt;/code&gt;&lt;/a&gt; pour éviter les plantages lors de l&amp;rsquo;entrée de clés dupliquées.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;mise-à-jour&#34;&gt;Mise à jour&lt;/h2&gt;
&lt;p&gt;Toutes les publications de mises à jour de PostgreSQL sont
cumulatives. Comme pour les autres mises à jour mineures, il n&amp;rsquo;est pas
nécessaire d&amp;rsquo;extraire et de recharger les bases de données ni
d&amp;rsquo;utiliser &lt;code&gt;pg_upgrade&lt;/code&gt; pour appliquer cette mise à jour ; il
suffit simplement d&amp;rsquo;arrêter PostgreSQL et de mettre à jour les
binaires.&lt;/p&gt;
&lt;p&gt;Si vous aviez mis à jour depuis la version 18.0, 18.1 ou 18.2 de PostgreSQL, vous aurez besoin d&amp;rsquo;exécuter le script SQL suivant avec un rôle PostgreSQL &lt;code&gt;superuser&lt;/code&gt; dans toutes vos bases de données pour rendre les fonctions &lt;code&gt;json_strip_nulls()&lt;/code&gt; et &lt;code&gt;jsonb_strip_nulls()&lt;/code&gt; immutables.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;UPDATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_catalog&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_proc&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;provolatile&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;i&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;oid&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;3261&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;3262&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Vous devrez exécuter cette commande dans les bases de données &lt;code&gt;template0&lt;/code&gt; et &lt;code&gt;template1&lt;/code&gt; pour que les futures bases de données créées disposent du bon type de volatilité pour les fonctions ci-dessus. Vous pouvez vous référer à la &lt;a href=&#34;https://www.postgresql.org/docs/current/manage-ag-templatedbs.html&#34;&gt;documentation&lt;/a&gt; sur les bases de données templates.&lt;/p&gt;
&lt;p&gt;Les utilisateurs ayant sauté une ou plusieurs mises à jour peuvent
avoir besoin d&amp;rsquo;étapes additionnelles après la mise à jour.  Les notes
de publication des versions précédentes fournissent les détails.&lt;/p&gt;
&lt;p&gt;Pour plus de détails, se référer à la &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;note de publication de
versions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Vous pouvez utiliser les commandes suivantes pour exécuter la requête sur toutes vos bases de données :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; db in &lt;span class=&#34;k&#34;&gt;$(&lt;/span&gt;psql -XAt -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;select datname from pg_database where datname not in (&amp;#39;template0&amp;#39;)&amp;#34;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;k&#34;&gt;do&lt;/span&gt; psql -d &lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;db&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt; -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;UPDATE pg_catalog.pg_proc SET provolatile = &amp;#39;i&amp;#39; WHERE oid IN (&amp;#39;3261&amp;#39;,&amp;#39;3262&amp;#39;);&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;done&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;De même, pour l&amp;rsquo;appliquer sur la base de données &lt;code&gt;template0&lt;/code&gt;, vous pouvez utiliser les commandes suivantes :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;psql -U postgres &lt;span class=&#34;s&#34;&gt;&amp;lt;&amp;lt;_EOF_
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;ALTER DATABASE template0 ALLOW_CONNECTIONS = true; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;\c template0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;UPDATE pg_catalog.pg_proc SET provolatile = &amp;#39;i&amp;#39; WHERE oid IN (&amp;#39;3261&amp;#39;,&amp;#39;3262&amp;#39;);
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;\c postgres
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;ALTER DATABASE template0 ALLOW_CONNECTIONS = false;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;_EOF_&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;liens&#34;&gt;Liens&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/download/&#34;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/&#34;&gt;Page sur la sécurité&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/versioning/&#34;&gt;Politique de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;Soumettre un bogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/about/donate/&#34;&gt;Faire un don&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vous avez des corrections ou suggestions sur cette annonce de
publication, merci de les envoyer à la mailing liste publique
&lt;a href=&#34;https://www.postgresql.org/list/&#34;&gt;&lt;em&gt;pgsql-www@lists.postgresql.org&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostgreSQL 18.2 et autres correctifs</title>
      <link>http://www.loxodata.com/post/postgresql-18-2/</link>
      <pubDate>Fri, 13 Feb 2026 09:00:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/postgresql-18-2/</guid>
      <description>&lt;p&gt;Le PGDG (PostgreSQL Global Development Group) a publié une mise à jour
de toutes les versions supportées de PostgreSQL, incluant 18.2, 17.8, 16.12, 15.16, et 14.21.&lt;/p&gt;
&lt;p&gt;Cette publication corrige également 5 vulnérabilités de sécurité et
plus de 65 bogues reportés dans les mois précédents.&lt;/p&gt;
&lt;p&gt;Pour la liste complète des changements, se référer à la section &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes
de publication&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;problèmes-de-sécurité&#34;&gt;Problèmes de sécurité&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2003/&#34;&gt;CVE-2026-2003&lt;/a&gt; : Le type &lt;code&gt;oidvector&lt;/code&gt; divulgue quelques octets de mémoire.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVSS v3.1 Base Score: 4.3&lt;/p&gt;
&lt;p&gt;versions vulnérables et supportées : 14 - 18.&lt;/p&gt;
&lt;p&gt;Une validation incorrecte du type oidvector dans PostgreSQL permet à un utilisateur de la base de données de divulguer quelques octets de la mémoire du serveur. Nous n’avons pas exclu la possibilité d’attaques visant à obtenir des informations confidentielles dans les octets divulgués, mais celles-ci semblent peu probables. Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Altan Birler pour avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2004/&#34;&gt;CVE-2026-2004&lt;/a&gt; : L&amp;rsquo;extension &lt;code&gt;intarray&lt;/code&gt; manquant une validation du type d&amp;rsquo;entrée vers l&amp;rsquo;estimateur de sélectivité permettant l&amp;rsquo;exécution de code arbitraire.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;/p&gt;
&lt;p&gt;versions vulnérables et supportées : 14 - 18.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;absence de validation du type d&amp;rsquo;entrée dans la fonction d&amp;rsquo;estimation de la sélectivité de l&amp;rsquo;extension &lt;code&gt;intarray&lt;/code&gt; permet à un créateur d&amp;rsquo;objet d&amp;rsquo;exécuter du code arbitraire en tant qu&amp;rsquo;utilisateur du système d&amp;rsquo;exploitation exécutant la base de données. Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Daniel Firer durant le zeroday.cloud, pour avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2005/&#34;&gt;CVE-2026-2005&lt;/a&gt; : Débordement de la mémoire tampon de l&amp;rsquo;extension &lt;code&gt;pgcrypto&lt;/code&gt; permettant l&amp;rsquo;exécution de code arbitraire&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;/p&gt;
&lt;p&gt;versions vulnérables et supportées : 14 - 18.&lt;/p&gt;
&lt;p&gt;Un débordement de la mémoire tampon dans l&amp;rsquo;extension &lt;code&gt;pgcrypto&lt;/code&gt; permet à un fournisseur de texte chiffré d&amp;rsquo;exécuter un code arbitraire en tant qu&amp;rsquo;utilisateur du système d&amp;rsquo;exploitation exécutant la base de données.  Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie l&amp;rsquo;équipe Xint Code durant le zeroday.cloud pour avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2006/&#34;&gt;CVE-2026-2006&lt;/a&gt; : Absence de validation de la longueur des caractères multioctets permettant l&amp;rsquo;exécution de code arbitraire.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.8&lt;/p&gt;
&lt;p&gt;versions vulnérables et supportées : 14 - 18.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;absence de validation de la longueur des caractères multioctets dans la manipulation de texte PostgreSQL permet à un utilisateur de la base de données d&amp;rsquo;émettre des requêtes spécialement conçues pour provoquer un dépassement de tampon. Cela suffit pour exécuter du code arbitraire en tant qu&amp;rsquo;utilisateur du système d&amp;rsquo;exploitation exécutant la base de données. Les versions antérieures à PostgreSQL 18.2, 17.8, 16.12, 15.16 et 14.21 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Paul Gerste et Moritz Sanft durant le zeroday.cloud pour avoir reporté ce problème.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/CVE-2026-2007/&#34;&gt;CVE-2026-2007&lt;/a&gt; : Le débordement de la mémoire tampon de l&amp;rsquo;extension &lt;code&gt;pg_trgm&lt;/code&gt; écrit un motif dans la mémoire du serveur.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CVSS v3.1 Base Score: 8.2&lt;/p&gt;
&lt;p&gt;versions vulnérables et supportées : 18.&lt;/p&gt;
&lt;p&gt;Un débordement de la mémoire tampon dans l&amp;rsquo;extension &lt;code&gt;pg_trgm&lt;/code&gt; permet à un utilisateur de la base de données d&amp;rsquo;obtenir des effets inconnus via une chaîne de caractères spécialement conçue. L&amp;rsquo;attaquant a un contrôle limité sur les modèles d&amp;rsquo;octets à écrire, mais nous n&amp;rsquo;avons pas exclu la possibilité d&amp;rsquo;attaques conduisant à une élévation des privilèges. Les versions antérieures à PostgreSQL 18.1 et 18.0 sont concernées.&lt;/p&gt;
&lt;p&gt;Le projet PostgreSQL remercie Heikki Linnakangas pour avoir reporté ce problème.&lt;/p&gt;
&lt;h2 id=&#34;corrections-de-bogues-et-améliorations&#34;&gt;Corrections de bogues et améliorations&lt;/h2&gt;
&lt;p&gt;Cette mise à jour corrige plus de 65 bogues ayant été signalés durant
les mois précédents. Les problèmes ci-dessous concernent
PostgreSQL 18. Certains de ces problèmes peuvent aussi concerner
d&amp;rsquo;autres versions de PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;correction de la correspondance incohérente de texte insensible à la casse dans l&amp;rsquo;extension &lt;code&gt;ltree&lt;/code&gt;. Si vous utilisez un index sur une colonne &lt;code&gt;ltree&lt;/code&gt;, vous devrez peut-être, dans certains cas, effectuer une réindexation. Reportez-vous à la section « Mise à jour » pour obtenir des instructions supplémentaires;&lt;/li&gt;
&lt;li&gt;la commande &lt;code&gt;ALTER TABLE ... ADD CONSTRAINT&lt;/code&gt; pour ajouter une contrainte &lt;code&gt;NOT NULL&lt;/code&gt; à une colonne déjà marquée comme &lt;code&gt;NOT NULL&lt;/code&gt; nécessite désormais que le nom de la contrainte corresponde au nom de la contrainte existante;&lt;/li&gt;
&lt;li&gt;correction du comportement du déclencheur lorsque &lt;code&gt;MERGE&lt;/code&gt; est exécuté à partir d&amp;rsquo;une requête &lt;code&gt;WITH&lt;/code&gt; afin d&amp;rsquo;inclure les lignes affectées par &lt;code&gt;MERGE&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correctifs sur le planificateur de requêtes;&lt;/li&gt;
&lt;li&gt;correction de la recherche de sous-chaînes de texte pour les collations non déterministes;&lt;/li&gt;
&lt;li&gt;correctifs pour la gestion et le signalement des erreurs &lt;code&gt;NOTIFY&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;utilisation de la fonction de tri correcte dans les constructions parallèles d&amp;rsquo;index &lt;code&gt;GIN&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correction du traitement incorrect des sauvegardes incrémentales avec des tables de plus de 1 Go;&lt;/li&gt;
&lt;li&gt;arrêt de la restauration si le WAL n&amp;rsquo;existe pas jusqu&amp;rsquo;au point de reprise indiqué par l&amp;rsquo;enregistrement du checkpoint;&lt;/li&gt;
&lt;li&gt;correctif pour &lt;code&gt;ALTER PUBLICATION&lt;/code&gt; pour garantir que les déclencheurs d&amp;rsquo;événements contiennent toutes les options définies;&lt;/li&gt;
&lt;li&gt;correctifs concernant l&amp;rsquo;initialisation des slots de réplication;&lt;/li&gt;
&lt;li&gt;mise en pause du slot de réplication après un échec d&amp;rsquo;application d&amp;rsquo;un worker parallèle de réplication logique afin d&amp;rsquo;éviter la perte de transactions côté abonné;&lt;/li&gt;
&lt;li&gt;correctif du rapport d&amp;rsquo;erreurs pour les incompatibilités de type de chemin &lt;code&gt;SQL/JSON&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correction de l&amp;rsquo;inlining de la fonction de compilation JIT lors de l&amp;rsquo;utilisation de LLVM 17 ou ultérieure;&lt;/li&gt;
&lt;li&gt;ajout d&amp;rsquo;un nouveau paramètre serveur &lt;code&gt;file_extend_method&lt;/code&gt; pour contrôler l&amp;rsquo;utilisation de &lt;code&gt;posix_fallocate()&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correction de la complétion auto de l&amp;rsquo;utilitaire &lt;code&gt;psql&lt;/code&gt; pour les options de la commande &lt;code&gt;VACUUM&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;correctif pour &lt;code&gt;pg_dump&lt;/code&gt; pour gérer correctement les suppressions simultanées de séquences et échouer si l&amp;rsquo;utilisateur appelant ne dispose pas explicitement des privilèges nécessaires pour lire la séquence;&lt;/li&gt;
&lt;li&gt;correctifs pour &lt;code&gt;amcheck&lt;/code&gt; concernant l&amp;rsquo;inspection &lt;code&gt;btree&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;empêcher le plantage de &lt;code&gt;pg_stat_statements&lt;/code&gt; lorsqu&amp;rsquo;une liste &lt;code&gt;IN&lt;/code&gt; contient à la fois des constantes et des expressions non constantes;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cette publication met également à jour les fichiers de données de fuseaux horaires vers la version &lt;code&gt;2025c&lt;/code&gt; de &lt;code&gt;tzdata&lt;/code&gt;, qui ne comporte qu&amp;rsquo;une modification des données historiques pour les horodatages antérieurs à 1976 à Baja, en Californie.&lt;/p&gt;
&lt;h2 id=&#34;mise-à-jour&#34;&gt;Mise à jour&lt;/h2&gt;
&lt;p&gt;Toutes les publications de mises à jour de PostgreSQL sont
cumulatives. Comme pour les autres mises à jour mineures, il n&amp;rsquo;est pas
nécessaire d&amp;rsquo;extraire et de recharger les bases de données ni
d&amp;rsquo;utiliser &lt;code&gt;pg_upgrade&lt;/code&gt; pour appliquer cette mise à jour ; il
suffit simplement d&amp;rsquo;arrêter PostgreSQL et de mettre à jour les
binaires.&lt;/p&gt;
&lt;p&gt;Si vous avez des index sur des colonnes &lt;code&gt;ltree&lt;/code&gt; et n&amp;rsquo;utilisant pas le fournisseur
de collation &lt;code&gt;libc&lt;/code&gt;, après la mise à jour vers la dernière version, vous devrez
réindexer les données de type &lt;code&gt;ltree&lt;/code&gt;. Vous pouvez utiliser &lt;code&gt;REINDEX INDEX CONCURRENTLY&lt;/code&gt;
pour réduire l&amp;rsquo;impact sur votre système.&lt;/p&gt;
&lt;p&gt;Les utilisateurs ayant sauté une ou plusieurs mises à jour peuvent
avoir besoin d&amp;rsquo;étapes additionnelles après la mise à jour.  Les notes
de publication des versions précédentes fournissent les détails.&lt;/p&gt;
&lt;p&gt;Pour plus de détails, se référer à la &lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;note de publication de
versions&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;liens&#34;&gt;Liens&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/download/&#34;&gt;Téléchargements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/docs/release/&#34;&gt;Notes de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/security/&#34;&gt;Page sur la sécurité&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/support/versioning/&#34;&gt;Politique de version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/account/submitbug/&#34;&gt;Soumettre un bogue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.org/about/donate/&#34;&gt;Faire un don&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Si vous avez des corrections ou suggestions sur cette annonce de
publication, merci de les envoyer à la mailing liste publique
&lt;a href=&#34;https://www.postgresql.org/list/&#34;&gt;&lt;em&gt;pgsql-www@lists.postgresql.org&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>De retour du FOSDEM PGDay 2026 </title>
      <link>http://www.loxodata.com/post/fosdem-2026/</link>
      <pubDate>Tue, 10 Feb 2026 09:30:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/fosdem-2026/</guid>
      <description>&lt;h2 id=&#34;de-retour-du-fosdem-pgday-2026&#34;&gt;De retour du FOSDEM PGDay 2026&lt;/h2&gt;
&lt;p&gt;Le 30 janvier 2026 s&amp;rsquo;est déroulé le FOSDEM PGDay, un événement annuel entièrement dédié à PostgreSQL, organisé à Bruxelles en amont du FOSDEM.
Cette conférence marque le début de la saison des conférences PostgreSQL en Europe.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;édition 2026  nous a offert un programme varié, couvrant à la fois les mises à jour majeures sans interruption de service, l&amp;rsquo;optimisation des performances et l&amp;rsquo;analyse statistique avancée. Les sessions ont également exploré en profondeur le fonctionnement interne de l’exécuteur, les mécanismes de détection et de correction des corruptions, ainsi que de nombreux retours d’expérience sur la performance sur Kubernetes et bien entendu du vibe coding au-dessus de PostgreSQL managé dans le cloud.&lt;/p&gt;
&lt;h2 id=&#34;zero-downtime-upgrades-postgresql-and-osglibc-at-global-scale&#34;&gt;Zero-Downtime Upgrades: PostgreSQL and OS/glibc at Global Scale&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/459-alexander-sosna/&#34;&gt;Alexander Sosna&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ce retour d’expérience de GitLab décrit une stratégie d’upgrade PostgreSQL réellement sans interruption à très grande échelle (40–60 To, multi-zones), où seule la réplication logique s’est révélée viable. Le pilotage repose sur l’Apdex afin de mesurer l’impact utilisateur réel des opérations. L’architecture combine pg_upgrade sur un nœud cible, resynchronisation logique et possibilité de rollback. Un point critique concerne les upgrades OS/glibc et les collations, traitées via une gestion fine et progressive des index, entièrement automatisée.&lt;/p&gt;
&lt;h2 id=&#34;efficiently-approximatingestimating-percentiles-and-histograms&#34;&gt;Efficiently approximating/estimating percentiles and histograms&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/116-tomas-vondra/&#34;&gt;Tomas Vondra&lt;/a&gt;
Le calcul des percentiles et quantiles est une opération analytique courante, mais coûteuse lorsqu’il est exact. Cette présentation montre comment y répondre à l’aide de méthodes d’approximation, en s’appuyant notamment sur les extensions tdigest et ddsketch. Tomas y expose les principes sous-jacents à ces types de données et leur utilisation pratique, en particulier pour produire des histogrammes offrant une représentation lisible des distributions.&lt;/p&gt;
&lt;h2 id=&#34;storage-performance-matters-benchmarking-postgresql-on-kubernetes&#34;&gt;Storage Performance Matters: Benchmarking PostgreSQL on Kubernetes&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/1310-jonathan-battiato/&#34;&gt;Jonathan Battiato&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;L’exécution de PostgreSQL sur Kubernetes impose des choix de stockage déterminants pour les performances et la fiabilité, CloudNativePG fournissant un cadre de gestion natif, mais volontairement agnostique du stockage.
Cette présentation analyse l’impact des comportements internes de PostgreSQL (WAL, buffers, scans séquentiels) sur les performances d’E/S.
Elle compare les volumes locaux et les volumes réseau afin d’en mesurer les effets sur les charges de travail.
Des retours terrain et des benchmarks (FIO, pgbench) permettent d’identifier les goulets d’étranglement et d’optimiser les plateformes Data sur Kubernetes. Une initiative de containers est, à ce titre, en cours de développement afin de permettre d&amp;rsquo;automatiser la caractérisation des stockages envisagés pour stocker les données des bases.&lt;/p&gt;
&lt;h2 id=&#34;lighting-talks&#34;&gt;Lighting talks&lt;/h2&gt;
&lt;p&gt;Après la pause déjeuner, c&amp;rsquo;est le temps du Lighting talks. Les orateurs ont 5 min pour parler d&amp;rsquo;un sujet autour de PostgreSQL.&lt;/p&gt;
&lt;p&gt;Les sujets abordés :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LISTEN / NOTIFY
Présenté comme une file sérialisée avec table interne et advisory locks. Très utile, mais peut devenir un hotspot.&lt;/li&gt;
&lt;li&gt;One Database to Rule Them All
Mise en perspective des bases se disant « compatibles PostgreSQL » via pgscorecard.&lt;/li&gt;
&lt;li&gt;RPM Packaging
Devrim explique les contraintes réelles du packaging PostgreSQL.&lt;/li&gt;
&lt;li&gt;AI Code &amp;amp; PostgreSQL
Retour d’expérience critique sur les PR générées par IA.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;batching-in-executor&#34;&gt;Batching in Executor&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/654-amit-langote/&#34;&gt;Amit Langote&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cette conférence, très technique, a mis en lumière les limites historiques de l’exécuteur de PostgreSQL, toujours basé sur un traitement tuple par tuple.
Malgré des optimisations récentes, ce modèle reste coûteux sur les CPU modernes, notamment pour les workloads analytiques.
Amit nous présente un prototype introduisant un traitement par lots de tuples au sein de l’exécuteur. L&amp;rsquo;idée est de tirer partie à la fois des capacités SIMD des processeurs et de mieux gérer la localité des données dans le cache processeur.
Celui-ci repose sur une nouvelle API, une abstraction de batch et des extensions des Table AM.
Les premiers résultats sont prometteurs et ouvrent la voie à un exécuteur PostgreSQL plus efficace et orienté batch.
Le principe proposé par Amit est de permettre de détecter au plus tôt les cas où les données sont adjacentes en mémoire (SeqScan, par exemple) et de basculer sur le mode Batch dans ces cas.
Cela permet de faire coexister à la fois les traitements OLTP standards et ce nouveau mode batch (qui a pour vocation d&amp;rsquo;adresser les trafics OLAP).&lt;/p&gt;
&lt;h2 id=&#34;from-crisis-to-control-detect-and-fix-corruptions&#34;&gt;From Crisis to Control: Detect and Fix Corruptions&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/859-derk-van-veen/&#34;&gt;Derk van Veen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Un sujet redouté de tous les DBA : la corruption de données dans PostgreSQL.
Derk partage son retour d’expérience concret sur des corruptions réelles, parfois anciennes, pour lesquelles une restauration depuis les sauvegardes n’était pas toujours possible.
La présentation détaille tout le processus, depuis la détection de la corruption et le déblocage du vacuum jusqu’aux choix techniques permettant de limiter l’impact et corriger le problème.
Cette présentation a mis en évidence la nécessité d’une compréhension fine du fonctionnement interne de PostgreSQL et l’usage combiné de plusieurs extensions spécialisées.
Une session très pédagogique, qui donne de véritables clés pour affronter les corruptions avec méthode et confiance, et éviter la perte de données.&lt;/p&gt;
&lt;p&gt;Pour plus de détails, il a écrit un article sur le sujet &lt;a href=&#34;https://www.adyen.com/knowledge-hub/database-corruption-in-postgresql&#34;&gt;&amp;ldquo;Database corruption in PostgreSQL&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;vibe-coding-with-postgres-really&#34;&gt;Vibe-coding with Postgres: really?&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.postgresql.eu/events/fosdem2026/schedule/speaker/978-matt-cornillon/&#34;&gt;Matt Cornillon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cette présentation de fin de journée était rafraîchissante : comment
faire évoluer une application web python en utilisant PostgreSQL avec
des agents IA pour réaliser l&amp;rsquo;implémentation de nouvelles
fonctionnalités utilisant des &amp;ldquo;embeddings&amp;rdquo;. Matt nous a montré
comment, à l&amp;rsquo;aide de plusieurs agents (un pour le code, un pour la
base) et Gemini, il a pu implémenter une fonctionnalité étendue de
recherche sur un site web fictif de vente de fleurs. Outre l&amp;rsquo;agent
générant le code python, nous avons pu voir comment l&amp;rsquo;agent PostgreSQL
utilisé dans ce projet a repris le schéma pour le transformer. Cela
passe par l&amp;rsquo;analyse de l&amp;rsquo;existant par l&amp;rsquo;agent et la proposition
d&amp;rsquo;implémentation (que le développeur peut modifier) avant que les
agents effectuent les modifications réellement.&lt;/p&gt;
&lt;h2 id=&#34;conclusion--&#34;&gt;Conclusion  :&lt;/h2&gt;
&lt;p&gt;Le FOSDEM PGDay 2026 confirme son positionnement de conférence technique, orientée production réelle et évolution du moteur PostgreSQL.
Pour un consultant PostgreSQL, c’est un événement à forte valeur ajoutée.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Retour sur le DevFest Toulouse 2025</title>
      <link>http://www.loxodata.com/post/devfest-toulouse-2025/</link>
      <pubDate>Fri, 14 Nov 2025 15:00:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/devfest-toulouse-2025/</guid>
      <description>&lt;h1 id=&#34;retour-sur-le-devfest-toulouse-2025&#34;&gt;Retour sur le DevFest Toulouse 2025&lt;/h1&gt;
&lt;p&gt;Le &lt;a href=&#34;https://devfesttoulouse.fr/&#34;&gt;DevFest Toulouse 2025&lt;/a&gt;, organisé par le &lt;a href=&#34;https://gdg.community.dev/gdg-toulouse/&#34;&gt;GDG Toulouse&lt;/a&gt;,
s&amp;rsquo;est tenu le jeudi 13 novembre au centre de congrès Diagora à Labège, dans l&amp;rsquo;Est Toulousain.&lt;/p&gt;
&lt;p&gt;Il y avait six salles en parallèle pour offrir des conférences sur des sujets techniques variés allant des langages de programmation, aux méthodes de
développement, à l&amp;rsquo;infrastructure, au frontend et l&amp;rsquo;IA.&lt;/p&gt;
&lt;p&gt;Une salle dédiée aux sponsors permettait d&amp;rsquo;échanger avec les équipes autour d&amp;rsquo;animations et de cafés.&lt;/p&gt;
&lt;h2 id=&#34;les-conférences&#34;&gt;Les conférences&lt;/h2&gt;
&lt;p&gt;Au vu du nombre de conférences, il faut faire des choix. Je vous présente donc ici les conférences auxquelles j&amp;rsquo;ai pu participer durant la journée.&lt;/p&gt;
&lt;p&gt;Vous pouvez consulter l&amp;rsquo;&lt;a href=&#34;https://devfesttoulouse.fr/agenda-2025/&#34;&gt;agenda complet&lt;/a&gt; pour visualiser la liste complète des conférences.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://www.loxodata.com/images/post/devfest-toulouse-2025/dev-fest-toulouse-anotherworld.jpg&#34; alt=&#34;DevFest Toulouse intro&#34;&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Another World, une belle leçon d’architecture logicielle&lt;/em&gt;, Olivier Poncet : la conférence d&amp;rsquo;ouverture permet de revenir sur l&amp;rsquo;architecture du célèbre jeu &lt;code&gt;Another World&lt;/code&gt;
créé par Éric Chahi et de son &lt;a href=&#34;https://github.com/ponceto/another-world-interpreter&#34;&gt;portage&lt;/a&gt; par Olivier pour le faire tourner dans un navigateur avec WebAssembly.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Docker Bake, élégance et standardisation pour le build de vos images Docker&lt;/em&gt;, Mazlum Tosun : Mazlum nous présente l&amp;rsquo;outil &lt;a href=&#34;https://docs.docker.com/build/bake/&#34;&gt;Docker Bake&lt;/a&gt; basé sur Docker Buildx
pour construire vos images Docker de manière déclarative avec le format HCL, et de manière concurrente.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Toute ma stack est dans ma BDD : Postgres et quelques &amp;ldquo;power tools&amp;rdquo; pour mon backend&lt;/em&gt;, Mathieu Passenau et Loïc des Rochettes : Mathieu et Loïc de chez &lt;a href=&#34;https://please-open.it/&#34;&gt;Please-open.it&lt;/a&gt; nous présentent leur idée d&amp;rsquo;utiliser PostgreSQL pour
toute la pile logiciel, en passant par le stockage, l&amp;rsquo;authentification via Keycloak, l&amp;rsquo;utilisation de fonctions pour la partie contrôleur et les APIs via PostgREST.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Conception de logiciels : le match humains vs AI&lt;/em&gt;, Olivier Azeau : Olivier nous propose de participer à un quiz sur la conception logiciel et de comparer nos résultats avec ceux obtenus avec l&amp;rsquo;aide de l&amp;rsquo;IA.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Renovate à la rescousse : Automatisez la dette technique de votre infra Kubernetes&lt;/em&gt;, Paul Vulliemin : Paul nous propose de découvrir l&amp;rsquo;outil &lt;a href=&#34;https://github.com/renovatebot/renovate&#34;&gt;Renovate&lt;/a&gt; pour la
mise à jour des dépendances d&amp;rsquo;outils dans le cadre de l&amp;rsquo;Infrastructure as code/Continous delivery avec un cluster Kubernetes.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Metal-As-A-Service : Gérer votre bare-metal en MaaS, comme si c&amp;rsquo;était une machine virtuelle !&lt;/em&gt;, Julien Briault : Julien nous présente le &lt;code&gt;cloud du coeur&lt;/code&gt; mis en place aux restos du coeur et l&amp;rsquo;utilisation
d&amp;rsquo;un outil open source pour gérer ses serveurs physiques aussi simplement qu&amp;rsquo;une machine virtuelle afin de réduire les coûts d&amp;rsquo;exploitation du matériel.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;REX: une approche moderne de gestion de clusters Kubernetes&lt;/em&gt; : Alexandre Dias et Thomas Martin de chez Qonto nous présentent leur retour d&amp;rsquo;expérience sur l&amp;rsquo;administration de leurs clusters Kubernetes dans
une optique de réduction des coûts, de facilité de gestion et de résilience de la production.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;em&gt;Beyond agile : Dans les coulisses des licornes géantes de la Tech !&lt;/em&gt;, Rachel Dubois : Rachel nous propose une conférence sur les bonnes pratiques utilisées par des grandes sociétés de la tech dans l&amp;rsquo;agilité
afin d&amp;rsquo;innover, et comment échouer leur permet de livrer des expériences utilisateurs toujours plus appétentes.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Cette édition du DevFest Toulouse montre à quel point les communautés de développeuses et développeurs sont dynamiques un peu partout en France.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostgreSQL Conference Europe 2025</title>
      <link>http://www.loxodata.com/post/pgconf-eu-2025-report/</link>
      <pubDate>Wed, 05 Nov 2025 11:10:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/pgconf-eu-2025-report/</guid>
      <description>&lt;h1 id=&#34;retour-sur-la-postgresql-conference-europe-2025&#34;&gt;Retour sur la PostgreSQL Conference Europe 2025&lt;/h1&gt;
&lt;p&gt;Cette année, la PostgreSQL Conference Europe 2025 s&amp;rsquo;est déroulée à
Riga, en Lettonie. Cet évènement autour de PostgreSQL rassemble le
plus grand nombre de participants en Europe.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://www.loxodata.com/images/post/pgconf-eu-2025/monument-liberte.jpg&#34; alt=&#34;Le monument de la liberté à Riga&#34;&gt;&lt;/p&gt;
&lt;p&gt;La liste des conférences est disponible sur le site de
l&amp;rsquo;évènement : &lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/&#34;&gt;https://2025.pgconf.eu/&lt;/a&gt;.
Les supports de présentations, ainsi que les enregistrements vidéos sont
également mis à disposition dans la mesure du possible.&lt;/p&gt;
&lt;h2 id=&#34;community-events-day&#34;&gt;Community events day&lt;/h2&gt;
&lt;p&gt;Le mardi, pour la première fois cette année, était consacré à la communauté.&lt;/p&gt;
&lt;p&gt;La journée était découpée en ateliers d&amp;rsquo;une demi-journée. Les ateliers étaient
aussi divers qu&amp;rsquo;intéressants.&lt;/p&gt;
&lt;p&gt;Le nombre de places était limité, ce qui a engendré un peu de frustration.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7150-postgresql-on-kubernetes-summit/&#34;&gt;PostgreSQL on Kubernetes Summit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;De nombreuses interventions d&amp;rsquo;une dizaine de minutes devaient permettre de
dresser un état des lieux des opérateurs autour de PostgreSQL. Malheureusement,
la plupart des présentations ont été consacrées à l&amp;rsquo;opérateur CloudNativePG.&lt;/p&gt;
&lt;p&gt;Celui-ci présente toutefois un réel intérêt, puisqu&amp;rsquo;il est désormais
complètement libre.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7151-community-organizers-conf/&#34;&gt;Community Organizers Conf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un atelier à destination des organisateurs de conférences communautaires, avec
des conseils intéressants, et des retours d&amp;rsquo;expérience.&lt;/p&gt;
&lt;p&gt;Encore une preuve, s&amp;rsquo;il en fallait que la communauté est active et accueillante.&lt;/p&gt;
&lt;h2 id=&#34;la-conférence&#34;&gt;La conférence&lt;/h2&gt;
&lt;p&gt;Lors de la première intervention de la journée, Magnus Hagander a évoqué le
nombre de 650 participants. Encore une très nombreuse audience cette année.&lt;/p&gt;
&lt;p&gt;La &lt;a href=&#34;https://buff.ly/4b483Ff&#34;&gt;conférence d&amp;rsquo;ouverture&lt;/a&gt; est donnée par
Karen Sandler, de la &lt;a href=&#34;https://sfconservancy.org/&#34;&gt;Software Freedom Conservancy&lt;/a&gt;.
Le sujet abordé est celui de l&amp;rsquo;importance des logiciels libres dans le monde actuel.&lt;/p&gt;
&lt;p&gt;Les conférences sont ensuite réparties dans différentes salles, avec 4
conférences simultanées, dont une réservée aux sponsors. Nous résumons
ici nos notes à propos des présentations auxquelles nous avons
assisté.&lt;/p&gt;
&lt;h2 id=&#34;performance&#34;&gt;Performance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6952-improved-freezing-in-postgres-vacuum-from-idea-to-commit/&#34;&gt;Improved Freezing in Postgres Vacuum: From Idea to Commit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;oratrice Melanie Plageman évoque les travaux entrepris depuis des
années pour améliorer le freeze des tuples visibles : de nombreuses
tentatives ont été abandonnées, car les solutions expérimentées ne sont pas
toujours meilleures que la situation actuelle.&lt;/p&gt;
&lt;p&gt;Pour rappel, le freeze d&amp;rsquo;un tuple visible consiste à oublier la
transaction ayant rendu visible la ligne, permettant ainsi le cycle
des identifiants de transaction. Un des inconvénients de ces tâches de
maintenance est l&amp;rsquo;amplification en écriture : une même page de
données est écrite plusieurs fois si nécessaire, à chaque itération
des maintenances.&lt;/p&gt;
&lt;p&gt;Finalement, la solution retenue, et livrée avec la version 18 de
PostgreSQL, est de freezer autant que possible les lignes pendant un
vacuum régulier, diminuant l&amp;rsquo;amplification en écriture.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://anarazel.de/talks/2025-10-23-pgconf-eu-aio-in-PG-18-and-beyond/aio-in-PG-18-and-beyond.pdf&#34;&gt;AIO in PG 18 and beyond&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Andres Freund est l&amp;rsquo;auteur principal d&amp;rsquo;une nouvelle
fonctionnalité de PostgreSQL 18 : les entrées-sorties asynchrones.&lt;/p&gt;
&lt;p&gt;Après un rappel des enjeux et des possibilités de cette
fonctionnalité, il nous montre les gains potentiels, en intégrant dans
le test les travaux en cours pour les futures versions de PostgreSQL.&lt;/p&gt;
&lt;p&gt;En effet, si la fonctionnalité actuelle est limitée aux lectures
séquentielles et aux lectures « bitmap » des index, les lectures
indexées et les écritures sont prévues pour les versions 19, 20 ou 21
de PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6891/slides/759/fast-path-locking-pg18-pgconfeu-2025.pdf&#34;&gt;Fast-path locking improvements in PG18&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Tomas Vondra est un développeur habituel de PostgreSQL et
s&amp;rsquo;est trouvé confronté à un problème de performance d&amp;rsquo;une requête
utilisant un grand nombre de partitions. Cela l&amp;rsquo;a amené à se pencher
sur la façon dont les verrous sont obtenus lors de l&amp;rsquo;exécution d&amp;rsquo;une
requête, et en particulier le « fast-path locking ». Apparue dans la
version 9.2 de PostgreSQL, cette fonctionnalité permet d&amp;rsquo;avoir un
cache local de la table des verrous, mais seulement pour 16 objets, ce
qui pose un problème lorsqu&amp;rsquo;il y a un grand nombre de partitions : les
verrous sont alors notés dans la mémoire partagée, ce qui est plus lent.&lt;/p&gt;
&lt;p&gt;Tomas Vondra travaille alors pour proposer une solution permettant de
noter un plus grand nombre de verrous dans ce cache local : la
proposition, présente dans PostgreSQL 18, consiste à utiliser un
« &lt;a href=&#34;https://en.algorithmica.org/hpc/cpu-cache/associativity/&#34;&gt;set-associative
cache&lt;/a&gt; »
afin d&amp;rsquo;augmenter le nombre d&amp;rsquo;entrées possibles avec le même niveau de
performance.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;orateur constate alors le gain de performance, très visible dans les
Flame Graphs présentés. Pour terminer, outre la liste de toutes les
possibilités que cela ouvre pour les prochaines versions de
PostgreSQL, Tomas Vondra remercie l&amp;rsquo;auteur original de la
fonctionnalité, Robert Haas, qui a livré un code de qualité,
facilitant les améliorations proposées par la suite, et ce détail est
très important pour comprendre pourquoi PostgreSQL est un bon outil :
il est bien écrit !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://resources.pganalyze.com/pganalyze_PGConf_EU_2025_pg_stat_plans.pdf&#34;&gt;Tracking plan shapes over time with Plan IDs and the new pg_stat_plans&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Lukas Fittl explique en quoi une nouvelle fonctionnalité de
PostgreSQL 18 lui a permis de reprendre une idée déjà présente, mais
en l&amp;rsquo;améliorant pour la rendre utilisable.&lt;/p&gt;
&lt;p&gt;La nouveauté de PostgreSQL 18 est la possibilité pour une extension de
stocker un identifiant de plan d&amp;rsquo;exécution, ce qui permet de suivre un
même plan au cours de l&amp;rsquo;exécution d&amp;rsquo;une requête, à travers les
différents « hooks » de PostgreSQL. À cela s&amp;rsquo;ajoute la possibilité
pour une extension d&amp;rsquo;utiliser des statistiques cumulatives.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;extension &lt;a href=&#34;https://github.com/pganalyze/pg_stat_plans&#34;&gt;&lt;code&gt;pg_stat_plans&lt;/code&gt;&lt;/a&gt;
permet alors de suivre l&amp;rsquo;utilisation des plans d&amp;rsquo;exécution par les requêtes
d&amp;rsquo;une instance PostgreSQL, permettant ainsi des analyses fines des
performances de nos requêtes, sans grever les performances de ces dernières.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/7010/slides/799/PgConfEU_MVCC_bmejias_ajaimini.pdf&#34;&gt;We have multiple concurrent versions of this title trying to understand MVCC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Boriss Mejias revient sur un sujet couramment abordé dans
les conférences PostgreSQL, mais toujours nécessaire : la gestion de
la concurrence dans PostgreSQL.&lt;/p&gt;
&lt;p&gt;La présentation revient sur tous les éléments importants qui sont la
conséquence de l&amp;rsquo;implémentation de MVCC dans PostgreSQL : l&amp;rsquo;isolation
des transactions, la notion de lignes mortes, les raisons pour
lesquelles VACUUM est utile et a des conséquences, y compris sur la
réplication et le freeze des tuples visibles.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://www.loxodata.com/images/post/pgconf-eu-2025/riga-aldaru-iela.jpg&#34; alt=&#34;rue du centre historique de Riga&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;administration&#34;&gt;Administration&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://drive.google.com/file/d/1iq40z1SEQGUPFrJcAph8Hmw6w7g5-Mig/view?usp=sharing&#34;&gt;What implementing pg_tde taught us about PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Jan Wieremjewicz détaille le besoin exprimé par de plus en
plus d&amp;rsquo;utilisateurs de PostgreSQL : le chiffrement transparent des
données, ou TDE.&lt;/p&gt;
&lt;p&gt;Entre autres besoins, il nous rappelle que, pour des raisons
règlementaires, le chiffrement sur disque n&amp;rsquo;est plus suffisant, et que
certains utilisateurs ont maintenant besoin d&amp;rsquo;une solution de
chiffrement native dans leur base de données.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;orateur explique alors la démarche de recension des besoins des
utilisateurs pour aboutir à une solution. Un des besoins identifiés
est d&amp;rsquo;utiliser une solution open-source, et dont le code, à terme, est
présent dans PostgreSQL.&lt;/p&gt;
&lt;p&gt;Les solutions déjà existantes ne correspondant pas, Percona développe
alors une réponse aux besoins, avec comme objectif l&amp;rsquo;intégration dans
PostgreSQL.&lt;/p&gt;
&lt;p&gt;Ça n&amp;rsquo;est pas le cas actuellement : Percona propose une version
modifiée de PostgreSQL et une extension :
&lt;a href=&#34;https://github.com/percona/pg_tde&#34;&gt;pg_tde&lt;/a&gt;. Deux patchs proposés,
mais pas encore intégrés sont en effet nécessaires pour proposer un
chiffrement des tables.&lt;/p&gt;
&lt;p&gt;La solution est donc open-source, et utilisable, dans des limites
connues, et l&amp;rsquo;objectif de l&amp;rsquo;intégration dans PostgreSQL reste à
atteindre.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7191-tde-as-an-extension-a-different-path-for-postgresql-encryption/&#34;&gt;TDE as an Extension: A Different Path for PostgreSQL Encryption&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;À la suite de la présentation précédente, l&amp;rsquo;orateur Zsolt Parragi
détaille l&amp;rsquo;implémentation actuelle de
&lt;a href=&#34;https://github.com/percona/pg_tde&#34;&gt;pg_tde&lt;/a&gt; : quel chemin pour y
arriver, qu&amp;rsquo;est-ce qui fonctionne, que reste-t-il à faire ?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6975/slides/746/pgconfeu25_Postgres_Logparsing.pdf&#34;&gt;Parsing Postgres logs the non-pgBadger way&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Kaarel Moppel présente les différentes approches possibles
pour analyser les logs d&amp;rsquo;une instance PostgreSQL : d&amp;rsquo;outils Unix comme
sed/awk, en passant par pgBadger jusqu&amp;rsquo;au chargement des logs dans une
table de PostgreSQL, les possibilités sont nombreuses.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;orateur présente un nouvel outil :
&lt;a href=&#34;https://github.com/kmoppel/pgweasel&#34;&gt;pgweasel&lt;/a&gt;, écrit en GO,
permettant d&amp;rsquo;extraire des informations agrégées des fichiers de logs,
en visant de meilleures performances que les outils existants. Une
réécriture en Rust permet d&amp;rsquo;ailleurs d&amp;rsquo;être encore plus rapide qu&amp;rsquo;en
GO.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/7103/slides/780/Barman,%20past,%20present,%20and%20future%20of%20a%20pioneer%20community%20project.pdf&#34;&gt;Barman, past, present, and future of a pioneer community project&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les orateurs Giulio Calacoci et Martín Marqués reviennent sur
l&amp;rsquo;histoire de l&amp;rsquo;outil Barman, connu et utilisé depuis des années par
de nombreux utilisateurs pour mettre en œuvre leurs stratégies de
sauvegardes et restaurations des instances PostgreSQL.&lt;/p&gt;
&lt;p&gt;Si l&amp;rsquo;activité de l&amp;rsquo;outil, sous-entendu, son développement, a été
chaotique ces dernières années, il a été décidé de relancer, à travers
une communauté d&amp;rsquo;utilisateurs, la vie de l&amp;rsquo;outil pour répondre aux
besoins actuels.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6908/slides/785/20251023_dkrautschick_PGConfEU_KafkaDebeziumForDBPeople.pdf&#34;&gt;Why PostgreSQL people should really care about Kafka and Debezium?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Dirk Krautschick explique le fonctionnement et l&amp;rsquo;utilisation
du couple Kafka/Debezium pour « consommer » les flux de données d&amp;rsquo;une
instance PostgreSQL.&lt;/p&gt;
&lt;p&gt;Debezium est le connecteur utilisé par Kafka pour consommer les
données issues du décodage logique des journaux de transactions d&amp;rsquo;une
instance PostgreSQL. Cela permet de concevoir des architectures de
données évitant de devoir copier des données ou requêter une base :
tous les changements de données sont envoyés dans le flux.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;orateur mentionne pour finir un nouvel outil : &lt;a href=&#34;https://flink.apache.org/&#34;&gt;Apache
Flink&lt;/a&gt;, conçu très récemment !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/7094/slides/772/herrera-houska-repack-2025.pdf&#34;&gt;Table repacking, done right&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les orateurs Álvaro Herrera et Antonin Houska détaillent un besoin
très présent pour les administrateurs de bases de données : devoir
réorganiser physiquement une table. Après un historique des
différentes solutions présentes dans PostgreSQL (&lt;code&gt;VACUUM FULL&lt;/code&gt;), les
orateurs expliquent la difficulté d&amp;rsquo;intégrer l&amp;rsquo;outil
&lt;a href=&#34;https://github.com/cybertec-postgresql/pg_squeeze&#34;&gt;pg_squeeze&lt;/a&gt; dans
PostgreSQL, ce second outil faisant la même chose que la première
commande, mais en minimisant le verrouillage de l&amp;rsquo;objet traité.&lt;/p&gt;
&lt;p&gt;En effet, les orateurs proposent le renommage de &lt;code&gt;VACUUM FULL&lt;/code&gt; et
l&amp;rsquo;intégration de &lt;code&gt;pg_squeeze&lt;/code&gt; dans une commande &lt;code&gt;REPACK&lt;/code&gt; et son option
&lt;code&gt;CONCURRENTLY&lt;/code&gt;. Le patch est en cours d&amp;rsquo;intégration et a besoin de
testeurs !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6817-operational-hazards-of-managing-postgresql-dbs-over-100tb/&#34;&gt;Operational hazards of managing PostgreSQL DBs over 100TB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;oratrice Teresa Lopes expose un certain nombre de bonnes pratiques à
intégrer lorsque l&amp;rsquo;on s&amp;rsquo;attaque à des bases dépassant les 100TB.&lt;/p&gt;
&lt;p&gt;Parmi les pistes évoquées, Teresa détaille les opérations de &lt;code&gt;VACUUM&lt;/code&gt;,
les sauvegardes, et la réorganisation des colonnes en fonction de leur
type.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6960-have-you-ever-wondered-how-a-cloud-platform-works/&#34;&gt;Have you ever wondered, how a cloud platform works?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les orateurs Maximilian Stefanac et Philipp Thun présentent Cloud
Foundry, PaaS utilisé par SAP Business Technology, et reposant sur
PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6795-explain-make-it-make-sense/&#34;&gt;EXPLAIN: make it make sense&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Aivars Kalvāns explique ce qu&amp;rsquo;on peut retirer comme
information d&amp;rsquo;un plan d&amp;rsquo;exécution PostgreSQL.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/6825-database-in-distress-testing-and-repairing-different-types-of-database-corruption/&#34;&gt;Database in Distress: Testing and Repairing Different Types of Database Corruption&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Josef Machytka revient sur les cas de corruption qu&amp;rsquo;il a eu
à traiter.&lt;/p&gt;
&lt;p&gt;Il présente un outil qu&amp;rsquo;il a écrit pour générer des crashs de bases de données
de manière à étudier les solutions envisageables pour corriger les problèmes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://www.loxodata.com/images/post/pgconf-eu-2025/fusiliers-lettons.jpg&#34; alt=&#34;Monument dédié aux fusiliers lettons (1915-1920) à Riga&#34;&gt;&lt;/p&gt;
&lt;h2 id=&#34;high-availibility&#34;&gt;High availibility&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pgstef.github.io/talks/en/20251022_PGConfEU_Patroni-and-pgBackRest.pdf&#34;&gt;Patroni and pgBackRest: better together&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Stefan Fercot évoque l&amp;rsquo;intégration de deux outils
complémentaires : Patroni pour la haute disponibilité et pgBackRest
pour les sauvegardes et restauration des instances PostgreSQL.&lt;/p&gt;
&lt;p&gt;Quelles sont les différentes étapes où Patroni utilise pgBackRest :
archivage, réinitialisation d&amp;rsquo;un nœud, bootstrap du cluster. On
comprend que pgBackRest intervient aux moments critiques de la gestion
des données de PostgreSQL.&lt;/p&gt;
&lt;p&gt;Un point important noté par Stefan : pour savoir si tout se passe
bien, il est essentiel de lire les logs des trois composants impliqués !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7134-kubernetes-from-the-database-out/&#34;&gt;Kubernetes from the Database Out&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Alastair Turner explique les points importants à savoir
lorsqu&amp;rsquo;on souhaite utiliser PostgreSQL dans un cluster Kubernetes.&lt;/p&gt;
&lt;p&gt;Quels sont les composants et concepts utilisés : réseau, stockage,
automatisation…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://speakerdeck.com/hugh0capet/hazards-of-logical-decoding-in-postgresql&#34;&gt;Hazards of logical decoding in PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;oratrice Polina Bungina revient sur ce qu&amp;rsquo;implique le décodage
logique dans PostgreSQL, au regard de son expérience chez Zalando. En
effet, cette technologie est loin d&amp;rsquo;être simple et peut entrainer des
effets de bords désastreux pour une instance de production.&lt;/p&gt;
&lt;p&gt;De la définition d&amp;rsquo;un LSN (Log Sequence Number) à la description d&amp;rsquo;un
slot et des différentes informations qui le constitue, on comprend au
fur et à mesure les différents points critiques qui peuvent entrainer
de vraies difficultés en cas de problèmes.&lt;/p&gt;
&lt;p&gt;En effet, une simple commande de maintenance sur une table répliquée
peut entrainer le stockage d&amp;rsquo;un gros volume de données, en plus des
WALs habituels, à cause du réordonnancement des transactions
répliquées. Il faut alors surveiller la vue &lt;code&gt;pg_stat_replication_slots&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/7018/slides/771/patroni_talk_pgconf2025.pdf&#34;&gt;Patroni: what the blog posts don&amp;rsquo;t tell you&amp;hellip;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Cameron Murdoch souhaite ajouter quelques points importants
qu&amp;rsquo;on ne lit pas dans les blogposts habituels sur Patroni, notamment
la nécessité de sécuriser les flux vers les différents composants d&amp;rsquo;un
cluster.&lt;/p&gt;
&lt;p&gt;Création d&amp;rsquo;utilisateurs dédiés, de certificats pour des flux sécurisés,
procédures de mises à jour des différents composants : autant de
points critiques qui doivent faire partie de l&amp;rsquo;intégration de Patroni,
et le plus tôt possible pour éviter d&amp;rsquo;avoir à corriger plus tard.&lt;/p&gt;
&lt;h2 id=&#34;autres&#34;&gt;Autres&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://speakerdeck.com/clairegiordano/behind-postgres-18-the-people-the-code-and-the-invisible-work-claire-giordano-pgconfeu-2025&#34;&gt;Behind Postgres 18: The People, the Code, &amp;amp; the Invisible Work&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;oratrice Claire Giordano fait le bilan des nombreuses contributions
nécessaire à fabriquer PostgreSQL 18 : le code, bien sûr, mais pas
seulement : la documentation, les évènements communautaires, les
contributions financières : de nombreux acteurs s&amp;rsquo;associent pour former
une communauté riche et diverse !&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/sessions/session/6832/slides/800/all_about_cve_pgconf_eu_2025.pdf&#34;&gt;All about Common Vulnerabilities and exposures in PostgreSQL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;oratrice Priyanka Chatterjee évoque un aspect mal connu : la gestion
des vulnérabilités dans le projet PostgreSQL. Qu&amp;rsquo;est-ce qu&amp;rsquo;un CVE,
comment le projet PostgreSQL est organisé pour répondre, et qu&amp;rsquo;est-ce
qu&amp;rsquo;un utilisateur doit comprendre des informations publiées lors de la
publication d&amp;rsquo;un correctif de sécurité.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.postgresql.eu/events/pgconfeu2025/schedule/session/7138-from-stars-to-storage-engines-migrating-big-science-workloads-beyond-greenplum/&#34;&gt;From Stars to Storage Engines: Migrating Big Science Workloads Beyond Greenplum&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;L&amp;rsquo;orateur Joaquim Oliveira, détaille les difficultés rencontrées par
l&amp;rsquo;agence spatiale européenne (ESA) suite au rachat de VMware par
Broadcom, et le passage en produit commercial fermé de Greenplum.&lt;/p&gt;
&lt;p&gt;L&amp;rsquo;agence a étudié différentes solutions pour rester dans un monde
moins fermé. La décision a finalement été prise de travailler avec la
solution Warehouse de EDB.&lt;/p&gt;
&lt;p&gt;Bonne nouvelle, &lt;a href=&#34;https://warehouse-pg.io&#34;&gt;WarehousePG&lt;/a&gt; sur lequel est
basée l&amp;rsquo;offre d&amp;rsquo;EDB est open source.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;À nouveau, cette conférence a apporté aux quelques centaines de
présents de la matière pour l&amp;rsquo;avenir, en plus des nombreuses
rencontres et discussions : la communauté PostgreSQL est plus riche et
diverse que jamais !&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Plusieurs évènements sur Toulouse à ne pas rater en Novembre</title>
      <link>http://www.loxodata.com/post/events-toulouse-2025/</link>
      <pubDate>Tue, 28 Oct 2025 16:00:00 +0100</pubDate>
      
      <guid>http://www.loxodata.com/post/events-toulouse-2025/</guid>
      <description>&lt;p&gt;Le mois prochain se tiendra deux évènements sur Toulouse autour du logiciel libre, mais pas seulement :
j&amp;rsquo;ai nommé le &lt;a href=&#34;https://devfesttoulouse.fr/&#34;&gt;DevFest Toulouse&lt;/a&gt; et le &lt;a href=&#34;https://capitoledulibre.org/&#34;&gt;Capitole du Libre&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Le &lt;a href=&#34;https://devfesttoulouse.fr/&#34;&gt;DevFest Toulouse&lt;/a&gt; organisé par le &lt;a href=&#34;https://gdg.community.dev/gdg-toulouse/&#34;&gt;GDG Toulouse&lt;/a&gt; qui se tiendra le jeudi 13 novembre à Diagora (Labège), un évènement orienté plutôt développement. Un sujet autour de PostgreSQL sera proposé sur comment constituer toute une pile logicielle avec PostgreSQL.&lt;/p&gt;
&lt;p&gt;Le &lt;a href=&#34;https://capitoledulibre.org/&#34;&gt;Capitole du Libre&lt;/a&gt; organisé par l&amp;rsquo;&lt;a href=&#34;https://toulibre.org/&#34;&gt;association Toulibre&lt;/a&gt; qui aura lieu le weekend du 15 au 16 novembre à l&amp;rsquo;ENSEEIHT (Toulouse), autour du logiciel libre. Vous pourrez participer par exemple à un atelier qui présentera CloudNativePG afin d&amp;rsquo;opérer PostgreSQL
dans un cluster Kubernetes.&lt;/p&gt;
&lt;p&gt;J&amp;rsquo;en profite pour vous rappeler le redémarrage des meetups Toulousains de PostgreSQL. Si vous avez raté l&amp;rsquo;&lt;a href=&#34;https://www.loxodata.com/post/meetup-toulouse-2025-10/&#34;&gt;édition précédente&lt;/a&gt;, ça se passait chez &lt;a href=&#34;https://pictarine.com/&#34;&gt;Pictarine&lt;/a&gt; et organisé par le Toulouse PostgreSQL User Group.&lt;/p&gt;
&lt;p&gt;Crédits photo : Arthur Chauvineau&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Éviter les chevauchements temporels</title>
      <link>http://www.loxodata.com/post/without_overlaps/</link>
      <pubDate>Fri, 24 Oct 2025 02:00:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/without_overlaps/</guid>
      <description>&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;&lt;em&gt;Dans un &lt;a href=&#34;../type-range-1&#34;&gt;précédent&lt;/a&gt; article, nous avons présenté les
plages de valeurs. Nous allons voir qu&amp;rsquo;avec ce type de données, il est possible, entre autres,
de mettre en place un contrôle sur les chevauchements de données.
Pour cela, faisons un peu de pratique avec la mise en place du modèle de données d&amp;rsquo;une application de location de
vélos, nécessitant une gestion de chevauchement des locations et une recherche
de plages de disponibilité.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Nous comparons la mise en oeuvre et les performances d&amp;rsquo;une plage de
dates et la gestion d&amp;rsquo;intervalles avec l&amp;rsquo;utilisation de dates de
début et de fin utilisant les types scalaires traditionnels.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Plusieurs stratégies existent :&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Deux colonnes : &lt;code&gt;start_datetime&lt;/code&gt; et &lt;code&gt;end_datetime&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;La forme la plus classique consiste à stocker les bornes dans deux colonnes.
Le problème : aucune contrainte SQL native n’empêche deux lignes de se chevaucher en combinant deux colonnes.
Il faut alors recourir à un déclencheur vérifiant, à l’insertion ou la mise à jour, qu’aucune autre réservation n’entre en conflit.&lt;/p&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Colonnes range + contrainte d’exclusion&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Une solution plus élégante, disponible depuis PostgreSQL 9.2, consiste à utiliser un type &lt;code&gt;range&lt;/code&gt; (&lt;code&gt;tsrange&lt;/code&gt;, &lt;code&gt;tstzrange&lt;/code&gt;, &lt;code&gt;daterange&lt;/code&gt;) et une contrainte d’exclusion avec un index GiST.&lt;/p&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;PostgreSQL 18+ : la clause &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Depuis PostgreSQL 18, il est désormais possible de déclarer cette logique directement dans la clé primaire ou une contrainte unique. Pour cela, on utilise la clause
&lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; pour la dernière colonne de la contrainte d&amp;rsquo;unicité.&lt;/p&gt;
&lt;h2 id=&#34;et-en-pratique&#34;&gt;Et en pratique&lt;/h2&gt;
&lt;p&gt;Créons trois tables correspondant aux trois stratégies :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rents_exclude&lt;/code&gt; : contient des locations de vélos utilisant le type plage de dates et la contrainte d&amp;rsquo;exclusion ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rents_wo_overlaps&lt;/code&gt; : les mêmes locations utilisant le type plage de dates et la clause &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rents_2_dates&lt;/code&gt; : les mêmes locations de vélos que dans la table &lt;code&gt;rents_exclude&lt;/code&gt; mais en utilisant deux dates.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;avec-deux-dates&#34;&gt;Avec deux dates&lt;/h3&gt;
&lt;p&gt;Voici comment nous pouvons gérer des locations avec une
date de début et une date de fin utilisant des types &lt;code&gt;timestamptz&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nous créons une table contenant l&amp;rsquo;&lt;code&gt;id&lt;/code&gt; de location, les dates et heures de début de la
location, de fin de la location et l&amp;rsquo;identifiant du vélo.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GENERATED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamptz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;timestamptz&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CONSTRAINT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_date_sup_start_date_chk&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CHECK&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent2dates_start_datetime_idx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent2dates_end_datetime_idx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent2dates_bike_id_idx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous utilisons une contrainte &lt;code&gt;CHECK&lt;/code&gt; pour vérifier que &lt;code&gt;end_datetime&lt;/code&gt;
est supérieure à &lt;code&gt;start_datetime&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Nous créons ensuite un déclencheur de contrôle sur les commandes
&lt;code&gt;INSERT&lt;/code&gt; et &lt;code&gt;UPDATE&lt;/code&gt;, et sa fonction en langage PL/pgSQL, assurant
l&amp;rsquo;intégrité des données. Dans le cas présent, il s&amp;rsquo;agit d&amp;rsquo;empêcher le
chevauchement de périodes de location pour un même vélo :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;REPLACE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FUNCTION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RETURNS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TRIGGER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DECLARE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;counting_of_existing_rentals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DECLARE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number_of_rents&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INTEGER&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEGIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;counting_of_existing_rentals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;    SELECT COUNT(*) AS count_rent
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        FROM rents_2_dates
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        WHERE (($1 &amp;gt;= start_datetime  AND $1 &amp;lt; end_datetime   )
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;                OR ($2 &amp;gt; start_datetime AND $2 &amp;lt; end_datetime  ) )
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s1&#34;&gt;        AND bike_id = $3 &amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TG_OP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;UPDATE&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;THEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXECUTE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;counting_of_existing_rentals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39; AND id &amp;lt;&amp;gt; $4&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number_of_rents&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ELSIF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TG_OP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;INSERT&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;THEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXECUTE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;counting_of_existing_rentals&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number_of_rents&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;number_of_rents&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;THEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXCEPTION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Cette plage horaire n&amp;#39;&amp;#39;est pas disponible pour bike_id % pour la période % - % &amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;new&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RETURN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NULL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;RETURN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;NEW&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;END&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;$&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates$&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;LANGUAGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plpgsql&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TRIGGER&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;trg_check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BEFORE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;UPDATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FOR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EACH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ROW&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXECUTE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PROCEDURE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Maintenant que le déclencheur de contrôle est prêt, passons à quelques tests.&lt;/p&gt;
&lt;p&gt;Insérons une location pour le vélo d&amp;rsquo;id 7, le 2025-09-01 de 09:00 à 11:00 et
de 12:00 à 18:00 :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;09 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;11 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;12 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;18 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RETURNING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;┌─────────┬────────────────────────┬────────────────────────┬─────────┐&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;├─────────┼────────────────────────┼────────────────────────┼─────────┤&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;12&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;└─────────┴────────────────────────┴────────────────────────┴─────────┘&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Avec l&amp;rsquo;outil &lt;code&gt;psql&lt;/code&gt;, vous pouvez définir des variables lors de la session avec &lt;code&gt;\set&lt;/code&gt;.
Pour les tests suivants, nous allons affecter &lt;code&gt;test_day&lt;/code&gt; avec la valeur &lt;code&gt;&#39;2025-09-01&#39;::date&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Procédons alors au test d&amp;rsquo;insertion dans une plage horaire déjà
occupée.
Tentons d&amp;rsquo;insérer une location pour ce même &lt;code&gt;bike_id&lt;/code&gt; de
10:00 à 15:00 :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;10 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;15 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cette&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;horaire&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;est&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pas&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;disponible&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;la&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;période&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pgSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La fonction de contrôle remonte une erreur nous indiquant que la plage horaire n&amp;rsquo;est pas disponible
et la transaction est annulée.&lt;/p&gt;
&lt;p&gt;Après le test d&amp;rsquo;insertion, nous faisons un autre test, de mise à jour cette fois, en élargissant la période de la location &lt;code&gt;2&lt;/code&gt; (12:00 à 18:00) à 10:00-18:00 empiétant sur la location &lt;code&gt;1&lt;/code&gt; (09:00 à 11:00).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;UPDATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SET&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;10 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Cette&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;plage&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;horaire&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;est&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pas&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;disponible&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pour&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;la&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;période&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;18&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;CONTEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;PL&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pgSQL&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;function&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;line&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;31&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RAISE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Même phénomène que précédemment, le contrôle de la contrainte géré par la fonction annule la mise à jour et renvoie un message d&amp;rsquo;erreur avec le label défini.&lt;/p&gt;
&lt;h3 id=&#34;plage-de-dates-et-contraintes-dexclusion&#34;&gt;Plage de dates et contraintes d&amp;rsquo;exclusion&lt;/h3&gt;
&lt;p&gt;Utilisant le même principe, nous créons une table en remplaçant les deux
colonnes &lt;code&gt;date&lt;/code&gt; heure de début et de fin par une colonne de type
&lt;code&gt;range&lt;/code&gt;, ici un &lt;code&gt;TSTZRANGE&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXTENSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree_GiST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DROP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IF&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXISTS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GENERATED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GiST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;index créé est le suivant :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_exclude_rent_dates_bike_id_excl&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GiST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Nous avons un index multicolonne dont l&amp;rsquo;ordre est rent_dates, bike_id.&lt;/p&gt;
&lt;p&gt;Pourquoi devons-nous installer l&amp;rsquo;extension &lt;code&gt;btree_GiST&lt;/code&gt; ?
La liste des classes d&amp;rsquo;opérateurs pour un index &lt;code&gt;GiST&lt;/code&gt; est assez réduite :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;index_method&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;opclass_name&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;indexed_type&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;is_default&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;--------------+----------------+---------------+------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;box_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;box&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;circle_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;circle&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;multirange_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;anymultirange&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;point_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;poly_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;polygon&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;range_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;anyrange&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tsquery_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tsquery&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;gist&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;         &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tsvector_ops&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tsvector&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;t&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;extension &lt;code&gt;btree_GiST&lt;/code&gt; fournit des classes d&amp;rsquo;opérateurs &lt;code&gt;GiST&lt;/code&gt; supplémentaires équivalentes à celui du Btree pour les types de données numériques, temporelles et texte.
Ces opérateurs sont donc utilisables par les index, ce qui permet d&amp;rsquo;affiner la contrainte d&amp;rsquo;exclusion.
Dans notre cas, en plus de la contrainte de chevauchement &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; sur la plage de date, on y rajoutera la contrainte de &lt;code&gt;bike_id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Passons à quelques tests d&amp;rsquo;insertion et validons le comportement d&amp;rsquo;exclusion.
Prenons le vélo &lt;code&gt;7&lt;/code&gt; n&amp;rsquo;ayant pas d&amp;rsquo;entrées dans la table &lt;code&gt;rent_exclude&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Insérons deux locations : une le 2025-09-01 de 09:00 à 11:00 et une de 12:00 à 18:00.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;09 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;11 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;12 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;18 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;RETURNING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;┌─────────┬─────────────────────────────────────────────────────┬─────────┐&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;   &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                     &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;                      &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;├─────────┼─────────────────────────────────────────────────────┼─────────┤&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 09:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 11:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 12:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 18:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;       &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;└─────────┴─────────────────────────────────────────────────────┴─────────┘&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Insérons une location pour le vélo &lt;code&gt;7&lt;/code&gt; sur une période déjà occupée (12:00 à 18:00) :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;VALUES&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;11 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;17 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conflicting&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;violates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exclusion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;constraint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_bike_id_rent_dates_excl&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DETAIL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;Key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 11:00:00+01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 17:00:00+01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conflicts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;existing&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 12:00:00+01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 18:00:00+01&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)).&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Comme on le constate, une tentative d&amp;rsquo;insertion a échoué dans un
créneau déjà occupé pour le même &lt;code&gt;bike_id&lt;/code&gt; en raison
de la contrainte d&amp;rsquo;exclusion mise en place.&lt;/p&gt;
&lt;p&gt;Après le test d&amp;rsquo;insertion, nous faisons un autre test, de mise à jour cette fois, en élargissant la période de la location &lt;code&gt;2&lt;/code&gt; (12:00 à 18:00) à 10:00-18:00 en empiétant sur la location &lt;code&gt;1&lt;/code&gt; (09:00 à 11:00).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;UPDATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;10 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;test_day&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;18 hour&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;where&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ERROR&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conflicting&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;value&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;violates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;exclusion&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;constraint&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_rent_dates_bike_id_excl&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;DETAIL&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;Key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 10:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 18:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;conflicts&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;with&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;existing&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;key&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;([&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 09:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-09-01 11:00:00+02&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;),&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;).&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;La transaction est annulée et un message d&amp;rsquo;erreur nous indique une violation de contrainte, car le créneau est déjà occupé pour le même &lt;code&gt;bike_id&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;plage-de-dates-et-la-clause-without-overlaps&#34;&gt;Plage de dates et la clause WITHOUT OVERLAPS&lt;/h3&gt;
&lt;p&gt;À présent, utilisons la nouvelle fonctionnalité &lt;a href=&#34;https://doc.postgresql.fr/18/sql-createtable.html#SQL-CREATETABLE-PARMS-UNIQUE&#34;&gt;&amp;ldquo;WITHOUT OVERLAPS&amp;rdquo;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Si cette option &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; est spécifiée pour la dernière colonne, celle-ci est alors vérifiée pour les chevauchements plutôt que pour l&amp;rsquo;égalité.
Dans ce cas, les autres colonnes de la contrainte autorisent les doublons, à condition qu&amp;rsquo;ils ne se chevauchent pas dans la colonne WITHOUT OVERLAPS.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXTENSION&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree_GiST&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_wo_overlaps&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;GENERATED&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;IDENTITY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;UNIQUE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITHOUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OVERLAPS&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dans ce cas, l&amp;rsquo;index est le suivant :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_wo_overlaps_bike_id_rent_dates_key&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; 
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;UNIQUE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITHOUT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OVERLAPS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;L&amp;rsquo;ordre des colonnes est différent de celui créé pour la table &lt;code&gt;rents_exclude&lt;/code&gt;, nous avons &lt;code&gt;bike_id&lt;/code&gt;, &lt;code&gt;rent_dates&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Comme pour la contrainte d&amp;rsquo;exclusion un index de type &lt;code&gt;GiST&lt;/code&gt; est créé avec les mêmes types de contraintes.
Le comportement est donc le même que pour la table &lt;code&gt;rents_exclude&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;performance-et-taille-sur-le-disque&#34;&gt;Performance et taille sur le disque&lt;/h2&gt;
&lt;p&gt;Dans cette partie, nous allons contrôler les temps d&amp;rsquo;insertions avec des volumes conséquents,
le volume des index et analyser les temps d&amp;rsquo;exécution des requêtes.&lt;/p&gt;
&lt;h3 id=&#34;performance-en-insertion&#34;&gt;Performance en insertion&lt;/h3&gt;
&lt;p&gt;La création du jeu de données s&amp;rsquo;est effectuée de la façon suivante :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;insertion de 1000 vélos de catégorie aléatoire ;&lt;/li&gt;
&lt;li&gt;création de trois locations par jour pour chaque vélo sur deux années calendaires.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ce qui produit une table avec 2 190 000 entrées.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Le jeu de test est produit et inséré sur un ordinateur de bureau avec la configuration par défaut de PostgreSQL.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Vous pouvez trouver l&amp;rsquo;ensemble du jeu de test sur notre &lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/&#34;&gt;gitlab&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Tout d&amp;rsquo;abord, comparons les vitesses d&amp;rsquo;insertions :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Insertion dans la table &lt;code&gt;rents_2_dates&lt;/code&gt;, où le contrôle d&amp;rsquo;intégrité des données se fait par une fonction déclencheur :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;track_functions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pl&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_stat_reset&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2190000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;244937&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;342&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;04&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;04&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;937&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Insertion dans la table &lt;code&gt;rents_exclude&lt;/code&gt;, où le contrôle d&amp;rsquo;intégrité des données se fait par contrainte d&amp;rsquo;exclusion :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_exclude&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2190000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;148393&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;870&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;02&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;28&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;394&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Insertion dans la table &lt;code&gt;rents_wo_overlaps&lt;/code&gt;, où le contrôle d&amp;rsquo;intégrité des données se fait par contrainte d&amp;rsquo;exclusion et clause &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; :&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_wo_overlaps&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2190000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;Time&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;119230&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;806&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;ms&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;01&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;59&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;231&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les opérations d’insertion sont plus performantes avec le type range, dans la mesure où le contrôle d’intégrité est assuré directement par la contrainte d’exclusion.
En revanche, dans la table &lt;code&gt;rents_2_date&lt;/code&gt;, ce contrôle est effectué par un déclencheur qui vérifie pour chaque ligne insérée ou mise à jour,
l’absence de tout chevauchement avec les enregistrements existants.&lt;/p&gt;
&lt;p&gt;Il est possible d&amp;rsquo;obtenir certaines informations sur le temps d&amp;rsquo;exécution de la fonction grâce à la vue
&lt;code&gt;pg_stat_user_functions&lt;/code&gt;. Pour cela, il faut activer le paramètre &lt;code&gt;track_functions&lt;/code&gt; dans la configuration de l&amp;rsquo;instance.&lt;/p&gt;
&lt;p&gt;Dans notre cas, nous avons activé le traçage sur les fonctions &lt;code&gt;PL/pgSQL&lt;/code&gt; dans la transaction d&amp;rsquo;insertion des données via la commande :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;track_functions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;pl&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Après l&amp;rsquo;import des données, voici les informations :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;funcname&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calls&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;self_time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39; milliseconds&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;as&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;self_time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_stat_user_functions&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;┌──────────────────────────────┬─────────┬─────────────────┐&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;funcname&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;           &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;calls&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;self_time&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;    &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;├──────────────────────────────┼─────────┼─────────────────┤&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;check_rent_datetime_validity&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2190000&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;00&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;03&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;51&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;925302&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;err&#34;&gt;│&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;└──────────────────────────────┴─────────┴─────────────────┘&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le temps total d&amp;rsquo;insertion est de 04 min 05s. 03 min 52s sont occupées par
le traitement de la fonction, soit plus de 90% du temps.&lt;/p&gt;
&lt;h3 id=&#34;volume-des-index&#34;&gt;Volume des index&lt;/h3&gt;
&lt;p&gt;L&amp;rsquo;index &lt;code&gt;GiST&lt;/code&gt; est une structure arborescente équilibrée comme le &lt;code&gt;Btree&lt;/code&gt; contenant
des paires &lt;code&gt;clé, pointeur&lt;/code&gt;, mais les clés &lt;code&gt;GiST&lt;/code&gt; sont plus complexes qu&amp;rsquo;un &lt;code&gt;Btree&lt;/code&gt;,
ce qui amène un volume plus important.&lt;/p&gt;
&lt;p&gt;D&amp;rsquo;un côté, les tables &lt;code&gt;rents_exclude&lt;/code&gt; et &lt;code&gt;rents_wo_overlaps&lt;/code&gt; disposent d&amp;rsquo;un seul index &lt;code&gt;GiST&lt;/code&gt; spécifique pour le range :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_pkey&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_bike_id_rent_dates_excl&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;EXCLUDE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GiST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WITH&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;De l&amp;rsquo;autre, la table &lt;code&gt;rents_2_dates&lt;/code&gt; avec trois index de type &lt;code&gt;Btree&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_2_dates_pkey&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;PRIMARY&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;KEY&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rent2dates_end_datetime_idx&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rent2dates_start_datetime_idx&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;tart_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;rent2dates_bike_id_idx&amp;#34;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;stat_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On trouve ci-dessous un tableau donnant par table le volume des données et le volume des index :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;┌─────────────────────────────────────┬────────────┬──────────────┬────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│             table_name              │ table_size │ indexes_size │ total_size │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├─────────────────────────────────────┼────────────┼──────────────┼────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &lt;span class=&#34;s2&#34;&gt;&amp;#34;ams_rent_bike&amp;#34;&lt;/span&gt;.&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_exclude&amp;#34;&lt;/span&gt;     │ &lt;span class=&#34;m&#34;&gt;126&lt;/span&gt; MB     │ &lt;span class=&#34;m&#34;&gt;222&lt;/span&gt; MB       │ &lt;span class=&#34;m&#34;&gt;348&lt;/span&gt; MB     │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &lt;span class=&#34;s2&#34;&gt;&amp;#34;ams_rent_bike&amp;#34;&lt;/span&gt;.&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_2_dates&amp;#34;&lt;/span&gt;     │ &lt;span class=&#34;m&#34;&gt;126&lt;/span&gt; MB     │ &lt;span class=&#34;m&#34;&gt;97&lt;/span&gt; MB        │ &lt;span class=&#34;m&#34;&gt;223&lt;/span&gt; MB     │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ &lt;span class=&#34;s2&#34;&gt;&amp;#34;ams_rent_bike&amp;#34;&lt;/span&gt;.&lt;span class=&#34;s2&#34;&gt;&amp;#34;rents_wo_overlaps&amp;#34;&lt;/span&gt; │ &lt;span class=&#34;m&#34;&gt;126&lt;/span&gt; MB     │ &lt;span class=&#34;m&#34;&gt;229&lt;/span&gt; MB       │ &lt;span class=&#34;m&#34;&gt;354&lt;/span&gt; MB     │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└─────────────────────────────────────┴────────────┴──────────────┴────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Voyons maintenant le volume de chaque index :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;┌───────────────────┬──────────────────────────────────────────┬────────────┬────────┬─────────────────────┐
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│     rel_name      │                index_name                │ type_index │  size  │       columns       │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;├───────────────────┼──────────────────────────────────────────┼────────────┼────────┼─────────────────────┤
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ rents_wo_overlaps │ rents_wo_overlaps_bike_id_rent_dates_key │ GiST       │ &lt;span class=&#34;m&#34;&gt;182&lt;/span&gt; MB │ rent_dates, bike_id │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ rents_exclude     │ rents_exclude_rent_dates_bike_id_excl    │ GiST       │ &lt;span class=&#34;m&#34;&gt;173&lt;/span&gt; MB │ rent_dates, bike_id │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ rents_2_dates     │ rent2dates_start_datetime_idx            │ btree      │ &lt;span class=&#34;m&#34;&gt;17&lt;/span&gt; MB  │ start_datetime      │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ rents_2_dates     │ rent2dates_end_datetime_idx              │ btree      │ &lt;span class=&#34;m&#34;&gt;17&lt;/span&gt; MB  │ end_datetime        │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;│ rents_2_dates     │ rent2dates_bike_id_idx                   │ btree      │ &lt;span class=&#34;m&#34;&gt;16&lt;/span&gt; MB  │ bike_id             │
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;└───────────────────┴──────────────────────────────────────────┴────────────┴────────┴─────────────────────┘
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dans notre cas, nous comparons le volume de la somme des trois index &lt;code&gt;btree&lt;/code&gt; liés au stockage sur 2
colonnes avec le volume de l&amp;rsquo;index &lt;code&gt;GiST&lt;/code&gt; de la contrainte d&amp;rsquo;exclusion et avec l&amp;rsquo;index &lt;code&gt;GisT&lt;/code&gt; de la
contrainte d&amp;rsquo;unicité (qui utilise &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt;).
Comme nous l&amp;rsquo;avons indiqué plus haut, la clé dans ce dernier cas contient à la fois les données de la plage de date et le &lt;code&gt;bike_id&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Le volume est différent entre les index &lt;code&gt;GiST&lt;/code&gt; car l&amp;rsquo;ordre des colonnes n&amp;rsquo;est pas le même.
On s&amp;rsquo;aperçoit également que chaque index &lt;code&gt;GiST&lt;/code&gt; est 3x plus volumineux que la somme des 3 index &lt;code&gt;Btree&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;performance-de-recherche&#34;&gt;Performance de recherche&lt;/h2&gt;
&lt;p&gt;Voyons à présent une mise en situation. Nous souhaitons connaître les disponibilités des vélos sur une journée donnée.&lt;/p&gt;
&lt;p&gt;Vous trouverez les requêtes dans les liens suivants :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/queries/available_with_range_exclude.sql&#34;&gt;available_with_range_exclude.sql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/queries/available_with_range_without_overlaps.sql&#34;&gt;available_with_range_without_overlaps.sql&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/queries/available_with_2_dates.sql&#34;&gt;available_with_2_dates.sql&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Les structures des requêtes sont assez proches les unes des autres ; leur but est de
contrôler le bon usage des index et de comparer les temps des réponses.&lt;/p&gt;
&lt;p&gt;En ce qui concerne les performances, l&amp;rsquo;avantage est donné à l&amp;rsquo;utilisation de deux colonnes.&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Temps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_2_dates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;10 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_exclude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;15 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_wo_overlaps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;30 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;La différence de temps entre &lt;code&gt;rents_exclude&lt;/code&gt; et &lt;code&gt;rents_wo_overlaps&lt;/code&gt; est dû a l&amp;rsquo;ordre des colonnes dans l&amp;rsquo;index.&lt;/p&gt;
&lt;p&gt;Vous pouvez trouver les résultats des &lt;code&gt;EXPLAIN (ANALYSE, buffers)&lt;/code&gt; ici :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/explain_analyse/available_period_with_2_dates.txt&#34;&gt;available_period_with_2_dates.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/explain_analyse/available_period_with_range_exclude.txt&#34;&gt;available_period_with_range_exclude.txt&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/explain_analyse/available_period_with_range_without_overlaps.txt&#34;&gt;available_period_with_range_without_overlaps.txt&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prenons un autre exemple, la liste des réservations pour une liste de vélos sur une période donnée :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;TSTZRANGE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;09 hour&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39; 20 hour&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ANALYSE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BUFFERS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;amp;&amp;amp;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;search_range&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vstart_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;09 hour&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;set&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vend_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;2025-09-01&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;::&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;date&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;+&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;interval&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;&amp;#39;&amp;#39;20 hour&amp;#39;&amp;#39;&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;EXPLAIN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ANALYSE&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;BUFFERS&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;WHERE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;      &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BETWEEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vstart_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vend_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;OR&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;     &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;BETWEEN&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vstart_datetime&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;vend_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;AND&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;r&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Dans ce cas, la lecture des plans d&amp;rsquo;exécutions nous indique que, pour l&amp;rsquo;interrogation des données dans la table &lt;code&gt;rents_2_dates&lt;/code&gt;, PostgreSQL parcourt trois index :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rent2dates_start_datetime_idx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rent2dates_end_datetime_idx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;rent2dates_bike_id_idx&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces informations sont visibles dans le fichier &lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/explain_analyse/rents_for_period_some_bikes_2_dates.txt?ref_type=heads&#34;&gt;rents_for_period_some_bikes_2_dates.txt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Pour la recherche dans la table &lt;code&gt;rents_exclude&lt;/code&gt;, il n&amp;rsquo;y a qu&amp;rsquo;un parcours d&amp;rsquo;index :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rents_bike_id_rent_dates_excl&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces informations sont visibles dans le fichier &lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/explain_analyse/rents_for_period_some_bikes_range_exclude.txt?ref_type=heads&#34;&gt;rents_for_period_some_bikes_range_exclude.txt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;De plus, nous pouvons constater que moins de blocs de données sont lus.&lt;/p&gt;
&lt;p&gt;Pour la recherche dans la table &lt;code&gt;rents_wo_overlaps&lt;/code&gt;, il n&amp;rsquo;y a qu&amp;rsquo;un parcours d&amp;rsquo;index :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rents_wo_overlaps_bike_id_rent_dates_key&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ces informations sont visibles dans le fichier &lt;a href=&#34;https://gitlab.com/loxo-articles/without_overlaps/-/raw/main/rents_for_period_some_bikes_range_without_overlaps.txt?ref_type=heads&#34;&gt;rents_for_period_some_bikes_range_exclude.txt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Dans notre exemple avec une clause where &lt;code&gt;bike_id &amp;lt; 100&lt;/code&gt;, le résultat est le suivant :&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Temps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_2_dates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;8 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_exlude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_wo_overlaps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;4 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;En regardant de plus près le plan d&amp;rsquo;exécution, une piste d&amp;rsquo;amélioration sur la requête avec deux dates serait d&amp;rsquo;ajouter un index sur les trois colonnes &lt;code&gt;start_datetime&lt;/code&gt;, &lt;code&gt;end_datetime&lt;/code&gt;, &lt;code&gt;bike_id&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent2dates_start_end_bike_id_idx&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_2_dates&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;btree&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;start_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;end_datetime&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Effectivement le temps d&amp;rsquo;exécution est amélioré, car la requête répond en 1.7ms.
Néanmoins, dans ce cas, l&amp;rsquo;index ajoute un volume de 85Mo.&lt;/p&gt;
&lt;p&gt;Voir le fichier &lt;a href=&#34;https://gitlab.com/loxo-articles/type-range/blob/master/explain_analyse/rents_for_period_some_bikes_2_date_optim.txt&#34;&gt;rents_for_period_some_bikes_2_date_optim.txt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Idem pour la table &lt;code&gt;rents_wo_overlaps&lt;/code&gt; en créant un index GiST (rent_dates, bike_id).&lt;/p&gt;
&lt;p&gt;Voici le plan &lt;a href=&#34;https://gitlab.com/loxo-articles/type-range/blob/master/explain_analyse/rents_for_period_some_bikes_range_wo_overlaps_optim.txt&#34;&gt;d&amp;rsquo;execution&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INDEX&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_wo_overlaps_rents_date_bike_id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;ON&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rents_wo_overlaps&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;USING&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;GiST&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;rent_dates&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;bike_id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Le temps d&amp;rsquo;exécution est de 0.5ms contre 4ms, mais nous rajoutons un index de 112 Mo.&lt;/p&gt;
&lt;p&gt;Après l&amp;rsquo;ajout des index, nous avons les temps suivants :&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Temps&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_2_dates&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;1.7 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_exlude&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.7 ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;rents_wo_overlaps&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;0.5ms&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;La gestion des chevauchements temporels est un sujet qui peut devenir un vrai casse-tête lorsqu’il s’agit de modéliser des réservations, des plannings ou des périodes de validité.
Le type range facilite la manipulation des données.&lt;/p&gt;
&lt;p&gt;Il apporte notamment un avantage indéniable : le contrôle de l&amp;rsquo;intégrité des données, entièrement géré par la base de données.
Même si l&amp;rsquo;utilisation du type &lt;code&gt;TSTZRANGE&lt;/code&gt; ne semble pas naturelle de prime abord,
nous pouvons observer qu&amp;rsquo;une fois mis en place, ce type et les index &lt;code&gt;GiST&lt;/code&gt; proposent un ensemble concis et élégant à l&amp;rsquo;utilisation.&lt;/p&gt;
&lt;p&gt;La nouvelle fonctionnalité &lt;code&gt;WITHOUT OVERLAPS&lt;/code&gt; apporte une écriture simplifiée mais impose que la contrainte de non-chevauchement se trouve sur la dernière colonne.
Dans notre cas, nous avons dû créer un autre index composite avec une meilleure sélectivité sur les premières colonnes.&lt;/p&gt;
&lt;p&gt;En ce qui concerne les tests de performance en insertion, l&amp;rsquo;avantage est en faveur du type range. La contrainte d&amp;rsquo;exclusion étant intégrée, elle rend l&amp;rsquo;opération 2,4 fois plus rapide.&lt;/p&gt;
&lt;p&gt;Le volume sur disque d&amp;rsquo;un index GiST est deux à trois fois plus volumineux que la somme des trois index Btree de notre exemple.&lt;/p&gt;
&lt;p&gt;Pour l&amp;rsquo;exécution des requêtes, nous avons testé deux profils de requête : un complexe (CTE, jointure, etc.) et un plus simple (un &lt;code&gt;WHERE&lt;/code&gt; dans la table de location).
On se rend compte qu&amp;rsquo;il n&amp;rsquo;y a pas de grandes différences sur les temps d&amp;rsquo;exécution.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Meetups PostgreSQL à Toulouse : c&#39;est reparti !</title>
      <link>http://www.loxodata.com/post/meetup-toulouse-2025-10/</link>
      <pubDate>Fri, 10 Oct 2025 15:11:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/meetup-toulouse-2025-10/</guid>
      <description>&lt;h2 id=&#34;meetup-pg_ctl-restart--d-toulouse&#34;&gt;Meetup &lt;code&gt;pg_ctl restart -D Toulouse&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;Par le passé, des meetups PostgreSQL ont eu lieu à Toulouse.
L&amp;rsquo;initiative s&amp;rsquo;est essoufflée et la pandémie est passée par là.&lt;/p&gt;
&lt;p&gt;Mais
en novembre 2025, au &lt;a href=&#34;../feedback-cdl-2024&#34;&gt;Capitole du Libre&lt;/a&gt;,
Geoffrey de &lt;a href=&#34;https://pictarine.com&#34;&gt;Pictarine&lt;/a&gt; est venu vers moi après
une conférence en évoquant la possibilité de relancer cette
initiative. J&amp;rsquo;ai dit « banco! ».&lt;/p&gt;
&lt;p&gt;En juin, Pictarine nous donnait son
feu vert pour effectuer cette rencontre dans leurs locaux à Labège
Innopole, et nous nous sommes lancés dans l&amp;rsquo;organisation de
l&amp;rsquo;événement.&lt;/p&gt;
&lt;p&gt;Pour cela, nous avions, Geoffrey et moi, chacun un sujet :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Geoffrey a proposé une présentation de la migration de 10 années de
business de Datastore vers PostgreSQL. Il y explique les enjeux,
la stratégie et les enseignements de cet exercice qui fut un succès
pour Pictarine ;&lt;/li&gt;
&lt;li&gt;Pour ma part, j&amp;rsquo;ai présenté les grandes nouveautés de PostgreSQL
18 (dont le support peut être &lt;a href=&#34;http://www.loxodata.com/downloads/slides/2025-10-09-Quoi-de-neuf-dans-postgresql-18.pdf&#34;&gt;téléchargé
ici&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Pour une reprise, c&amp;rsquo;est une réussite : 22 fans de PostgreSQL ont
participé à l&amp;rsquo;événement !&lt;/p&gt;
&lt;p&gt;Après une brève
&lt;a href=&#34;http://www.loxodata.com/downloads/slides/2025-10-09-meetup-tls-intro.pdf&#34;&gt;introduction&lt;/a&gt; sur
le déroulement du meetup, Geoffrey avons enchaîné nos présentations.
La soirée s&amp;rsquo;est terminée par un apéritif dînatoire avec des
discussions sur l&amp;rsquo;utilisation de notre SGBD préféré. Nous avons
également parlé de pouvoir participer au &lt;a href=&#34;https://devfesttoulouse.fr/&#34;&gt;DevFest
Toulouse&lt;/a&gt; cette année. De nombreuses
connexions se sont créées lors de cet événement.&lt;/p&gt;
&lt;p&gt;Je tiens à remercier encore une fois Pictarine d&amp;rsquo;avoir rendu ce
meetup possible en nous proposant ses locaux et en sponsorisant
l&amp;rsquo;apéritif dînatoire.&lt;/p&gt;
&lt;p&gt;Nous nous sommes entendus pour organiser le prochain meetup dans le
courant du mois de janvier 2026.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Restauration Point-In-Time d’un cluster Patroni avec pgBackRest</title>
      <link>http://www.loxodata.com/post/pitr-with-patroni/</link>
      <pubDate>Thu, 02 Oct 2025 08:00:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/pitr-with-patroni/</guid>
      <description>&lt;h1 id=&#34;restauration-point-in-time-dun-cluster-patroni-avec-pgbackrest&#34;&gt;Restauration Point-In-Time d’un cluster Patroni avec pgBackRest&lt;/h1&gt;
&lt;p&gt;Dans un &lt;a href=&#34;../logical-replication-with-patroni/&#34;&gt;article précédent&lt;/a&gt;, nous avons vu comment mettre en place une réplication logique avec &lt;strong&gt;Patroni&lt;/strong&gt;. Nous allons voir les méthodes de  &lt;strong&gt;restauration à un instant donné&lt;/strong&gt; (PITR - Point-In-Time Recovery) avec ce même outil.&lt;/p&gt;
&lt;p&gt;Grâce à l’intégration de &lt;strong&gt;pgBackRest&lt;/strong&gt; et &lt;strong&gt;Patroni&lt;/strong&gt;, il est possible de reconstruire proprement un cluster en cas de suppression ou corruption de données — tout en remontant précisément à une date ou une transaction cible.&lt;/p&gt;
&lt;h2 id=&#34;prérequis-pour-la-restauration-pitr&#34;&gt;Prérequis pour la restauration PITR&lt;/h2&gt;
&lt;p&gt;Avant toute tentative de restauration temporelle, assurez-vous que :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pgBackRest est correctement configuré&lt;/strong&gt; ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;L’archivage des WAL est activé&lt;/strong&gt; ;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Au moins une sauvegarde complète est disponible&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&#34;mise-en-situation--suppression-de-données&#34;&gt;Mise en situation : suppression de données&lt;/h2&gt;
&lt;p&gt;Créons une base de test et insérons quelques lignes dans une table :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DATABASE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pitr_test&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;err&#34;&gt;\&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;c&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pitr_test&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;CREATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TABLE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;INT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;TEXT&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inserted_at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;TIMESTAMP&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;DEFAULT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;);&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INSERT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;INTO&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;text_&amp;#39;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;||&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;generate_series&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Résultat :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; id | payload |        inserted_at
----+---------+---------------------------
  0 | text_0  | 2025-07-21 09:14:15.78179
...
 10 | text_10 | 2025-07-21 09:14:15.78179
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;La transaction d’insertion est identifiable via le champ &lt;code&gt;xmin&lt;/code&gt; :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmin&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;xmax&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;FROM&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt; xmin | xmax | id | payload | inserted_at
------+-------+----+---------+----------------------------
  752 |     0 |  0 | text_0  | 2025-07-21 09:14:15.78179
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Supposons qu’une action destructive intervienne :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;TRUNCATE&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;On force ensuite l&amp;rsquo;écriture des journaux de transaction pour garantir leur archivage :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_switch_wal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;SELECT&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;now&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h2 id=&#34;étapes-de-restauration&#34;&gt;Étapes de restauration&lt;/h2&gt;
&lt;p&gt;Nous vous proposons deux méthodes afin de restaurer vos instances à la cible
voulue.&lt;/p&gt;
&lt;h3 id=&#34;méthode-1--restauration-manuelle-du-primaire&#34;&gt;Méthode 1 : restauration manuelle du primaire&lt;/h3&gt;
&lt;h4 id=&#34;1-identifier-le-nœud-primaire&#34;&gt;1. Identifier le nœud primaire&lt;/h4&gt;
&lt;p&gt;Dans notre exemple, le primaire est &lt;code&gt;pgdeb01&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml topology
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cluster: loxodemo &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7427142939826752414&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; ------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Host        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Role    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; State     &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; TL &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Lag in MB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgdeb01   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.11 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Leader  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; running   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;           &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb02 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.12 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb03 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.13 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;3&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;2-stopper-patroni-sur-les-réplicas&#34;&gt;2. Stopper Patroni sur les réplicas&lt;/h4&gt;
&lt;p&gt;Dans notre exemple, sur &lt;code&gt;pgdeb02&lt;/code&gt; et &lt;code&gt;pgdeb03&lt;/code&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl stop patroni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;3-stopper-patroni-sur-le-primaire&#34;&gt;3. Stopper Patroni sur le primaire&lt;/h4&gt;
&lt;p&gt;Une fois arrêté, le cluster doit apparaître vide :&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml topology
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cluster: loxodemo &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7427142939826752414&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; ------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Host &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Role &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; State &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; TL &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Lag in MB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+--------+------+------+-------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+--------+------+------+-------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;4-restaurer-les-données-sur-le-futur-primaire&#34;&gt;4. Restaurer les données sur le futur primaire&lt;/h4&gt;
&lt;p&gt;On peut choisir n&amp;rsquo;importe quel nœud du cluster patroni pour effectuer cette opération.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pgbackrest --stanza&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;loxodemo --delta restore &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --type&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;time&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --target&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;2025-07-21 09:14:16.78179+00&amp;#34;&lt;/span&gt; &lt;span class=&#34;se&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;se&#34;&gt;&lt;/span&gt;  --target-action&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;promote
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;5-lancer-postgresql-localement-sans-patroni&#34;&gt;5. Lancer PostgreSQL localement (sans Patroni)&lt;/h4&gt;
&lt;p&gt;Cette opération s&amp;rsquo;effectue toujours sur le futur primaire.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;su - postgres -c &lt;span class=&#34;s2&#34;&gt;&amp;#34;/usr/lib/postgresql/16/bin/postgres -D /data/postgres/loxodemo ...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;6-vérifier-les-logs-de-postgresql&#34;&gt;6. Vérifier les logs de PostgreSQL&lt;/h4&gt;
&lt;p&gt;Extrait typique indiquant la fin de la restauration :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;recovery stopping before commit of transaction 753
last completed transaction was at log time 2025-07-21 09:14:15.792863+00
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;7-vérifier-les-données-restaurées&#34;&gt;7. Vérifier les données restaurées&lt;/h4&gt;
&lt;p&gt;Dans un autre terminal, lancez &lt;code&gt;psql&lt;/code&gt; sur la base à vérifier.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;pitr_test&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=#&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;*&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;from&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;mytable&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;payload&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;        &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;inserted_at&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;----+---------+---------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_1&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_2&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_3&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_4&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_5&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_6&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_7&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_8&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_9&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;  &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;text_10&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;o&#34;&gt;|&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2025&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;07&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;-&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;21&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;09&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;14&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;15&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;78179&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;11&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;k&#34;&gt;rows&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les données insérées à &lt;code&gt;09:14:15&lt;/code&gt; sont bien présentes, la suppression ayant eu lieu après.&lt;/p&gt;
&lt;p&gt;Forcer l’écriture des journaux de transaction.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-sql&#34; data-lang=&#34;sql&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;k&#34;&gt;select&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_switch_wal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;();&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;n&#34;&gt;pg_switch_wal&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;w&#34;&gt;&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;---------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;w&#34;&gt; &lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;100072&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D0&lt;/span&gt;&lt;span class=&#34;w&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;8-stopper-postgresql-localement&#34;&gt;8. Stopper PostgreSQL localement&lt;/h4&gt;
&lt;h4 id=&#34;9-redémarrer-patroni-sur-le-primaire-choisi&#34;&gt;9. Redémarrer Patroni sur le primaire choisi&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start patroni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;10-vérifier-la-promotion&#34;&gt;10. Vérifier la promotion&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml topology
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cluster: loxodemo &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7427142939826752414&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; -+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Host        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Role   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; State   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; TL &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Lag in MB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+---------+-------------+--------+---------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgdeb01 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.11 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Leader &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; running &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;           &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+---------+-------------+--------+---------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;11-redémarrer-patroni-sur-chaque-réplica&#34;&gt;11. Redémarrer Patroni sur chaque réplica&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start patroni
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml topology
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cluster: loxodemo &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7427142939826752414&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; ------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Host        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Role    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; State     &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; TL &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Lag in MB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgdeb01   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.11 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Leader  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; running   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;           &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb02 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.12 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb03 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.13 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;5&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;h3 id=&#34;méthode-2--bootstrap-du-cluster-avec-patroni&#34;&gt;Méthode 2 : Bootstrap du cluster avec Patroni&lt;/h3&gt;
&lt;p&gt;Cette méthode est plus lourde, mais parfois nécessaire (ex. : restauration complète ou scriptée).&lt;/p&gt;
&lt;h4 id=&#34;1-connectez-vous-sur-une-des-machines-qui-sera-le-futur-primaire&#34;&gt;1. Connectez-vous sur une des machines qui sera le futur primaire.&lt;/h4&gt;
&lt;h4 id=&#34;2-supprimer-ou-déplacer-le-répertoire-de-données-de-postgresql&#34;&gt;2. Supprimer ou déplacer le répertoire de données de PostgreSQL&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;rm -rf /data/postgres/loxodemo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;ou&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;mv /data/postgres/loxodemo /data/postgres/loxodemo_archive
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;3-supprimer-le-cluster-dans-etcd&#34;&gt;3. Supprimer le cluster dans Etcd&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml remove loxodemo
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Confirmation obligatoire :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;Please confirm the cluster name to remove: loxodemo
You are about to remove all information ... please type: &amp;#34;Yes I am aware&amp;#34;: Yes I am aware
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;4-modifier-la-configuration-de-patroni&#34;&gt;4. Modifier la configuration de Patroni&lt;/h4&gt;
&lt;p&gt;Ajoutez à la section &lt;code&gt;bootstrap&lt;/code&gt; :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;bootstrap:
  method: pgbackrest
  pgbackrest:
    command: &amp;#39;/usr/bin/pgbackrest --stanza=loxodemo --delta restore&amp;#39;
    keep_existing_recovery_conf: false
    no_params: true
    recovery_conf:
      recovery_target_action: promote
      recovery_target_time: &amp;#34;2025-07-21 09:14:16.78179+00&amp;#34;
      restore_command: pgbackrest --stanza=loxodemo archive-get %f %p
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;5-redémarrer-patroni-sur-le-futur-primaire&#34;&gt;5. Redémarrer Patroni sur le futur primaire&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start patroni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Les logs doivent indiquer la séquence de bootstrap :&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;2025-07-21 12:59:23 INFO: Selected new etcd server http://10.200.0.12:2379
2025-07-21 12:59:23 INFO: No PostgreSQL configuration items changed, nothing to reload.
2025-07-21 12:59:23 INFO: Lock owner: None; I am pgdeb01
2025-07-21 12:59:23 INFO: trying to bootstrap a new cluster
2025-07-21 12:59:23 INFO: Running custom bootstrap script: /usr/bin/pgbackrest --stanza=loxodemo restore
2025-07-21 12:59:24 INFO: Lock owner: None; I am pgdeb01
2025-07-21 12:59:24 INFO: not healthy enough for leader race
2025-07-21 12:59:24 INFO: bootstrap in progress
2025-07-21 12:59:25 INFO: Lock owner: None; I am pgdeb01
2025-07-21 12:59:25 INFO: not healthy enough for leader race
2025-07-21 12:59:25 INFO: bootstrap in progress
2025-07-21 12:59:26 INFO: Lock owner: None; I am pgdeb01
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Forcer l’écriture des journaux de transaction et par conséquent l’archivage.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-sql=&#34; data-lang=&#34;sql=&#34;&gt;select * from pg_switch_wal();
 pg_switch_wal
---------------
 0/9004A00
(1 row)
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id=&#34;6-redémarrer-patroni-sur-chaque-réplica&#34;&gt;6. Redémarrer Patroni sur chaque réplica&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;systemctl start patroni
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Contrôler l&amp;rsquo;état du cluster:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;patronictl -c /etc/patroni/config.yml topology
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+ Cluster: loxodemo &lt;span class=&#34;o&#34;&gt;(&lt;/span&gt;7427142939826752414&lt;span class=&#34;o&#34;&gt;)&lt;/span&gt; ------+-----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Member    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Host        &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Role    &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; State     &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  TL &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Lag in MB &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+-----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; pgdeb01   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.11 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Leader  &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; running   &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;           &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb02 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.12 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; + pgdeb03 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; 10.200.0.13 &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; Replica &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; streaming &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;  &lt;span class=&#34;m&#34;&gt;10&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;         &lt;span class=&#34;m&#34;&gt;0&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;+-----------+-------------+---------+-----------+-----+-----------+
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;quelle-méthode-choisir-&#34;&gt;Quelle méthode choisir ?&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Méthode&lt;/th&gt;
&lt;th&gt;Avantages&lt;/th&gt;
&lt;th&gt;Inconvénients&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Manuelle (&amp;ndash;delta)&lt;/td&gt;
&lt;td&gt;Restauration plus rapide, plus granulaire&lt;/td&gt;
&lt;td&gt;Plus de manipulation manuelle&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bootstrap Patroni&lt;/td&gt;
&lt;td&gt;Automatisable, plus propre dans certains cas&lt;/td&gt;
&lt;td&gt;Plus long, pas de restauration delta&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Grâce à &lt;strong&gt;pgBackRest&lt;/strong&gt; et &lt;strong&gt;Patroni&lt;/strong&gt;, il est possible de restaurer un cluster PostgreSQL à un instant précis, que ce soit pour corriger une erreur humaine ou revenir à un état stable après une défaillance. Selon les besoins (rapidité vs réinitialisation complète), l’une ou l’autre des méthodes peut être utilisée efficacement.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>PostgreSQL 18</title>
      <link>http://www.loxodata.com/post/postgresql-18/</link>
      <pubDate>Mon, 29 Sep 2025 10:45:00 +0200</pubDate>
      
      <guid>http://www.loxodata.com/post/postgresql-18/</guid>
      <description>&lt;h1 id=&#34;sortie-de-postgresql-18&#34;&gt;Sortie de PostgreSQL 18&lt;/h1&gt;
&lt;p&gt;Le &lt;a href=&#34;https://www.postgresql.org&#34;&gt;PostgreSQL Global Development Group&lt;/a&gt; a annoncé
le 25 septembre 2025 la publication de &lt;a href=&#34;https://www.postgresql.org/docs/18/release-18.html&#34;&gt;PostgreSQL 18&lt;/a&gt;,
dernière version de la base de données open source de référence.&lt;/p&gt;
&lt;p&gt;Vous pouvez retrouver la &lt;a href=&#34;https://www.postgresql.org/about/news/postgresql-18-released-3142/&#34;&gt;note de sortie de PostgreSQL 18&lt;/a&gt;
sur le site officiel, ainsi que les dossiers de presse, dont celui traduit &lt;a href=&#34;https://www.postgresql.org/about/press/presskit18/fr/&#34;&gt;en français&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;les-nouveautés&#34;&gt;Les nouveautés&lt;/h2&gt;
&lt;p&gt;Plutôt que de passer en revue tous les éléments de la note de sortie, on peut
rappeler les nouveautés qu&amp;rsquo;apporte cette version 18 de PostgreSQL dont la
maintenance nous amènera jusqu&amp;rsquo;en 2030.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;La fonctionnalité la plus attendue est la prise en charge des entrées/sorties
asynchrones. Cette dernière permet d&amp;rsquo;améliorer certains types de lecture et des
tâches de maintenance comme le &lt;code&gt;vacuum&lt;/code&gt;. Le nouveau paramètre &lt;a href=&#34;https://www.postgresql.org/docs/18/runtime-config-resource.html#GUC-IO-METHOD&#34;&gt;io_method&lt;/a&gt;
permet de configurer la méthode utilisée.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L&amp;rsquo;introduction des recherches &lt;a href=&#34;https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=92fe23d93aa3bbbc40fca669cabc4a4d7975e327&#34;&gt;skip scan&lt;/a&gt;
sur les &lt;a href=&#34;https://www.postgresql.org/docs/18/indexes-multicolumn.html&#34;&gt;index B-tree multicolonnes&lt;/a&gt;
afin d&amp;rsquo;améliorer les temps d&amp;rsquo;exécution pour les requêtes qui omettent une
condition &lt;code&gt;=&lt;/code&gt; sur une ou plusieurs colonnes préfixes de l&amp;rsquo;index.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;La conservation des statistiques utilisées par le planificateur lors des mises
à jour majeur avec &lt;a href=&#34;https://www.postgresql.org/docs/18/pgupgrade.html&#34;&gt;pg_upgrade&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L&amp;rsquo;ajout de la fonction &lt;a href=&#34;https://www.postgresql.org/docs/18/functions-uuid.html#FUNC_UUID_GEN_TABLE&#34;&gt;uuidv7()&lt;/a&gt;
pour générer des UUIDs aléatoire ordonnées dans le temps, ou l&amp;rsquo;ajout de &lt;a href=&#34;https://www.postgresql.org/docs/18/sql-createtable.html#SQL-CREATETABLE-PARMS-UNIQUE&#34;&gt;contraintes
temporelles&lt;/a&gt;
ou sur intervalles sur les contraintes &lt;code&gt;PRIMARY KEY&lt;/code&gt;, &lt;code&gt;UNIQUE&lt;/code&gt; et &lt;code&gt;FOREIGN KEY&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;L&amp;rsquo;ajout des variables &lt;code&gt;OLD&lt;/code&gt; et &lt;code&gt;NEW&lt;/code&gt; dans les clauses &lt;a href=&#34;https://www.postgresql.org/docs/18/dml-returning.html&#34;&gt;RETURNING&lt;/a&gt;
pour les ordres de modifications SQL (&lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt;, &lt;code&gt;DELETE&lt;/code&gt;, and &lt;code&gt;MERGE&lt;/code&gt;).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Les &lt;a href=&#34;https://www.postgresql.org/docs/18/sql-createtable.html#SQL-CREATETABLE-PARMS-GENERATED-STORED&#34;&gt;colonnes générées virtuelles&lt;/a&gt;
qui permettent de calculer à la volée les valeurs et ne plus les stocker, et
devient le comportement par défaut pour les colonnes générées.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Concernant la réplication logique, l&amp;rsquo;application des transactions par des flux
parallèles par défaut (&lt;a href=&#34;https://www.postgresql.org/docs/18/sql-createsubscription.html&#34;&gt;CREATE SUBSCRIPTION&lt;/a&gt;
et le paramètre &lt;code&gt;streaming&lt;/code&gt;), la suppression des slots de réplication inactifs,
la journalisation des conflits en écriture et l&amp;rsquo;ajout d&amp;rsquo;un nouveau paramètre &lt;code&gt;--all&lt;/code&gt;
dans l&amp;rsquo;utilitaire &lt;a href=&#34;https://www.postgresql.org/docs/18/app-pgcreatesubscriber.html&#34;&gt;pg_createsubcriber&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Le support du framework d&amp;rsquo;authentification &lt;a href=&#34;https://www.postgresql.org/docs/18/auth-oauth.html&#34;&gt;OAuth 2.0&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Crédits photo Richard Jacobs.&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
