CREATE FUNCTION — definir una nueva función
CREATE [ OR REPLACE ] FUNCTION
nombre ( [ [ modo_arg ] [ nombre_arg ] tipo_arg [ { DEFAULT | = } expresión_por_defecto ] [, ...] ] )
[ RETURNS tipo_retorno
| RETURNS TABLE ( nombre_columna tipo_columna [, ...] ) ]
{ LANGUAGE nombre_lenguaje
| TRANSFORM { FOR TYPE nombre_tipo } [, ... ]
| WINDOW
| { IMMUTABLE | STABLE | VOLATILE }
| [ NOT ] LEAKPROOF
| { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
| { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
| PARALLEL { UNSAFE | RESTRICTED | SAFE }
| COST costo_ejecución
| ROWS filas_resultado
| SUPPORT función_soporte
| SET parámetro_configuración { TO valor | = valor | FROM CURRENT }
| AS 'definición'
| AS 'archivo_objeto', 'símbolo_enlace'
| cuerpo_sql
} ...
CREATE FUNCTION define una nueva función.
CREATE OR REPLACE FUNCTION creará una nueva función o
reemplazará una definición existente.
Para poder definir una función, el usuario debe tener el privilegio
USAGE en el lenguaje.
Si se incluye un nombre de esquema, la función se crea en el esquema especificado. De lo contrario, se crea en el esquema actual. El nombre de la nueva función no debe coincidir con ninguna función o procedimiento existente con los mismos tipos de argumentos de entrada en el mismo esquema. Sin embargo, las funciones y procedimientos con diferentes tipos de argumentos pueden compartir el nombre (esto se conoce como sobrecarga).
Para reemplazar la definición actual de una función existente, utiliza
CREATE OR REPLACE FUNCTION. No es posible cambiar el nombre
o los tipos de argumentos de una función de esta manera (si lo intentaras, en realidad
estarías creando una función nueva y distinta). Además, CREATE OR REPLACE FUNCTION
no te permitirá cambiar el tipo de retorno de una función existente. Para hacer eso,
debes eliminar y volver a crear la función. (Cuando utilizas parámetros OUT,
eso significa que no puedes cambiar los tipos de ningún parámetro OUT
excepto eliminando la función).
Cuando se utiliza CREATE OR REPLACE FUNCTION para reemplazar una
función existente, la propiedad y los permisos de la función no cambian. Todas las demás
propiedades de la función reciben los valores especificados o implícitos en el comando.
Debes ser el propietario de la función para reemplazarla (esto incluye ser miembro del rol propietario).
Si eliminas y luego vuelves a crear una función, la nueva función no es la misma entidad
que la antigua; tendrás que eliminar las reglas, vistas, disparadores (triggers), etc., existentes
que hagan referencia a la función antigua. Utiliza CREATE OR REPLACE FUNCTION
para cambiar la definición de una función sin romper los objetos que hacen referencia a ella.
Además, se puede usar ALTER FUNCTION para cambiar la mayoría de las
propiedades auxiliares de una función existente.
El usuario que crea la función se convierte en su propietario.
Para poder crear una función, debes tener el privilegio USAGE
en los tipos de argumentos y en el tipo de retorno.
Consulta la Section 36.3 para obtener más información sobre cómo escribir funciones.
nombreEl nombre (opcionalmente calificado por esquema) de la función que se va a crear.
modo_arg
El modo de un argumento: IN, OUT,
INOUT o VARIADIC. Si se omite, el valor
predeterminado es IN. Solo los argumentos OUT
pueden seguir a uno VARIADIC. Además, los argumentos OUT
y INOUT no se pueden usar junto con la notación RETURNS TABLE.
nombre_argEl nombre de un argumento. Algunos lenguajes (incluidos SQL y PL/pgSQL) te permiten usar el nombre en el cuerpo de la función. Para otros lenguajes, el nombre de un argumento de entrada es solo documentación adicional en lo que respecta a la función en sí; pero puedes usar los nombres de los argumentos de entrada al llamar a una función para mejorar la legibilidad (consulta la Section 4.3). En cualquier caso, el nombre de un argumento de salida es significativo, porque define el nombre de la columna en el tipo de fila del resultado. (Si omites el nombre de un argumento de salida, el sistema elegirá un nombre de columna por defecto).
tipo_argEl tipo o tipos de datos de los argumentos de la función (opcionalmente calificados por esquema), si los hay. Los tipos de argumentos pueden ser tipos base, compuestos o dominios, o pueden hacer referencia al tipo de una columna de tabla.
Según el lenguaje de implementación, también puede estar permitido especificar «pseudotipos»
como cstring. Los pseudotipos indican que el tipo de argumento real está especificado
de forma incompleta o está fuera del conjunto de tipos de datos SQL ordinarios.
Se hace referencia al tipo de una columna escribiendo
.
El uso de esta característica a veces puede ayudar a que una función sea independiente de los
cambios en la definición de una tabla.
nombre_tabla.nombre_columna%TYPE
expresión_por_defecto
Una expresión que se utilizará como valor predeterminado si no se especifica el parámetro.
La expresión debe ser coercible al tipo de argumento del parámetro. Solo los parámetros de
entrada (incluido INOUT) pueden tener un valor predeterminado. Todos los
parámetros de entrada que siguen a un parámetro con un valor predeterminado también deben tener
valores predeterminados.
tipo_retorno
El tipo de datos de retorno (opcionalmente calificado por esquema). El tipo de retorno puede
ser un tipo base, compuesto o dominio, o puede hacer referencia al tipo de una columna de tabla.
Según el lenguaje de implementación, también puede estar permitido especificar «pseudotipos»
como cstring. Si la función no debe devolver un valor, especifica void
como tipo de retorno.
Cuando hay parámetros OUT o INOUT, la cláusula
RETURNS se puede omitir. Si está presente, debe coincidir con el tipo de resultado
implícito por los parámetros de salida: RECORD si hay múltiples parámetros de salida,
o el mismo tipo que el único parámetro de salida.
El modificador SETOF indica que la función devolverá un conjunto de elementos,
en lugar de un solo elemento.
Se hace referencia al tipo de una columna escribiendo
.
nombre_tabla.nombre_columna%TYPE
nombre_columna
El nombre de una columna de salida en la sintaxis RETURNS TABLE. Esta es efectivamente
otra forma de declarar un parámetro OUT nombrado, excepto que RETURNS TABLE
también implica RETURNS SETOF.
tipo_columna
El tipo de datos de una columna de salida en la sintaxis RETURNS TABLE.
nombre_lenguaje
El nombre del lenguaje en el que está implementada la función. Puede ser sql,
c, internal o el nombre de un lenguaje procedimental definido
por el usuario, por ejemplo, plpgsql. El valor por defecto es sql
si se especifica cuerpo_sql. Encerrar el nombre entre
comillas simples está obsoleto y requiere que coincidan las mayúsculas y minúsculas.
TRANSFORM { FOR TYPE nombre_tipo } [, ... ] }Enumera qué transformaciones debe aplicar una llamada a la función. Las transformaciones convierten entre tipos SQL y tipos de datos específicos del lenguaje; consulta la CREATE TRANSFORM. Las implementaciones de lenguajes procedimentales suelen tener un conocimiento codificado de los tipos incorporados, por lo que no es necesario enumerarlos aquí. Si una implementación de lenguaje procedimental no sabe cómo manejar un tipo y no se proporciona ninguna transformación, recurrirá a un comportamiento predeterminado para convertir los tipos de datos, pero esto depende de la implementación.
WINDOWWINDOW indica que la función es una función de ventana (window function)
en lugar de una función común. Actualmente, esto solo es útil para funciones escritas en C.
El atributo WINDOW no se puede cambiar al reemplazar la definición de una función existente.
IMMUTABLESTABLEVOLATILE
Estos atributos informan al optimizador de consultas sobre el comportamiento de la función.
Se puede especificar como máximo una opción. Si no aparece ninguna de estas, se asume
VOLATILE por defecto.
IMMUTABLE indica que la función no puede modificar la base de datos y
siempre devuelve el mismo resultado cuando se le proporcionan los mismos valores de argumentos; es decir,
no realiza búsquedas en la base de datos ni utiliza de otro modo información que no esté directamente
presente en su lista de argumentos. Si se proporciona esta opción, cualquier llamada a la función con
argumentos completamente constantes se puede reemplazar inmediatamente por el valor de la función.
STABLE indica que la función no puede modificar la base de datos y que, dentro
de un mismo escaneo de tabla, devolverá consistentemente el mismo resultado para los mismos valores de
argumentos, pero que su resultado podría cambiar entre sentencias SQL. Esta es la selección adecuada para
funciones cuyos resultados dependen de búsquedas en la base de datos, variables de parámetros (como la zona
horaria actual), etc. (Es inapropiada para disparadores AFTER que desean consultar filas
modificadas por el comando actual). Ten en cuenta también que la familia de funciones
current_timestamp califica como estable, ya que sus valores no cambian dentro de una transacción.
VOLATILE indica que el valor de la función puede cambiar incluso dentro de un mismo
escaneo de tabla, por lo que no se pueden realizar optimizaciones. Relativamente pocas funciones de base de datos
son volátiles en este sentido; algunos ejemplos son random(), currval(),
timeofday(). Pero ten en cuenta que cualquier función que tenga efectos secundarios debe clasificarse
como volátil, incluso si su resultado es bastante predecible, para evitar que las llamadas se optimicen y eliminen;
un ejemplo es setval().
Para obtener detalles adicionales, consulta la Section 36.7.
LEAKPROOF
LEAKPROOF indica que la función no tiene efectos secundarios. No revela información sobre
sus argumentos más que a través de su valor de retorno. Por ejemplo, una función que lanza un mensaje de error
para algunos valores de argumentos pero no para otros, o que incluye los valores de los argumentos en cualquier
mensaje de error, no es estanca (leakproof). Esto afecta a cómo el sistema ejecuta las consultas contra vistas creadas
con la opción security_barrier o tablas con seguridad a nivel de fila (RLS) habilitada. El sistema
hará cumplir las condiciones de las políticas de seguridad y de las vistas de barrera de seguridad antes de cualquier
condición proporcionada por el usuario desde la propia consulta que contenga funciones no estancas, con el fin de evitar
la exposición involuntaria de datos. Las funciones y operadores marcados como estancos se asumen confiables y pueden
ejecutarse antes de las condiciones de las políticas de seguridad y vistas de barrera de seguridad. Además, las funciones
que no reciben argumentos o a las que no se les pasa ningún argumento desde la vista de barrera de seguridad o la tabla
no tienen que estar marcadas como estancas para ejecutarse antes de las condiciones de seguridad. Consulta la
CREATE VIEW y la Section 39.5. Esta opción solo puede ser establecida por el superusuario.
CALLED ON NULL INPUTRETURNS NULL ON NULL INPUTSTRICTCALLED ON NULL INPUT (el valor predeterminado) indica que la función se llamará normalmente
cuando algunos de sus argumentos sean nulos. Es entonces responsabilidad del autor de la función verificar si hay
valores nulos si es necesario y responder adecuadamente.
RETURNS NULL ON NULL INPUT o STRICT indica que la función siempre devuelve
nulo cuando alguno de sus argumentos es nulo. Si se especifica este parámetro, la función no se ejecuta cuando hay
argumentos nulos; en su lugar, se asume automáticamente un resultado nulo.
[EXTERNAL] SECURITY INVOKER[EXTERNAL] SECURITY DEFINERSECURITY INVOKER indica que la función se debe ejecutar con los privilegios del usuario
que la llama. Ese es el valor predeterminado. SECURITY DEFINER especifica que la función se debe
ejecutar con los privilegios del usuario que la posee. Para obtener información sobre cómo escribir funciones
SECURITY DEFINER de forma segura, consulta más abajo.
La palabra clave EXTERNAL se permite para cumplir con el estándar SQL, pero es opcional ya que, a
diferencia de SQL, esta característica se aplica a todas las funciones, no solo a las externas.
PARALLEL
PARALLEL UNSAFE indica que la función no se puede ejecutar en modo paralelo; la presencia de dicha
función en una sentencia SQL fuerza un plan de ejecución secuencial. Este es el valor por defecto.
PARALLEL RESTRICTED indica que la función se puede ejecutar en modo paralelo, pero solo en el proceso
líder del grupo paralelo. PARALLEL SAFE indica que la función es segura para ejecutarse en modo paralelo
sin restricciones, incluso en procesos trabajadores paralelos.
Las funciones deben etiquetarse como inseguras para paralelismo (parallel unsafe) si modifican cualquier estado de la base
de datos, cambian el estado de la transacción (salvo mediante el uso de una subtransacción para la recuperación de errores),
acceden a secuencias (por ejemplo, llamando a currval) o realizan cambios persistentes en la configuración.
Deben etiquetarse como restringidas para paralelismo (parallel restricted) si acceden a tablas temporales, al estado de la
conexión del cliente, cursores, sentencias preparadas o estado local del backend diverso que el sistema no puede sincronizar
en modo paralelo (por ejemplo, setseed no puede ser ejecutado por otro proceso que no sea el líder del grupo
porque un cambio realizado por otro proceso no se reflejaría en el líder). En general, si una función se etiqueta como segura
cuando en realidad es restringida o insegura, o si se etiqueta como restringida cuando en realidad es insegura, puede lanzar
errores o producir respuestas incorrectas cuando se utiliza en una consulta paralela. Las funciones en lenguaje C podrían,
en teoría, exhibir un comportamiento totalmente indefinido si se etiquetan incorrectamente, ya que no hay forma de que el
sistema se proteja contra código C arbitrario, pero en la mayoría de los casos probables el resultado no será peor que para
cualquier otra función. En caso de duda, las funciones deben etiquetarse como UNSAFE, que es el valor por defecto.
COST costo_ejecuciónUn número positivo que indica el costo de ejecución estimado para la función, en unidades de cpu_operator_cost. Si la función devuelve un conjunto, este es el costo por fila devuelta. Si no se especifica el costo, se asume 1 unidad para las funciones en lenguaje C e internas, y 100 unidades para las funciones en todos los demás lenguajes. Los valores más grandes hacen que el planificador intente evitar evaluar la función más a menudo de lo necesario.
ROWS filas_resultadoUn número positivo que proporciona el número estimado de filas que el planificador debe esperar que devuelva la función. Esto solo se permite cuando la función se declara para devolver un conjunto. Se asume por defecto 1000 filas.
SUPPORT función_soporteEl nombre (opcionalmente calificado por esquema) de una función de soporte del planificador (planner support function) para usar con esta función. Consulta la Section 36.11 para más detalles. Debes ser superusuario para usar esta opción.
parámetro_configuraciónvalor
La cláusula SET hace que el parámetro de configuración especificado se establezca en el valor indicado
al entrar a la función, y luego se restaure a su valor anterior al salir de ella. SET FROM CURRENT
guarda el valor del parámetro que está activo cuando se ejecuta CREATE FUNCTION como el valor que se aplicará
al entrar a la función.
Si se adjunta una cláusula SET a una función, los efectos de un comando SET LOCAL
ejecutado dentro de la función para la misma variable se limitan a la función: el valor anterior del parámetro de configuración
se restaura al salir de la función. Sin embargo, un comando SET ordinario (sin LOCAL)
anula la cláusula SET, al igual que lo haría para un comando SET LOCAL anterior: los efectos
de dicho comando persistirán después de salir de la función, a menos que se revierta la transacción actual.
Consulta la SET y la Chapter 19 para obtener más información sobre los nombres y valores de parámetros permitidos.
definiciónUna constante de cadena que define la función; el significado depende del lenguaje. Puede ser el nombre de una función interna, la ruta a un archivo de objeto, un comando SQL o texto en un lenguaje procedimental.
A menudo resulta útil usar la delimitación por dólares (dollar quoting, consulta la Section 4.1.2.4) para escribir la cadena de definición de la función, en lugar de la sintaxis normal de comillas simples. Sin la delimitación por dólares, las comillas simples o barras invertidas en la definición de la función deben escaparse duplicándolas.
archivo_objeto, símbolo_enlace
Esta forma de la cláusula AS se utiliza para funciones en lenguaje C cargables dinámicamente cuando el
nombre de la función en el código fuente del lenguaje C no es el mismo que el nombre de la función SQL. La cadena
archivo_objeto es el nombre del archivo de biblioteca compartida que contiene
la función C compilada, y se interpreta como en el comando LOAD. La cadena
símbolo_enlace es el símbolo de enlace de la función, es decir, el nombre de la
función en el código fuente del lenguaje C. Si se omite el símbolo de enlace, se asume que es el mismo que el nombre de la
función SQL que se está definiendo. Los nombres C de todas las funciones deben ser diferentes, por lo que debes dar a las
funciones C sobrecargadas diferentes nombres C (por ejemplo, usar los tipos de argumentos como parte de los nombres C).
Cuando llamadas repetidas a CREATE FUNCTION hacen referencia al mismo archivo de objeto, el archivo solo
se carga una vez por sesión. Para descargar y volver a cargar el archivo (quizás durante el desarrollo), inicia una nueva sesión.
cuerpo_sql
El cuerpo de una función LANGUAGE SQL. Esto puede ser una sola sentencia
RETURN expresión
o un bloque
BEGIN ATOMICsentencia;sentencia; ...sentencia; END
Esto es similar a escribir el texto del cuerpo de la función como una constante de cadena (consulta
definición más arriba), pero existen algunas diferencias: esta forma solo funciona para
LANGUAGE SQL, mientras que la forma de constante de cadena funciona para todos los lenguajes. Esta forma se
analiza (parse) en el momento de la definición de la función, mientras que la forma de constante de cadena se analiza en el momento
de la ejecución; por lo tanto, esta forma no admite tipos de argumentos polimórficos ni otros constructos que no se puedan
resolver en el momento de la definición de la función. Esta forma rastrea las dependencias entre la función y los objetos utilizados
en el cuerpo de la función, por lo que DROP ... CASCADE funcionará correctamente, mientras que la forma que utiliza
literales de cadena puede dejar funciones huérfanas. Finalmente, esta forma es más compatible con el estándar SQL y otras
implementaciones de SQL.
PostgreSQL permite la sobrecarga de funciones; es decir, se puede usar el mismo nombre para varias funciones diferentes siempre que tengan tipos de argumentos de entrada distintos. Utilices o no esta capacidad, conlleva precauciones de seguridad al llamar a funciones en bases de datos donde algunos usuarios desconfían de otros; consulta la Section 10.3.
Dos funciones se consideran iguales si tienen los mismos nombres y tipos de argumentos de entrada,
ignorando cualquier parámetro OUT. Por lo tanto, por ejemplo, estas declaraciones entran en conflicto:
CREATE FUNCTION foo(int) ... CREATE FUNCTION foo(int, out text) ...
Las funciones que tienen diferentes listas de tipos de argumentos no se considerarán en conflicto en el momento de la creación, pero si se proporcionan valores predeterminados podrían entrar en conflicto en su uso. Por ejemplo, considera:
CREATE FUNCTION foo(int) ... CREATE FUNCTION foo(int, int default 42) ...
Una llamada foo(10) fallará debido a la ambigüedad sobre qué función debe llamarse.
Se permite la sintaxis completa de tipos SQL para declarar los argumentos y el valor de retorno de una función.
Sin embargo, los modificadores de tipo entre paréntesis (por ejemplo, el campo de precisión para el tipo numeric)
son descartados por CREATE FUNCTION. Por lo tanto, por ejemplo,
CREATE FUNCTION foo (varchar(10)) ...
es exactamente lo mismo que
CREATE FUNCTION foo (varchar) ....
Al reemplazar una función existente con CREATE OR REPLACE FUNCTION, existen restricciones para cambiar los
nombres de los parámetros. No puedes cambiar el nombre ya asignado a ningún parámetro de entrada (aunque puedes agregar nombres
a parámetros que no tenían ninguno antes). Si hay más de un parámetro de salida, no puedes cambiar los nombres de los parámetros de
salida, porque eso cambiaría los nombres de las columnas del tipo compuesto anónimo que describe el resultado de la función.
Estas restricciones se realizan para garantizar que las llamadas existentes a la función no dejen de funcionar cuando se reemplace.
Si una función se declara como STRICT con un argumento VARIADIC, la verificación de estrictez
comprueba que el array variádico en su conjunto no sea nulo. La función se seguirá llamando si el array tiene
elementos nulos.
Suma dos enteros usando una función SQL:
CREATE FUNCTION add(integer, integer) RETURNS integer
AS 'select $1 + $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;
La misma función escrita en un estilo más conforme al estándar SQL, usando nombres de argumentos y un cuerpo sin comillas:
CREATE FUNCTION add(a integer, b integer) RETURNS integer
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT
RETURN a + b;
Incrementa un entero, haciendo uso de un nombre de argumento, en PL/pgSQL:
CREATE OR REPLACE FUNCTION increment(i integer) RETURNS integer AS $$
BEGIN
RETURN i + 1;
END;
$$ LANGUAGE plpgsql;
Devuelve un registro que contiene múltiples parámetros de salida:
CREATE FUNCTION dup(in int, out f1 int, out f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
Puedes hacer lo mismo de manera más verbosa con un tipo compuesto nombrado explícitamente:
CREATE TYPE dup_result AS (f1 int, f2 text);
CREATE FUNCTION dup(int) RETURNS dup_result
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
Otra forma de devolver múltiples columnas es usar una función TABLE:
CREATE FUNCTION dup(int) RETURNS TABLE(f1 int, f2 text)
AS $$ SELECT $1, CAST($1 AS text) || ' is text' $$
LANGUAGE SQL;
SELECT * FROM dup(42);
Sin embargo, una función TABLE es diferente de los ejemplos anteriores, porque en realidad devuelve un
conjunto de registros, no solo un registro.
SECURITY DEFINER de forma segura
Debido a que una función SECURITY DEFINER se ejecuta con los privilegios del usuario que la posee, se debe tener
cuidado para garantizar que la función no pueda ser utilizada indebidamente. Para mayor seguridad, search_path
debe establecerse para excluir cualquier esquema en el que puedan escribir usuarios no confiables. Esto evita que usuarios maliciosos
creen objetos (por ejemplo, tablas, funciones y operadores) que enmascaren los objetos que la función debe utilizar. Especialmente
importante a este respecto es el esquema de tablas temporales, que se busca primero por defecto y en el que normalmente cualquiera
puede escribir. Se puede obtener una configuración segura forzando a que el esquema temporal se busque al final. Para hacer esto,
escribe pg_temp como la
última entrada en search_path.
Esta función ilustra el uso seguro:
CREATE FUNCTION check_password(uname TEXT, pass TEXT)
RETURNS BOOLEAN AS $$
DECLARE passed BOOLEAN;
BEGIN
SELECT (pwd = $2) INTO passed
FROM pwds
WHERE username = $1;
RETURN passed;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
-- Establecer un search_path seguro: esquemas de confianza, luego 'pg_temp'.
SET search_path = admin, pg_temp;
La intención de esta función es acceder a una tabla admin.pwds. Pero sin la cláusula SET, o con
una cláusula SET que mencione solo admin, la función podría ser saboteada creando una tabla
temporal llamada pwds.
Si la función security definer tiene la intención de crear roles, y se está ejecutando como un no superusuario,
createrole_self_grant también debe establecerse en un valor conocido utilizando la cláusula SET.
Otro punto a tener en cuenta es que, por defecto, el privilegio de ejecución se otorga a PUBLIC para las funciones
recién creadas (consulta la Section 5.8 para obtener más información). Con frecuencia desearás restringir el uso de una
función security definer a solo algunos usuarios. Para hacer eso, debes revocar los privilegios PUBLIC por defecto
y luego otorgar el privilegio de ejecución de forma selectiva. Para evitar tener una ventana de tiempo donde la nueva función sea
accesible para todos, créala y establece los privilegios dentro de una sola transacción. Por ejemplo:
BEGIN; CREATE FUNCTION check_password(uname TEXT, pass TEXT) ... SECURITY DEFINER; REVOKE ALL ON FUNCTION check_password(uname TEXT, pass TEXT) FROM PUBLIC; GRANT EXECUTE ON FUNCTION check_password(uname TEXT, pass TEXT) TO admins; COMMIT;
El estándar SQL define un comando CREATE FUNCTION. La implementación de PostgreSQL
se puede utilizar de forma compatible pero tiene muchas extensiones. Por el contrario, el estándar SQL especifica una serie de
características opcionales que no están implementadas en PostgreSQL.
Los siguientes son problemas importantes de compatibilidad:
OR REPLACE es una extensión de PostgreSQL.
Para la compatibilidad con otros sistemas de bases de datos, modo_arg se puede escribir
ya sea antes o después de nombre_arg. Pero solo la primera forma cumple con el estándar.
Para los valores predeterminados de los parámetros, el estándar SQL especifica solo la sintaxis con la palabra clave DEFAULT.
La sintaxis con = se utiliza en T-SQL y Firebird.
El modificador SETOF es una extensión de PostgreSQL.
Solo SQL está estandarizado como lenguaje.
Todos los demás atributos excepto CALLED ON NULL INPUT y RETURNS NULL ON NULL INPUT
no están estandarizados.
Para el cuerpo de las funciones LANGUAGE SQL, el estándar SQL solo especifica la forma cuerpo_sql.
Las funciones simples LANGUAGE SQL se pueden escribir de manera que cumplan con el estándar y sean portables a otras
implementaciones. Las funciones más complejas que utilizan características avanzadas, atributos de optimización u otros lenguajes
serán necesariamente específicas de PostgreSQL de manera significativa.