Der er faktisk tre spørgsmål derinde, som jeg vil forsøge at besvare.
-
Hvad er formålet med
unknown
?Dette er den datatype, der oprindeligt blev tildelt NULL'er og strengliteraler i SQL-sætninger. Hvis sådanne bogstaver blev tildelt, skriv
text
umiddelbart ville det være svært at udlede den korrekte type.For eksempel vil du have
myfunc('hello')
at påkaldemyfunc(character varying)
, men der er ingen implicit type cast fratext
tilcharacter varying
(og det ville forårsage tvetydighed, hvis du oprettede en). -
Hvorfor er
SELECT null
returnere en kolonne af typenunknown
?Det traditionelle svar er:Fordi brugeren ikke har angivet typen.
Denne adfærd har dog været problematisk. For eksempel, hvis du opretter en tabel som denne:
CREATE TABLE test AS SELECT 'hello';
du ville ende med en kolonne af typen
unknown
, hvilket er uønsket og vil give problemer længere fremme. Typenunknown
burde egentlig ikke være brugersynlig, men snarere en implementeringsdetalje.Derfor er this commit har ændret adfærden fra PostgreSQL v10 på:Nu enhver
unknown
er tilbage i enSELECT
ellerRETURNING
liste tvinges til attext
, og tabeller kan ikke oprettes med kolonner af typenunknown
. -
Hvorfor vælger
SELECT NULL UNION SELECT 42
virker, men ikkeSELECT NULL UNION SELECT NULL UNION SELECT 42
?Dette skyldes typekonverteringsreglerne .
UNION
efterlades associativ, så sidstnævnte forespørgsel tolkes som(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Nu den første
UNION
løses til datatypentext
på grund af regel 3:Dette forårsager en fejl, når du forsøger at løse typen for den anden
UNION
på grund af regel 4:På den anden side i forespørgslen
SELECT NULL UNION SELECT 42;
"NULL" har typen
unknown
, og "42" har typeninteger
(den valgte type for numeriske bogstaver uden decimaltegn).Regel 5
gælder ikke her, fordi
integer
er ikke en foretrukken type i sin kategori (det ville væreoid
ogdouble precision
), så regel 6 bruges:Dette resulterer i en type
integer
.