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

O que significa regclass no Postgresql


Não, você não precisa do cast para regclass ao chamar uma função como nextval que aceita uma regclass parâmetro, pois há uma conversão implícita de text para regclass . Em alguns outros contextos, uma conversão explícita para regclass pode ser necessário.

Explicação:

::regclass é uma conversão, como ::integer .

regclass é um tipo de dados "mágico"; na verdade é um alias para oid , ou "identificador de objeto". Consulte Tipos de identificador de objeto na documentação. Transmitindo para regclass é um atalho para dizer "este é o nome de uma relação, por favor converta-o para o oid dessa relação". Transmissões para regclass estão cientes do search_path , ao contrário de consultar pg_class para o oid de uma relação diretamente, então a conversão para regclass não é exatamente equivalente a subconsultar pg_class .

Tabelas são relações. Assim são sequências e visualizações. Assim, você pode obter o oid de uma visão ou sequência lançando para regclass também.

Existem casts implícitos definidos para text para regclass , portanto, se você omitir o cast explícito e estiver chamando uma função que aceita regclass o elenco é feito automaticamente. Então você não precisa dele em, por exemplo, nextval chamadas.

Existem outros lugares onde você pode. Por exemplo, você não pode comparar text diretamente com oid; então você pode fazer isso:
regress=> select * from pg_class where oid = 'table1'::regclass;

mas não isso:
regress=> select * from pg_class where oid = 'table1';
ERROR:  invalid input syntax for type oid: "table1"
LINE 1: select * from pg_class where oid = 'table1';

Apenas por diversão, tentei escrever uma consulta que executasse a operação equivalente de conversão para regclass . Não use, é principalmente por diversão e como uma tentativa de demonstrar o que está realmente acontecendo. A menos que você esteja realmente interessado em como a coragem de Pg funciona, você pode parar de ler aqui.

Pelo que entendi, 'sequence_name'::regclass::oid é aproximadamente equivalente à seguinte consulta:
WITH sp(sp_ord, sp_schema) AS (
  SELECT 
    generate_series(1, array_length(current_schemas('t'),1)),
    unnest(current_schemas('t'))
)
SELECT c.oid
FROM pg_class c INNER JOIN pg_namespace n ON (c.relnamespace = n.oid)
INNER JOIN sp ON (n.nspname = sp.sp_schema)
WHERE c.relname = 'sequence_name'
ORDER BY sp.sp_ord
LIMIT 1;

exceto que é muito mais curto e muito mais rápido. Consulte Funções de informações do sistema para a definição de current_schemas(...) , etc

Em outras palavras:
  • Obtenha uma matriz ab listando todos os esquemas aos quais temos acesso e emparelhe cada entrada com um número ordinal para sua posição na matriz
  • Pesquisar pg_class para relações com nomes correspondentes e associe cada um ao seu namespace (esquema)
  • Classifique a lista de relações restantes pela ordem em que seus esquemas apareceram em search_path
  • e escolha a primeira correspondência