> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-fix-nav-issues.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> Документация по обычным функциям

# Обычные функции

Существует как минимум\* два типа функций: обычные функции (их обычно называют просто «функциями») и агрегатные функции. Это совершенно разные понятия. Обычные функции работают так, как если бы они применялись к каждой строке отдельно (для каждой строки результат функции не зависит от других строк). Агрегатные функции накапливают набор значений из разных строк (то есть зависят от всего набора строк).

В этом разделе рассматриваются обычные функции. Об агрегатных функциях см. раздел «Агрегатные функции».

<Note>
  Существует и третий тип функций, к которому относится [функция 'arrayJoin'](/ru/reference/functions/regular-functions/array-join). Кроме того, отдельно можно упомянуть и [табличные функции](/ru/reference/functions/table-functions).
</Note>

<div id="strong-typing">
  ## Строгая типизация
</div>

В отличие от стандартного SQL, в ClickHouse действует строгая типизация. Иными словами, он не выполняет неявных преобразований типов. Каждая функция работает с определённым набором типов. Это означает, что иногда необходимо использовать функции преобразования типов.

<div id="common-subexpression-elimination">
  ## Устранение общих подвыражений
</div>

Все выражения в запросе с одинаковым AST (то есть с одинаковой записью или одинаковым результатом синтаксического разбора) считаются имеющими одинаковые значения. Такие выражения объединяются и вычисляются один раз. Идентичные подзапросы также устраняются аналогичным образом.

<div id="types-of-results">
  ## Типы результатов
</div>

Все функции возвращают в результате одно значение (не несколько и не ноль). Тип результата обычно определяется только типами аргументов, а не их значениями. Исключения — функция tupleElement (оператор a.N) и функция toFixedString.

<div id="constants">
  ## Константы
</div>

Для упрощения некоторые функции для отдельных аргументов могут работать только с константами. Например, правый аргумент оператора LIKE должен быть константой.
Почти все функции возвращают константу для константных аргументов. Исключение составляют функции, генерирующие случайные числа.
Функция 'now' возвращает разные значения для запросов, выполнявшихся в разное время, но результат считается константой, поскольку константность важна только в рамках одного запроса.
Константное выражение также считается константой (например, правая часть оператора LIKE может быть составлена из нескольких констант).

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

<div id="null-processing">
  ## Обработка NULL
</div>

Для функций характерно следующее поведение:

* Если хотя бы один из аргументов функции равен `NULL`, результат функции также будет `NULL`.
* Особое поведение, которое отдельно указывается в описании каждой функции. В исходном коде ClickHouse для таких функций задано `UseDefaultImplementationForNulls=false`.

<div id="constancy">
  ## Константность
</div>

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

<div id="higher-order-functions">
  ## Функции высшего порядка
</div>

<div id="arrow-operator-and-lambda">
  ### оператор `->` и функции lambda(params, expr)
</div>

Функции высшего порядка могут принимать в качестве функционального аргумента только лямбда-функции. Чтобы передать лямбда-функцию в функцию высшего порядка, используйте оператор `->`. В левой части стрелки указывается формальный параметр, которым может быть любой идентификатор, или несколько формальных параметров — любые идентификаторы в кортеже. В правой части стрелки указывается выражение, которое может использовать эти формальные параметры, а также любые столбцы таблицы.

Примеры:

```python theme={null}
x -> 2 * x
str -> str != Referer
```

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

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

<div id="bare-function-names-as-lambdas">
  ### Имена функций как лямбда-выражения
</div>

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

Например, следующие пары эквивалентны:

```sql theme={null}
SELECT arrayMap(negate, [1, 2, 3]);            -- [-1, -2, -3]
SELECT arrayMap(x -> negate(x), [1, 2, 3]);    -- [-1, -2, -3]

SELECT arrayMap(plus, [1, 2, 3], [10, 20, 30]);            -- [11, 22, 33]
SELECT arrayMap((x, y) -> plus(x, y), [1, 2, 3], [10, 20, 30]); -- [11, 22, 33]

SELECT arrayFilter(isNotNull, [1, NULL, 3, NULL, 5]);            -- [1, 3, 5]
SELECT arrayFilter(x -> isNotNull(x), [1, NULL, 3, NULL, 5]);    -- [1, 3, 5]

SELECT arrayFold(plus, [1, 2, 3, 4, 5], toUInt64(0));                      -- 15
SELECT arrayFold((acc, x) -> plus(acc, x), [1, 2, 3, 4, 5], toUInt64(0));  -- 15
```

Это работает со встроенными функциями, SQL UDF, executable UDF и WebAssembly UDF. При неоднозначности имена столбцов и псевдонимы имеют приоритет над именами функций.

Арность лямбда-функции определяется по внутренней функции. Например, `arrayMap(plus, ...)` использует арность 2, потому что `plus` принимает два аргумента, поэтому это также работает с входными кортежами, например `arrayMap(plus, [(1, 10), (2, 20)])`, где элементы кортежа распаковываются в аргументы лямбда-функции.

Для вариативных внутренних функций (например, `concat`, которая принимает любое число аргументов) арность лямбда-функции определяется по числу аргументов-массивов. Это корректно для функций высшего порядка, таких как `arrayMap`, `arrayFilter` и `arrayFold`. Для функций высшего порядка, которые помимо массивов принимают фиксированные параметры, не являющиеся массивами, — например, `arrayPartialSort(f, limit, arr)` — использование имени вариативной функции без лямбды может дать неправильную арность; в этом случае требуется явная лямбда-функция.

Вариативные внутренние функции также не распаковывают входные кортежи автоматически. Например, `arrayMap(concat, [('a', 'b'), ('c', 'd')])` переписывается в унарную лямбда-функцию и не эквивалентно `arrayMap((x, y) -> concat(x, y), [('a', 'b'), ('c', 'd')])`. Используйте явную лямбда-функцию, если хотите деструктурировать элементы кортежа при вариативном вызове.

<div id="user-defined-functions-udfs">
  ## Пользовательские функции (UDF)
</div>

ClickHouse поддерживает пользовательские функции. См. раздел [UDFs](/ru/reference/functions/regular-functions/udf).
