sql >> Base de Datos >  >> RDS >> PostgreSQL

¿Cuál es la regla para 'desconocido' y tipo de inferencia?

En realidad, hay tres preguntas que intentaré responder.

  1. ¿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 invocar myfunc(character varying) , pero no hay una conversión de tipos implícita de text a character varying (y causaría ambigüedad si crearas uno).

  2. ¿Por qué SELECT null devolver una columna de tipo unknown ?

    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 tipo unknown 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 un SELECT o RETURNING la lista está obligada a text , y las tablas no se pueden crear con columnas de tipo unknown .

  3. ¿Por qué SELECT NULL UNION SELECT 42 funciona, pero no SELECT 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 datos text 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 tipo integer (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ía oid y double precision ), por lo que se utiliza la regla 6:

    Esto da como resultado un tipo de integer .