¿De dónde viene la columna mágica "nombre"?

11

Obtuve esto por accidente:

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)

La segunda consulta devuelve una tupla que contiene una fila completa. Usando postgres 9.0.1.

Editar: la definición de sitio por solicitud. Realmente no importa, esta peculiaridad funciona para cualquier mesa.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null
hegemon
fuente
Sería útil mostrar la definición de site.
Peter Eisentraut
~ Se hace importa porque ahora podemos ver que no hay un "nombre" en siteprimer lugar. ¿Por qué preguntarías por una columna que no existe?
jcolebrand
1
Inténtalo select site from site: esto te ayudará a comprender la respuesta de Gaius con más detalle
Jack dice que pruebes topanswers.xyz el

Respuestas:

11

NAMEEn realidad es una función . Es una peculiaridad de Postgres que una función con un argumento, por ejemplo function(arg), también se puede llamar como arg.function. De los documentos:

La equivalencia entre notación funcional y notación de atributo hace posible el uso de funciones en tipos compuestos para emular "campos calculados".

NAMEes un tipo interno para nombres de objetos , y esta función está lanzando su argumento a ese tipo y devolviéndolo.

Gayo
fuente
Gracias, no lo sabía. ¿Qué me molesta si esta función particular "nombre" está documentada en alguna parte?
hegemon
Actualicé mi respuesta
Cayo el
2
Más precisamente, rowse está convirtiendo el tipo textporque ese es el tipo de entrada de la función name. La namefunción está convirtiendo después (no casting) la cadena de entrada con el tipo name(que también tendrá el efecto secundario de truncar a 64 bytes)
Jack dice tratar topanswers.xyz
3

También tenga en cuenta que la conversión implícita a nombre se eliminó en PostgreSQL 8.3, lo que significa que este comportamiento ya no funciona. Es prácticamente imposible obtener accidentalmente este comportamiento en PostgreSQL 8.3 y versiones posteriores porque las tuplas no se convierten automáticamente en texto.

Entonces en 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;

pero para obtener ese comportamiento tenemos que:

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

O podríamos definir nuestra propia función de nombre tomando el tipo comp_table_test y devolviendo lo que queramos.

Chris Travers
fuente
No entiendo esta respuesta. ¿Estás diciendo que la pregunta planteada anteriormente ya no debería ser un problema en 8.3 o superior? Sin embargo, la pregunta se refiere a 9.0
Colin 't Hart
0

"nombre" es una palabra clave reservada . Por lo tanto, debe "citar" la palabra clave para usarla:

SELECT "name" FROM site;

Esto ha resuelto algunos de estos problemas en el pasado, aunque el código que publicaste también debería funcionar sin citar. Por otra parte

select site.name from site;

palabra porque está utilizando explícitamente el esquema para resolver el nombre de la columna

DrColossos
fuente
1
Se pueden usar muchas palabras reservadas y, en este caso, las citas no ayudan. Esto se debe a que si site.name no existe como una columna, entonces, antes de 8.3, lo que sucedería es que comenzaría a buscar funciones de nombre que incluyan un tipo de datos del sitio o un tipo implícitamente emitido desde el sitio. Dado que el sitio podría convertirse implícitamente en texto, se usaría el nombre (texto). En consecuencia, select site.name from sitepodría transformarse implícitamente de select name(site::text) from sitedónde proviene la magia.
Chris Travers