Sebenarnya ada tiga pertanyaan di sana yang akan saya coba jawab.
-
Apa tujuan dari
unknown
?Ini adalah tipe data yang awalnya ditetapkan untuk NULL dan literal string dalam pernyataan SQL. Jika literal tersebut diberikan ketik
text
segera, akan sulit untuk menyimpulkan jenis yang benar.Misalnya, Anda ingin
myfunc('hello')
untuk memanggilmyfunc(character varying)
, tetapi tidak ada tipe implisit yang dilemparkan daritext
untukcharacter varying
(dan akan menyebabkan ambiguitas jika Anda membuatnya). -
Mengapa
SELECT null
kembalikan kolom jenisunknown
?Jawaban tradisionalnya adalah:Karena pengguna tidak menentukan jenisnya.
Namun, perilaku ini bermasalah. Misalnya, jika Anda membuat tabel seperti ini:
CREATE TABLE test AS SELECT 'hello';
Anda akan berakhir dengan kolom jenis
unknown
, yang tidak diinginkan dan akan menyebabkan masalah lebih lanjut. Jenisunknown
seharusnya tidak terlihat oleh pengguna, melainkan detail implementasi.Akibatnya, komit ini telah mengubah perilaku dari PostgreSQL v10 pada:Sekarang
unknown
s tersisa diSELECT
atauRETURNING
daftar dipaksa untuktext
, dan tabel tidak dapat dibuat dengan kolom bertipeunknown
. -
Mengapa
SELECT NULL UNION SELECT 42
bekerja, tetapi tidakSELECT NULL UNION SELECT NULL UNION SELECT 42
?Ini karena aturan konversi jenis .
UNION
dibiarkan asosiatif, sehingga kueri terakhir ditafsirkan sebagai(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Sekarang
UNION
pertama memutuskan untuk tipe datatext
karena aturan 3:Ini menyebabkan kesalahan saat mencoba menyelesaikan jenis untuk
UNION
kedua karena aturan 4:Di sisi lain, dalam kueri
SELECT NULL UNION SELECT 42;
“NULL” memiliki tipe
unknown
, dan “42” memiliki tipeinteger
(tipe yang dipilih untuk literal numerik tanpa titik desimal).Aturan 5
tidak berlaku di sini, karena
integer
bukan tipe yang disukai dalam kategorinya (yaituoid
dandouble precision
), jadi aturan 6 digunakan:Ini menghasilkan jenis
integer
.