SQL es un lenguaje fuertemente tipado. Es decir, cada elemento de datos tiene un tipo de datos asociado que determina su comportamiento y el uso permitido. PostgreSQL tiene un sistema de tipos extensible que es más general y flexible que otras implementaciones de SQL. Por lo tanto, la mayor parte del comportamiento de conversión de tipos en PostgreSQL se rige por reglas generales en lugar de heurísticas ad hoc. Esto permite el uso de expresiones de tipos mixtos incluso con tipos definidos por el usuario.
El escáner/analizador (scanner/parser) de PostgreSQL divide los elementos léxicos en cinco categorías fundamentales: enteros, números no enteros, cadenas, identificadores y palabras clave. Las constantes de la mayoría de los tipos no numéricos se clasifican primero como cadenas. La definición del lenguaje SQL permite especificar nombres de tipo con cadenas, y este mecanismo se puede utilizar en PostgreSQL para iniciar el analizador por el camino correcto. Por ejemplo, la consulta:
SELECT text 'Origin' AS "label", point '(0,0)' AS "value"; label | value --------+------- Origin | (0,0) (1 row)
tiene dos constantes literales, de tipo text y point.
Si no se especifica un tipo para un literal de cadena, inicialmente se asigna el tipo
provisional unknown, que se resolverá en etapas posteriores como se describe a
continuación.
Existen cuatro constructores SQL fundamentales que requieren reglas de conversión de tipos distintas en el analizador de PostgreSQL:
Gran parte del sistema de tipos de PostgreSQL está construido alrededor de un rico conjunto de funciones. Las funciones pueden tener uno o más argumentos. Dado que PostgreSQL permite la sobrecarga de funciones, el nombre de la función por sí solo no identifica de forma única la función que se llamará; el analizador debe seleccionar la función correcta basándose en los tipos de datos de los argumentos suministrados.
PostgreSQL permite expresiones con operadores prefijos (de un argumento), así como operadores infijos (de dos argumentos). Al igual que las funciones, los operadores se pueden sobrecargar, por lo que existe el mismo problema de seleccionar el operador correcto.
Las sentencias SQL INSERT y UPDATE
colocan los resultados de las expresiones en una tabla. Las expresiones en la sentencia
deben coincidir con los tipos de las columnas de destino, y tal vez convertirse a ellos.
UNION, CASE y constructores relacionados
Dado que todos los resultados de una consulta de una sentencia SELECT
con unión deben aparecer en un único conjunto de columnas, los tipos de los resultados de
cada cláusula SELECT deben coincidir y convertirse en un conjunto uniforme.
Del mismo modo, las expresiones de resultado de un constructor CASE deben
convertirse a un tipo común para que la expresión CASE en su conjunto
tenga un tipo de salida conocido. Algunos otros constructores, como ARRAY[]
y las funciones GREATEST y LEAST, requieren asimismo
la determinación de un tipo común para varias subexpresiones.
Los catálogos del sistema almacenan información sobre qué conversiones, o casts (moldes), existen entre qué tipos de datos y cómo realizar esas conversiones. El usuario puede agregar casts adicionales con el comando CREATE CAST. (Esto generalmente se hace junto con la definición de nuevos tipos de datos. El conjunto de casts entre tipos incorporados se ha diseñado cuidadosamente y es mejor no alterarlo).
Una heurística adicional proporcionada por el analizador permite una mejor determinación
del comportamiento de casting adecuado entre grupos de tipos que tienen casts implícitos.
Los tipos de datos se dividen en varias categorías de tipos
básicas, que incluyen boolean, numeric,
string, bitstring, datetime,
timespan, geometric, network y
definidos por el usuario. (Para una lista, consulta Table 52.65;
pero ten en cuenta que también es posible crear categorías de tipos personalizadas). Dentro de
cada categoría puede haber uno o más tipos preferidos, que
se prefieren cuando hay una opción de tipos posibles. Con una selección cuidadosa de los
tipos preferidos y de los casts implícitos disponibles, es posible asegurar que las expresiones
ambiguas (aquellas con múltiples soluciones candidatas de análisis) se puedan resolver de una
manera útil.
Todas las reglas de conversión de tipos se diseñan teniendo en cuenta varios principios:
Las conversiones implícitas nunca deberían tener resultados sorprendentes o impredecibles.
No debería haber una sobrecarga adicional en el analizador o el ejecutor si una consulta no necesita conversión de tipos implícita. Es decir, si una consulta está bien formada y los tipos ya coinciden, la consulta debería ejecutarse sin gastar tiempo extra en el analizador y sin introducir llamadas de conversión implícita innecesarias en la consulta.
Además, si una consulta generalmente requiere una conversión implícita para una función, y si luego el usuario define una nueva función con los tipos de argumentos correctos, el analizador debería usar esta nueva función y dejar de realizar la conversión implícita para usar la función antigua.