

   Une extension à PostgreSQL utile contient généralement
   plusieurs objets SQL. Par exemple, un nouveau type de données va nécessiter de
   nouvelles fonctions, de nouveaux opérateurs et probablement de nouvelles méthodes
   d'indexation.
   Il peut être utile de les grouper en un unique paquetage pour simplifier la gestion
   des bases de données. Avec PostgreSQL, ces paquetages sont
   appelés extension. Pour créer une extension, vous avez besoin
   au minimum d'un fichier de script qui contient les commandes
   SQL permettant de créer ses objets, et un
   fichier de contrôle qui rapporte quelques propriétés de base
   de cette extension. Si cette extension inclut du code C, elle sera aussi généralement
   accompagnée d'une bibliothèque dans lequel le code C aura été compilé.
   Une fois ces fichiers en votre possession, un simple appel à la commande
   CREATE EXTENSION vous permettra de charger ses objets dans la base
   de données.
  
   Le principal avantage des extensions n'est toutefois pas de pouvoir de charger une
   grande quantité d'objets dans votre base de donnée. Les extensions permettent en effet
   surtout à PostgreSQL de comprendre que ces objets sont liés par cette
   extension. Vous pouvez par exemple supprimer tous ces objets avec une simple commande
   DROP EXTENSION. Il n'est
   ainsi pas nécessaire de maintenir un script de
   « désinstallation ».
   Plus utile encore, l'outil pg_dump saura reconnaître les objets
   appartenant à une extension et, plutôt que de les extraire individuellement, ajoutera simplement
   une commande CREATE EXTENSION à la sauvegarde.
   Ce mécanisme simplifie aussi la migration à une nouvelle version de l'extension
   qui peut contenir de nouveaux objets ou des objets différents de la version d'origine.
   Notez bien toutefois qu'il est nécessaire de disposer des fichiers de contrôles, de script,
   et autres pour permettre la restauration d'une telle sauvegarde dans une nouvelle base
   de donnée.
  
   PostgreSQL ne vous laissera pas supprimer
   de manière individuelle les objets d'une extension sans supprimer
   l'extension tout entière.
   Aussi, bien que vous ayez la possibilité de modifier la définition d'un objet inclus dans
   une extension (par exemple via la commande CREATE OR REPLACE FUNCTION dans
   le cas d'une fonction), il faut garder en tête que cette modification ne sera pas sauvegardée
   par l'outil pg_dump. Une telle modification n'est en pratique raisonnable
   que si vous modifiez parallèlement le fichier de script de l'extension. Il existe toutefois des
   cas particuliers comme celui des tables qui contiennent des données de
   configuration (voir Section 36.17.3.)
   Dans les situations de production, il est généralement préférable de créer
   un script de mise à jour de l'extension pour réaliser les modifications sur
   les objets membres de l'extension.
  
   Le script de l'extension peut mettre en place des droits sur les objets qui
   font partie de l'extension via les instructions GRANT et
   REVOKE. La configuration finale des droits pour chaque
   objet (si des droits sont à configurer) sera enregistrée dans le catalogue
   système pg_init_privs.
   Quand pg_dump est utilisé, la commande
   CREATE EXTENSION sera inclue dans la sauvegarde, suivi
   de la mise en place des instructions GRANT et
   REVOKE pour configurer les droits sur les objets, tels
   qu'ils étaient au moment où la sauvegarde a été faite.
  
   PostgreSQL ne supporte pas l'exécution
   d'instructions CREATE POLICY et SECURITY
    LABEL par le script. Elles doivent être exécutées après la
   création de l'extension. Toutes les politiques RLS et les labels de
   sécurité placés sur les objets d'une extension seront inclus dans les
   sauvegardes créées par pg_dump.
  
   Il existe aussi un mécanisme permettant de créer des scripts de mise à jour de la définition des objets
   SQL contenus dans une extension.
   Par exemple, si la version 1.1 d'une extension ajoute une fonction et change le corps d'une autre
   vis-à-vis de la version 1.0 d'origine, l'auteur de l'extension peut fournir un script
    de mise à jour qui effectue uniquement ces deux modifications. La commande 
    ALTER EXTENSION UPDATE peut alors être utilisée pour appliquer ces changements et vérifier
   quelle version de l'extension est actuellement installée sur une base de donnée spécifiée.
  
   Les catégories d'objets SQL qui peuvent être inclus dans une extension
   sont spécifiées dans la description de la commande ALTER EXTENSION.
   D'une manière générale, les objets qui sont communs à l'ensemble de la base ou du cluster,
   comme les bases de données, les rôles, les tablespaces ne peuvent être inclus dans une
   extension car une extension n'est référencée qu'à l'intérieur d'une base de donnée.
   À noter que rien n'empêche la création de fichier de script qui crée de tels objets, mais
   qu'ils ne seront alors pas considérés après leur création comme faisant partie de l'extension.
   À savoir en outre que bien que les tables puissent être incluses dans une extension, les objets
   annexes tels que les index ne sont pas automatiquement inclus dans l'extension et devront être
   explicitement mentionnés dans les fichiers de script.
  
Si un script d'extension créé n'importe quel objet temporaire (comme des tables temporaires), ces objets seront traités comme des membres de l'extension pour le reste de la session courante, mais seront automatiquement supprimés à la fin de la session, tout comme n'importe quel objet temporaire le serait également. C'est une exception à la règle que les objets membres d'une extension ne peuvent pas être supprimés sans supprimer l'intégralité de l'extension.
    La commande CREATE EXTENSION repose sur un fichier de contrôle
    associé à chaque extension. Ce fichier doit avoir le même nom que l'extension suivi du suffixe
    .control, et doit être placé dans le sous-répertoire SHAREDIR/extension
    du répertoire d'installation. Il doit être accompagné d'au moins un fichier de script SQL
    dont le nom doit répondre à la syntaxe extension--version.sqlfoo--1.0.sql pour la version 1.0 de l'extension foo).
    Par défaut, les fichiers de script sont eux-aussi situés dans le répertoire SHAREDIR/extension. Le fichier
    de contrôle peut toutefois spécifier un répertoire différent pour chaque fichier de script.
   
Des emplacements supplémentaires pour les fichiers de contrôle d'extension peuvent être configurés à l'aide du paramètre extension_control_path.
    Le format du fichier de contrôle d'une extension est le même que pour le
    fichier postgresql.conf, à savoir une liste d'affectation
    nom_paramètre = valeur
    avec un maximum d'une affectation par ligne.
    Les lignes vides et les commentaires introduits par # sont eux-aussi autorisés.
    Prenez garde à placer entre guillemets les valeurs qui ne sont ni des nombres ni des mots isolés.
   
Un fichier de contrôle peut définir les paramètres suivants :
directory (string) #Le répertoire qui inclut les scripts SQL de l'extension. Si un chemin relatif est spécifié, le nom est relatif au répertoire où le fichier de contrôle a été trouvé. Par défaut, les scripts sont recherchés dans le même répertoire que celui où le fichier de contrôle a été trouvé.
default_version (string) #
       La version par défaut de l'extension, qui sera installée si aucune
       version n'est spécifiée avec la commande CREATE EXTENSION.
       Ainsi, bien que ce paramètre puisse ne pas être précisé, il reste
       recommandé de le définir pour éviter que la commande
       CREATE EXTENSION ne provoque une erreur
       en l'absence de l'option VERSION.
      
comment (string) #Un commentaire de type chaîne de caractère au sujet de l'extension. Le commentaire est appliqué à la création de l'extension, mais pas pendant les mises à jour de cette extension (car cela pourrait écraser des commentaires ajoutés par l'utilisateur). Une alternative consiste à utiliser la commande COMMENT dans le script de l'extension.
encoding (string) #L'encodage des caractères utilisé par les fichiers de script. Ce paramètre doit être spécifié si les fichiers de script contiennent des caractères non ASCII. Le comportement par défaut en l'absence de ce paramètre consiste à utiliser l'encodage de la base de donnée.
module_pathname (string) #
       La valeur de ce paramètre sera utilisée pour toute référence à MODULE_PATHNAME
       dans les fichiers de script. Si ce paramètre n'est pas défini, la substitution ne sera pas effectuée.
       La valeur nom_de_bibliothèqueMODULE_PATHNAME est utilisé dans la commande CREATE
        FUNCTION concernant les fonctions en langage C, de manière à ne pas mentionner « en dur »
       le nom de la bibliothèque partagée.
      
requires (string) #
       Une liste de noms d'extension dont dépend cette extension, comme
       par exemple requires = 'foo, bar'.  Ces extensions
       doivent être installées avant que l'extension puisse être installée.
      
no_relocate (string) #
       Une liste de noms d'extensions dont dépend cette extension et qui
       doivent être empêchées de changer de schéma via ALTER
       EXTENSION ... SET SCHEMA.
       Ceci est nécessaire si le script de l'extension fait référence au nom du
       schéma d'une extension requise (en utilisant
       la syntaxe @extschema:)
       d'une façon qui ne permet de tracer les renommages.
      nom@
superuser (boolean) #
       Si ce paramètre est à true (il s'agit de la valeur par défaut),
       seuls les superutilisateurs pourront créer cet extension ou la mettre à jour.
       Si ce paramètre est à false, seuls les droits nécessaires
       seront requis pour installer ou mettre à jour l'extension.
       Ce paramètre devrait normalement être mis à true si au moins
       une commandes du script nécessite les privilèges superuser. (Ces commandes
       échoueront en tous cas, mais il est plus convivial de fournir une erreur en amont.)
      
trusted (boolean) #
       Ce paramètre, si mis à true (qui n'est pas le défaut),
       permet à des utilisateurs standards, sans attribut SUPERUSER,
       d'installer une extension qui a
       superuser affecté à true.
       Plus précisemment, l'installation sera permise pour toute personne
       qui a le droit CREATE sur la base courante.
       Si l'utilisateur qui exécute CREATE EXTENSION n'est
       pas superutilisateur mais est autorisé à installer de part ce paramètre, alors
       le script d'installation ou de mise à jour est exécuté comme bootstrap
       superutilisateur, et non pas comme l'utilisateur appelant.
       Ce paramètre n'as pas d'effet si superuser est
       false.
       En général, le paramètre ne doit pas être mis à true pour
       les extensions qui peuvent autoriser des accès aux capacités réservées aux
       superutilisateurs, telles que les accès au système de fichiers.
      
relocatable (boolean) #
       Une extension est dite « déplaçable » (relocatable)
       s'il est possible de déplacer les objets qu'elle contient dans un schéma différent
       de celui attribué initialement par l'extension. La valeur par défaut est à
       false, ce qui signifie que l'extension n'est pas déplaçable.
       Voir Section 36.17.2 pour des
       informations complémentaires.
      
schema (string) #
       Ce paramètre ne peut être spécifié que pour les extensions non
       déplaçables. Il permet de forcer l'extension à charger ses objets dans
       le schéma spécifié et aucun autre. Le paramètre
       schema est uniquement consulté lors de la création
       initiale de l'extension, pas pendant ses mises à jour. Voir Section 36.17.2 pour plus d'informations.
      
    En complément au fichier de contrôle extension.controlextension--version.controldirectory et
    default_version dans un fichier de contrôle secondaire.
   
    Un fichier de script SQL d'une extension peut contenir toute commande
    SQL, à l'exception des commandes de contrôle de transaction (BEGIN,
    COMMIT, etc), et des commandes qui ne peuvent être exécutées au sein
    d'un bloc transactionnel (comme la commande VACUUM). Cette contrainte
    est liée au fait que les fichiers de script sont implicitement exécutés dans une transaction.
   
    Les scripts SQL d'une extension peuvent aussi contenir
    des lignes commençant par \echo, qui seront ignorées
    (traitées comme des commentaires) par le mécanisme d'extension. Ceci est
    souvent utilisé pour renvoyer une erreur si le script est passé à
    psql plutôt qu'exécuter par CREATE
     EXTENSION (voir un script d'exemple dans Section 36.17.7). Sans cela, les utilisateurs
    pourraient charger accidentellement le contenu de l'extension sous la
    forme d'objets « autonomes » plutôt que faisant partie d'une
    extension, ce qui est assez pénible à corriger.
   
    Si le script d'extension contient la chaine @extowner@,
    celle-ci est remplacé avec le nom (encadré de double apostrophe si nécessaire)
    de l'utilisateur exécutant CREATE
     EXTENSION ou ALTER EXTENSION. Habituellement,
    cette fonctionnalité est employée par les extensions notées de confiance pour
    affecter l'appropriation des objets sélectionnés par l'utilisateur exécutant plutôt
    que par le bootstrap superuser. (Il faut cependant être prudent avec cela. Par
    exemple, affecter à une fonction en langage C un propriétaire non superutilisateur
    ouvre une voie pour une escalade de privilèges à cet utilisateur.)
   
    Bien que les fichiers de script puissent contenir n'importe quel caractère
    autorisé par l'encodage spécifié, les fichiers de contrôle ne peuvent
    contenir que des caractères ASCII non formatés. En effet,
    PostgreSQL ne peut pas déterminer l'encodage
    utilisé par les fichiers de contrôle. Dans la pratique, cela ne pose
    problème que dans le cas où vous voudriez utiliser des caractères non
    ASCII dans le commentaire de l'extension. Dans ce cas de figure, il est
    recommandé de ne pas utiliser le paramètre comment du
    fichier de contrôle pour définir ce commentaire, mais plutôt la commande
    COMMENT ON EXTENSION dans un fichier de script.
   
Les utilisateurs souhaitent souvent charger les objets d'une extension dans un schéma différent de celui imposé par l'auteur. Trois niveaux de déplacement sont supportés :
      Une extension supportant complétement le déplacement peut être déplacé
      dans un autre schéma à tout moment, y compris après son chargement
      dans une base de donnée.
      Initialement, tous les objets de l'extension installée appartiennent à un
      premier schéma (excepté les objets qui n'appartiennent à aucun schéma comme les
      langages procéduraux).
      L'opération de déplacement peut alors être réalisée avec la commande ALTER EXTENSION SET SCHEMA,
      qui renomme automatiquement tous les objets de l'extension pour être intégrés dans le nouveau
      schéma.  Le déplacement ne sera toutefois fonctionnel
      que si l'extension ne contient aucune référence de l'appartenance d'un de ses objets à un schéma.
      Dans ce cadre, il est alors possible de spécifier qu'une extension supporte complétement le déplacement en initialisant
      relocatable = true dans son fichier de contrôle.
     
      Une extension peut être déplaçable durant l'installation et ne plus l'être
      par la suite. Un exemple courant est celui du fichier de script de l'extension
      qui doit référencer un schéma cible de manière explicite pour des fonctions SQL, par exemple en définissant
      la propriété search_path.
      Pour de telles extensions, il faut définir relocatable = false dans
      son fichier de contrôle, et utiliser @extschema@ pour référencer
      le schéma cible dans le fichier de script. Toutes les occurrences de cette chaîne dans le
      fichier de script seront remplacées par le nom du schéma choisi (entre guillemets doubles
      si nécessaire) avant son exécution.
      Le nom du schéma choisi peut être fixé par l'option SCHEMA de la
      commande CREATE EXTENSION.
     
      Si l'extension ne permet pas du tout le déplacement, il faut définir relocatable = false
      dans le fichier de contrôle, mais aussi définir schema comme étant le nom du schéma cible.
      Cette précaution permettra d'empêcher l'usage de l'option SCHEMA de la commande CREATE
       EXTENSION, à moins que cette option ne référence la même valeur que celle spécifiée dans le fichier de
      contrôle. Ce choix est à priori nécessaire si l'extension contient des références à son nom
      de schéma qui ne peuvent être remplacés par @extschema@. À noter que même si son usage reste
      relativement limité dans ce cas de figure puisque le nom du schéma est alors fixé dans le fichier de contrôle,
      le mécanisme de substitution de @extschema@ reste toujours opérationnel.
     
    Dans tous les cas, le fichier de script sera exécuté avec comme valeur de search_path
    le schéma cible. Cela signifie que la commande CREATE EXTENSION réalisera l'équivalent
    de la commande suivante :
    
SET LOCAL search_path TO @extschema@, pg_temp;
    
    Cela permettra aux objets du fichier de script d'être créés dans le schéma cible. Le fichier de script
    peut toutefois modifier la valeur de search_path si nécessaire, mais cela n'est
    généralement pas le comportement souhaité. La variable search_path retrouvera sa valeur
    initiale à la fin de l'exécution de la commande CREATE EXTENSION.
   
    Le schéma cible est déterminé par le paramètre schema dans le
    fichier de contrôle s'il est précisé, sinon par l'option SCHEMA
    de la commande CREATE EXTENSION si elle est spécifiée, sinon
    par le schéma de création par défaut actuel (le premier rencontré en suivant le
    chemin de recherche search_path de l'appelant). Quand le paramètre
    schema du fichier de contrôle est utilisé, le schéma cible sera créé
    s'il n'existe pas encore. Dans les autres cas, il devra exister au préalable.
   
    Si des extensions requises sont définies par requires dans le fichier
    de contrôle, leur schéma cible est ajouté à la valeur initiale de
    search_path, d'après le schéma cible de la nouvelle
    extension.
    Cela permet à leurs objets d'être visibles dans le fichier de script de l'extension installée.
   
    Pour des raisons de sécurité, pg_temp est ajouté
    automatiquement à la fin de search_path dans tous les
    cas.
   
    Une extension peut contenir des objets répartis dans plusieurs schémas.
    Il est alors conseillé de regrouper dans un unique schéma l'ensemble des objets destinés à un usage
    externe à l'extension, qui sera alors le schéma cible de l'extension. Une telle organisation est compatible
    avec la définition par défaut de search_path pour la création d'extensions
    qui en seront dépendantes.
   
    Si une extension référence des objets appartenant à une autre extension,
    il est recommandé de qualifier ces références avec le nom du schéma.
    Pour faire cela, écrivez @extschema:
    dans le script de l'extension, où nom@nom
    est le nom de l'autre extension (qui doit être listé dans la liste
    requires de cette extension). Cette chaîne sera
    remplacée par le nom (avec guillemets doubles si nécessaire) du schéma
    cible de cette extension. Bien que cette notation évite le besoin de
    coder en dur le nom supposé des schémas dans le script de l'extension,
    son utilisation peut intégrer le nom du schéma de l'autre extension
    dans les objets installés de cette extension. (Typiquement, ceci
    survient quand @extschema:
    est utilisé dans une chaîne constante, telle que le corps d'une fonction
    ou dans le paramétrage du name@search_path. Dans d'autres cas,
    la référence de l'objet est réduite à son OID lors de l'analyse, et ne
    requiert pas de recherche ultérieure.) Si le nom du schéma de l'autre
    extension est très embarquée, vous devez empêcher l'autre extension
    d'être changée de schéma après que la votre ne soit installée, en ajoutant
    le nom de l'autre extension dans votre liste no_relocate.
   
Certaines extensions incluent des tables de configuration, contenant des données qui peuvent être ajoutées ou changées par l'utilisateur après l'installation de l'extension. Normalement, si la table fait partie de l'extension, ni la définition de la table, ni son contenu ne sera sauvegardé par pg_dump. Mais ce comportement n'est pas celui attendu pour une table de configuration. Les données modifiées par un utilisateur nécessitent d'être sauvegardées, ou l'extension aura un comportement différent après rechargement.
    Pour résoudre ce problème, un fichier de script d'extension peut marquer
    une table ou une séquence comme étant une relation de configuration, ce qui indiquera à pg_dump
    d'inclure le contenu de la table ou de la séquence (et non sa définition) dans la sauvegarde. Pour cela, il s'agit d'appeler
    la fonction pg_extension_config_dump(regclass, text) après avoir
    créé la table ou la séquence, par exemple
    
CREATE TABLE my_config (key text, value text);
CREATE SEQUENCE my_config_seq;
SELECT pg_catalog.pg_extension_config_dump('my_config', '');
SELECT pg_catalog.pg_extension_config_dump('my_config_seq', '');
    
    Cette fonction permet de marquer autant de tables ou de séquences
    que nécessaire. Les séquences associées avec des colonnes de type
    serial ou bigserial peuvent être marquées
    ainsi.
   
    Si le second argument de pg_extension_config_dump est une
    chaîne vide, le contenu entier de la table sera sauvegardé par l'application
    pg_dump. Cela n'est correct que si la table
    était initialement vide après l'installation du script. Si un mélange de données
    initiales et de données ajoutées par l'utilisateur est présent dans la table,
    le second argument de pg_extension_config_dump permet de
    spécifier une condition WHERE qui sélectionne les données à
    sauvegarder.
    Par exemple, vous pourriez faire
    
CREATE TABLE my_config (key text, value text, standard_entry boolean);
SELECT pg_catalog.pg_extension_config_dump('my_config', 'WHERE NOT standard_entry');
    
    et vous assurer que la valeur de standard_entry soit
    true uniquement lorsque les lignes ont été créées par le script de l'extension.
   
    Pour les séquences, le deuxième argument de pg_extension_config_dump
    n'a pas d'effet.
   
Des situations plus compliquées, comme des données initiales qui peuvent être modifiées par l'utilisateur, peuvent être prises en charge en créant des triggers sur la table de configuration pour s'assurer que les lignes ont été marquées correctement.
    Vous pouvez modifier la condition du filtre associé avec une table de
    configuration en appelant de nouveau
    pg_extension_config_dump. (Ceci serait typiquement
    utile dans un script de mise à jour d'extension.)  La seule façon de marquer
    une table est de la dissocier de l'extension avec la commande
    ALTER EXTENSION ... DROP TABLE.
   
Notez que les relations de clés étrangères entre ces tables dicteront l'ordre dans lequel les tables seront sauvegardées par pg_dump. Plus spécifiquement, pg_dump tentera de sauvegarder en premier la table référencé, puis la table référante. Comme les relations de clés étrangères sont configurées lors du CREATE EXTENSION (avant que les données ne soient chargées dans les tables), les dépendances circulaires ne sont pas gérées. Quand des dépendances circulaires existent, les données seront toujours sauvegardées mais ne seront pas restaurables directement. Une intervention de l'utilisateur sera nécessaire.
    Les séquences associées avec des colonnes de type serial ou
    bigserial doivent être directement marquées pour sauvegarder
    leur état. Marquer la relation parent n'est pas suffisant pour ça.
   
    Un des avantages du mécanisme d'extension est de proposer un moyen
    simple de gérer la mise à jour des commandes SQL qui définissent les objets
    de l'extension. Cela est rendu possible par l'association d'un nom ou d'un numéro
    de version à chaque nouvelle version du script d'installation de l'extension.
    En complément, si vous voulez qu'un utilisateur soit capable de mettre à jour
    sa base de données dynamiquement d'une version à une autre, vous pouvez
    fournir des scripts de mise à jour qui feront les
    modifications nécessaires. Les scripts de mise à jour ont un nom qui correspond au format
    extension--ancienne_version--nouvelle_version.sqlfoo--1.0--1.1.sql contient les commandes pour modifier
    la version 1.0 de l'extension foo en la version
    1.1).
   
    En admettant qu'un tel script de mise à jour soit disponible, la commande
    ALTER EXTENSION UPDATE mettra à jour une extension installée
    vers la nouvelle version spécifiée. Le script de mise à jour est exécuté dans le
    même environnement que celui que la commande CREATE EXTENSION
    fournit pour l'installation de scripts : en particulier, la variable search_path
    est définie de la même façon et tout nouvel objet créé par le script est automatiquement
    ajouté à l'extension.  De plus, si le script choisit de supprimer des
    objets membres de l'extension, ils sont automatiquement dissociés de
    l'extension.
   
Si une extension a un fichier de contrôle secondaire, les paramètres de contrôle qui sont utilisés par un script de mise à jour sont ceux définis par le script de la version cible.
    La commande ALTER EXTENSION peut exécuter des mises à jour en séquence pour
    réussir une mise à jour. Par exemple, si seuls les fichiers foo--1.0--1.1.sql
    et foo--1.1--2.0.sql sont disponibles, la commande ALTER
     EXTENSION les exécutera séquentiellement si une mise à jour vers la version 2.0
    est demandée alors que la version 1.0 est installée.
   
    PostgreSQL ne suppose rien au sujet des noms de version.
    Par exemple, il ne sait pas si 1.1 suit 1.0.
    Il effectue juste une correspondance entre les noms de version et suit un chemin
    qui nécessite d'appliquer le moins de fichier de script possible.
    Un nom de version peut en réalité être toute chaîne qui ne contiendrait pas
    -- ou qui ne commencerait ou ne finirait pas par -.
   
    Il peut parfois être utile de fournir des scripts de retour en arrière, comme par exemple
    foo--1.1--1.0.sql pour autoriser d'inverser les modifications effectuées
    par la mise à jour en version 1.1. Si vous procédez ainsi, ayez conscience
    de la possibilité laissée à PostgreSQL d'exécuter un tel script de retour
    en arrière s'il permet d'atteindre la version cible d'une mise à jour en un nombre réduit d'étapes.
    La cause du risque se trouve dans les scripts de mise à jour optimisés permettant de passer
    plusieurs versions en un seul script. La longueur du chemin commençant par un retour en
    arrière suivi d'un script optimisé pourrait être inférieure à la longueur du chemin qui monterait
    de version une par une. Si le script de retour en arrière supprime un objet irremplaçable, les conséquences
    pourraient en être facheuses.
   
Pour vérifier que vous ne serez pas confronté à des chemins de mise à jour inattendus, utilisez cette commande :
SELECT * FROM pg_extension_update_paths('extension_name');
    
    Cette commande permet d'afficher chaque paire de noms de version connues pour l'extension spécifiée, ainsi
    que le chemin de mise à jour qui serait suivi depuis la version de départ jusque la version cible, ou la valeur
    NULL si aucun chemin valable n'est disponible. Le chemin est affiché sous une forme textuelle
    avec des séparateurs --. Vous pouvez utiliser regexp_split_to_array(path,'--')
    si vous préférez le format tableau.
   
    Une extension qui a existé un certain temps existera probabement dans
    plusieurs version, pour lesquelles l'auteur devra écrire des scripts de
    mise à jour.  Par exemple, si vous avez sorti une extension
    foo dans les versions 1.0,
    1.1, et 1.2, il devrait exister les
    scripts de mise à jour foo--1.0--1.1.sql et
    foo--1.1--1.2.sql.  Avant
    PostgreSQL 10, il était nécessaire de créer
    également de nouveaux fichiers de scripts
    foo--1.1.sql et foo--1.2.sql qui
    construisent directement les nouvelles versions de l'extension, ou sinon
    les nouvelles version ne pourraient pas être installées directement, mais
    uniquement en installant 1.0 puis en effectuant les
    mises à jour.  C'était fastidieux et source de doublons, mais c'est
    maintenant inutile car CREATE EXTENSION peut suivre les
    chaînes de mise à jour automatiquement.
    Par exemple, si seuls les fichiers de script
    foo--1.0.sql, foo--1.0--1.1.sql,
    et foo--1.1--1.2.sql sont disponibles, alors une demande d'installation
    de la version 1.2 pourra être effectuée en lançant ces
    trois scripts les uns à la suite des autres.  Le traitement est le même
    que si vous aviez d'abord installé 1.0 puis mis à jour
    vers 1.2.  (Comme pour ALTER EXTENSION
     UPDATE, si de multiples chemins sont disponibles alors le plus
    court sera choisi.)  Arranger les fichiers de script d'une extension de
    cette façon peut réduire la quantité nécessaire d'effort de maintenance à
    fournir pour produires de petites mises à jour.
   
    Si vous utilisez des fichiers de contrôle secondaires (spécifique à la
    version) avec une extension maintenant de cette façon, gardez à l'esprit
    que chaque version nécessite un fichier de contrôle même s'il n'y a pas de
    script d'installation spécifique pour cette version, car ce fichier de
    contrôle déterminera comment une mise à jour implicite vers cette version
    est effectuée.  Par exemple, si foo--1.0.control
    spécifie requires = 'bar' mais que l'autre fichier de
    contrôle de foo ne le spécifie pas, la dépendance sur
    l'extension bar sera supprimée lors de la mise à jour de
    1.0 vers une autre version.
   
Les extensions largement distribuées devraient assumer peu sur la base qu'elles occupent. De ce fait, il est adéquat d'écrire des fonctions fournies par une extension dans un style sécurisé qui ne peut pas être compromis par des attaques basées sur le search_path.
    Une extension qui dispose de la propriété superuser
    configurée à true doit aussi considérer les risques de sécurité pour les
    actions effectuées par ses scripts d'installation et de mise à jour. Il
    n'est pas particulièrement compliqué pour un utilisateur mal intentionné
    de créer des objets chevaux de Troie qui compromettront une exécution
    ultérieure d'un script d'extension mal écrit, permettant à son utilisateur
    de gagner les droits d'un superutilisateur.
   
Des conseils sur l'écriture de fonctions sécurisées sont donnés dans Section 36.17.6.1 ci-dessous, et d'autres conseils, sur l'écriture de scripts d'installation sécurisés, sont donnés dans Section 36.17.6.2.
Les fonctions en langage SQL et PL fournies par les extensions peuvent être l'objet d'attaques basées sur le search_path quand elles sont exécutées car l'analyse de ces fonctions survient lors de leur exécution et non pas lors de leur création.
     La page de référence de CREATE
       FUNCTION contient des conseils sur la bonne écriture de
     fonctions SECURITY DEFINER. Il est conseillé
     d'appliquer ces techniques pour toute fonction fournie par une extension
     car la fonction pourrait être appelée par un utilisateur avec des droits
     importants.
    
     Si vous ne pouvez pas configurer le search_path pour
     contenir seulement les schémas sécurisés, supposez que chaque nom non
     qualifié pourrait désigner un objet défini par un utilisateur mal
     intentionné. Faites attention aux requêtes qui pourraient dépendre
     implicitement d'un search_path ; par exemple,
     IN et CASE  sélectionnent toujours un opérateur utilisant le chemin de
     recherche. À la place, utilisez
     expression
      WHENOPERATOR( et
     schema.=) ANYCASE WHEN .
    expression
     Une extension standard ne devrait généralement pas supposer qu'elle a été
     installée dans un schéma sécurisé, ce qui signifie que même les
     références à ses propres objets en qualifiant leur nom de celui du schéma
     ne sont pas entièrement sans risque. Par exemple, si l'extension a défini
     une fonction monschema.mafonction(bigint), alors un
     appel tel que monschema.mafonction(42) pourrait être
     capturée par une fonction hostile
     monschema.mafonction(integer). Faites attention que
     les types de données de la fonction et les paramètres de l'opérateur
     correspondent exactement aux types d'argument déclarés, en utilisant des
     conversions explicites si nécessaire.
    
Un script d'installation ou de mise à jour d'extension devrait être écrit pour se garder contre les attaques se basant sur le schéma, survenant lors de l'exécution du script. Si la référence d'un objet dans le script peut se faire en résolvant un autre objet que celui voulu par l'auteur de script, une compromission peut survenir immédiatement ou ultérieurement quand l'object mal défini est utilisé.
     Les commandes DDL telles que CREATE FUNCTION et
     CREATE OPERATOR CLASS sont généralement sécurisées,
     mais il convient de faire attention à toute commande ayant une expression
     standard comme composant. Par exemple, CREATE VIEW
     nécessite d'être validé, comme une expression DEFAULT
     dans CREATE FUNCTION.
    
     Quelque fois, un script d'extension peut avoir besoin d'exécuter un SQL,
     par exemple pour réaliser des ajustements sur le catalogue qui ne
     seraient pas possibles via une DDL. Faites bien attention d'exécuter de
     telles commandes avec un search_path sécurisé ;
     ne faites pas confiance au chemin fourni par
     CREATE/ALTER EXTENSION comme étant sécurisé. Une
     meilleure approche est de configurer temporairement
     search_path à pg_catalog, pg_temp
     et d'insérer explicitement des références au schéma d'installation de
     l'expression si nécessaire. (Cette pratique peut être utile pour créer
     des vues.) Des exemples sont disponibles dans les modules
     contrib de la distribution des sources de
     PostgreSQL.
    
     Les références inter-extensions sécurisées nécessitent généralement une qualification de schéma
     des noms des objets de l'autre extension, à l'aide de la syntaxe
     @extschema:
     , en plus d'une correspondance rigoureuse des types d'arguments pour les fonctions
     et les opérateurs.
    name@
Ci-après, un exemple complet d'une extension écrite uniquement en SQL, un type composite de deux éléments qui peut stocker n'importe quelle valeur dans chaque emplacement, qui sont nommés « k » et « v ». Les valeurs non textuelles sont automatiquement changées en texte avant stockage.
    Le fichier de script pair--1.0.sql ressemble à ceci:
    
-- se plaint si le script est exécuté directement dans psql, plutôt que via CREATE EXTENSION
\echo Use "CREATE EXTENSION pair" to load this file. \quit
CREATE TYPE pair AS ( k text, v text );
CREATE pair(text, text)
RETURNS pair LANGUAGE SQL AS 'SELECT ROW($1, $2)::@extschema@.pair;';
CREATE OPERATOR ~> (LEFTARG = text, RIGHTARG = text, FUNCTION = pair);
-- "SET search_path" is easy to get right, but qualified names perform better.
CREATE FUNCTION lower(pair)
RETURNS pair LANGUAGE SQL
AS 'SELECT ROW(lower($1.k), lower($1.v))::@extschema@.pair;'
SET search_path = pg_temp;
CREATE FUNCTION pair_concat(pair, pair)
RETURNS pair LANGUAGE SQL
AS 'SELECT ROW($1.k OPERATOR(pg_catalog.||) $2.k,
               $1.v OPERATOR(pg_catalog.||) $2.v)::@extschema@.pair;';
    
    Le fichier de contrôle pair.control ressemble à ceci:
    
# extension pair
comment = 'Un type de donnees representant un couple clef/valeur'
default_version = '1.0'
# n'est pas déplaçable à cause de l'utilisation de @extschema@
relocatable = false
    
    Si vous avez besoin d'un fichier d'installation pour installer ces deux fichiers dans le bon répertoire,
    vous pouvez utiliser le fichier Makefile qui suit :
    
EXTENSION = pair
DATA = pair--1.0.sql
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
    
    Ce fichier d'installation s'appuye sur PGXS, qui est décrit dans Section 36.18.
    La commande make install va installer les fichiers de contrôle et de script dans le
    répertoire adéquat tel qu'indiqué par pg_config.
   
    Une fois les fichiers installés, utilisez la commande CREATE
    EXTENSION pour charger les objets dans une base de donnée.