Как автоматически добавить модификатор ВЫБРАТЬ РАЗРЕШЕННЫЕ в запросы при настройке RLS

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

После включения механизма ограничения прав доступа на уровне записей (RLS) разработчики часто сталкиваются с ситуацией, когда типовые и доработанные алгоритмы конфигурации начинают вызывать исключения о нехватке прав при обращении к защищенным таблицам. Стандартной реакцией на такое поведение становится попытка массово пропарсить модули конфигурации и заменить конструкцию ВЫБРАТЬ на ВЫБРАТЬ РАЗРЕШЕННЫЕ. Разберем, почему простая контекстная автозамена приводит к ошибкам, какие синтаксические ограничения накладывает платформа 1С:Предприятие и как решить задачу корректно.

Ограничения синтаксиса языка запросов 1С

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

  1. Запрет использования во вложенных запросах: Ключевое слово РАЗРЕШЕННЫЕ может быть указано только в первом операторе ВЫБРАТЬ пакета запросов или объединения (ОБЪЕДИНИТЬ / ОБЪЕДИНИТЬ ВСЕ). Если заменить ключевое слово во вложенном подзапросе (например, в условии ГДЕ Поле В (ВЫБРАТЬ ...) или в подзапросе секции ИЗ), платформа выдаст критическую синтаксическую ошибку: «Ключевое слово РАЗРЕШЕННЫЕ доступно только у первого запроса».
  2. Динамические списки: Запросы динамических списков на уровне платформы всегда неявно выполняются с модификатором РАЗРЕШЕННЫЕ. Добавлять его вручную в текст запроса динамического списка не требуется.
  3. Повторные замены и англоязычный синтаксис: При простой текстовой замене легко испортить код, если в конфигурации уже присутствуют конструкции ВЫБРАТЬ РАЗРЕШЕННЫЕ (получится дублирование ключевого слова) либо используется англоязычный оператор SELECT.

Метод 1. Автоматизация парсинга через объект СхемаЗапроса

Вместо регулярных выражений и текстовой замены разберем надежный программный способ модификации запросов с помощью встроенного объекта СхемаЗапроса. Этот объект строит абстрактное синтаксическое дерево (AST) запроса и гарантирует корректную расстановку ключевых слов без нарушения синтаксиса во вложенных запросах.

Посмотрим на пример обработки исходного текста запроса:


Функция ДобавитьРазрешенныеВЗапрос(Знач ИсходныйТекст)
    Схема = Новый СхемаЗапроса;
    Попытка
        Схема.УстановитьТекстЗапроса(ИсходныйТекст);
    Исключение
        // Текст содержит ошибки либо является динамически формируемым
        Возврат ИсходныйТекст;
    КонецПопытки;
    
    Для Каждого ЭлементПакета Из Схема.ПакетЗапросов Цикл
        Если ТипЗнч(ЭлементПакета) = Тип("ЗапросВыбораСхемыЗапроса") Тогда
            // Устанавливаем признак только для основного запроса выборки
            ЭлементПакета.ВыбиратьРазрешенные = Истина;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Схема.ПолучитьТекстЗапроса();
КонецФункции

Такой подход защищает от ошибок во вложенных запросах, поскольку СхемаЗапроса применяет свойство ВыбиратьРазрешенные исключительно к допустимым корневым узлам пакета.

Метод 2. Использование привилегированного режима вместо модификации запросов

Массовое внедрение модификатора РАЗРЕШЕННЫЕ во все запросы конфигурации несет серьезные методологические и архитектурные риски. Проанализируем последствия слепого скрытия прав:

  1. Искажение учетных данных: Если запрос участвует в расчете себестоимости, проведении документов, списании партий или формировании движений по регистрам, модификатор РАЗРЕШЕННЫЕ молча скроет недоступные строки. В результате алгоритм рассчитает остатки на неполных данных, что приведет к скрытым учетным ошибкам и появлению отрицательных остатков.
  2. Деградация производительности: Выполнение запросов под RLS заставляет СУБД накладывать множество дополнительных условий соединения с таблицами прав. Массовые служебные выборки под RLS существенно замедляют работу базы данных.

Стандартом разработки 1С для служебных алгоритмов, регламентных заданий и проведения документов является использование привилегированного режима. Выясним, как правильно применить этот механизм:


// Включение привилегированного режима для служебных расчетов
УстановитьПривилегированныйРежим(Истина);

Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура,
    |   ТоварыНаСкладахОстатки.КоличествоОстаток КАК КоличествоОстаток
    |ИЗ
    |   РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки";
Запрос.УстановитьПараметр("Период", ТекущаяДатаСеанса());

РезультатЗапроса = Запрос.Выполнить();

УстановитьПривилегированныйРежим(Ложь);

Альтернативно служебные процедуры и функции можно выносить в общие модули с установленным флажком «Привилегированный». В таком случае отпадает необходимость модифицировать сотни прикладных запросов, исключаются синтаксические ошибки, а СУБД выполняет запросы без лишних накладных расходов RLS.

Рекомендации по внедрению

При настройке RLS рекомендуется следовать четкому алгоритму:

  1. Разделение запросов по назначению: Модификатор ВЫБРАТЬ РАЗРЕШЕННЫЕ следует добавлять только в те отчеты и интерфейсные выборки, где пользователю действительно необходимо показать исключительно доступную ему часть данных.
  2. Служебный контекст: Для алгоритмов контроля остатков, проведения документов и фоновых обработок использовать УстановитьПривилегированныйРежим(Истина) или привилегированные модули.
  3. Автоматизированный рефакторинг: При необходимости массовой корректировки применять выгрузку модулей в файлы с последующей обработкой через СхемаЗапроса либо инструменты статического анализа кода (например, на базе 1C:Enterprise Development Tools / EDT), избегая механической текстовой автозамены.
← На главную