Dari mana "nama" kolom ajaib itu berasal?


11

Saya mendapatkan ini secara tidak sengaja:

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)

Kueri kedua mengembalikan tupel yang berisi seluruh baris. Menggunakan postgres 9.0.1.

Edit: definisi situs berdasarkan permintaan. Saya tidak terlalu peduli, kekhasan ini cocok untuk semua meja

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

Akan membantu untuk menunjukkan definisi site.
Peter Eisentraut

~ Ini tidak peduli karena sekarang kita dapat melihat bahwa tidak ada "nama" di siteuntuk mulai dengan. Mengapa Anda meminta kolom yang tidak ada?
jcolebrand

1
Coba select site from site- ini akan membantu Anda memahami jawaban Gayus lebih terinci
Jack mengatakan coba topanswers.xyz

Jawaban:


11

NAMEsebenarnya adalah suatu fungsi . Ini adalah kekhasan dari Postgres bahwa fungsi dengan satu argumen misalnya function(arg)dapat juga disebut sebagai arg.function. Dari dokumen:

Kesetaraan antara notasi fungsional dan notasi atribut memungkinkan untuk menggunakan fungsi pada tipe komposit untuk meniru "bidang yang dikomputasi".

NAMEadalah tipe internal untuk nama objek , dan fungsi ini melemparkan argumennya ke tipe itu dan mengembalikannya.


Terima kasih, saya tidak tahu itu. Apa yang mengganggu saya, jika fungsi "nama" khusus ini didokumentasikan di mana saja?
hegemon

Diperbarui jawaban saya
Gayus

2
Lebih tepatnya, rowtipe sedang digunakan textkarena itu adalah tipe input dari fungsi name. The namefungsi kemudian mengkonversi (tidak pengecoran) string masukan untuk jenis name(yang juga akan memiliki efek samping truncating ke 64 bytes)
Jack mengatakan mencoba topanswers.xyz

3

Perhatikan juga bahwa pemeran implisit untuk nama dihapus di PostgreSQL 8.3, yang berarti perilaku ini tidak lagi berfungsi. Hampir mustahil untuk secara tidak sengaja mendapatkan perilaku ini di PostgreSQL 8.3 dan lebih tinggi karena tupel tidak secara otomatis dikonversi ke teks.

Jadi dalam 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;

tetapi untuk mendapatkan perilaku itu kita harus:

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

Atau kita bisa mendefinisikan fungsi nama kita sendiri dengan mengetikkan comp_table_test dan mengembalikan apa pun yang kita inginkan.


Saya tidak mengerti jawaban ini. Anda mengatakan pertanyaan yang diajukan di atas seharusnya tidak menjadi masalah lagi pada 8.3 atau lebih tinggi? Namun pertanyaannya bertanya tentang 9.0
Colin 't Hart

0

"nama" adalah kata kunci yang dilindungi undang-undang . Jadi Anda harus "mengutip" kata kunci untuk menggunakannya:

SELECT "name" FROM site;

Ini telah menyelesaikan beberapa masalah ini bagi saya di masa lalu, meskipun kode yang Anda posting juga harus berfungsi tanpa mengutip. Di samping itu

select site.name from site;

kata karena Anda secara eksplisit menggunakan skema untuk menyelesaikan nama kolom


1
Banyak kata yang dipesan dapat digunakan, dan dalam hal ini mengutip tidak membantu. Ini karena jika site.name tidak ada sebagai kolom, pra-8.3, yang akan terjadi adalah Anda akan mulai mencari fungsi nama dalam tipe data situs atau tipe yang secara implisit dilemparkan dari situs. Karena situs dapat secara implisit dilemparkan ke teks, nama (teks) akan digunakan. Akibatnya select site.name from sitemungkin secara implisit ditransformasikan ke select name(site::text) from sitemana sihir itu berasal.
Chris Travers
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.