Os identificadores de objeto (OIDs) são usados internamente pelo
PostgreSQL como chaves primárias para
várias tabelas do sistema.
O tipo de dados oid representa um identificador de objeto.
Existem também vários tipos de dados alias para oid,
cada um chamado reg.
A Tabela 8.26 mostra uma visão geral.
alguma_coisa
No momento, o tipo de dados oid é implementado como
inteiro sem sinal de quatro bytes.
Portanto, não é grande o suficiente para fornecer unicidade em
todo o banco de dados em grandes bancos de dados, ou mesmo em
grandes tabelas individualmente.
O próprio tipo de dados oid tem poucas operações além
da de comparação. Entretanto, pode ser convertido em inteiro e
depois tratado usando os operadores padrão para inteiros.
(Cuidado com a possível confusão entre “com sinal”
versus “sem sinal”, se isto for feito.)
Os tipos de dados alias de OID não têm operações próprias, exceto
rotinas de entrada e saída especializadas.
Estas rotinas conseguem aceitar e exibir nomes simbólicos para
objetos do sistema, em vez do valor numérico bruto que o tipo de dados
oid usaria.
Os tipos de dados alias permitem a procura simplificada de valores de
OID para objetos.
Por exemplo, para examinar as linhas da tabela
pg_attribute relacionadas a uma tabela
minha_tabela, pode ser escrito:
SELECT *
FROM pg_attribute
WHERE attrelid = 'minha_tabela'::regclass;
em vez de:
SELECT * FROM pg_attribute
WHERE attrelid =
(SELECT oid
FROM pg_class
WHERE relname = 'minha_tabela');
Embora isto não pareça tão ruim por si só, ainda assim é simplificado
demais. Seria necessária uma subconsulta muito mais complicada
para selecionar o OID correto se houvesse várias tabelas chamadas
minha_tabela em esquemas diferentes.
O conversor de entrada regclass trata a procura de
tabela segundo a configuração do caminho do esquema e,
portanto faz a “coisa certa” automaticamente.
Da mesma forma, converter o OID de uma tabela para o tipo de dados
regclass é útil para a exibição simbólica de um OID
numérico.
Tabela 8.26. Tipos de dados de identificador de objeto
| Nome | Referência | Descrição | Exemplo de valor |
|---|---|---|---|
oid | todos | identificador numérico de objeto | 564182 |
regclass | pg_class | nome da relação | pg_type |
regcollation | pg_collation | nome da ordenação | "POSIX" |
regconfig | pg_ts_config | configuração da procura de texto | english |
regdictionary | pg_ts_dict | dicionário de procura de texto | simple |
regnamespace | pg_namespace | nome do espaço de nomes | pg_catalog |
regoper | pg_operator | nome do operador | + |
regoperator | pg_operator | operador com os tipos de dados dos argumentos | *(integer,integer)
ou -(NONE,integer) |
regproc | pg_proc | nome da função | sum |
regprocedure | pg_proc | função com os tipos de dados dos argumentos | sum(int4) |
regrole | pg_authid | nome do papel (role) | smithee |
regtype | pg_type | nome do tipo de dados | integer |
Todos os tipos de dados alias de OID para objetos agrupados por
espaço de nome aceitam nomes qualificados pelo esquema, e exibem
nomes qualificados pelo esquema na saída, se o objeto não for
encontrado no caminho de procura corrente sem ser qualificado.
Por exemplo, meu_esquema.minha_tabela é uma entrada
aceitável para regclass (se houver tal tabela).
Esse valor pode ser gerado como
meu_esquema.minha_tabela, ou apenas
minha_tabela, dependendo do caminho de procura
corrente.
Os tipos de dados alias regproc e regoper
só aceitam nomes de entrada únicos (não sobrecarregados),
portanto são de uso limitado; para a maioria dos usos,
regprocedure ou regoperator são mais
apropriados.
Para regoperator, os operadores unários são
identificados escrevendo NONE para
o operando não utilizado.
As funções de entrada para esses tipos de dados permitem espaços em
branco entre os tokens, e transformam letras maiúsculas em minúsculas,
exceto quando estão entre aspas; isto é feito para tornar as regras
de sintaxe semelhantes à maneira como os nomes de objetos são
escritos no SQL.
Por outro lado, as funções de saída usam aspas, se necessário, para
tornar a saída um identificador SQL válido.
Por exemplo, o OID da função chamada Foo
(com F maiúsculo) aceitando dois argumentos
inteiros pode ser entrada como
' "Foo" ( int, integer ) '::regprocedure.
A saída ficaria parecida com
"Foo"(integer,integer).
Tanto o nome da função quanto o nome do tipo de dados do argumento
também podem ser qualificados pelo esquema.
Muitas funções nativas do PostgreSQL
aceitam o OID de uma tabela, ou outro tipo de objeto de banco de
dados, e por conveniência são declarados como tendo o tipo de dados
regclass (ou o tipo de dados alias de OID apropriado),
significando não ser necessário procurar manualmente o OID do
objeto, permitindo apenas inserir o seu nome como literal cadeia
de caracteres.
Por exemplo, se a função nextval(regclass)
recebe o OID de uma relação de sequência, então pode ser
chamada assim:
nextval('foo') opera na sequência foo
nextval('FOO') idêntico ao acima
nextval('"Foo"') opera na sequência Foo
nextval('meu_esquema.foo') opera em meu_esquema.foo
nextval('"meu_esquema".foo') idêntico ao acima
nextval('foo') pesquisa o caminho de procura por foo
Quando se escreve o argumento de tal função como literal
cadeia de caracteres sem adornos, a cadeia se torna uma constante
do tipo de dados regclass (ou do tipo de dados apropriado).
Como esse é realmente apenas um OID, será rastreado o objeto
originalmente identificado, apesar da posterior troca de nome,
reatribuição de esquema etc.
Esse comportamento de “vinculação precoce”
(early binding)
[58]
é geralmente desejável para referências de objetos em padrões de
coluna e visões.
Mas às vezes pode-se desejar a “vinculação tardia”
(late binding), onde a referência do
objeto é resolvida em tempo de execução.
Para obter o comportamento de vinculação tardia, deve-se forçar a
constante a ser armazenada como text, em vez de
regclass:
nextval('foo'::text) foo é procurado em tempo de execução
Também podem ser usadas a função to_regclass()
e suas irmãs para realizar a procura em tempo de execução.
Veja a Tabela 9.76.
Outro exemplo prático de uso do tipo de dados regclass é
procurar o OID de uma tabela listada nas visões do
esquema de informações,
que não fornecem esses OIDs diretamente.
Pode-se, por exemplo, desejar chamar a função
pg_relation_size(), que requer o OID da tabela.
Considerando as regras acima, a maneira correta de fazer
isto é:
SELECT table_schema, table_name,
pg_relation_size((quote_ident(table_schema) || '.' ||
quote_ident(table_name))::regclass)
FROM information_schema.tables
WHERE ...
A função quote_ident() cuida de colocar aspas
nos identificadores quando for necessário.
A forma aparentemente mais fácil
SELECT pg_relation_size(table_name) FROM information_schema.tables WHERE ...
não é recomendada, porque vai falhar para tabelas fora de seu caminho de procura, ou que tenham nomes que exijam aspas.
Uma propriedade adicional da maioria dos tipos de dados alias de OID
é a criação de dependências.
Se uma constante de um desses tipos de dados aparecer em uma expressão
armazenada (como expressão de padrão de uma coluna, ou visão),
ela cria uma dependência no objeto referenciado.
Por exemplo, se uma coluna tiver como expressão de padrão
nextval('minha_seq'::regclass), o
PostgreSQL entende que a expressão de
padrão depende da sequência minha_seq, portanto
o sistema não permite que a sequência seja excluída, sem que
primeiro seja removida a expressão de padrão.
A forma alternativa nextval('minha_seq'::text)
não cria dependência.
(regrole é uma exceção a essa propriedade.
Não são permitidas constantes desse tipo de dados em expressões armazenadas.)
Outro tipo de dados identificador usado pelo sistema é o xid,
ou identificador de transação (abreviado como xact).
Esse é o tipo de dados das colunas do sistema
xmin e xmax.
Os identificadores de transação são quantidades de 32 bits.
Em alguns contextos, é usada a forma alternativa de 64 bits xid8.
Ao contrário dos valores xid, os valores
xid8 aumentam estritamente monotonicamente, não podendo
ser reutilizados durante o tempo de vida de um agrupamento
(cluster) de bancos de dados.
Veja a Seção 67.1 para obter mais detalhes.
Um terceiro tipo de dados de identificador usado pelo sistema é o
cid, ou identificador de comando.
Esse é o tipo de dados das colunas do sistema
cmin e cmax.
Os identificadores de comando também são quantidades de 32 bits.
O último tipo de dados de identificador usado pelo sistema é o
tid, ou identificador de tupla (identificador de linha).
Esse é o tipo de dados da coluna do sistema ctid.
Um ID de tupla é um par (número de bloco, índice da tupla dentro do
bloco) que identifica a localização física da linha na sua tabela.
(As colunas do sistema são explicadas com mais detalhes na Seção 5.6.)
[58] A vinculação refere-se ao processo de conversão de identificadores (como nomes de variáveis e de funções) em endereços. A vinculação é feita para cada variável e função. Para as funções, significa combinar a chamada com a definição correta da função pelo compilador. Ocorre em tempo de compilação ou em tempo de execução. Early Binding (polimorfismo em tempo de compilação), como o nome indica, o compilador (ou vinculador) associa diretamente um endereço à chamada da função. Early binding and Late binding in C++ (N. T.)