De onde vem a coluna mágica "nome"?

11

Eu peguei isso por acidente:

db=> select name from site;
ERROR:  column "name" does not exist
LINE 1: select name from site;
               ^
db=> select site.name from site;
     name
---------------
 (1,mysitename)
(1 row)

A segunda consulta retorna uma tupla contendo uma linha inteira. Usando o postgres 9.0.1.

Edit: a definição de site por solicitação. Realmente não importa, essa peculiaridade funciona para qualquer tabela.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null
hegemon
fonte
Ajudaria a mostrar a definição de site.
Peter Eisentraut
~ Ele faz questão porque agora podemos ver que não existe um "nome" em sitepara começar. Por que você consultaria uma coluna que não existe?
Jcolebrand
1
Tente select site from site- o que irá ajudar você a entender a resposta de Caio em mais detalhes
Jack diz tentativa topanswers.xyz

Respostas:

11

NAMEé realmente uma função . É uma peculiaridade do Postgres que uma função com um argumento, por exemplo, function(arg)também possa ser chamada como arg.function. Dos documentos:

A equivalência entre notação funcional e notação de atributo torna possível o uso de funções em tipos compostos para emular "campos computados".

NAMEé um tipo interno para nomes de objetos e essa função está lançando seu argumento para esse tipo e retornando-o.

Gaius
fonte
Obrigado, eu não sabia disso. O que me incomoda, se esta função específica "nome" está documentada em algum lugar?
hegêmona
Atualizei minha resposta
Gaius
2
Mais precisamente, o rowtipo está sendo convertido, textporque esse é o tipo de entrada da função name. A namefunção é, em seguida, converter (não seleção de elenco) a cadeia de entrada com o tipo name(que também vai ter o efeito colateral de truncar a 64 bytes)
Jack diz tentar topanswers.xyz
3

Observe também que a conversão implícita para o nome foi removida no PostgreSQL 8.3, o que significa que esse comportamento não funciona mais. É praticamente impossível obter esse comportamento acidentalmente no PostgreSQL 8.3 e superior, porque as tuplas não são convertidas automaticamente em texto.

Então, na 9.1:

or_examples=# select c.name from comp_table_test c;
ERROR:  column c.name does not exist
LINE 1: select c.name from comp_table_test c;

mas para obter esse comportamento, precisamos:

or_examples=# select name(c::text) from comp_table_test c;

Ou podemos definir nossa própria função de nome, digitando comp_table_test e retornando o que gostaríamos.

Chris Travers
fonte
Eu não entendo essa resposta. Você está dizendo que a pergunta colocada acima não deve mais ser um problema na versão 8.3 ou superior? No entanto, a pergunta é de cerca de 9,0.
Colin 'Hart #
0

"nome" é uma palavra-chave reservada . Portanto, você deve "citar" a palavra-chave para usá-la:

SELECT "name" FROM site;

Isso resolveu alguns desses problemas para mim no passado, apesar do código que você postou também deve funcionar sem citar. Por outro lado

select site.name from site;

palavra porque você está usando explicitamente o esquema para resolver o nome da coluna

DrColossos
fonte
1
Muitas palavras reservadas podem ser usadas e, neste caso, a citação não ajuda. Isso ocorre porque, se site.name não existir como uma coluna, antes da versão 8.3, o que aconteceria é que você começaria a procurar funções de nome que incluíssem um tipo de dados do site ou um tipo implicitamente convertido do site. Como o site pode ser convertido implicitamente em texto, o nome (texto) seria usado. Consequentemente, select site.name from sitepode ser implicitamente transformado para o select name(site::text) from sitequal é de onde vem a mágica.
precisa saber é o seguinte