

# `CREATE FUNCTION`
<a name="create-function-syntax-support"></a>

`CREATE FUNCTION` define una nueva función.

**importante**  
En Amazon Aurora DSQL, `CREATE FUNCTION` solo admite funciones en lenguaje SQL (`LANGUAGE sql`). 

## Sintaxis admitida
<a name="create-function-supported-syntax"></a>

```
CREATE [ OR REPLACE ] FUNCTION
    name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
    [ RETURNS rettype
      | RETURNS TABLE ( column_name column_type [, ...] ) ]
  { LANGUAGE sql
    | { IMMUTABLE | STABLE | VOLATILE }
    | { CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT }
    | { [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER }
    | PARALLEL { UNSAFE | RESTRICTED | SAFE }
    | COST execution_cost
    | ROWS result_rows
    | SET configuration_parameter { TO value | = value | FROM CURRENT }
    | AS 'definition'
    | RETURN expression
    | BEGIN ATOMIC statement; [ statement; ... ] END
  } ...

where LANGUAGE must be sql
```

## Descripción
<a name="create-function-description"></a>

`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, 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, la función se crea en el esquema actual. El nombre de la nueva función no debe coincidir con ninguna función existente con los mismos tipos de argumentos de entrada en el mismo esquema. Sin embargo, las funciones de distintos tipos de argumentos pueden compartir un nombre (esto se denomina *sobrecarga*).

Para reemplazar la definición actual de una función existente, utilice `CREATE OR REPLACE FUNCTION`. No puede cambiar el nombre o los tipos de argumentos de una función de esta manera (de hecho, crearía una función nueva y distinta). Además, no puede utilizar `CREATE OR REPLACE FUNCTION` para cambiar el tipo de retorno de una función existente. Para ello, debe descartar y volver a crear la función.

Cuando `CREATE OR REPLACE FUNCTION` se usa para reemplazar una función existente, la propiedad y los permisos de la función no cambian. A todas las demás propiedades de la función se les asignan los valores especificados o implícitos en el comando. Debe tener la función para reemplazarla (esto incluye ser miembro del rol de propietario). 

Si borra una función y, a continuación, la vuelve a crear, la nueva función no será la misma entidad que la anterior; tendrá que eliminar las reglas, vistas, etc. existentes que hagan referencia a la función anterior. Use `CREATE OR REPLACE FUNCTION` para cambiar la definición de una función sin romper los objetos que hacen referencia a la función. 

Se convierte en propietario de una función que ha creado.

Para poder crear una función, debe tener privilegios `USAGE` sobre los tipos de argumento y el tipo de retorno.

Una función `SQL` agrupa una o más instrucciones `SQL` en una unidad reutilizable e invocable. Utilice funciones para centralizar expresiones o cálculos comunes, aplicar una lógica coherente en varias consultas y simplificar el código de la aplicación llamando a una sola función en lugar de repetir la misma `SQL`. 

## Parameters
<a name="create-function-parameters"></a>

**{{name}}**  
El nombre (opcionalmente calificado por el esquema) de la función que se va a crear.

**{{argmode}}**  
El modo de un argumento: `IN`, `OUT`, `INOUT` o `VARIADIC`. Si se omite, el valor predeterminado es `IN`. `VARIADIC` debe ser el último parámetro de entrada; solo los argumentos `OUT` pueden seguirlo. Los argumentos `OUT` y `INOUT` no se pueden combinar con la notación `RETURNS TABLE`.

**{{argname}}**  
El nombre de un argumento. En una función SQL, puede hacer referencia a un argumento por su nombre en el cuerpo de la función. El nombre de un argumento `OUT` o `INOUT` también es importante porque define el nombre de la columna correspondiente en el tipo de fila de resultados.

**{{argtype}}**  
El tipo de datos de un argumento. Puede ser cualquier tipo base, tipo de matriz o dominio compatible con Aurora DSQL. Para obtener más información, consulte [Tipos de datos admitidos en Aurora DSQL](working-with-postgresql-compatibility-supported-data-types.md). También puede hacer referencia al tipo de columna de una tabla existente mediante la notación `%TYPE`.

**{{default\_expr}}**  
Una expresión que se utilizará como valor predeterminado si no se especifica el argumento. La expresión debe ser coercible para el tipo de argumento del parámetro. Solo los argumentos `IN` y `INOUT` pueden tener un valor predeterminado. Cada argumento después de uno con un valor predeterminado también debe tener un valor predeterminado.

**{{rettype}}**  
Un tipo de datos de retorno. Puede ser cualquier tipo base, tipo de matriz o dominio compatible con Aurora DSQL. Para obtener más información, consulte [Tipos de datos admitidos en Aurora DSQL](working-with-postgresql-compatibility-supported-data-types.md). Para devolver un conjunto de filas, utilice `SETOF {{rettype}}` o `RETURNS TABLE`. Si se supone que la función no debe devolver un valor, especifique `void` como tipo de retorno. Cuando hay parámetros `OUT` o `INOUT`, la cláusula `RETURNS` se puede omitir y la función devuelve un `record` o el tipo de fila correspondiente.

**`RETURNS TABLE ( {{column_name}} {{column_type}} [, ...] )`**  
Especifica que la función devuelve un conjunto de filas con las columnas nombradas y sus tipos. Esto equivale a declarar uno o más parámetros de `OUT` y especificar `SETOF` como el tipo de retorno.

**`LANGUAGE sql`**  
El lenguaje utilizado para implementar la función. En Aurora DSQL, esto debe ser `sql`. Si omite la cláusula `LANGUAGE` y proporciona un cuerpo `BEGIN ATOMIC` o `RETURN`, `sql` se asume. Un cuerpo de cadena coherente (`AS '{{definition}}'`) requiere una cláusula `LANGUAGE sql` explícita; si se omite, se produce el error `no language specified`.

**`IMMUTABLE` / `STABLE` / `VOLATILE`**  
Estos atributos informan al optimizador de consultas acerca del comportamiento de la función. Puede especificar como máximo uno. Si omite los tres, la función tendrá el valor predeterminado `VOLATILE`.  
+ `IMMUTABLE` indica que la función no puede modificar la base de datos y siempre devuelve el mismo resultado cuando se le dan los mismos valores de argumento.
+ `STABLE` indica que la función no puede modificar la base de datos. En un solo análisis de la tabla, devuelve de forma coherente el mismo resultado para los mismos valores de argumento, pero el resultado puede cambiar según las instrucciones SQL.
+ `VOLATILE` indica que el valor de la función puede cambiar incluso en un solo análisis de la tabla, por lo que no se pueden realizar optimizaciones.

**`CALLED ON NULL INPUT` / `RETURNS NULL ON NULL INPUT` / `STRICT`**  
`CALLED ON NULL INPUT` (valor predeterminado) indica que la función se llama normalmente cuando algunos de sus argumentos son nulos. `RETURNS NULL ON NULL INPUT` o `STRICT` indica que la función siempre devuelve un valor nulo cuando alguno de sus argumentos es nulo. Si se especifica, Aurora DSQL no ejecuta la función cuando algún argumento es nulo; en su lugar, la función devuelve automáticamente un valor nulo. 

**`[ EXTERNAL ] SECURITY INVOKER` / `[ EXTERNAL ] SECURITY DEFINER`**  
`SECURITY INVOKER` (valor predeterminado) indica que la función debe ejecutarse con los privilegios del usuario que la invoca. `SECURITY DEFINER` especifica que la función se debe ejecutar con los privilegios del usuario propietario. La palabra clave `EXTERNAL` está permitida para garantizar la conformidad con SQL, pero es opcional.

**`PARALLEL { UNSAFE | RESTRICTED | SAFE }`**  
Aurora DSQL acepta y almacena la marca `PARALLEL`. Sin embargo, esta marca no afecta a la ejecución de la consulta. 

**`COST {{execution_cost}}`**  
Un número positivo que indique el costo estimado de ejecución para la función. Si la función devuelve un conjunto, este valor es el costo estimado por fila devuelta. El planificador de consultas utiliza esta estimación cuando no inserta la función.

**`ROWS {{result_rows}}`**  
Un número positivo que indica el número estimado de filas que el planificador de consultas debería esperar que devuelva la función. Esto solo está permitido cuando se declara que la función devuelve un conjunto. El supuesto predeterminado es 1000 filas.

**`SET {{configuration_parameter}} { TO {{value}} | = {{value}} | FROM CURRENT }`**  
La cláusula `SET` hace que el parámetro de configuración especificado se establezca en el valor especificado cuando se introduce la función y, a continuación, se restablece a su valor anterior cuando se cierra la función. `SET FROM CURRENT` guarda el valor del parámetro que es actual cuando `CREATE FUNCTION` se ejecuta como el valor que se aplicará al ingresar la función.

**`AS '{{definition}}'`**  
Una constante de cadena que define la función; el significado depende del idioma. En el caso de una función en lenguaje SQL, son las instrucciones SQL las que componen el cuerpo de la función.

**`RETURN {{expression}}`**  
Define el cuerpo de la función mediante la sintaxis estándar de SQL para una función que devuelve una sola expresión. Esta es una alternativa al formulario de cadena coherente.

**`BEGIN ATOMIC {{statement}}; [ ... ] END`**  
Define el cuerpo de la función mediante la sintaxis estándar de SQL. El cuerpo consta de una o más instrucciones SQL. Este formulario solo es válido para `LANGUAGE sql`. Las instrucciones de un cuerpo atómico se rastrean como dependencias de la función. Por ejemplo, una tabla a la que se hace referencia en el cuerpo no se puede eliminar sin eliminar también la función, o mediante `DROP ... CASCADE`.

## Notas
<a name="create-function-notes"></a>

Use la instrucción `DROP FUNCTION` para eliminar una función. También puede conceder y revocar privilegios en una función con `GRANT` y `REVOKE` (por ejemplo, `REVOKE ALL ON FUNCTION`).

Cualquier función que lea o modifique los datos de las tablas está sujeta al mismo comportamiento de transacción y simultaneidad que las instrucciones SQL equivalentes que se ejecutan directamente. Las funciones declaradas `IMMUTABLE` o `STABLE` no deben modificar la base de datos.

Para actualizar la definición de una función existente, utilice `CREATE OR REPLACE FUNCTION`. No puede cambiar los tipos de argumentos ni el tipo de retorno de una función de esta manera; en su lugar, elimine y vuelva a crear la función.

Para cambiar el nombre de una función, cambiar su propietario o moverla a otro esquema, utilice `ALTER FUNCTION`. Para cambiar cualquier otro atributo, use `CREATE OR REPLACE FUNCTION` con los cambios deseados. Para obtener más información, consulte [`ALTER FUNCTION`](alter-function-syntax-support.md).

Se admite la sobrecarga de funciones: puede definir varias funciones con el mismo nombre siempre que los tipos de argumentos de entrada sean diferentes. Una función definida por el usuario también puede llamar a otras funciones y puede ocultar una función integrada con el mismo nombre y tipo de argumento.

En el caso de una función que devuelve un conjunto (`SETOF` o `RETURNS TABLE`) cuyo cuerpo contiene más de una instrucción, solo se devuelve el resultado de la instrucción final. La función sigue ejecutando las instrucciones anteriores, pero descarta sus resultados. Este es el comportamiento estándar de las funciones del lenguaje SQL. Estructure la función de modo que la instrucción final produzca el conjunto de resultados completo.

Una función de devolución de conjuntos no garantiza ningún orden de filas en particular. Para controlar el orden de las filas, incluya una cláusula `ORDER BY` en la consulta.

## Consideraciones
<a name="create-function-considerations"></a>

Las capacidades `CREATE FUNCTION` siguientes devuelven el error mostrado.

**`LEAKPROOF`**  
Devuelve el error `only superuser can define a leakproof function`. `NOT LEAKPROOF` (predeterminado) se acepta.

**`TRANSFORM FOR TYPE`**  
Devuelve el error `transform for type {{type}} language "sql" does not exist`.

**`SUPPORT` (función de soporte del planificador)**  
Devuelve el error `function {{name}}(internal) does not exist`.

**Tipos compuestos definidos por el usuario (`CREATE TYPE ... AS`), incluidas las funciones que devuelven un tipo compuesto**  
Devuelve el error `unsupported statement: CompositeType`.

Aurora DSQL no es compatible con `CREATE PROCEDURE`, lo que produce el error `PROCEDURE is not supported`.

El atributo `WINDOW` se acepta sintácticamente, pero no es útil para las funciones del lenguaje SQL. Evite usar este atributo.

## Ejemplos
<a name="create-function-examples"></a>

Cree una función SQL sencilla que sume dos números enteros, con un cuerpo coherente de cadena:

```
CREATE FUNCTION add(integer, integer) RETURNS integer
    AS 'SELECT $1 + $2;'
    LANGUAGE sql
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;
```

Cree la misma función con el cuerpo `RETURN` estándar de SQL y los argumentos con nombre:

```
CREATE FUNCTION add(a integer, b integer) RETURNS integer
    LANGUAGE sql
    IMMUTABLE
    RETURN a + b;
```

Cree una función que devuelva un conjunto de filas mediante `RETURNS TABLE` y un cuerpo `BEGIN ATOMIC`:

```
CREATE FUNCTION employees_in_dept(dept_id integer)
    RETURNS TABLE (id integer, name text)
    LANGUAGE sql
    STABLE
    BEGIN ATOMIC
        SELECT id, name FROM employees WHERE department_id = dept_id;
    END;
```

Cree una función que se ejecute con los privilegios de su propietario y establezca un parámetro de configuración durante la llamada:

```
CREATE FUNCTION current_department() RETURNS text
    LANGUAGE sql
    STABLE
    SECURITY DEFINER
    SET search_path = app
    AS 'SELECT current_setting(''app.department'');';
```

## Compatibilidad
<a name="create-function-compatibility"></a>

Un comando `CREATE FUNCTION` se define en el estándar SQL. 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 funciones opcionales que no están implementadas en PostgreSQL.

A continuación, se muestran problemas de compatibilidad importantes:
+ `OR REPLACE` es una extensión de PostgreSQL.
+ Para garantizar la compatibilidad con otros sistemas de bases de datos, {{argmode}} se puede escribir antes o después de {{argname}}. Pero solo la primera forma es compatible con el estándar.
+ Para los parámetros predeterminados, el estándar SQL especifica solo la sintaxis con la palabra clave `DEFAULT`. La sintaxis con `=` se usa 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 el formulario {{sql\_body}}.

Las funciones `LANGUAGE sql` simples se pueden escribir de forma que se ajusten a los estándares y se puedan llevar a otras implementaciones. Las funciones más complejas que utilizan funciones avanzadas, atributos de optimización u otros lenguajes serán necesariamente específicas de PostgreSQL de manera significativa.