При работе с языком запросов 1С начинающие и даже опытные разработчики часто сталкиваются с особенностью поведения Конструктора запросов: при сохранении текста запроса расставленные вручную скобки в блоке ГДЕ или в условиях связи ПО внезапно исчезают. Это вызывает опасения, не нарушится ли логика вычислений, особенно когда условие содержит комбинацию операторов И и ИЛИ. В этой статье мы подробно разберем, почему это происходит, как работают приоритеты логических операций и стоит ли беспокоиться за результат выполнения запроса.
Рассмотрим ситуацию, с которой столкнулся автор темы. Ему необходимо отобрать данные по двум группам условий. Логика звучит так: "Выбрать записи, где либо ведется учет по характеристикам и характеристика не заполнена, либо ведется учет по сериям и серия не заполнена".
Изначально программист пишет условие со скобками для визуального разделения логических блоков:
ГДЕ
(ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоХарактеристикам
И ОприходованиеТоваровТовары.ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка))
ИЛИ (ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоСериям
И ОприходованиеТоваровТовары.СерияНоменклатуры = ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка))
Однако после нажатия кнопки "ОК" в Конструкторе запросов 1С, текст трансформируется в следующий вид:
ГДЕ
ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоХарактеристикам
И ОприходованиеТоваровТовары.ХарактеристикаНоменклатуры = ЗНАЧЕНИЕ(Справочник.ХарактеристикиНоменклатуры.ПустаяСсылка)
ИЛИ ОприходованиеТоваровТовары.Номенклатура.ВестиУчетПоСериям
И ОприходованиеТоваровТовары.СерияНоменклатуры = ЗНАЧЕНИЕ(Справочник.СерииНоменклатуры.ПустаяСсылка)
На первый взгляд кажется, что логика нарушена, но это не так. Давайте разберемся, почему результат останется прежним.
В языке запросов 1С, как и в большинстве языков программирования (и в математике), существует строгая иерархия выполнения операций. Разберем приоритеты от самого высокого к самому низкому:
Проанализируем наше выражение. Поскольку оператор И имеет более высокий приоритет, чем ИЛИ, система сначала вычислит выражения, связанные через И, а затем объединит полученные результаты по ИЛИ. Это в точности соответствует математическому правилу: (A * B) + (C * D) дает тот же результат, что и A * B + C * D. Скобки в данном случае являются избыточными.
Важно понимать, что Конструктор запросов — это не текстовый редактор. Это мощный инструмент синтаксического анализа (парсер). Когда вы открываете запрос в конструкторе:
Таким образом, исчезновение скобок — это признак того, что Конструктор "понял" вашу логику и подтвердил, что она будет работать корректно согласно стандартным приоритетам.
Многие разработчики переживают, не станет ли запрос работать медленнее без явного указания скобок. Выясним причину этого спокойствия: платформа 1С не исполняет запрос напрямую. Она транслирует его в SQL-запрос, который отправляется на СУБД (MS SQL, PostgreSQL, Oracle или IBM DB2).
Оптимизатор СУБД строит план выполнения запроса, исходя из логической структуры условий. Наличие избыточных скобок в исходном тексте никак не влияет на итоговый Execution Plan. Для сервера базы данных выражения (A AND B) OR C и A AND B OR C абсолютно идентичны.
Конструктор сохранит скобки только в одном случае: если они изменяют стандартный порядок операций. Рассмотрим пример, где нам нужно сначала выполнить сложение (ИЛИ), а потом умножение (И):
ГДЕ
Номенклатура.Тип = ЗНАЧЕНИЕ(Перечисление.ТипыНоменклатуры.Товар)
И (Номенклатура.Услуга ИЛИ Номенклатура.БезвозвратнаяТара)
В этом случае, если убрать скобки, условие Номенклатура.Тип = ... И Номенклатура.Услуга выполнится первым, что полностью исказит смысл запроса. В таких ситуациях Конструктор никогда не удалит скобки, так как они являются семантически значимыми.
Проанализируем несколько рекомендаций, которые помогут вам комфортно работать с текстами запросов:
И и ИЛИ соблюден верно. Если же вы сомневаетесь в приоритетах, лучше оставить скобки и проверить, не удалит ли их система.И, написаны с отступом относительно ИЛИ, это подсказка о том, что они сгруппированы.ЛЕВОЕ СОЕДИНЕНИЕ ... ПО. Там логика может быть более запутанной, и визуальная чистота кода помогает избежать ошибок.Исчезновение скобок в Конструкторе запросов 1С — это штатное поведение системы, обусловленное правилами логического приоритета. Операция И всегда сильнее, чем ИЛИ. Если вы видите, что скобки пропали, это означает, что ваш запрос написан логически верно и платформа оптимизировала его текст, удалив лишние синтаксические конструкции. Это не является ошибкой "сырой" платформы, а является следствием работы парсера, приводящего код к каноническому виду.