PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Como o search_path influencia a resolução do identificador e o esquema atual



Qual ​​é o caminho de pesquisa do esquema search_path ?


O manual:

[...] as tabelas são muitas vezes referidas por nomes não qualificados, que consistem apenas no nome da tabela. O sistema determina qual tabela se refere a seguir um caminho de pesquisa, que é uma lista de esquemas a serem pesquisados .

Minha ênfase em negrito. Isso explica a resolução do identificador .

O "esquema atual" (ou “esquema padrão”) é, por documentação:

O primeiro esquema nomeado no caminho de pesquisa é chamado de esquema atual . Além de ser o primeiro esquema pesquisado, também é o esquema no qual novas tabelas serão criadas se o CREATE TABLE comando não especifica um nome de esquema.

Minha ênfase em negrito. Os esquemas do sistema pg_temp (esquema para objetos temporários da sessão atual) e pg_catalog são automaticamente parte do caminho de pesquisa e pesquisados ​​primeiro , nesta ordem. O manual:

pg_catalog é sempre efetivamente parte do caminho de pesquisa. Se não for nomeado explicitamente no caminho, ele será pesquisado implicitamente antes pesquisando os esquemas do caminho. Isso garante que os nomes internos sempre possam ser encontrados. No entanto, você pode colocar explicitamente pg_catalog no final do caminho de pesquisa, se preferir que os nomes definidos pelo usuário substituam os nomes internos.

Destaque em negrito conforme original. E pg_temp vem antes disso, a menos que seja colocado em uma posição diferente.

Como definir?


Existem várias maneiras de definir a variável de tempo de execução search_path .

  1. Definir um cluster -wide default para todas as funções em todos os bancos de dados em postgresql.conf (e recarregar). Cuidado com isso!
    search_path = 'blarg,public'
    

    O padrão enviado para esta configuração é:
    search_path = "$user",public
    

    O primeiro elemento especifica que um esquema com o mesmo nome do usuário atual deve ser pesquisado. Se não existir tal esquema, a entrada será ignorada.

  2. Defina-o como padrão para um banco de dados :
    ALTER DATABASE test SET search_path = blarg,public;
    

  3. Defina-o como padrão para a função você se conecta (efetivo em todo o cluster):
    ALTER ROLE foo SET search_path = blarg,public;
    

  4. Ou mesmo (geralmente melhor!) como padrão para uma função em um banco de dados :
    ALTER ROLE foo IN DATABASE test SET search_path = blarg,public;
    

  5. Escreva o comando no topo do seu script. Ou execute-o em sua sessão do banco de dados :
    SET search_path = blarg,public;
    

  6. Defina um search_path específico para o escopo de uma função (para estar seguro de usuários mal-intencionados com privilégios suficientes). Leia sobre como escrever SECURITY DEFINER Funções com segurança no manual.
CREATE FUNCTION foo() RETURNS void AS
$func$
BEGIN
   -- do stuff
END
$func$ LANGUAGE plpgsql SECURITY DEFINER
       SET search_path=blarg,public,pg_temp;



O número mais alto na minha lista supera o número mais baixo.
O manual tem ainda mais maneiras , como definir variáveis ​​de ambiente ou usar opções de linha de comando.

Para ver a configuração atual:
SHOW search_path;

Para redefini-lo:
RESET search_path;

O manual:

O valor padrão é definido como o valor que o parâmetro teria, se não houvesse SET já havia sido emitido para ele na sessão atual.