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

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

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

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

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

CedrusData поддерживает добавление пользовательских табличных функций с помощью коннекторов, см. Table functions.

Информация о табличных функциях, предоставляемых отдельными коннекторами, доступна в документации коннекторов.

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

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

Исключает из table все столбцы, перечисленные в descriptor:

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

Аргумент input представляет собой таблицу или запрос. Аргумент columns - это дескриптор без типов.

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

Возвращает один столбец sequential_number, содержащий последовательность bigint:

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

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

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

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

Примечание

Порядок результатов табличной функции sequence не гарантирован.

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

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

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

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

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

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

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

Аргументы#

Существует три типа аргументов табличных функций.

  1. Скалярный аргумент

    Должен быть константой. Могут иметь любому типу SQL, совместимый с ожидаемым типом аргумента функции:

    factor => 42
    
  2. Дескриптор

    Представляет собой список полей с именами и опциональными типами данных:

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

    Чтобы передать null в качестве дескриптора, используйте функцию CAST:

    schema => CAST(null AS DESCRIPTOR)
    
  3. Таблица

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

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

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

Вы также можете указать необязательные выражения PRUNE WHEN EMPTY или KEEP WHEN EMPTY. Опция PRUNE WHEN EMPTY указывает, что вас не интересует результат функции, если аргумент является пусты. Эта информация может быть использована CedrusData для оптимизации запроса. Опция 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;