Da sind eigentlich drei Fragen drin, die ich versuchen werde zu beantworten.
-
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
textein sofort wäre es schwierig, auf den richtigen Typ zu schließen.Zum Beispiel möchten Sie
myfunc('hello')ummyfunc(character varying)aufzurufen , aber es gibt keine implizite Typumwandlung vontextzucharacter varying(und es würde Unklarheiten verursachen, wenn Sie eine erstellen). -
Warum ist
SELECT nullgibt eine Spalte vom Typunknownzurü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
unknownerhalten , was unerwünscht ist und später zu Problemen führen wird. Der Typunknownsollte 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
unknowns links in einemSELECToderRETURNINGlist werden zutextgezwungen , und Tabellen können nicht mit Spalten des Typsunknownerstellt werden . -
Warum
SELECT NULL UNION SELECT 42funktionieren, aber nichtSELECT NULL UNION SELECT NULL UNION SELECT 42?Dies ist den Typkonvertierungsregeln geschuldet .
interpretiertUNIONbleibt assoziativ, daher wird letztere Abfrage als(SELECT NULL UNION SELECT NULL) UNION SELECT 42;Nun die erste
UNIONwird in den Datentyptextaufgelöst wegen Regel 3:Dies verursacht einen Fehler beim Versuch, den Typ für die zweite
UNIONaufzulösen wegen Regel 4:Andererseits in der Abfrage
SELECT NULL UNION SELECT 42;„NULL“ hat den Typ
unknown, und „42“ hat den Typinteger(der für numerische Literale ohne Dezimalpunkt gewählte Typ).Regel 5
trifft hier nicht zu, weil
integerist kein bevorzugter Typ in seiner Kategorie (das wäreoidunddouble precision), also wird Regel 6 verwendet:Dies ergibt eine Art
integer.