Er zijn eigenlijk drie vragen die ik zal proberen te beantwoorden.
-
Wat is het doel van
unknown
?Dit is het gegevenstype dat aanvankelijk is toegewezen aan NULL's en letterlijke tekenreeksen in SQL-instructies. Als dergelijke letterlijke waarden werden toegewezen, typt u
text
onmiddellijk zou het moeilijk zijn om het juiste type af te leiden.U wilt bijvoorbeeld
myfunc('hello')
ommyfunc(character varying)
. aan te roepen , maar er is geen impliciete typecast vantext
naarcharacter varying
(en het zou dubbelzinnigheid veroorzaken als je er een zou maken). -
Waarom is
SELECT null
retourneer een kolom van het typeunknown
?Het traditionele antwoord is:omdat de gebruiker het type niet heeft gespecificeerd.
Dit gedrag is echter problematisch. Als u bijvoorbeeld een tabel als deze maakt:
CREATE TABLE test AS SELECT 'hello';
je zou eindigen met een kolom van het type
unknown
, wat ongewenst is en later voor problemen zal zorgen. Het typeunknown
zou eigenlijk niet zichtbaar moeten zijn voor de gebruiker, maar eerder een implementatiedetail.Daarom deze toezegging heeft het gedrag veranderd vanaf PostgreSQL v10:Nu elke
unknown
s achtergelaten in eenSELECT
ofRETURNING
lijst worden gedwongen omtext
, en tabellen kunnen niet worden gemaakt met kolommen van het typeunknown
. -
Waarom
SELECT NULL UNION SELECT 42
werken, maar nietSELECT NULL UNION SELECT NULL UNION SELECT 42
?Dit is te danken aan de typeconversieregels .
UNION
wordt associatief gelaten, dus de laatste zoekopdracht wordt geïnterpreteerd als(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Nu de eerste
UNION
wordt omgezet in gegevenstypetext
vanwege regel 3:Dit veroorzaakt een fout bij het oplossen van het type voor de tweede
UNION
vanwege regel 4:Aan de andere kant, in de zoekopdracht
SELECT NULL UNION SELECT 42;
“NULL” heeft het type
unknown
, en "42" heeft het typeinteger
(het gekozen type voor numerieke literalen zonder decimale punt).Regel 5
is hier niet van toepassing, omdat
integer
is geen voorkeurstype in zijn categorie (dat zouoid
zijn endouble precision
), dus regel 6 wordt gebruikt:Dit resulteert in een type
integer
.