Jsou tam vlastně tři otázky, na které se pokusím odpovědět.
-
Jaký je účel
unknown
?Toto je datový typ, který byl původně přiřazen hodnotám NULL a řetězcovým literálům v příkazech SQL. Pokud by takovým literálům byl přiřazen typ
text
okamžitě by bylo obtížné odvodit správný typ.Například chcete
myfunc('hello')
pro vyvolánímyfunc(character varying)
, ale neexistuje žádné implicitní přetypování ztext
nacharacter varying
(a pokud byste jej vytvořili, způsobilo by to nejednoznačnost). -
Proč
SELECT null
vrátí sloupec typuunknown
?Tradiční odpověď zní:Protože uživatel nespecifikoval typ.
Toto chování však bylo problematické. Pokud například vytvoříte tabulku takto:
CREATE TABLE test AS SELECT 'hello';
skončili byste se sloupcem typu
unknown
, což je nežádoucí a způsobí další problémy. Typunknown
skutečně by neměl být viditelný pro uživatele, ale spíše detail implementace. -
Proč
SELECT NULL UNION SELECT 42
fungovat, ale neSELECT NULL UNION SELECT NULL UNION SELECT 42
?To je způsobeno pravidly konverze typů .
UNION
je vlevo asociativní, takže druhý dotaz je interpretován jako(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Nyní první
UNION
překládá na datový typtext
kvůli pravidlu 3:To způsobí chybu při pokusu o vyřešení typu pro druhý
UNION
kvůli pravidlu 4:Na druhou stranu v dotaz
SELECT NULL UNION SELECT 42;
„NULL“ má typ
unknown
a „42“ má typinteger
(typ zvolený pro číselné literály bez desetinné čárky).Pravidlo 5
zde neplatí, protože
integer
není preferovaným typem ve své kategorii (to by bylooid
adouble precision
), takže se použije pravidlo 6:Výsledkem je typ
integer
.