Da dove viene la colonna magica "nome"?


11

L'ho preso per caso:

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 seconda query restituisce una tupla contenente un'intera riga. Utilizzando Postgres 9.0.1.

Modifica: la definizione del sito su richiesta. Non importa, questa stranezza funziona per qualsiasi tavolo.

db=> \d site
                         Table "public.site"
 Column |  Type   |                     Modifiers
--------+---------+---------------------------------------------------
 id     | integer | not null default nextval('site_id_seq'::regclass)
 title  | text    | not null

Aiuterebbe a mostrare la definizione di site.
Peter Eisentraut,

~ E non importa perché ora possiamo vedere che non v'è alcun "nome" in siteper cominciare. Perché dovresti cercare una colonna che non esiste?
jcolebrand

1
Prova select site from site- questo ti aiuterà a capire la risposta di Gaius in modo più dettagliato
Jack dice che prova topanswers.xyz il

Risposte:


11

NAMEè in realtà una funzione . È una stranezza di Postgres che una funzione con un argomento, ad esempio, function(arg)può anche essere chiamata come arg.function. Dai documenti:

L'equivalenza tra notazione funzionale e notazione di attributo consente di utilizzare funzioni su tipi compositi per emulare "campi calcolati".

NAMEè un tipo interno per i nomi degli oggetti e questa funzione sta trasmettendo il suo argomento a quel tipo e lo restituisce.


Grazie, non lo sapevo. Cosa mi disturba, se questa particolare funzione "nome" è documentata ovunque?
egemon

Aggiornata la mia risposta
Gaius,

2
Più precisamente, il rowtipo viene trasmesso textperché è il tipo di input della funzione name. La namefunzione sta quindi convertendo (non lanciando) la stringa di input in tipo name(che avrà anche l'effetto collaterale di troncare a 64 byte)
Jack dice che prova topanswers.xyz il

3

Si noti inoltre che il cast implicito per il nome è stato rimosso in PostgreSQL 8.3, il che significa che questo comportamento non funziona più. È praticamente impossibile ottenere accidentalmente questo comportamento in PostgreSQL 8.3 e versioni successive perché le tuple non si convertono automaticamente in testo.

Quindi in 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;

ma per ottenere quel comportamento dobbiamo:

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

Oppure potremmo definire la nostra funzione nome prendendo il tipo comp_table_test e restituendo quello che vorremmo.


Non capisco questa risposta. Stai dicendo che la domanda posta sopra non dovrebbe più essere un problema su 8.3 o versioni successive? Eppure la domanda pone circa 9.0
Colin 't Hart,

0

"nome" è una parola chiave riservata . Quindi dovresti "citare" la parola chiave per usarla:

SELECT "name" FROM site;

Questo ha risolto alcuni di questi problemi per me in passato, anche se il codice che hai pubblicato dovrebbe funzionare anche senza virgolette. D'altra parte

select site.name from site;

parola perché stai esplicitamente usando lo schema per risolvere il nome della colonna


1
È possibile utilizzare molte parole riservate e in questo caso la citazione non aiuta. Questo perché se site.name non esiste come colonna, prima della 8.3, ciò che accadrebbe sarebbe che inizieresti a cercare le funzioni name che assumono un tipo di dati del sito o un tipo implicitamente cast dal sito. Poiché il sito potrebbe essere implicitamente trasmesso al testo, verrebbe utilizzato il nome (testo). Di conseguenza select site.name from sitepotrebbe essere implicitamente trasformato da select name(site::text) from sitedove proviene la magia.
Chris Travers,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.