PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

In che modo il percorso_ricerca influenza la risoluzione dell'identificatore e lo schema corrente

Qual ​​è il percorso di ricerca dello schema search_path ?

Il manuale:

[...] le tabelle sono spesso indicate con nomi non qualificati, che consistono solo nel nome della tabella. Il sistema determina quale tabella si intende seguendo un percorso di ricerca, che è un elenco di schemi in cui cercare .

Enfasi in grassetto mio. Questo spiega la risoluzione dell'identificatore .

Lo "schema attuale" (o "schema predefinito") è, per documentazione:

Il primo schema denominato nel percorso di ricerca è chiamato schema corrente . Oltre ad essere il primo schema cercato, è anche lo schema in cui verranno create nuove tabelle se il CREATE TABLE commandnon specifica un nome di schema.

Enfasi in grassetto mio. Gli schemi di sistema pg_temp (schema per oggetti temporanei della sessione corrente) e pg_catalog fanno automaticamente parte del percorso di ricerca e vengono cercati prima , in questo ordine. Il manuale:

pg_catalog è sempre effettivamente parte del percorso di ricerca. Se non è nominato in modo esplicito nel percorso, viene cercato implicitamente prima ricerca negli schemi del percorso. Ciò garantisce che i nomi incorporati siano sempre reperibili. Tuttavia, puoi inserire esplicitamente pg_catalog alla fine del percorso di ricerca se preferisci che i nomi definiti dall'utente prevalgano sui nomi incorporati.

Enfasi in grassetto come da originale. E pg_temp viene prima, a meno che non sia messo in una posizione diversa.

Come si imposta?

Esistono vari modi per impostare la variabile di runtime search_path .

  1. Imposta un cluster -wide predefinito per tutti i ruoli in tutti i database in postgresql.conf (e ricaricare). Attento!

    search_path = 'blarg,public'
    

    L'impostazione predefinita fornita per questa impostazione è:

    search_path = "$user",public
    

    Il primo elemento specifica che deve essere ricercato uno schema con lo stesso nome dell'utente corrente. Se non esiste uno schema di questo tipo, la voce viene ignorata.

  2. Impostalo come predefinito per un database :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Impostalo come predefinito per il ruolo con cui ti connetti (efficace a livello di cluster):

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. O anche (spesso il migliore!) come predefinito per un ruolo in un database :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Scrivi il comando nella parte superiore del tuo script. Oppure eseguilo nella tua sessione DB :

    SET search_path = blarg,public;
    
  6. Imposta un search_path specifico per l'ambito di una funzione (per essere al sicuro da utenti malintenzionati con privilegi sufficienti). Leggi come scrivere SECURITY DEFINER Funziona in modo sicuro nel manuale.

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

Un numero più alto nella mia lista prevale su un numero più basso.
Il manuale ha ancora più modi , come impostare le variabili di ambiente o utilizzare le opzioni della riga di comando.

Per vedere l'impostazione corrente:

SHOW search_path;

Per ripristinarlo:

RESET search_path;

Il manuale:

Il valore predefinito è definito come il valore che il parametro avrebbe avuto, se non fosse presente SET era mai stato emesso per esso nella sessione corrente.