Всъщност има три въпроса, на които ще се опитам да отговоря.
-
Каква е целта на
unknown?Това е типът данни, първоначално присвоен на NULL и низови литерали в SQL изрази. Ако на такива литерали е присвоен тип
textнезабавно би било трудно да се направи извод за правилния тип.Например искате
myfunc('hello')за извикване наmyfunc(character varying), но няма имплицитно преобразуване на тип отtextкъмcharacter varying(и би причинило неяснота, ако сте създали такъв). -
Защо
SELECT nullвръща колона от типunknown?Традиционният отговор е:Защото потребителят не е посочил типа.
Това поведение обаче е проблематично. Например, ако създадете таблица като тази:
CREATE TABLE test AS SELECT 'hello';ще получите колона от тип
unknown, което е нежелателно и ще създава проблеми по-нататък. Типътunknownнаистина не трябва да се вижда от потребителя, а по-скоро детайл от изпълнението.Следователно този ангажимент промени поведението от PostgreSQL v10 на:Сега всеки
unknownостава вSELECTилиRETURNINGсписък са принудени даtextи не могат да се създават таблици с колони от типunknown. -
Защо
SELECT NULL UNION SELECT 42работи, но неSELECT NULL UNION SELECT NULL UNION SELECT 42?Това се дължи на правилата за преобразуване на типове .
UNIONостава асоциативен, така че последната заявка се интерпретира като(SELECT NULL UNION SELECT NULL) UNION SELECT 42;Сега първият
UNIONразрешава до тип данниtextпоради правило 3:Това причинява грешка при опит за разрешаване на типа за втория
UNIONпоради правило 4:От друга страна, в заявката
SELECT NULL UNION SELECT 42;„NULL“ има тип
unknown, а „42“ има типinteger(избраният тип за числови литерали без десетична запетая).Правило 5
не се прилага тук, защото
integerне е предпочитан тип в своята категория (това би билоoidиdouble precision), затова се използва правило 6:Това води до тип
integer.