Всъщност има три въпроса, на които ще се опитам да отговоря.
-
Каква е целта на
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
.