SQL est un langage fortement typé. C'est-à-dire que chaque élément de données est associé à un type de données qui détermine son comportement et son utilisation permise. PostgreSQL a un système de types extensible qui est beaucoup plus général et flexible que les autres implémentations de SQL. Par conséquent, la plupart des comportements de conversion de types dans PostgreSQL est régie par des règles générales plutôt que par une heuristique ad hoc. Cela permet aux expressions de types mixtes d'être significatives, même avec des types définis par l'utilisateur.
L'analyseur de PostgreSQL divise les éléments lexicaux en cinq catégories fondamentales : les entiers, les nombres non entiers, les chaînes de caractères, les identifiants et les mots-clés. Les constantes de la plupart des types non numériques sont d'abord classifiées comme chaînes de caractères. La définition du langage SQL permet de spécifier le nom des types avec une chaîne et ce mécanisme peut être utilisé dans PostgreSQL pour lancer l'analyseur sur le bon chemin. Par exemple, la requête :
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
a deux constantes littérales, de types text
et
point
. Si un type n'est pas spécifié pour une chaîne
littérale, alors le type unknown
est assigné
initialement pour être résolu dans les étapes ultérieures comme décrit
plus bas.
Il y a quatre constructions SQL fondamentales qui exigent des règles distinctes de conversion de types dans l'analyseur de PostgreSQL :
Une grande partie du système de types de PostgreSQL est construite autour d'un riche ensemble de fonctions. Les fonctions peuvent avoir un ou plusieurs arguments. Puisque PostgreSQL permet la surcharge des fonctions, le nom seul de la fonction n'identifie pas de manière unique la fonction à appeler ; l'analyseur doit sélectionner la bonne fonction par rapport aux types des arguments fournis.
PostgreSQL autorise les expressions avec des opérateurs de préfixe (un argument) aussi bien que infixes (deux arguments). Comme les fonctions, les opérateurs peuvent être surchargés. Du coup, le même problème existe pour sélectionner le bon opérateur.
Les instructions SQL INSERT
et
UPDATE
placent le résultat des expressions dans
une table. Les expressions dans une instruction doivent être en accord avec
le type des colonnes cibles et peuvent être converties vers celles-ci.
UNION
, CASE
et des
constructions relatives
Comme toutes les requêtes issues d'une instruction
SELECT
utilisant une union doivent apparaître dans
un ensemble unique de colonnes, les types de résultats de chaque
instruction SELECT
doivent être assortis et convertis en un
ensemble uniforme. De façon similaire, les expressions de résultats d'une
construction CASE
doivent être converties vers un type commun
de façon à ce que l'ensemble de l'expression CASE
ait un
type de sortie connu. Quelques autres constructions, telles que
ARRAY[]
et les fonctions GREATEST
et LEAST
, nécessitent de la même façon la détermination
d'un type commun aux différentes sous-expressions.
Les catalogues systèmes stockent les informations concernant l'existence de conversions entre certains types de données et la façon d'exécuter ces conversions. Les conversions sont appelées casts en anglais. Des conversions de types supplémentaires peuvent être ajoutées par l'utilisateur avec la commande CREATE CAST (c'est habituellement réalisé en conjonction avec la définition de nouveaux types de données. L'ensemble des conversions entre les types prédéfinis a été soigneusement choisi et le mieux est de ne pas le modifier).
Une heuristique supplémentaire est fournie dans l'analyseur pour permettre de
meilleures estimations sur la bonne conversion de type parmi un groupe de types
qui ont des conversions implicites. Les types de données sont divisés en
plusieurs catégories de type basiques, incluant
boolean
, numeric
, string
,
bitstring
, datetime
, timespan
,
geometric
, network
et définis par l'utilisateur.
(Pour une liste, voir Tableau 51.65 ; mais
notez qu'il est aussi possible de créer des catégories de type personnalisées.)
À l'intérieur de chaque catégorie, il peut y avoir un ou plusieurs
types préférés, qui sont sélectionnés quand il y a un
choix possible de types. Avec une sélection attentive des types
préférés et des conversions implicites disponibles, il est possible de s'assurer
que les expressions ambiguës (celles avec plusieurs solutions candidates) peuvent
être résolues d'une façon utile.
Toutes les règles de conversions de types sont écrites en gardant à l'esprit plusieurs principes :
Les conversions implicites ne doivent jamais avoir de résultats surprenants ou imprévisibles.
Il n'y aura pas de surcharge depuis l'analyseur ou l'exécuteur si une requête n'a pas besoin d'une conversion implicite de types. C'est-à-dire que si une requête est bien formulée et si les types sont déjà bien distinguables, alors la requête devra s'exécuter sans perte de temps supplémentaire et sans introduire à l'intérieur de celle-ci des appels à des conversions implicites non nécessaires.
De plus, si une requête nécessite habituellement une conversion implicite pour une fonction et si l'utilisateur définit une nouvelle fonction avec les types des arguments corrects, l'analyseur devrait utiliser cette nouvelle fonction et ne fera plus des conversions implicites en utilisant l'ancienne fonction.