Почему 1С аварийно завершает работу при быстром поиске в выпадающих списках на PostgreSQL?

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

При вводе определенных комбинаций символов в строке быстрого поиска или выпадающем списке (например, конструкций вида [5-0] или [6-0]) платформа «1С:Предприятие» в клиент-серверном варианте под управлением PostgreSQL может аварийно завершать работу с ошибкой: 2201B: ERROR: invalid regular expression: invalid character range. Разберем детально, почему это происходит и как устранить данную проблему.

Проанализируем природу ошибки, механизм трансляции запросов платформой и эффективные способы решения задачи.

Причины возникновения ошибки на стороне PostgreSQL

Выясним причину сбоя при работе со строками поиска:

  1. Трансляция поиска в POSIX-выражения: В некоторых версиях платформы «1С:Предприятие» при работе с СУБД PostgreSQL поиск подстроки и автоподбор в полях ввода транслируются в SQL-запрос с использованием операторов регулярных выражений (POSIX-операторы ~, ~* или SIMILAR TO), а не классической конструкции LIKE.
  2. Отсутствие экранирования спецсимволов: Вводимый пользователем текст передается в тело SQL-запроса без предварительного экранирования управляющих символов регулярных выражений. Квадратные скобки [...] определяют класс или диапазон символов.
  3. Некорректный порядок символов в диапазоне: Конструкция [5-0] задает диапазон от символа «5» до символа «0». В кодовой таблице ASCII/Unicode код символа '5' (код 53) больше кода символа '0' (код 48). PostgreSQL считает такой диапазон синтаксически неверным и возвращает ошибку базы данных с кодом состояния SQLSTATE 2201B.
  4. Поведение на других СУБД: В файловом режиме поиск осуществляется встроенными механизмами платформы в оперативной памяти, а в Microsoft SQL Server обработка шаблонов оператора LIKE работает по другим правилам, поэтому сбой специфичен преимущественно для связки 1С и PostgreSQL.

Способ 1. Обновление версии платформы 1С:Предприятие

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

Способ 2. Программная обработка ввода в модулях менеджеров

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

  1. Откроем модуль менеджера нужного объекта метаданных.
  2. Создадим или модифицируем экспортную процедуру ОбработкаПолученияДанныхВыбора.
  3. Заменим системный автоподбор собственным запросом с безопасным оператором ПОДОБНО, который исключает вызов невалидных регулярных выражений на стороне СУБД.

Посмотрим на пример реализации обработчика:


Процедура ОбработкаПолученияДанныхВыбора(ДанныеВыбора, Параметры, СтандартнаяОбработка) Экспорт
	
	СтандартнаяОбработка = Ложь;
	
	ДанныеВыбора = Новый СписокЗначений;
	
	СтрокаПоиска = СокрЛП(Параметры.СтрокаПоиска);
	Если ПустаяСтрока(СтрокаПоиска) Тогда
		Возврат;
	КонецЕсли;
	
	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ ПЕРВЫЕ 20
		|	Спр.Ссылка КАК Ссылка,
		|	Спр.Наименование КАК Представление
		|ИЗ
		|	Справочник.Номенклатура КАК Спр
		|ГДЕ
		|	НЕ Спр.ПометкаУдаления
		|	И Спр.Наименование ПОДОБНО &ШаблонПоиска
		|АВТОУПОРЯДОЧИВАНИЕ";
		
	Запрос.УстановитьПараметр("ШаблонПоиска", "%" + СтрокаПоиска + "%");
	
	Выборка = Запрос.Выполнить().Выбрать();
	Пока Выборка.Следующий() Цикл
		ДанныеВыбора.Добавить(Выборка.Ссылка, Выборка.Представление);
	КонецЦикла;
	
КонецПроцедуры

Способ 3. Экранирование спецсимволов на форме

Рассмотрим вариант фильтрации вводимого текста в формах ввода. В событиях элементов формы АвтоПодбор или ОкончаниеВводаТекста можно программно очищать текст от квадратных скобок и других управляющих символов:


&НаКлиенте
Процедура ПолеПоискаАвтоПодбор(Элемент, Текст, ДанныеВыбора, Параметры, СтандартнаяОбработка)
	
	ОчищенныйТекст = СтрЗаменить(Текст, "[", "");
	ОчищенныйТекст = СтрЗаменить(ОчищенныйТекст, "]", "");
	
	Если ОчищенныйТекст <> Текст Тогда
		Текст = ОчищенныйТекст;
	КонецЕсли;
	
КонецПроцедуры

Способ 4. Использование полнотекстового поиска

Проанализируем альтернативный механизм поиска больших объемов данных. При реализации поиска по динамическим спискам или справочникам можно задействовать штатный Полнотекстовый поиск 1С. Его синтаксический анализатор работает изолированно от синтаксиса PostgreSQL и корректно обрабатывает невалидные диапазоны символов, не вызывая исключений СУБД.

← На главную