| PostgreSQL: Das Offizielle Handbuch | ||||
|---|---|---|---|---|
| Zurück | Schnell zurück | Schnell nach vorne | Nach vorne | |
In SQL-Befehlen kann es, absichtlich oder nicht, vorkommen, dass unterschiedliche Datentypen in einem Ausdruck auftreten. PostgreSQL hat diverse Mechanismen, um Ausdrücke mit gemischten Typen auszuwerten.
In vielen Fällen müssen Endanwender die Einzelheiten der Typumwandlungsmechanismen nicht kennen. Die impliziten Umwandlungen, die von PostgreSQL vorgenommen werden, können allerdings die Ergebnisse einer Anfrage beeinflussen. Wenn es notwendig ist, kann der Benutzer oder Programmierer diese Ergebnisse mit expliziten Umwandlungen kontrollieren.
Dieses Kapitel gibt eine Einführung in die Typumwandlungsmechanismen und -konventionen in PostgreSQL. Mehr Informationen über bestimmte Datentypen und die verfügbaren Funktionen und Operatoren finden Sie in Kapitel 8 bzw. Kapitel 9.
SQL ist eine Sprache mit einem starken Typensystem. Das heißt, jedes Stück Daten hat einen zugehörigen Datentyp, der das Verhalten und die erlaubte Verwendung bestimmt. PostgreSQL hat ein erweiterbares Typensystem, dass allgemeiner und flexibler als in anderen SQL-Implementierungen ist. Daher sollten die meisten Typumwandlungen in PostgreSQL von Regeln bestimmt werden, die allgemeingültig sind und nicht aus einer bestimmten Situation heraus aufgestellt wurden, damit Ausdrücke mit gemischten Datentypen auch mit benutzerdefinierten Typen funktionieren können.
Der Parser in PostgreSQL kategorisiert lexikalische Elemente in eine von nur fünf allgemeinen Gruppen: ganze Zahlen, Fließkommazahlen, Zeichenketten, Namen und Schlüsselwörter. Die meisten Erweiterungstypen werden am Anfang als Zeichenkette kategorisiert. Die Definition der SQL-Sprache erlaubt, dass man bei der Zeichenkette den Typ angeben kann, und damit kann man in PostgreSQL erreichen, dass der Parser gleich den korrekten Typ erfährt. Zum Beispiel hat die Anfrage
SELECT text 'Ursprung' AS "bezeichnung", point '(0,0)' AS "wert"; bezeichnung | wert -------------+------- Ursprung | (0,0) (1 row)
zwei Konstanten, mit den Typen text und point. Wenn kein Typ für eine Zeichenkettenkonstante angegeben wurde, dann wird erstmal der Platzhaltertyp unknown zugewiesen, der in späteren Phasen, wie unten beschrieben, aufgelöst wird.
Es gibt grundsätzlich vier SQL-Konstruktionen, wo im PostgreSQL-Parser unterschiedliche Regeln zur Umwandlung von Typen vonnöten sind:
PostgreSQL erlaubt Ausdrücke mit Präfix- und Postfix-Operatoren (unär/ein Operand), sowie binären (zwei Operanden) Operatoren.
Ein Großteil des PostgreSQL-Typensystems ist um eine große Zahl Funktionen aufgebaut. Funktionsaufrufe können ein oder mehrere Argumente haben. Da PostgreSQL das Überladen von Funktionen erlaubt, kann die aufzurufende Funktion nicht allein durch den Funktionsnamen identifiziert werden; das System wählt die richtige Funktion auf Grundlage der Datentypen der angegebenen Funktionsargumente.
Die SQL-Befehle INSERT und UPDATE speichern die Ergebnisse von Ausdrücken in einer Tabelle. Die Ausdrücke in dem Befehl müssen an die Datentypen der Zielspalten angepasst oder womöglich in diese umgewandelt werden.
Da alle Anfrageergebnisse eines SELECT-Befehls mit Mengenoperationen in den selben Ergebnisspalten erscheinen müssen, müssen die Ergebnistypen eines jeden SELECT angepasst und in einen jeweils einheitlichen Endergebnistyp umgewandelt werden. Auf ähnliche Art müssen die Teilausdrücke eines CASE-Ausdrucks in einen einheitlichen Typ umgewandelt werden, damit der gesamte CASE-Ausdruck einen vorhersehbaren Ergebnistyp haben kann.
Die Systemkatalogtabellen speichern Informationen darüber, welche Umwandlungen (englisch cast) zwischen Datentypen gültig sind und wie diese Umwandlungen durchzuführen sind. Zusätzliche Umwandlungen können vom Benutzer mit dem Befehl CREATE CAST bestimmt werden. (Das wird normalerweise in Verbindung mit der Erzeugung eines neuen Datentyps gemacht. Die Umwandlungsmöglichkeiten zwischen den eingebauten Typen wurden sehr sorgfältig ausgewählt und sollten nicht verändert werden.)
Außerdem gibt es einige eingebaute Regeln im Parser, um das erwartete Verhalten von Typen aus dem SQL-Standard zu ermöglichen. Dafür wurden mehrere allgemeine Typenkategorien festgelegt: boolean, numeric, string, bitstring, datetime, timespan, geometric, network und benutzerdefiniert. Jede Kategorie, mit Ausnahme der benutzerdefinierten Typen, hat einen bevorzugten Typ, welcher bevorzugt ausgewählt wird, wenn es Unklarheiten gibt. In der Kategorie der benutzerdefinierten Typen ist jeder Typ sein eigener bevorzugter Typ. Zweideutige Ausdrücke (mit mehreren möglichen Parse-Ergebnissen) können daher bei mehreren möglichen eingebauten Typen oft aufgelöst werden, aber bei mehreren möglichen benutzerdefinierten Typen gibt es eine Fehlermeldung.
Alle Regeln zur Typumwandlung wurden auf Grund mehrerer Prinzipien entworfen:
Implizite Umwandlungen sollten niemals überraschende oder unvorhersehbare Ergebnisse haben.
Benutzerdefinierte Typen, von denen der Parser von vornherein keine Kenntnis hat, sollten „höher“ in der Typenhierarchie stehen. In Ausdrücken mit gemischten Typen sollten eingebaute Typen immer in benutzerdefinierte Typen umgewandelt werden (natürlich nur wenn eine Umwandlung nötig ist).
Benutzerdefinierte Typen stehen in keinem Verhältnis zu einander. Gegenwärtig verfügt PostgreSQL über keine Informationen über Verhältnisse zwischen Typen, außer den Regeln für eingebaute Typen und den Beziehungen, die sich aus vorhandenen Funktionen ergeben.
Parser oder Executor sollten keine zusätzliche Arbeit haben, wenn eine Anfrage keine implizite Typumwandlung benötigt. Das heißt, wenn die Anfrage gut formuliert wurde und die Typen alle passen, dann sollte es möglich sein, die Anfrage zu verarbeiten, ohne zusätzliche Zeit im Parser aufzubringen oder unnötige implizite Umwandlungsfunktionen anzuwenden.
Zusätzlich sollte gelten, wenn eine Anfrage normalerweise für eine Funktion eine implizite Umwandlung nötig hat und der Benutzer dann eine neue Funktion mit den passenden Argumenttypen erzeugt, dann sollte der Parser diese neue Funktion verwenden und nicht mehr die alte Funktion mit der nötigen impliziten Umwandlung.
| Zurück | Zum Anfang | Nach vorne |
| Ausdrücke mit Unteranfragen | Nach oben | Operatoren |