Как исправить ошибку RLS при разыменовании полей составного типа в 1С:Предприятие?

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

При разработке и обновлении нетиповых конфигураций на платформе «1С:Предприятие 8.3» разработчики часто сталкиваются с неожиданными сбоями в работе запросов. Одна из самых коварных ошибок возникает при выполнении, казалось бы, простого запроса к табличной части документа, содержащей реквизит составного типа данных. Запрос внезапно аварийно завершается с ошибкой ограничения прав доступа на уровне записей (RLS), указывая на несуществующий метаобъект.

В этой статье мы подробно разберем природу этого явления, выясним, как связаны разыменование полей типа ЛюбаяСсылка, справочник ИдентификаторыОбъектовМетаданных и шаблоны ограничений доступа Библиотеки стандартных подсистем (БСП). Также мы рассмотрим несколько практических способов решения данной проблемы — от быстрого исправления «в лоб» до архитектурно правильных подходов.

В чем суть проблемы: разыменование «ЛюбойСсылки»

Рассмотрим классическую ситуацию. В конфигурацию добавлен новый документ, в табличной части которого присутствует реквизит с широким составным типом (например, ЛюбаяСсылка или объединение десятков справочников), предназначенный для хранения ссылки на контрагента или другой объект. В коде запроса разработчик обращается к свойствам этого реквизита через точку:


ВЫБРАТЬ
    НовыйДокументТабличнаяЧасть.Контрагент.Наименование КАК НаименованиеКонтрагента
ИЗ
    Документ.НовыйДокумент.ТабличнаяЧасть КАК НовыйДокументТабличнаяЧасть

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

Когда СУБД транслирует этот запрос, платформа обязана гарантировать, что текущий пользователь имеет права на чтение всех соединяемых таблиц. Для этого система выполняет следующие действия:

  1. Анализирует все справочники, которые потенциально входят в составной тип реквизита Контрагент.
  2. Для каждого из этих справочников находит активные роли пользователя и применяет к ним правила RLS.
  3. Внедряет условия ограничений доступа по каждому справочнику в итоговый SQL-запрос.

Если хотя бы для одного из сотен потенциально возможных справочников настроено некорректное правило RLS (даже если этот справочник физически никогда не запишется в данный документ), весь запрос целиком завершится аварийной ошибкой.

Связь RLS со справочником «Идентификаторы объектов метаданных»

Современные конфигурации на базе БСП используют универсальные шаблоны RLS, такие как #ПоЗначениям. Внутри этих шаблонов часто фигурируют строковые имена таблиц, например, "Справочник.СоглашенияОбИспользованииЭД". Для оптимизации работы и проверки прав система сопоставляет эти строки с уникальными ключами в базе данных.

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

  1. В прошлых релизах конфигурации существовал справочник СоглашенияОбИспользованииЭД. Для него в роли ЧтениеЭД было прописано правило ограничения доступа:
    
    #Если &ОграничениеДоступаНаУровнеЗаписейУниверсально #Тогда
        #ДляОбъекта("")
    #Иначе
        #ПоЗначениям("Справочник.СоглашенияОбИспользованииЭД", "", "", "Организации", "Организация", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
    #КонецЕсли
    
  2. В новом релизе разработчики фирмы «1С» переименовали данный справочник в УдалитьСоглашенияОбИспользованииЭД (или полностью удалили его), а саму устаревшую роль ЧтениеЭД исключили из поставки.
  3. При обновлении информационной базы справочник ИдентификаторыОбъектовМетаданных был актуализирован. Запись для Справочник.СоглашенияОбИспользованииЭД исчезла.
  4. Если обновление конфигурации прошло не полностью или в системе остались нетиповые (кастомизированные) роли, ссылающиеся на старый шаблон RLS, то в шаблоне по-прежнему остается обращение к имени "Справочник.СоглашенияОбИспользованииЭД".
  5. При попытке выполнить запрос с разыменованием составного типа платформа компилирует условия RLS для всех справочников. Платформа обращается к справочнику ИдентификаторыОбъектовМетаданных, пытается найти запись со значением "Справочник.СоглашенияОбИспользованииЭД" по полю ПолноеИмя, получает пустой результат и прерывает транзакцию с критической ошибкой.

Выяснив причину проблемы, рассмотрим несколько способов её решения и предотвращения в будущем.

Способ 1. Архитектурно верное решение через оператор ВЫРАЗИТЬ

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


ВЫБРАТЬ
    ВЫРАЗИТЬ(НовыйДокументТабличнаяЧасть.Контрагент КАК Справочник.Контрагенты).Наименование КАК НаименованиеКонтрагента
ИЗ
    Документ.НовыйДокумент.ТабличнаяЧасть КАК НовыйДокументТабличнаяЧасть

Почему это решает проблему: Платформа «1С» на уровне СУБД строит связь LEFT JOIN только с одной физической таблицей — Справочник.Контрагенты. Система полностью игнорирует все остальные справочники, входящие в составной тип. Следовательно, шаблоны RLS для неиспользуемых справочников (включая проблемный СоглашенияОбИспользованииЭД) даже не пытаются компилироваться, и запрос отрабатывает мгновенно и без ошибок.

Способ 2. Использование функции ПРЕДСТАВЛЕНИЕ

Если нам нужно просто вывести текстовое представление объекта на форму или в отчет, и при этом детальные поля (такие как ИНН, КПП или отдельные реквизиты справочника) нам не требуются, мы можем воспользоваться функцией ПРЕДСТАВЛЕНИЕ:


ВЫБРАТЬ
    ПРЕДСТАВЛЕНИЕ(НовыйДокументТабличнаяЧасть.Contragent) КАК КонтрагентПредставление
ИЗ
    Документ.НовыйДокумент.ТабличнаяЧасть КАК НовыйДокументТабличнаяЧасть

Преимущества метода: Для получения строкового представления ссылки платформа задействует оптимизированные внутренние механизмы СУБД. При этом не происходит полного разыменования таблиц и наложения индивидуальных RLS-ограничений для каждого возможного справочника составного типа.

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

Способ 3. Диагностика и исправление «битых» ролей

Если ошибка RLS возникает из-за того, что при обновлении системы затесались устаревшие роли, необходимо локализовать и исправить эти роли. Проанализируем этот процесс по шагам:

  1. Откроем конфигуратор и воспользуемся функцией «Глобальный поиск» (сочетание клавиш Ctrl + Shift + F).
  2. В поле поиска введем имя старого метаобъекта, вызвавшего ошибку (в нашем примере это "Справочник.СоглашенияОбИспользованииЭД").
  3. Обязательно в области поиска установим флаг «Роли» (включая шаблоны ограничений доступа и сами тексты ограничений). Если этот флаг снят, глобальный поиск пропустит тексты RLS.
  4. После нахождения проблемной роли (например, ЧтениеЭД), откроем ее ограничения доступа и заменим устаревшее имя актуальным (например, "Справочник.УдалитьСоглашенияОбИспользованииЭД") либо полностью удалим роль, если она больше не поставляется разработчиком конфигурации.

Способ 4. Проверка внедрения БСП и обновление вспомогательных данных

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

Выполним проверку системы с помощью внешней обработки:

  1. Найдем в дистрибутиве используемой версии БСП внешнюю обработку «ПроверкаВнедренияБСП.erf».
  2. Запустим ее в режиме «1С:Предприятие» под правами администратора.
  3. Перейдем в раздел проверки прав доступа, выберем подсистему «Управление доступом» и установим флаг «Исправлять ошибки».
  4. Запустим процесс анализа. Обработка автоматически найдет все «битые» ссылки на метаданные в шаблонах RLS и предложит варианты их исправления.

После исправления ролей в конфигураторе необходимо принудительно запустить обновление служебных регистров и справочника идентификаторов метаданных в режиме «1С:Предприятие». Для этого выполним следующий код на стороне сервера (например, во внешней обработке):


УправлениеДоступомСлужебный.ОбновитьВспомогательныеДанныеПоИзменениямКонфигурации();

Также рекомендуется запустить стандартное регламентное задание «Заполнение данных для ограничения доступа» через консоль регламентных заданий, чтобы полностью актуализировать кэш прав доступа для всех пользователей системы.

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

← На главную