PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Was ist die Regel für "unbekannt" und Typrückschluss?

Da sind eigentlich drei Fragen drin, die ich versuchen werde zu beantworten.

  1. Was ist der Zweck von unknown ?

    Dies ist der Datentyp, der ursprünglich NULL-Werten und Zeichenfolgenliteralen in SQL-Anweisungen zugewiesen wurde. Wenn solche Literale zugewiesen wurden, geben Sie text ein sofort wäre es schwierig, auf den richtigen Typ zu schließen.

    Zum Beispiel möchten Sie myfunc('hello') um myfunc(character varying) aufzurufen , aber es gibt keine implizite Typumwandlung von text zu character varying (und es würde Unklarheiten verursachen, wenn Sie eine erstellen).

  2. Warum ist SELECT null gibt eine Spalte vom Typ unknown zurück ?

    Die traditionelle Antwort lautet:Weil der Benutzer den Typ nicht angegeben hat.

    Dieses Verhalten war jedoch problematisch. Wenn Sie beispielsweise eine Tabelle wie diese erstellen:

    CREATE TABLE test
       AS SELECT 'hello';
    

    Sie würden am Ende eine Spalte vom Typ unknown erhalten , was unerwünscht ist und später zu Problemen führen wird. Der Typ unknown sollte wirklich nicht für den Benutzer sichtbar sein, sondern eher ein Implementierungsdetail.

    Folglich dieses Commit hat das Verhalten ab PostgreSQL v10 geändert:Jetzt jeder unknown s links in einem SELECT oder RETURNING list werden zu text gezwungen , und Tabellen können nicht mit Spalten des Typs unknown erstellt werden .

  3. Warum SELECT NULL UNION SELECT 42 funktionieren, aber nicht SELECT NULL UNION SELECT NULL UNION SELECT 42 ?

    Dies ist den Typkonvertierungsregeln geschuldet .UNION bleibt assoziativ, daher wird letztere Abfrage als

    interpretiert
    (SELECT NULL UNION SELECT NULL) UNION SELECT 42;
    

    Nun die erste UNION wird in den Datentyp text aufgelöst wegen Regel 3:

    Dies verursacht einen Fehler beim Versuch, den Typ für die zweite UNION aufzulösen wegen Regel 4:

    Andererseits in der Abfrage

    SELECT NULL UNION SELECT 42;
    

    „NULL“ hat den Typ unknown , und „42“ hat den Typ integer (der für numerische Literale ohne Dezimalpunkt gewählte Typ).

    Regel 5

    trifft hier nicht zu, weil integer ist kein bevorzugter Typ in seiner Kategorie (das wäre oid und double precision ), also wird Regel 6 verwendet:

    Dies ergibt eine Art integer .