Табличные функции#

Табличная функция - это функция, возвращающая таблицу. Ее можно вызывать внутри предложения FROM запроса:

SELECT * FROM TABLE(my_function(1, 100))

Тип строк возвращаемой таблицы может зависеть от аргументов, переданных при вызове функции. Если функция может возвращать разные типы строк, она является полиморфной табличной функцией.

Полиморфные табличные функции позволяют динамически вызывать пользовательскую логику из SQL-запроса. Их можно использовать для работы с внешними системами, а также для расширения Trino возможностями, выходящими за рамки стандарта SQL.

Список встроенных табличных функций, доступных в Trino, см. в разделе built-in table functions.

Trino поддерживает добавление пользовательских табличных функций. Они объявляются коннекторами через реализацию специальных интерфейсов. Руководство по добавлению новых табличных функций см. в руководстве разработчика.

Поддержка различных функций предоставляется коннекторами по-разному. Подробнее о поддерживаемых табличных функциях см. в документации коннекторов.

Встроенные табличные функции#

Табличная функция exclude_columns#

Используйте табличную функцию exclude_columns, чтобы вернуть новую таблицу на основе входной таблицы table, исключив все столбцы, указанные в descriptor:

exclude_columns(input => table, columns => descriptor) table

Аргумент input - таблица или запрос. Аргумент columns - descriptor без типов.

Пример запроса с использованием таблицы orders из набора данных TPC-H, предоставляемой TPC-H connector:

SELECT *
FROM TABLE(exclude_columns(
                        input => TABLE(orders),
                        columns => DESCRIPTOR(clerk, comment)));

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

Табличная функция sequence#

Используйте табличную функцию sequence, чтобы вернуть таблицу с одним столбцом sequential_number, содержащим последовательность bigint:

sequence(start => bigint, stop => bigint, step => bigint) -> table(sequential_number bigint)

start - первый элемент последовательности. Значение по умолчанию - 0.

stop - конец диапазона, включительно. Последний элемент последовательности равен stop, либо это последнее значение в диапазоне, достижимое с заданным шагом.

step - разница между соседними значениями. Значение по умолчанию - 1.

Пример запроса:

SELECT *
FROM TABLE(sequence(
                start => 1000000,
                stop => -2000000,
                step => -3));

Результат табличной функции sequence может быть неупорядоченным. При необходимости задайте сортировку во внешнем запросе:

SELECT *
FROM TABLE(sequence(
                start => 0,
                stop => 100,
                step => 5))
ORDER BY sequential_number;

Вызов табличной функции#

Табличная функция вызывается в предложении FROM запроса. Синтаксис вызова табличной функции похож на вызов скалярной функции.

Разрешение функции#

Каждая табличная функция предоставляется каталогом и принадлежит схеме в этом каталоге. Вы можете квалифицировать имя функции именем схемы или именами каталога и схемы:

SELECT * FROM TABLE(schema_name.my_function(1, 100))
SELECT * FROM TABLE(catalog_name.schema_name.my_function(1, 100))

В противном случае применяется стандартное разрешение имен Trino. Связь между функцией и каталогом должна быть определена, так как функция выполняется соответствующим коннектором. Если функция не зарегистрирована в указанном каталоге, запрос завершится ошибкой.

Имя табличной функции разрешается без учета регистра, аналогично разрешению имен скалярных функций и таблиц в Trino.

Аргументы#

Существует три типа аргументов.

  1. Scalar arguments

Они должны быть константными выражениями и могут иметь любой SQL-тип, совместимый с объявленным типом аргумента:

factor => 42
  1. Descriptor arguments

Descriptors состоят из полей с именами и необязательными типами данных:

schema => DESCRIPTOR(id BIGINT, name VARCHAR)
columns => DESCRIPTOR(date, status, comment)

Чтобы передать null для descriptor, используйте:

schema => CAST(null AS DESCRIPTOR)
  1. Table arguments

Вы можете передать имя таблицы или запрос. Используйте ключевое слово TABLE:

input => TABLE(orders)
data => TABLE(SELECT * FROM region, nation WHERE region.regionkey = nation.regionkey)

Если табличный аргумент объявлен с set semantics, можно задать partitioning и ordering. Каждый partition обрабатывается табличной функцией независимо. Если partitioning не задан, аргумент обрабатывается как один partition. Также можно указать PRUNE WHEN EMPTY или KEEP WHEN EMPTY. С PRUNE WHEN EMPTY вы объявляете, что результат функции не интересует, если аргумент пустой. Эта информация используется движком Trino для оптимизации запроса. Опция KEEP WHEN EMPTY указывает, что функция должна быть выполнена, даже если табличный аргумент пуст. Указывая KEEP WHEN EMPTY или PRUNE WHEN EMPTY, вы переопределяете свойство, установленное для аргумента автором функции.

Следующий пример показывает, в каком порядке должны задаваться свойства табличного аргумента:

input => TABLE(orders)
                    PARTITION BY orderstatus
                    KEEP WHEN EMPTY
                    ORDER BY orderdate

Соглашения о передаче аргументов#

Существует два соглашения передачи аргументов табличной функции:

  • Аргументы, передаваемые по имени:

    SELECT * FROM TABLE(my_function(row_count => 100, column_count => 1))
    

В этом соглашении аргументы можно передавать в произвольном порядке. Аргументы, объявленные со значениями по умолчанию, можно пропускать. Имена аргументов разрешаются с учетом регистра и с автоматическим преобразованием некавыченных имен в верхний регистр.

  • Аргументы, передаваемые позиционно:

    SELECT * FROM TABLE(my_function(1, 100))
    

В этом соглашении необходимо соблюдать порядок объявления аргументов. Можно пропустить суффикс списка аргументов при условии, что все пропущенные аргументы объявлены со значениями по умолчанию.

Нельзя смешивать соглашения передачи аргументов в одном вызове.

Также в аргументах можно использовать параметры:

PREPARE stmt FROM
SELECT * FROM TABLE(my_function(row_count => ? + 1, column_count => ?));

EXECUTE stmt USING 100, 1;