Привет, Я DocuDroid!
Оценка ИИ поиска
Спасибо за оценку нашего ИИ поиска!
Мы будем признательны, если вы поделитесь своими впечатлениями, чтобы мы могли улучшить наш ИИ поиск для вас и других читателей.
GitHub

CREATE AGGREGATE

Определяет новую агрегатную функцию.

Синтаксис

CREATE AGGREGATE <name> ( [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ) (
    SFUNC = <statefunc>,
    STYPE = <state_data_type>
    [ , SSPACE = <state_data_size> ]
    [ , FINALFUNC = <ffunc> ]
    [ , FINALFUNC_EXTRA ]
    [ , COMBINEFUNC = <combinefunc> ]
    [ , SERIALFUNC = <serialfunc> ]
    [ , DESERIALFUNC = <deserialfunc> ]
    [ , INITCOND = <initial_condition> ]
    [ , MSFUNC = <msfunc> ]
    [ , MINVFUNC = <minvfunc> ]
    [ , MSTYPE = <mstate_data_type> ]
    [ , MSSPACE = <mstate_data_size> ]
    [ , MFINALFUNC = <mffunc> ]
    [ , MFINALFUNC_EXTRA ]
    [ , MINITCOND = <minitial_condition> ]
    [ , SORTOP = <sort_operator> ]
  )

CREATE AGGREGATE <name> ( [ [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ]
      ORDER BY [ <argmode> ] [ <argname> ] <arg_data_type> [ , ... ] ) (
    SFUNC = <statefunc>,
    STYPE = <state_data_type>
    [ , SSPACE = <state_data_size> ]
    [ , FINALFUNC = <ffunc> ]
    [ , FINALFUNC_EXTRA ]
    [ , COMBINEFUNC = <combinefunc> ]
    [ , SERIALFUNC = <serialfunc> ]
    [ , DESERIALFUNC = <deserialfunc> ]
    [ , INITCOND = <initial_condition> ]
    [ , HYPOTHETICAL ]
)

Устаревший синтаксис:

CREATE AGGREGATE <name> (
    BASETYPE = <base_type>,
    SFUNC = <statefunc>,
    STYPE = <state_data_type>
    [ , SSPACE = <state_data_size> ]
    [ , FINALFUNC = <ffunc> ]
    [ , FINALFUNC_EXTRA ]
    [ , COMBINEFUNC = <combinefunc> ]
    [ , SERIALFUNC = <serialfunc> ]
    [ , DESERIALFUNC = <deserialfunc> ]
    [ , INITCOND = <initial_condition> ]
    [ , MSFUNC = <msfunc> ]
    [ , MINVFUNC = <minvfunc> ]
    [ , MSTYPE = <mstate_data_type> ]
    [ , MSSPACE = <mstate_data_size> ]
    [ , MFINALFUNC = <mffunc> ]
    [ , MFINALFUNC_EXTRA ]
    [ , MINITCOND = <minitial_condition> ]
    [ , SORTOP = <sort_operator> ]
)

Описание

CREATE AGGREGATE определяет новую агрегатную функцию. В Greengage DB уже предусмотрены некоторые базовые и часто используемые агрегатные функции, такие как count, min, max, sum, avg и другие. Если вы определяете новые типы или требуется агрегатная функция, которая еще не предусмотрена, вы можете использовать CREATE AGGREGATE для создания необходимых функций.

Если указано имя схемы (например, CREATE AGGREGATE myschema.myagg …​), то агрегатная функция создается в указанной схеме. В противном случае она создается в текущей схеме.

Агрегатная функция идентифицируется своим именем и типами входных данных. Две агрегатные функции в одной схеме могут иметь одинаковое имя, если они работают с разными входными типами. Имя и типы входных данных агрегатной функции также должны отличаться от имени и типов входных данных каждой обычной функции в той же схеме. Такое поведение идентично перегрузке имен обычных функций. См. CREATE FUNCTION.

Простая агрегатная функция состоит из одной, двух или трех обычных функций (которые должны быть помечены как IMMUTABLE):

  • функция перехода состояния (state transition function) statefunc;

  • необязательная функция финального вычисления (final calculation function) ffunc;

  • необязательная функция объединения (combine function) combinefunc.

Эти функции используются следующим образом:

<statefunc>( internal-state, next-data-values ) ---> next-internal-state
<ffunc>( internal-state ) ---> aggregate-value
<combinefunc>( internal-state, internal-state ) ---> next-internal-state

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

ПРИМЕЧАНИЕ

Если вы пишете пользовательскую агрегатную функцию на C и объявляете значение состояния (state_data_type) как тип internal, существует риск возникновения ошибки нехватки памяти (out-of-memory). Если значения состояния internal не управляются должным образом и запрос требует слишком много памяти для значений состояния, может возникнуть ошибка нехватки памяти. Чтобы предотвратить это, используйте mpool_alloc(mpool, size), чтобы Greengage DB управлял памятью и выделял ее для не временных значений состояния, то есть значений состояния, которые живут в течение всей агрегации. Аргумент mpool функции mpool_alloc() — это aggstate→hhashtable→group_buf. Пример см. в реализации агрегатов числовых типов данных в репозитории Greengage DB в файле src/backend/utils/adt/numeric.c.

Вы можете указать combinefunc как метод для оптимизации выполнения агрегатной функции. Указав combinefunc, агрегатную функцию можно запускать параллельно сначала на сегментах, а затем на мастере. При выполнении двухуровневого выполнения statefunc запускается на сегментах для генерации частичных результатов агрегации, а combinefunc запускается на мастере для агрегации частичных результатов с сегментов. Если выполняется одноуровневая агрегация, все строки отправляются на мастер, и к строкам применяется statefunc.

Одноуровневая агрегация и двухуровневая агрегация являются эквивалентными стратегиями выполнения. Любой тип агрегации может быть реализован в плане запроса. Когда вы реализуете функции combinefunc и statefunc, вы должны гарантировать, что вызов statefunc на экземплярах сегментов с последующим вызовом combinefunc на мастере дает тот же результат, что и одноуровневая агрегация, которая отправляет все строки на мастер, а затем применяет к строкам только statefunc.

Агрегатная функция может предоставлять необязательное начальное условие — начальное значение для внутреннего значения состояния. Оно указывается и хранится в базе данных как значение типа text, но должно быть допустимым внешним представлением константы типа данных значения состояния. Если оно не указано, значение состояния изначально равно NULL.

Если функция statefunc объявлена как STRICT, то она не может быть вызвана с входными значениями NULL. С такой функцией перехода выполнение агрегатной функции ведет себя следующим образом. Строки с любыми входными значениями NULL игнорируются (функция не вызывается, и сохраняется предыдущее значение состояния). Если начальное значение состояния равно NULL, то при первой строке со всеми значениями, отличными от NULL, первое значение аргумента заменяет значение состояния, и функция перехода вызывается для последующих строк со всеми значениями, отличными от NULL. Это полезно для реализации агрегатов, таких как max. Обратите внимание, что такое поведение доступно только тогда, когда state_data_type совпадает с первым arg_data_type. Когда эти типы различаются, вы должны предоставить начальное условие, отличное от NULL, или использовать нестрогую (nonstrict) функцию перехода.

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

Если финальная функция (ffunc) объявлена как STRICT, то она не будет вызвана, когда конечное значение состояния равно NULL; вместо этого результат NULL будет возвращен автоматически. Это нормальное поведение функций STRICT. В любом случае финальная функция имеет возможность вернуть значение NULL. Например, финальная функция для avg возвращает NULL, когда видит, что было ноль входных строк.

Иногда полезно объявить финальную функцию, принимающую не только значение состояния, но и дополнительные параметры, соответствующие входным значениям агрегата. Основная причина для этого — если финальная функция полиморфна, и типа данных значения состояния недостаточно для определения типа результата. Эти дополнительные параметры всегда передаются как NULL (поэтому финальная функция не должна быть строгой при использовании опции FINALFUNC_EXTRA), но тем не менее они являются валидными параметрами. Финальная функция может, например, использовать get_fn_expr_argtype для идентификации фактического типа аргумента в текущем вызове.

Агрегатная функция может при необходимости поддерживать режим скользящего агрегата (moving-aggregate mode), как описано в разделе Moving-Aggregate Mode документации PostgreSQL. Для этого требуется указать функции msfunc, minvfunc и mstype, а также опционально функции mspace, mfinalfunc, mfinalfunc_extra и minitcond. За исключением minvfunc, эти функции работают как соответствующие функции простого агрегата без префикса m; они определяют отдельную реализацию агрегата, которая включает обратную функцию перехода.

Синтаксис с ORDER BY в списке параметров создает специальный тип агрегата, называемый агрегатом упорядоченного набора (ordered-set aggregate); или, если указано HYPOTHETICAL, создается агрегат гипотетического набора (hypothetical-set aggregate). Эти агрегаты работают с группами отсортированных значений зависимым от порядка способом, поэтому указание порядка сортировки входных данных является неотъемлемой частью вызова. Кроме того, они могут иметь прямые (direct) аргументы, которые оцениваются только один раз на агрегацию, а не один раз для каждой входной строки. Агрегаты гипотетического набора — это подкласс агрегатов упорядоченного набора, в котором некоторые прямые аргументы должны соответствовать по количеству и типам данных агрегируемым столбцам аргументов. Это позволяет добавлять значения этих прямых аргументов к коллекции строк ввода агрегата как дополнительную "гипотетическую" строку.

Агрегатные функции с одним аргументом, такие как min или max, иногда можно оптимизировать, обращаясь к индексу, вместо того чтобы сканировать каждую входную строку. Если данную агрегатную функцию можно так оптимизировать, укажите это, задав оператор сортировки (sort operator). Основное требование заключается в том, что агрегатная функция должна выдавать первый элемент в порядке сортировки, заданном оператором. Другими словами, выражение:

SELECT <agg>(<col>) FROM <tab>;

должно быть эквивалентно:

SELECT <col> FROM <tab> ORDER BY <col> USING <sortop> LIMIT 1;

Дальнейшие предположения заключаются в том, что агрегатная функция игнорирует входные данные NULL и выдает результат NULL тогда и только тогда, когда не было входных данных, отличных от NULL. Обычно оператор < типа данных является правильным оператором сортировки для MIN, а > — правильным оператором сортировки для MAX. Обратите внимание, что оптимизация на самом деле не сработает, если указанный оператор не является членом стратегии "меньше чем" или "больше чем" класса операторов B-tree индекса.

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

Параметры

Параметр Описание

name

Имя (опционально указанное со схемой) создаваемой агрегатной функции

argmode

Режим аргумента: IN или VARIADIC. Агрегатные функции не поддерживают аргументы OUT. Если не указано, по умолчанию используется IN. Только последний аргумент может быть помечен как VARIADIC

argname

Имя аргумента. В настоящее время это полезно только для целей документации. Если не указано, аргумент не имеет имени

arg_data_type

Тип входных данных, с которым работает эта агрегатная функция. Чтобы создать агрегатную функцию без аргументов, укажите * вместо списка аргументов. Примером такого агрегата является count(*)

base_type

В старом синтаксисе для CREATE AGGREGATE тип входных данных указывается параметром basetype, а не пишется рядом с именем агрегата. Обратите внимание, что этот синтаксис допускает только один входной параметр. Чтобы определить агрегатную функцию без аргументов с этим синтаксисом, укажите basetype как "ANY" (не *). Агрегаты упорядоченного набора не могут быть определены с использованием старого синтаксиса

statefunc

Имя функции перехода состояния, вызываемой для каждой входной строки. Для обычной агрегатной функции с N аргументами функция перехода состояния statefunc должна принимать N+1 аргументов, первый из которых имеет тип state_data_type, а остальные соответствуют объявленным типам входных данных агрегата. Функция должна возвращать значение типа state_data_type. Эта функция принимает текущее значение состояния и текущие значения входных данных и возвращает следующее значение состояния.

Для агрегатов упорядоченного набора (включая гипотетический набор) функция перехода состояния statefunc получает только текущее значение состояния и агрегированные аргументы, но не прямые аргументы. В остальном она такая же

state_data_type

Тип данных для значения состояния агрегата

state_data_size

Приблизительный средний размер (в байтах) значения состояния агрегата. Если этот параметр не указан или равен нулю, используется оценка по умолчанию на основе state_data_type. Планировщик использует это значение для оценки памяти, необходимой для запроса с группировкой агрегатов. Большие значения этого параметра препятствуют использованию хеш-агрегации

ffunc

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

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

Если указан FINALFUNC_EXTRA, то в дополнение к конечному значению состояния и любым прямым аргументам финальная функция получает дополнительные значения NULL, соответствующие обычным (агрегируемым) аргументам агрегата. Это в основном полезно для обеспечения правильного разрешения типа результата агрегата при определении полиморфного агрегата

combinefunc

Имя функции объединения (combine function). Это функция двух аргументов, оба типа state_data_type. Она должна возвращать значение типа state_data_type. Функция объединения принимает два значения состояния перехода и возвращает новое значение состояния перехода, представляющее объединенную агрегацию. В Greengage DB, если результат агрегатной функции вычисляется сегментированным образом, функция объединения вызывается на отдельных внутренних состояниях, чтобы объединить их в конечное внутреннее состояние.

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

serialfunc

Агрегатная функция, у которой state_data_type равен internal, может участвовать в параллельной агрегации только в том случае, если у нее есть функция serialfunc, которая должна сериализовать состояние агрегата в значение bytea для передачи другому процессу. Эта функция должна принимать один аргумент типа internal и возвращать тип bytea. Также требуется соответствующая функция deserialfunc

deserialfunc

Десериализует ранее сериализованное состояние агрегата обратно в state_data_type. Эта функция должна принимать два аргумента типов bytea и internal и возвращать результат типа internal.

ПРИМЕЧАНИЕ

Второй аргумент internal не используется, но требуется по соображениям безопасности типов.

initial_condition

Начальная настройка для значения состояния. Это должна быть строковая константа в форме, принимаемой для типа данных state_data_type. Если не указано, значение состояния изначально равно NULL

msfunc

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

minvfunc

Имя функции обратного перехода состояния, используемой в режиме скользящего агрегата. Эта функция имеет те же типы аргументов и результатов, что и msfunc, но используется для удаления значения из текущего состояния агрегата, а не для добавления значения к нему. Обратная функция перехода должна иметь тот же атрибут строгости (strictness), что и функция прямого перехода состояния

mstate_data_type

Тип данных для значения состояния агрегата при использовании режима скользящего агрегата

mstate_data_size

Приблизительный средний размер (в байтах) значения состояния агрегата при использовании режима скользящего агрегата. Работает так же, как state_data_size

mffunc

Имя финальной функции, вызываемой для вычисления результата агрегата после прохождения всех входных строк при использовании режима скользящего агрегата. Работает так же, как ffunc, за исключением того, что тип ее первого аргумента — mstate_data_type, а дополнительные фиктивные аргументы указываются написанием MFINALFUNC_EXTRA. Тип результата агрегата, определенный mffunc или mstate_data_type, должен соответствовать типу, определенному обычной реализацией агрегата

minitial_condition

Начальная настройка для значения состояния при использовании режима скользящего агрегата. Работает так же, как initial_condition

sort_operator

Связанный оператор сортировки для агрегата типа MIN или MAX. Это просто имя оператора (опционально указанное со схемой). Предполагается, что оператор имеет те же типы входных данных, что и агрегатная функция (которая должна быть обычной агрегатной функцией с одним аргументом)

HYPOTHETICAL

Только для агрегатов упорядоченного набора этот флаг указывает, что аргументы агрегата должны обрабатываться в соответствии с требованиями для агрегатов гипотетического набора: то есть последние несколько прямых аргументов должны соответствовать типам данных агрегируемых (WITHIN GROUP) аргументов. Флаг HYPOTHETICAL не влияет на поведение во время выполнения, только на разрешение типов данных и сопоставлений (collation) аргументов агрегата во время разбора (parse-time)

Примечания

Обычные функции, используемые для определения новой агрегатной функции, должны быть определены первыми. Нет необходимости в том, чтобы функции statefunc, ffunc и combinefunc, используемые для создания агрегата, были определены как IMMUTABLE.

Если значение конфигурационного параметра сервера Greengage DB gp_enable_multiphase_agg равно off, выполняется только одноуровневая агрегация.

Любой скомпилированный код (файлы разделяемых библиотек) для пользовательских функций должен быть размещен в одном и том же месте на каждом хосте в кластере Greengage DB (мастер и все сегменты). Это местоположение также должно быть в LD_LIBRARY_PATH, чтобы сервер мог найти файлы.

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

name ( arg [ , ... ] [ORDER BY sortspec [ , ...]] )

Ключевое слово ORDERED принимается для обратной совместимости, но игнорируется.

В качестве синонима для COMBINEFUNC можно использовать ключевое слово PREFUNC, которое поддерживается для обратной совместимости.

Примеры

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

Перед созданием агрегатной функции создайте две функции, которые используются как функции statefunc и combinefunc агрегатной функции.

Следующая функция указывается как функция statefunc в агрегатной функции:

CREATE FUNCTION mysfunc_accum(numeric, numeric, numeric)
    RETURNS numeric
AS
'select $1 + $2 + $3'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

Следующая функция указывается как функция combinefunc в агрегатной функции:

CREATE FUNCTION mycombine_accum(numeric, numeric)
    RETURNS numeric
AS
'select $1 + $2'
    LANGUAGE SQL
    IMMUTABLE
    RETURNS NULL ON NULL INPUT;

Следующая команда CREATE AGGREGATE создает агрегатную функцию, которая суммирует два столбца:

CREATE AGGREGATE agg_prefunc(numeric, numeric) (
    SFUNC = mysfunc_accum,
    STYPE = numeric,
    COMBINEFUNC = mycombine_accum,
    INITCOND = 0 );

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

CREATE TABLE t1 (a int, b int) DISTRIBUTED BY (a);
INSERT INTO t1 values
   (10, 1),
   (20, 2),
   (30, 3);
SELECT agg_prefunc(a, b) FROM t1;

Эта команда EXPLAIN показывает двухфазную агрегацию:

EXPLAIN SELECT agg_prefunc(a, b) FROM t1;

Результат:

QUERY PLAN
--------------------------------------------------------------------------
Aggregate (cost=1.10..1.11 rows=1 width=32)
 -> Gather Motion 2:1 (slice1; segments: 2) (cost=1.04..1.08 rows=1
     width=32)
    -> Aggregate (cost=1.04..1.05 rows=1 width=32)
      -> Seq Scan on t1 (cost=0.00..1.03 rows=2 width=8)
 Optimizer: Pivotal Optimizer (GPORCA)
 (5 rows)

Совместимость

CREATE AGGREGATE является расширением языка Greengage DB. Стандарт SQL не предусматривает пользовательских агрегатных функций.

См. также