Перейти к основному содержимому
Версия: 7.0

Пользовательская формула (FORMULA)

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

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

Класс результата​

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

Обращение к параметрам​

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

Табличные формулы​

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

  • напрямую отобразить свойство lsFusion на внешнюю таблицу в базе данных;
  • использовать табличные SQL-функции как свойства lsFusion;
  • «разворачивать» строки, JSON-документы или массивы в свойства, индексированные по ключу.

Правила соотнесения параметров свойства с этой таблицей описаны в статье оператора FORMULA.

Обработка NULL​

Пользовательская формула выполняется в SQL ровно так, как записана, над SQL-значениями своих аргументов, и платформа не проверяет, что она соблюдает описанные ниже правила. Платформа сама определяет лишь условие, при котором свойство не NULL. Это условие используется везде, где свойство служит условием, в операторе выбора или в присваивании, тогда как значение, читаемое как есть, — это результат SQL-текста. Поэтому формула должна сама соблюдать правила своей формы, иначе её значение и её условие расходятся. Кроме второго ослабления ниже, аргумент, равный NULL по построению (литерал NULL, локальное свойство без значения), делает свойство NULL без выполнения формулы.

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

Это поведение по умолчанию ослабляется двумя способами. Первый объявляет, что формула может возвращать NULL даже при всех не-NULL аргументах: тогда свойство не NULL, когда вычисленное значение не NULL, поэтому формула выполняется и над NULL-аргументами и обязана возвращать для них NULL. Второй рассматривает формулу как объединение своих аргументов — это нужно для SQL-функций вроде COALESCE, объединяющих несколько возможно NULL аргументов: формула выполняется над NULL-аргументами, а свойство не NULL, когда хотя бы один аргумент не NULL. Формула обязана тогда вернуть не-NULL значение, а при всех NULL-аргументах — NULL.

Эти настройки относятся только к скалярным формулам. Для табличных формул поведение по NULL определяется самим SQL-выражением и таблицей, которую оно материализует.

Язык​

Для объявления свойства с помощью пользовательской формулы используется оператор FORMULA.

Примеры​

// свойство с двумя параметрами: округляемым числом и количеством знаков после запятой
round(number, digits) = FORMULA 'round(CAST(($1) as numeric),$2)';

// свойство, преобразовывающее значение, переданное в качестве аргумента, к строковому типу длиной в 15 символов.
toString15(str) = FORMULA BPSTRING[15] 'CAST($1 AS character(15))';

// свойство с двумя различными реализациями для разных диалектов SQL
jumpWorkdays = FORMULA NULL DATE PG 'jumpWorkdays($1, $2, $3)', MS 'dbo.jumpWorkdays($1, $2, $3)';

// табличная формула — параметр INTEGER row не используется в тексте и становится
// ключевой колонкой таблицы, возвращаемой jsonb_array_elements
array (JSON json, INTEGER row) = FORMULA JSON value 'jsonb_array_elements($json)';