En realidad, hay tres preguntas que intentaré responder.
-
¿Cuál es el propósito de
unknown
?Este es el tipo de datos asignado inicialmente a NULL y literales de cadena en declaraciones SQL. Si tales literales fueran asignados escriba
text
inmediatamente, sería difícil inferir el tipo correcto.Por ejemplo, quieres
myfunc('hello')
para invocarmyfunc(character varying)
, pero no hay una conversión de tipos implícita detext
acharacter varying
(y causaría ambigüedad si crearas uno). -
¿Por qué
SELECT null
devolver una columna de tipounknown
?La respuesta tradicional es:porque el usuario no especificó el tipo.
Sin embargo, este comportamiento ha sido problemático. Por ejemplo, si crea una tabla como esta:
CREATE TABLE test AS SELECT 'hello';
terminaría con una columna de tipo
unknown
, lo cual es indeseable y causará problemas más adelante. El tipounknown
realmente no debería ser visible para el usuario, sino más bien un detalle de implementación.En consecuencia, este compromiso ha cambiado el comportamiento de PostgreSQL v10 en:Ahora cualquier
unknown
queda en unSELECT
oRETURNING
la lista está obligada atext
, y las tablas no se pueden crear con columnas de tipounknown
. -
¿Por qué
SELECT NULL UNION SELECT 42
funciona, pero noSELECT NULL UNION SELECT NULL UNION SELECT 42
?Esto se debe a las reglas de conversión de tipos .
UNION
se deja asociativa, por lo que la última consulta se interpreta como(SELECT NULL UNION SELECT NULL) UNION SELECT 42;
Ahora el primer
UNION
se resuelve en el tipo de datostext
por la regla 3:Esto provoca un error al intentar resolver el tipo para el segundo
UNION
debido a la regla 4:Por otro lado, en la consulta
SELECT NULL UNION SELECT 42;
“NULL” tiene tipo
unknown
, y "42" tiene tipointeger
(el tipo elegido para literales numéricos sin punto decimal).Regla 5
no se aplica aquí, porque
integer
no es un tipo preferido en su categoría (que seríaoid
ydouble precision
), por lo que se utiliza la regla 6:Esto da como resultado un tipo de
integer
.