PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Comment le search_path influence-t-il la résolution de l'identifiant et le schéma actuel

Quel est le chemin de recherche du schéma ? search_path ?

Le manuel :

[...] les tables sont souvent désignées par des noms non qualifiés, constitués uniquement du nom de la table. Le système détermine de quelle table il s'agit en suivant un chemin de recherche, qui est une liste de schémas à rechercher .

Bold emphase mienne. Ceci explique la résolution de l'identifiant .

Le "schéma actuel" (ou "schéma par défaut") est, selon la documentation :

Le premier schéma nommé dans le chemin de recherche est appelé le schéma actuel . En plus d'être le premier schéma recherché, c'est aussi le schéma dans lequel de nouvelles tables seront créées si le CREATE TABLE commandne spécifie pas de nom de schéma.

Bold emphase mienne. Les schémas système pg_temp (schéma des objets temporaires de la session en cours) et pg_catalog font automatiquement partie du chemin de recherche et sont recherchés en premier , dans cet ordre. Le manuel :

pg_catalog fait toujours effectivement partie du chemin de recherche. S'il n'est pas nommé explicitement dans le chemin, il est implicitement recherché avant rechercher les schémas du chemin. Cela garantit que les noms intégrés seront toujours trouvables. Cependant, vous pouvez placer explicitement pg_catalog à la fin de votre chemin de recherche si vous préférez que les noms définis par l'utilisateur remplacent les noms intégrés.

Emphase audacieuse selon l'original. Et pg_temp vient avant cela, à moins qu'il ne soit placé dans une position différente.

Comment le configurer ?

Il existe différentes manières de définir la variable d'exécution search_path .

  1. Définir un cluster -wide par défaut pour tous les rôles dans toutes les bases de données dans postgresql.conf (et recharger). Attention avec ça !

    search_path = 'blarg,public'
    

    La valeur par défaut livrée pour ce paramètre est :

    search_path = "$user",public
    

    Le premier élément spécifie qu'un schéma portant le même nom que l'utilisateur actuel doit être recherché. Si aucun schéma de ce type n'existe, l'entrée est ignorée.

  2. Définissez-le par défaut pour une base de données :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Définissez-le par défaut pour le rôle avec qui vous vous connectez (effectif à l'échelle du cluster) :

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. Ou même (souvent mieux !) par défaut pour un rôle dans une base de données :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Écrivez la commande en haut de votre script. Ou exécutez-le dans votre session de base de données :

    SET search_path = blarg,public;
    
  6. Définir un search_path spécifique pour la portée d'une fonction (pour être à l'abri des utilisateurs malveillants avec des privilèges suffisants). En savoir plus sur l'écriture de SECURITY DEFINER Fonctions en toute sécurité dans le manuel.

CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;

Un nombre plus élevé dans ma liste l'emporte sur un nombre inférieur.
Le manuel a encore plus de façons , comme la définition de variables d'environnement ou l'utilisation d'options de ligne de commande.

Pour voir le paramètre actuel :

SHOW search_path;

Pour le réinitialiser :

RESET search_path;

Le manuel :

La valeur par défaut est définie comme la valeur qu'aurait eu le paramètre, s'il n'y avait pas de SET n'avait jamais été émis pour lui dans la session en cours.