Гриды — Справочник фильтров¶
Справочник соответствия типов колонок грида и применяемых фильтров.
Справочник описывает, какой фильтр применяется для каждого типа колонки в гриде задач и в ДП Таблица: текстовые фильтры, фильтры по пользователям, по подзадачам и вопросам, по дополнительным параметрам, а также фильтры колонок ДП Таблица и особую обработку сквозных ДП (Through).
Два контекста фильтрации¶
Каждый фильтр работает в одном или обоих контекстах:
- Грид задач — фильтрация списка задач категории;
- ДП Таблица — фильтрация строк внутри табличного дополнительного параметра.
Окно выбора задачи по ДП «Ссылка» и «Множественная ссылка» относится к первому контексту, но с оговоркой по правам: категории, задачи которых оно показывает, в параметры выборки попадают позже проверки доступа, поэтому для критерия доступа к колонкам ДП они подставляются отдельно — из описания лукапа, из контекста вызова или из категории-владельца. В саму выборку, сортировку и агрегаты этот набор не пишется. Если ни один из источников категорий не сработал, набор остаётся пустым и операции по любой колонке ДП запрещены; для сводного раздела параметр считается закрытым, если он закрыт хотя бы в одной из категорий-источников.

Фильтры гридов задач¶
Требования к имени колонки¶
Имя колонки, по которой строится критерий отбора, проходит проверку на допустимость перед привязкой к SQL. Разрешены обычные идентификаторы (в том числе квалифицированные — до трёх частей через точку, в скобочной или кавычечной форме) длиной до 400 символов. Одиночные внутренние дефисы допустимы — их содержат имена ДП планировщика ресурсов.
Не проходят проверку: пробелы, скобки и прочие спецсимволы внутри имени, сдвоенные и хвостовые дефисы. Последствие зависит от пути: в критерии отбора невалидное имя приводит к тому, что критерий молча отбрасывается (фильтр перестаёт влиять на выборку), на пути получения безопасного имени колонки — к ошибке «Filter '…' has an invalid column name for SQL criteria».
Симптом для поддержки: фильтр настроен, но выборка его игнорирует, либо запрос падает с этой ошибкой — проверить имя колонки в настройке фильтра.
Текстовые и поисковые¶
Фильтры по текстовым полям задачи:
| Колонки | Тип фильтра | Описание |
|---|---|---|
| TaskText, Description | TextFilter |
Фильтр по тексту задачи. Поддерживает contains, startsWith, endsWith, equals. Также используется для быстрого фильтра. |
| SubcategoryName | TextFilter |
Фильтр по названию категории. Условие «равно» обслуживает SubcategoryTextFilter: категория ищется по названию, а если у источника уже задан список категорий — среди них, и берётся первая найденная. В обычном режиме фильтр сужает SubcatIds до этой категории, у источника со сводными категориями вдобавок добавляет узел FlexExpr с условием $TASKS$.SubcatID = N. В расширенном поиске SubcatIds не меняется: в дерево фильтров добавляется только узел FlexExpr, поэтому условие участвует в логике «и/или» наравне с остальными. Если категория по названию не нашлась, в расширенном поиске запрос завершается ошибкой GridNotSupportedOperationException (кроме быстрого фильтра), в остальных режимах фильтр не применяется. |
| PerformerOrgUnit | PerformerOrgUnitFilter |
Фильтр по орг. единице исполнителя. Принимает текстовый фильтр с операциями «равно», «содержит», «начинается с», «заканчивается на», «не равно», «не содержит», «пусто», «не пусто». В хранимой процедуре колонке соответствует Tasks.DeptName. |
Колонка «Орг. единица исполнителя» обслуживается отдельным билдером и сравнивает не значение колонки, а результат подзапроса по идентификаторам задач: от ответственных исполнителей берётся основное назначение в оргструктуре, от него — родительское подразделение, имя которого и сопоставляется с введённым значением (с учётом локализации на язык сессии). Для обычного фильтра колонки подзапрос добавляется в CustomFlex, то есть отбор выполняется до основного запроса ShowTasksFeed и в дереве FilterNode такой фильтр не отображается. В быстром и расширенном фильтрах подзапрос попадает в дерево как flex-выражение TaskID in (…), для отрицающих операций — not in. Пустое значение фильтра не применяется, операции вне перечисленного списка приводят к ошибке «Filter '…' not supported for performerOrgUnit».
Пользователи и роли¶
Фильтры по участникам задачи:
| Колонки | Тип фильтра | Описание |
|---|---|---|
| Owner, OwnerName | SetFilter |
Фильтр по заказчику задачи. |
| Performer | SetFilter |
Фильтр по единственному исполнителю. |
| Performers | SetFilter |
Фильтр по множественным исполнителям. |
| Acceptors | SetFilter |
Фильтр по согласующим. |
| ExtParam{id} (SelectUsers type) | SetFilter |
Фильтр для ДП "Выбор пользователей/групп". |
Подзадачи и вопросы¶
Числовые фильтры по подзадачам и вопросам:
| Колонки | Тип фильтра | Описание |
|---|---|---|
| Subtasks | NumberFilter |
Фильтр по наличию подзадач. |
| ActiveSubtasks | NumberFilter |
Количество активных подзадач. |
| TotalSubtasks | NumberFilter |
Общее количество подзадач. |
| MyQuestions | NumberFilter |
Мои вопросы в задаче. |
| QuestionsToMe | NumberFilter |
Вопросы адресованные мне. |
| QuestionsFromMe | NumberFilter |
Вопросы от меня. |
ДП и специальные¶
Фильтры по дополнительным параметрам и специальные фильтры:
| Колонки | Тип фильтра | Описание |
|---|---|---|
| ExtParam{id} (MultiSelect types) | SetFilter |
Универсальный фильтр для ДП с множественным выбором (MultiSlctSubcatTasks, MultiCheckbox, etc.). |
| ExtParam{id} (LookUpField) | SetFilter / TextFilter |
Фильтр для lookup ДП. Фильтрует по связанной задаче. |
| ExtParam{id} (LookUpField, MultiSlctSubcatTasks) в режиме «Выбор значений» | TaskIdSetFilter |
Отбор по идентификаторам выбранных задач (SelectedTaskID), а не по отображаемому тексту. Клиент присылает filterType = taskIdSet, список отмеченных taskIds либо список снятых excludeTaskIds (режим «всё, кроме снятых» у колонки Лукап) и признак blank для отбора задач без значения ДП. Подробнее — в разделе «Маппинг: тип ДП → фильтр». |
| Любая | SmartFilter |
Фильтр через smart-выражение (ESQL). |
| Signatures* | SetFilter |
Фильтры по подписям задач. |
| Custom | AdvancedFilter |
Произвольный гибкий фильтр. |
| Table columns | SetFilter |
Мультивыбор строк в ДП Таблица. Работает в обоих контекстах. |
Пустой набор значений в SetFilter. Набор с пустой строкой (values: [""]) отбирает строки без значения, а пустой набор (values: []) не подходит ни одной строке: сервер подставляет заведомо ложное условие 1 = 0 (FilterHelpers.CreateAlwaysFalseFilter), и таблица возвращает ноль строк. В гриде задач и в виртуальных колонках ДП Таблица правило действует всегда; внутри ДП Таблица оно применяется только к фильтрам, пришедшим в filterModel от клиента, а служебные фильтры группировки по-прежнему строят условие «нет значения». Колонка состояния разбирается раньше остальных: пустой набор в фильтре state даёт ранний выход с пустым ответом, это поведение не менялось. Интерфейс пустой набор не отправляет: при снятии всех отметок фильтр колонки обычно снимается целиком. Исключение — фильтр «Выбор значений» у колонки «Ссылка»: состояние «ничего не отмечено» уходит как taskIds: [], то есть отбор на ноль строк, а повторный клик по «Выбрать все» снимает отбор совсем.
Фильтры колонок ДП Таблица¶
Эти фильтры работают только в контексте ДП Таблица:
| Тип колонки | Тип фильтра | Описание |
|---|---|---|
| Lookup-колонка в таблице | TextFilter |
Текстовый поиск по значению lookup-связи внутри ДП Таблица (по тексту связанной задачи и отображаемым полям справочника), как в гриде списка задач; не ограничен числом записей справочника. Зависит от LookupParamSettings. |
| Виртуальная (вычисляемая) колонка | TextFilter / NumberFilter |
Текстовые операции ищут по отображаемому значению колонки — тому, что видно в таблице, а не по идентификатору связанной задачи. Может не поддерживать все операции. |
| "Выбор пользователей" в таблице | SetFilter |
Фильтр по пользователям/группам внутри ДП Таблица. |
Маппинг: тип ДП → фильтр¶
Какой фильтр применяется для каждого типа дополнительного параметра:
| Тип ДП | Грид задач | ДП Таблица | Примечание |
|---|---|---|---|
String, MultiLineString |
TaskTextFilter (или стандартный) |
стандартный | Текстовый |
Number, Decimal, Money |
стандартный | стандартный | Числовой |
DateTime |
agDateColumnFilter |
agDateColumnFilter |
Дата и время: штатный фильтр даты AG Grid — время можно указать в самом фильтре, год ограничен диапазоном 1000–9999. Подробности — ниже |
Boolean |
стандартный | стандартный | Чекбокс |
LookUpField |
LookupFilter |
LookupColumnFilter |
Lookup |
MultiSlctSubcatTasks |
MultiSelectFilter |
стандартный | Мультилукап |
SelectUsersType, SelectGroupsType, SelectOrgUnit |
SelectUsersExtParamFilters |
SelectUsersColumnFilter |
Выбор пользователей |
MultiCheckbox, DropDown |
MultiSelectFilter |
стандартный | Множественный выбор |
Table |
Ограничено (не через ShowTasksFeed) |
N/A (Table — это сам грид) | Фильтрация задач возможна через HTML-представление при настройке шаблона. См. support-guide §1.3 |
Through |
Особая обработка | N/A | Сквозной ДП: действующий тип сервер берёт у параметра-источника в конце цепочки и по нему готовит значение фильтра, но в хранимую процедуру передаёт тип Through — процедура сама определяет целевой тип и применяет правильную логику. Замена на SelectUsersOrgUnits/SelectUsersGroups происходит только при группировке, не при фильтрации. Колонка, которая ссылается на удалённый или недоступный параметр, фильтр не ломает: условие по ней не применяется, остальные условия работают как обычно. Если у сквозного параметра источник не определяется и колонка доступна, фильтр прерывается сообщением о неверной настройке сквозного параметра — цепочку правит администратор. Типичные применения: Through → ДП «Выбор пользователей» (Менеджер клиента, РП, BDM и др.) |
File |
ИСКЛЮЧЁН | N/A | Файловый ДП |
Numerator |
стандартный | стандартный | Нумератор |
Virtual (колонка таблицы) |
N/A | VirtualColumnFilter |
Только внутри ДП Таблица |
Фильтр по дате и по дате-времени. Колонки «дата» и «дата и время» фильтруются штатным agDateColumnFilter AG Grid. Если время задано, операторы сравнивают дату вместе с ним; если время не указано — сравнение идёт по дате. Время вводится с точностью до минуты: секунды в пикере скрыты, поэтому условие «18:29» находит и значение 18:29:37, а полночь означает «время не задано». Оператор по умолчанию — «Равно», год в пикере ограничен диапазоном 1000–9999. Набор операторов зависит от источника данных грида: в гридах задач доступны «Равно», «Не равно», «Меньше», «Больше» и «Диапазон», а на формах — только «Равно» и «Диапазон», потому что на формах сервер отбрасывает время и остальные операторы дали бы неверную выборку. Отбор «Нет значения» и «Есть значение» доступен в обоих случаях.
Время по умолчанию и суточная семантика «Равно». При выборе дня в календаре и по кнопке «Сегодня» в поле времени подставляется 00:00, а не текущее время. Так как полночь в фильтре означает «время не задано», условие «Равно» без набранного времени отбирает записи за весь выбранный день: клиент разворачивает его в интервал от 00:00:00 этого дня до 00:00:00 следующего, то есть берёт сутки полуинтервалом — последняя секунда дня в отбор попадает. Границы «Диапазона» разворачиваются так же, поэтому конечный день входит в отбор целиком, а не до последней минуты суток. Сам фильтр при этом не переписывается: в сохранённом представлении и в чипе над таблицей условие остаётся «Равно» с 00:00. Набранное вручную время суточное правило не отменяет — условие «12:30» сравнивается по минуте. У колонок «только дата» поля времени нет, и фильтр по-прежнему сравнивает даты.
Пустое поле — это отсутствие значения. При выводе колонки поле пустое, текущая дата в него не подставляется; пустое поле означает, что значение не задано, а не полночь текущих суток. Повторная установка той же даты после очистки применяется так же, как первая: очистка сбрасывает состояние фильтра, поэтому значение с датой и временем 00:00 отличается от пустого состояния, и отбор запускается без перезагрузки страницы.
Суточная семантика «Не равно». Правило «полночь означает время не задано» разворачивает в сутки и утвердительные условия, и отрицательное, но результат зависит от типа колонки. По колонке «только дата» условие «Не равно» исключает выбранный день целиком. По колонке «Дата и время» действует то же правило, что и для «Равно»: день, выбранный в календаре без набранного времени, грид отправляет операцией notInRange — отрицанием полуинтервала от начала дня до полуночи следующих суток (контракт операции — в backend.md). В интерфейсе условие при этом остаётся «Не равно» с 00:00, а не превращается в отдельный пункт списка операций. «Не равно» с набранным вручную временем (например, 12:30) уходит как notEqual и исключает только эту минуту.
Если у колонки Лукап или Мультилукап выбран тип фильтра «Выбор значений» (для обоих типов он же и по умолчанию, второй возможный — «Текстовый»), отбор идёт по самим выбранным задачам, а не по их отображаемому тексту. Клиент присылает фильтр с дискриминатором filterType = taskIdSet; в DTO TaskIdSetFilter помимо общих полей ColumnFilter есть собственные поля: taskIds — список числовых идентификаторов задач, blank — признак отбора задач без значения ДП (описан ниже) и labels — необязательный список подписей выбранных задач, параллельный taskIds. В построении отбора labels не участвует: сервер хранит подписи вместе с фильтром в составе представления и возвращает их при чтении без изменений, чтобы чип над таблицей показывал названия, а не номера. Запрос без labels разбирается как раньше — поле десериализуется в null. Сервер строит из него один узел фильтра: операция =, в ParamType — обозначение типа колонки, которое понимает хранимая функция: LookupValue для Лукапа и MultiSlctSubcatTasks для Мультилукапа (в кэше ДП тип Лукапа называется LookUpField; ColumnFilterService.GetFilter переименовывает его в LookupValue до разбора фильтра, поэтому в разборе taskIdSet встречается уже переименованное значение), в DecimalValue — набор идентификаторов через запятую с префиксом any: — у Лукапа и Мультилукапа одинаково: подходит задача, у которой стоит хотя бы одно из отмеченных значений (объединение по «или»), поэтому несколько отмеченных значений расширяют выборку, а не сужают её. Текстовое значение (RawValue) не заполняется. Хранимая функция сопоставляет набор с SelectedTaskID в таблице выбранных задач ExtParamValueSelectedTasks.
Перевод сохранённых настроек. Настройки таблиц категории — и административные наборы колонок, и пользовательские виды — при обновлении на 2.268 один раз переведены с типа фильтра «Текстовый» на «Выбор значений» у колонок Лукап и Мультилукап. Замена выполнена в самих сохранённых настройках, подмены при чтении нет, и колонки остальных типов не затронуты. Перевод одноразовый: если после обновления вернуть колонке тип «Текстовый» и сохранить вид, этот выбор сохраняется.
Откуда берётся список значений. Значения для выбора отдаёт отдельная точка POST api-core/datasource/{type}/{entityId}/lookup-values: список строится из фактических значений колонки у задач, которые пользователь видит в этом гриде, с тем же отбором и тем же пользователем, что и страница грида. Поэтому в списке нет значений из недоступных задач, и наоборот — права на категорию-источник для показа списка не требуются. Запрос принимает имя колонки, строку поиска и постраничные skip и take (по умолчанию 50); ответ содержит страницу значений и признак hasMore, общее число не считается. Колонка дополнительного параметра с ограничением доступа даёт пустой список, как и при группировке. Операции по такой колонке проверяются на сервере, поэтому запрет не обходится прямым запросом мимо интерфейса. Колонка не того типа, параметр вне категории или источник типа «Таблица» — ошибка 400, отсутствие прав на грид — 403.
Когда уходит запрос и где работает этот источник. Список запрашивается при первом раскрытии попапа фильтра, а не при открытии представления: у сохранённого вида с уже применённым отбором «Выбор значений» запрос уходит только когда пользователь откроет фильтр. Источник подключён у грида категории и грида раздела; остальные хосты грида берут список прежним способом — задачами категории-источника под правами пользователя на неё, поэтому там пустой список у пользователя без прав на категорию-источник остаётся штатным поведением.
Перед построением набор нормализуется: повторы схлопываются, нулевые и отрицательные идентификаторы отбрасываются. Остальные случаи дают ошибку запроса (HTTP 400), а не молчаливый показ неотфильтрованного грида:
taskIdsне передан и признакblankне выставлен — ошибка «Фильтр taskIdSet требует список TaskIds». В живом запросе данных такой фильтр не отбрасывается при разборе и доходит до этой проверки; при чтении сохранённого представления он отбрасывается санитайзером, чтобы вид открывался;- тип ДП колонки не Лукап и не Мультилукап — ошибка «Фильтр taskIdSet не поддерживается для типа ДП …»; тип проверяется раньше содержимого набора;
- после нормализации не осталось ни одного положительного идентификатора, а исходный набор был непустой — ошибка «Фильтр taskIdSet требует хотя бы один положительный TaskID». Из интерфейса такой набор не приходит: состояние «ничего не отмечено» уходит пустым списком без мусорных значений;
- идентификаторов больше предела — тело ответа содержит код
taskIdSetLimitExceededи предельное число вmaxAllowed; набор не усекается. Предел задаёт настройкаTaskIdSetFilterMaxItems, при отсутствии или неположительном значении он равен 1000. - значение поля
taskIds,labels,excludeTaskIdsилиexcludeLabelsприслано в форме, которую контракт не разбирает, — ошибка запроса400с именем колонки и поля. Разбор мягкий, как у самого контракта: строки-числа в списке идентификаторов и числа в списке подписей принимаются. Проверка идёт до обращения к данным; в чтение сохранённого представления она не попадает — негодный фильтр там отбрасывает санитайзер.
Признак «без значения ДП». Поле blank в TaskIdSetFilter включает отбор задач, у которых у ДП нет значения. Признак работает только для колонок Лукап и Мультилукап: тип ДП проверяется раньше содержимого запроса, поэтому для остальных типов запрос отклоняется той же ошибкой про неподдерживаемый тип. JSON без поля blank разбирается в false, так что для клиентов, которые признак не присылают, поведение прежнее.
blank |
taskIds |
Что строит сервер |
|---|---|---|
не передан или false |
непустой | один узел = по набору идентификаторов, как описано выше |
не передан или false |
не передан | ошибка «Фильтр taskIdSet требует список TaskIds» |
не передан или false |
передан пустой | заведомо ложное условие 1 = 0 — ноль строк: состояние «ничего не отмечено» |
true |
не передан или пустой | один узел is null по тому же ParamType — задачи без значения ДП |
true |
непустой | два узла под «или»: is null и обычный отбор по набору, с префиксом any: — у Лукапа и Мультилукапа одинаково |
true |
непустой, но после нормализации пустой | ошибка «Фильтр taskIdSet требует хотя бы один положительный TaskID» |
Семантика объединения внутри набора (any:) та же, что и без признака. Признак blank отправляет и интерфейс: в фильтре «Выбор значений» колонок «Ссылка» и «Множественная ссылка» он отвечает за пункт «(Пусто)» — отмеченный пункт уходит как blank: true, снятый в режиме «всё, кроме снятых» — как blank: false. Отбор задач без значения ДП пользователь закрывает и другим способом: тип фильтра «Текстовый», оператор «Нет значения».
Режим «всё, кроме снятых». Фильтр «Выбор значений» у колонки Лукап работает в двух режимах: «Все» — отмечено всё, кроме снятых, и «Только отмеченные» — прежнее поведение. Режим задаёт параметр фильтра колонки, который ставит только маппер колонок Лукапа; у Мультилукапа и в гриде подписей параметра нет, и режим там прежний. В режиме «Все» клиент присылает в том же TaskIdSetFilter вместо taskIds два поля: excludeTaskIds — числовые идентификаторы снятых задач (сам факт наличия поля означает режим исключений) и excludeLabels — параллельный список подписей снятых задач, он участвует только в хранении и показе чипа. taskIds и excludeTaskIds в одном фильтре не допускаются.
excludeTaskIds |
blank |
Что строит сервер |
|---|---|---|
| непустой | не передан или false |
is not null под «и» с исключением набора: строка проходит, если у ДП есть значение и ни одно её значение не входит в набор |
| непустой | true |
то же исключение под «или» с is null: строки без значения ДП остаются в выборке |
| пустой | false |
один узел is not null — только строки со значением ДП |
| пустой | true |
ошибка «Фильтр taskIdSet с пустым excludeTaskIds и blank=true не ограничивает выборку»; интерфейс такой фильтр не отправляет |
Режим исключений работает только для колонок Лукап: у Мультилукапа и в гриде подписей его нет — параметр, переводящий фильтр в «всё, кроме снятых», ставит только маппер колонок Лукапа. Оба списка сразу и набор из одних неположительных идентификаторов — ошибка запроса 400, как и прежде. Предел набора не изменился: настройка TaskIdSetFilterMaxItems, при отсутствии или неположительном значении — 1000; превышение даёт taskIdSetLimitExceeded с предельным числом в maxAllowed.
Чего режим не требует. Условие собирается штатными узлами разбора — <> с набором any: (как «Исключая значение» у текстового фильтра Лукапа) и is null / is not null, — поэтому под режим «всё, кроме снятых» новых объектов в базе и миграции не требуется.
Сохранённый вид с негодным отбором. При чтении настроек санитайзер отбрасывает ровно те taskIdSet-фильтры, на которых живой отбор ответил бы ошибкой, — иначе вид открывался бы, а первый же запрос данных по нему падал. Отбрасываются: taskIds не передан и blank не выставлен; после нормализации не осталось ни одного положительного идентификатора, а исходный набор был непустой — в обоих режимах; оба списка сразу; taskIdSet на колонке, для которой контракт не заведён (для списка отмеченных — не Лукап и не Мультилукап, для режима исключений — не Лукап); пустой excludeTaskIds с blank: true; идентификаторов больше предела. Отборы, законные на живом запросе, остаются в виде как есть, в том числе taskIds: [] без blank («ничего не отмечено», ноль строк) и пустой excludeTaskIds с blank: false (только строки со значением ДП).
«Выбрать все». Без поиска пункт переключает два состояния: «всё отмечено» и «ничего не отмечено» (ноль строк). При заданном поиске — у Лукапа и Мультилукапа — меняются только найденные значения, причём со всех страниц: клиент догружает их страницами по 500 (верхний предел точки lookup-values), обычная прокрутка списка при этом остаётся по 50. Если найденных больше 1000, отметки не меняются, а в фильтре выводится сообщение о необходимости уточнить поиск. Состояние значений вне поиска сохраняется; в режиме «Только отмеченные» новые отметки объединяются с прежним выбором.
Пункты контекстного меню на таких колонках. «Фильтр по значению» и «Исключая значение» на колонке Лукап или Мультилукап с фильтром «Выбор значений» шлют не taskIdSet, а текстовую модель: filterType — text, операция — equals или notEqual, а идентификаторы значения ячейки лежат в customInfo ({ taskId, option }). Разбирает её MultiSelectFilter (core/Valhalla.Services/AgGridServices/Filters/MultiSelectFilter.cs): список из option подменяет собой текст фильтра и уходит в условие по идентификаторам задач (DecimalValue), поэтому сравнение идёт по связанным задачам, а не по отображаемому тексту. Префикс в option задаёт режим отбора (any: при его отсутствии, all:, exact: — см. выше); Мультилукап в обоих режимах отправляет exact:<ID>,<ID> — набор значений ячейки сравнивается целиком, Лукап при исключении отправляет голый список идентификаторов. Исключение строится как «значение пустое ИЛИ условие не выполнено», поэтому строки с незаполненной ячейкой остаются в выборке. Несовместимое значение option (пустой список после префикса, нечисловой остаток) фильтром не считается: условие не строится, в журнал уходит предупреждение.
Дерево FilterNode¶
Фильтры строят дерево FilterNode:
GeneralFilter (root, AND)
├── FilterNode (column=State, operand=IN, values=[1,3])
├── FilterNode (column=ExtParam42, operand=CONTAINS, value="test")
└── GeneralFilter (OR)
├── FilterNode (column=Owner, operand=EQUALS, value=123)
└── FilterNode (column=Performer, operand=EQUALS, value=456)
Дерево передаётся в SP ShowTasksFeed / ShowExtParamTableData и транслируется в WHERE-clause.