As funções escritas em PL/Python são definidas por meio da sintaxe de CREATE FUNCTION padrão:
CREATE FUNCTIONnome_da_função(lista_de_argumentos) RETURNStipo_retornadoAS $$ # Corpo da função PL/Python $$ LANGUAGE plpython3u;
O corpo da função é simplesmente um script
Python.
Quando a função é chamada, seus argumentos são passados como
elementos da lista args; os argumentos com nome
também são passados como variáveis comuns para o script
Python.
O uso de argumentos com nome é geralmente mais legível.
O resultado é retornado pelo código Python
da maneira usual, por meio de return ou
yield
(no caso de uma instrução com conjunto de resultados).
Se não for fornecido o valor de retorno, o
Python retornará o valor padrão
None.
O PL/Python traduz o None
do Python no valor nulo do
SQL.
Em um procedimento, o resultado do código
Python deve ser None
(normalmente obtido terminando o procedimento sem uma instrução
return, ou usando uma instrução
return sem argumento);
caso contrário, será relatado um erro.
Por exemplo, uma função para retornar o maior valor entre dois números inteiros pode ser definida como:
CREATE FUNCTION pymax (a integer, b integer)
RETURNS integer
AS $$
if a > b:
return a
return b
$$ LANGUAGE plpython3u;
O código Python fornecido como o corpo da definição da função é transformado em uma função Python. Por exemplo, a função acima resulta em
def __plpython_procedure_pymax_23456():
if a > b:
return a
return b
assumindo que 23456 é o OID atribuído à função pelo PostgreSQL.
Os argumentos são definidos como variáveis globais. Devido às regras de escopo do Python, isto tem a consequência sutil de que uma variável de argumento não pode ser reatribuída dentro da função ao valor de uma expressão que envolve o próprio nome da variável, a menos que a variável seja redeclarada como global no bloco. Por exemplo, o seguinte código não funciona
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ x = x.strip() # errado return x $$ LANGUAGE plpython3u;
porque atribuir um valor a x torna
x uma variável local para todo o bloco,
portanto, o x no lado direito da atribuição
refere-se a variável local ainda não atribuída x,
e não ao parâmetro da função PL/Python.
Usando a instrução global, vai funcionar:
CREATE FUNCTION pystrip(x text) RETURNS text AS $$ global x x = x.strip() # certo agora return x $$ LANGUAGE plpython3u;
Mas é aconselhável não confiar neste detalhe de implementação do PL/Python. É melhor tratar os parâmetros da função como de leitura-apenas.