Skąd pochodzi magiczna kolumna „nazwa”?


11

Dostałem to przez przypadek:

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)

Drugie zapytanie zwraca krotkę zawierającą cały wiersz. Korzystanie z Postgres 9.0.1.

Edycja: definicja strony na żądanie. Nie mam większego znaczenia, to dziwactwo działa na każdym stole.

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

Pomogłoby to pokazać definicję site.
Peter Eisentraut,

~ To ma znaczenie, ponieważ teraz widzimy, że na początku nie ma „imienia” site. Dlaczego pytasz o kolumnę, która nie istnieje?
jcolebrand

1
Spróbuj select site from site- pomoże ci to zrozumieć bardziej szczegółowo odpowiedź Gajusza
Jack mówi, spróbuj spróbować topanswers.xyz

Odpowiedzi:


11

NAMEjest właściwie funkcją . Dziwne jest to, że Postgres function(arg)może wywoływać funkcję z jednym argumentem np . Jako arg.function. Z dokumentów:

Równoważność między notacją funkcjonalną a notacją atrybutu umożliwia użycie funkcji na typach złożonych do emulacji „pól obliczeniowych”.

NAMEjest wewnętrznym typem nazw obiektów , a ta funkcja przekazuje swój argument do tego typu i zwraca go.


Dzięki, nie wiedziałem tego. Co mnie martwi, jeśli ta konkretna funkcja „nazwa” jest gdziekolwiek udokumentowana?
hegemon

Zaktualizowałem moją odpowiedź
Gajusz

2
Mówiąc dokładniej, rowtyp jest rzutowany, textponieważ jest to typ wejściowy funkcji name. Następnie namefunkcja konwertuje (nie rzutuje) ciąg wejściowy na typ name(co będzie miało również efekt uboczny obcięcia do 64 bajtów)
Jack mówi, spróbuj wypróbować topanswers.xyz

3

Zauważ również, że niejawna rzutowana na nazwę została usunięta w PostgreSQL 8.3, co oznacza, że ​​to zachowanie nie działa. Jest praktycznie niemożliwe przypadkowe uzyskanie tego zachowania w PostgreSQL 8.3 i nowszych, ponieważ krotki nie są automatycznie konwertowane na tekst.

W 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;

ale aby uzyskać takie zachowanie, musimy:

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

Lub moglibyśmy zdefiniować naszą własną nazwę, przyjmując typ comp_table_test i zwracając cokolwiek byśmy chcieli.


Nie rozumiem tej odpowiedzi. Mówisz, że pytanie postawione powyżej nie powinno stanowić problemu na wersji 8.3 lub wyższej? Jednak pytanie dotyczy około 9,0
Colin 't Hart

0

„nazwa” jest zastrzeżonym słowem kluczowym . Dlatego powinieneś „zacytować” słowo kluczowe, aby go użyć:

SELECT "name" FROM site;

W przeszłości rozwiązało to niektóre z tych problemów, chociaż kod, który opublikowałeś, powinien również działać bez cytowania. Z drugiej strony

select site.name from site;

słowo, ponieważ jawnie używasz schematu do rozwiązania nazwy kolumny


1
Można użyć wielu zastrzeżonych słów, w tym przypadku cytowanie nie pomaga. Wynika to z faktu, że jeśli site.name nie istnieje jako kolumna, to w wersji wcześniejszej niż 8.3, zacząłbyś szukać funkcji nazw przyjmujących typ danych witryny lub typ domyślnie rzutowany z witryny. Ponieważ witryna może być pośrednio rzutowana na tekst, nazwa (tekst) zostanie użyta. W związku select site.name from sitez tym można w sposób dorozumiany przekształcić się w select name(site::text) from siteto, skąd pochodzi magia.
Chris Travers
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.