Il y a en fait trois questions auxquelles je vais essayer de répondre.
-
Quel est le but de
unknown?Il s'agit du type de données initialement attribué aux valeurs NULL et aux littéraux de chaîne dans les instructions SQL. Si de tels littéraux ont été attribués, tapez
textimmédiatement, il serait difficile de déduire le type correct.Par exemple, vous voulez
myfunc('hello')pour invoquermyfunc(character varying), mais il n'y a pas de conversion de type implicite à partir detextàcharacter varying(et cela créerait une ambiguïté si vous en créiez un). -
Pourquoi
SELECT nullrenvoie une colonne de typeunknown?La réponse traditionnelle est :parce que l'utilisateur n'a pas spécifié le type.
Cependant, ce comportement a été problématique. Par exemple, si vous créez un tableau comme celui-ci :
CREATE TABLE test AS SELECT 'hello';vous vous retrouveriez avec une colonne de type
unknown, ce qui n'est pas souhaitable et causera des problèmes par la suite. Le typeunknownne devrait vraiment pas être visible par l'utilisateur, mais plutôt un détail de mise en œuvre.Par conséquent, ce commit a changé le comportement à partir de PostgreSQL v10 :Maintenant, tout
unknownest laissé dans unSELECTouRETURNINGlist sont forcés àtext, et les tables ne peuvent pas être créées avec des colonnes de typeunknown. -
Pourquoi
SELECT NULL UNION SELECT 42fonctionne, mais pasSELECT NULL UNION SELECT NULL UNION SELECT 42?Cela est dû aux règles de conversion de type .
UNIONest laissé associatif, donc la dernière requête est interprétée comme(SELECT NULL UNION SELECT NULL) UNION SELECT 42;Maintenant le premier
UNIONse résout au type de donnéestextà cause de la règle 3 :Cela provoque une erreur lors de la tentative de résolution du type pour le deuxième
UNIONà cause de la règle 4 :Par contre, dans la requête
SELECT NULL UNION SELECT 42;"NULL" a le type
unknown, et "42" est de typeinteger(le type choisi pour les littéraux numériques sans point décimal).Règle 5
ne s'applique pas ici, car
integern'est pas un type préféré dans sa catégorie (ce seraitoidetdouble precision), donc la règle 6 est utilisée :Cela se traduit par un type de
integer.