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
textonmiddellijk 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 vantextnaarcharacter varying(en het zou dubbelzinnigheid veroorzaken als je er een zou maken). -
Waarom is
SELECT nullretourneer 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 typeunknownzou eigenlijk niet zichtbaar moeten zijn voor de gebruiker, maar eerder een implementatiedetail.Daarom deze toezegging heeft het gedrag veranderd vanaf PostgreSQL v10:Nu elke
unknowns achtergelaten in eenSELECTofRETURNINGlijst worden gedwongen omtext, en tabellen kunnen niet worden gemaakt met kolommen van het typeunknown. -
Waarom
SELECT NULL UNION SELECT 42werken, maar nietSELECT NULL UNION SELECT NULL UNION SELECT 42?Dit is te danken aan de typeconversieregels .
UNIONwordt associatief gelaten, dus de laatste zoekopdracht wordt geïnterpreteerd als(SELECT NULL UNION SELECT NULL) UNION SELECT 42;Nu de eerste
UNIONwordt omgezet in gegevenstypetextvanwege regel 3:Dit veroorzaakt een fout bij het oplossen van het type voor de tweede
UNIONvanwege 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
integeris geen voorkeurstype in zijn categorie (dat zouoidzijn endouble precision), dus regel 6 wordt gebruikt:Dit resulteert in een type
integer.