PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Qual è la regola per "sconosciuto" e inferenza di tipo?

In realtà ci sono tre domande a cui cercherò di rispondere.

  1. Qual è lo scopo di unknown ?

    Questo è il tipo di dati inizialmente assegnato a NULL e letterali stringa nelle istruzioni SQL. Se sono stati assegnati tali valori letterali, digitare text immediatamente, sarebbe difficile dedurre il tipo corretto.

    Ad esempio, vuoi myfunc('hello') per invocare myfunc(character varying) , ma non esiste un cast di tipo implicito da text a character varying (e causerebbe ambiguità se ne creassi uno).

  2. Perché SELECT null restituisce una colonna di tipo unknown ?

    La risposta tradizionale è:perché l'utente non ha specificato il tipo.

    Tuttavia, questo comportamento è stato problematico. Ad esempio, se crei una tabella come questa:

    CREATE TABLE test
       AS SELECT 'hello';
    

    finiresti con una colonna di tipo unknown , che è indesiderabile e causerà problemi più avanti. Il tipo unknown in realtà non dovrebbe essere visibile dall'utente, ma piuttosto un dettaglio di implementazione.

    Di conseguenza, questo commit ha cambiato il comportamento da PostgreSQL v10 in poi:Ora qualsiasi unknown s lasciato in un SELECT o RETURNING list sono forzati a text e non è possibile creare tabelle con colonne di tipo unknown .

  3. Perché SELECT NULL UNION SELECT 42 funziona, ma non SELECT NULL UNION SELECT NULL UNION SELECT 42 ?

    Ciò è dovuto alle regole di conversione del tipo .UNION è associativa a sinistra, quindi quest'ultima query viene interpretata come

    (SELECT NULL UNION SELECT NULL) UNION SELECT 42;
    

    Ora il primo UNION si risolve nel tipo di dati text a causa della regola 3:

    Ciò provoca un errore quando si tenta di risolvere il tipo per il secondo UNION a causa della regola 4:

    D'altra parte, nella query

    SELECT NULL UNION SELECT 42;
    

    "NULL" ha il tipo unknown e "42" ha il tipo integer (il tipo scelto per i valori letterali numerici senza punto decimale).

    Regola 5

    non si applica qui, perché integer non è un tipo preferito nella sua categoria (che sarebbe oid e double precision ), quindi viene utilizzata la regola 6:

    Ciò si traduce in un tipo di integer .