43.1. Функции PL/Python#

43.1. Функции PL/Python

43.1. Функции PL/Python

Функции в PL/Python объявляются с использованием стандартного синтаксиса CREATE FUNCTION.

CREATE FUNCTION funcname (argument-list)
  RETURNS return-type
AS $$
  # PL/Python function body
$$ LANGUAGE plpython3u;

Тело функции представляет собой простой скрипт на языке Python. При вызове функции ее аргументы передаются в виде элементов списка args; именованные аргументы также передаются как обычные переменные в скрипт на языке Python. Использование именованных аргументов обычно делает код более читаемым. Результат возвращается из кода на языке Python обычным способом, с помощью операторов return или yield (в случае оператора, возвращающего набор результатов). Если вы не предоставляете возвращаемое значение, Python возвращает значение по умолчанию None. PL/Python преобразует значение None Python в значение SQL null. В процедуре результат из кода на языке Python должен быть None (обычно достигается путем завершения процедуры без оператора return или использования оператора return без аргумента); в противном случае будет сгенерирована ошибка.

Например, функция, возвращающая большее из двух целых чисел, может быть определена следующим образом:

CREATE FUNCTION pymax (a integer, b integer)
  RETURNS integer
AS $$
  if a > b:
    return a
  return b
$$ LANGUAGE plpython3u;

Python-код, который представлен в теле определения функции, преобразуется в функцию Python. Например, приведенный выше код преобразуется в:

def __plpython_procedure_pymax_23456():
  if a > b:
    return a
  return b

предполагая, что 23456 - это OID, присвоенный функции Tantor SE-1С.

Аргументы устанавливаются как глобальные переменные. Из-за правил области видимости в Python это имеет тонкое последствие: переменная аргумента не может быть переопределена внутри функции значением выражения, которое включает само имя переменной, если переменная не объявлена как глобальная в блоке. Например, следующий код не будет работать:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  x = x.strip()  # error
  return x
$$ LANGUAGE plpython3u;

потому что присваивание x делает x локальной переменной для всего блока, и поэтому x справа от присваивания ссылается на еще не присвоенную локальную переменную x, а не на параметр функции PL/Python. Используя оператор global, это можно исправить:

CREATE FUNCTION pystrip(x text)
  RETURNS text
AS $$
  global x
  x = x.strip()  # ok now
  return x
$$ LANGUAGE plpython3u;

Однако рекомендуется не полагаться на эту деталь реализации PL/Python. Лучше относиться к параметрам функции как к только для чтения.