sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cómo influye search_path en la resolución del identificador y el esquema actual?

¿Qué es la ruta de búsqueda del esquema search_path? ?

El manual:

[...] a menudo se hace referencia a las tablas con nombres no calificados, que consisten solo en el nombre de la tabla. El sistema determina a qué tabla se refiere siguiendo una ruta de búsqueda, que es una lista de esquemas para buscar .

Énfasis en negrita mío. Esto explica la resolución de identificadores .

El “esquema actual” (o "esquema predeterminado") es, según la documentación:

El primer esquema mencionado en la ruta de búsqueda se llama el esquema actual . Además de ser el primer esquema buscado, también es el esquema en el que se crearán nuevas tablas si CREATE TABLE comando no especifica un nombre de esquema.

Énfasis en negrita mío. Los esquemas del sistema pg_temp (esquema para objetos temporales de la sesión actual) y pg_catalog son automáticamente parte de la ruta de búsqueda y se buscan primero , en este orden. El manual:

pg_catalog es siempre efectivamente parte de la ruta de búsqueda. Si no se nombra explícitamente en la ruta, se busca implícitamente antes buscando los esquemas del camino. Esto asegura que los nombres integrados siempre se puedan encontrar. Sin embargo, puede colocar explícitamente pg_catalog al final de su ruta de búsqueda si prefiere que los nombres definidos por el usuario sobrescriban los nombres integrados.

Énfasis en negrita según el original. Y pg_temp viene antes de eso, a menos que se coloque en una posición diferente.

¿Cómo configurarlo?

Hay varias formas de configurar la variable de tiempo de ejecución search_path .

  1. Establecer un clúster -amplio valor predeterminado para todos los roles en todas las bases de datos en postgresql.conf (y recargar). ¡Cuidado con eso!

    search_path = 'blarg,public'
    

    El valor predeterminado enviado para esta configuración es:

    search_path = "$user",public
    

    El primer elemento especifica que se buscará un esquema con el mismo nombre que el usuario actual. Si no existe tal esquema, la entrada se ignora.

  2. Establézcalo como predeterminado para una base de datos :

    ALTER DATABASE test SET search_path = blarg,public;
    
  3. Establézcalo como predeterminado para el rol te conectas (efectivo en todo el clúster):

    ALTER ROLE foo SET search_path = blarg,public;
    
  4. O incluso (¡a menudo mejor!) como predeterminado para un rol en una base de datos :

    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    
  5. Escriba el comando en la parte superior de su secuencia de comandos. O ejecútelo en su sesión de base de datos :

    SET search_path = blarg,public;
    
  6. Establecer una search_path específica para el alcance de una función (para estar a salvo de usuarios maliciosos con suficientes privilegios). Lea acerca de escribir SECURITY DEFINER Funciones seguras en el manual.

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

El número más alto en mi lista triunfa sobre el número más bajo.
El manual tiene aún más formas , como establecer variables de entorno o usar opciones de línea de comandos.

Para ver la configuración actual:

SHOW search_path;

Para restablecerlo:

RESET search_path;

El manual:

El valor predeterminado se define como el valor que habría tenido el parámetro, si no SET nunca se había emitido para él en la sesión actual.