Skip to content

Latest commit

 

History

History
286 lines (246 loc) · 105 KB

File metadata and controls

286 lines (246 loc) · 105 KB

Язык запросов 1С: статус поддержки в open-sdbl

Сверка выполнена 2026-09-18 по версии 0.8.0. Перечень возможностей языка запросов взят из раздела «Язык запросов» Синтакс-помощника платформы 8.3.27.2342. Статус — из кода open-sdbl (src/lexer.rs, src/query/core/parser.rs, src/query/core/codegen/) и спецификаций openspec/specs/.

Обозначения: ✅ поддерживается · 🟡 частично (см. примечание) · ❌ не поддерживается. В графе «Примечание / реакция» — диагностика, которую выдаёт компилятор (QueryDiagnosticKind), если конструкция встречается в запросе.

Страницы Синтакс-помощника, по которым проверялись конструкции, названы во вводных абзацах разделов; открыть страницу можно поиском по её названию.

Обзор проекта, примеры запросов и описание API — в README.

Корпус реальных запросов демо-конфигурации и результат компилятора на них лежит в tests/fixtures/demo (описание — в README рядом): 382 запроса, из них 381 фикстура метаданных способна разрешить, компилируется 377. Это измерение, а не оценка: каждая строка таблицы ниже проверяется на пробной базе, а корпус показывает, на что запросы натыкаются чаще всего.

Каждый скомпилированный запрос корпуса выполняется на настоящей базе PostgreSQL (EXPLAIN): сервер принимает их все. Это отдельная проверка от голденов — те подтверждают, что SQL такой, каким его задумал компилятор, а выполнение подтверждает, что сервер его принимает.

1. Структура запроса

Порядок предложений по странице «Секция ВЫБРАТЬ (Описание запроса)»: ВЫБРАТЬ [РАЗРЕШЕННЫЕ] [РАЗЛИЧНЫЕ] [ПЕРВЫЕ n] <поля> [ПОМЕСТИТЬ …] [ИЗ …] [ИНДЕКСИРОВАТЬ ПО …] [ГДЕ …] [СГРУППИРОВАТЬ ПО …] [ИМЕЮЩИЕ …] [ДЛЯ ИЗМЕНЕНИЯ …], затем ОБЪЕДИНИТЬ, УПОРЯДОЧИТЬ ПО, АВТОУПОРЯДОЧИВАНИЕ, ИТОГИ. Три модификатора после ВЫБРАТЬ идут в любом порядке — замерено на 8.3.27, все шесть перестановок РАЗРЕШЕННЫЕ/РАЗЛИЧНЫЕ/ПЕРВЫЕ n дают один результат; повторённый модификатор — диагностика.

Статус Конструкция (RU / EN) Примечание / реакция
✅ ВЫБРАТЬ / SELECT
✅ РАЗЛИЧНЫЕ / DISTINCT оператор оставляет только проецируемые значения, поэтому УПОРЯДОЧИТЬ ПО адресует колонки выборки по позиции, как у группировки и объединения; поле, которого нет в выборке, — диагностика (иначе SQL отказывается: строковая колонка проецируется с приведением к тексту, а упорядочивание шло по самой колонке)
✅ УПОРЯДОЧИТЬ ПО по составному полю (Регистратор, субконто, момент времени) по пути и по псевдониму: сортировка раскладывается по всем колонкам поля в их порядке — тип, затем значение, — с направлением терма; при РАЗЛИЧНЫЕ, объединении и группировке ссылка адресуется позицией той колонки, которой её выводит проекция
✅ ПЕРВЫЕ n / TOP n TOP (n) на MSSQL, LIMIT n на PostgreSQL; n — целое ≥ 0, ПЕРВЫЕ 0 отвечает колонками без строк (так конфигурации заводят пустую временную таблицу)
🟡 РАЗРЕШЕННЫЕ / ALLOWED только после первого ВЫБРАТЬ оператора, действует на его вложенные запросы, В (…), объединение и виртуальные таблицы; операторы пакета независимы; фильтры не читаются из ролей, а запрашиваются у приложения (Prepared::restriction_request → CompileOptions::restrictions) как условия на SDBL (в том числе в полной форме ТекущаяТаблица [КАК Т] [ИЗ <таблица> [КАК Т]] [<соединения>] ГДЕ …, где ТекущаяТаблица и псевдоним квалифицируют поля таблицы и во вложенных запросах условия, описание источника называет саму ограничиваемую таблицу, а ЛЕВОЕ/ВНУТРЕННЕЕ СОЕДИНЕНИЕ … ПО … компилируются в коррелированный предикат, не размножающий строки; другой источник, ПРАВОЕ/ПОЛНОЕ соединение и соединение не с таблицей метаданных — диагностика) и оборачивают таблицу в производную (SELECT … FROM t AS "__restricted" WHERE …), у виртуальных таблиц добавляются к их условию (только прямые поля); разыменованные таблицы не фильтруются; в консоли — \restrict; подробнее — README «Ограничения доступа»
✅ Принудительный режим ограничений (RestrictionMode::Restricted) выбирается при prepare_with_options, хранится в Prepared и не понижается при компиляции; фильтрует каждый оператор пакета, вложенные запросы, ветки объединения, соединения, виртуальные и временные таблицы независимо от слова РАЗРЕШЕННЫЕ; в запрос ограничений добавляются неявные чтения — цель разыменования, каждый кандидат составной ссылки, цель представления — и решение по ним действительно оборачивает соединение; каждой цели нужен явный AccessDecision (можно всё / по условию / нельзя), цель без решения и ошибка в условии — Restriction, запрет — ложный предикат; обход иерархии, КритерийОтбора, Константы, проекция вложенной табличной части, отложенное представление ссылки и временная таблица из нерестриктивного пакета отклоняются UnsupportedFeature до генерации SQL
✅ Псевдонимы [КАК] / [AS] безымянная проекция поля получает метку по написанию в тексте (Т.Ссылка → «Ссылка», Т.Ref → «Ref», Д.Регистратор → «Регистратор»), а разыменование — по сегментам пути слитно (Д.Организация.Наименование → «ОрганизацияНаименование»), как на платформе, и под этим именем колонку читают вложенный запрос и временная таблица; после КАК псевдонимом может быть и ключевое слово, не открывающее следующую секцию (КАК Конец, КАК Порядок); для полей и источников; КАК необязательно — замерено на 8.3.27, короткая форма принимается у поля, агрегата, ВЫБОР, константы и разыменования, у объекта, соединения, вложенного запроса, виртуальной и временной таблицы, и на неё ссылаются УПОРЯДОЧИТЬ ПО, СГРУППИРОВАТЬ ПО и ИТОГИ; слово ровно одно (Имя Второе — синтаксическая ошибка), контекстное ключевое слово псевдонимом быть может (ВЫБРАТЬ 1 Сумма), а слово, открывающее следующую секцию (ИТОГИ, ИНДЕКСИРОВАТЬ), — нет
✅ Полное имя источника как квалификатор (Справочник.Товары.Наименование) работает, только если у источника нет псевдонима — замерено на 8.3.27; с псевдонимом платформа отвечает «Поле не найдено», и компилятор тоже; путь продолжается разыменованием (Справочник.Товары.Поставщик.Наименование)
✅ Разыменование через псевдоним выборки платформа его не принимает («Поле не найдено "К.Наименование"» для ВЫБРАТЬ Т.Клиент КАК К, К.Наименование, замерено на 8.3.27) — здесь оно тоже диагностика
🟡 *, Псевдоним.* * — только без других полей, без JOIN и при одном источнике в ИЗ (несколько через запятую — диагностика, платформа допускает); Псевдоним.* (по псевдониму или, без него, по имени объекта) разворачивается во все поля источника в порядке метаданных на своём месте в списке — и один, и рядом с другими полями, и в соединениях, повторные метки делаются уникальными; Имя.* не-источника называет табличную часть
✅ Запрос без ИЗ в 1С ИЗ можно опустить при полностью квалифицированных полях; open-sdbl без ИЗ компилирует только выражения без источника (ВЫБРАТЬ 1), в том числе с ГДЕ: условие превращается в WHERE без FROM, как отвечает платформа
🟡 Вложенные таблицы в выборке Состав, Состав.(Поле, …), Состав.* компилируются во второй оператор, связанный с главным по ссылке владельца: CompiledQuery.nested несёт его SQL, колонки и структурную связь (индексы колонок-ключей с обеих сторон), а главный оператор получает служебную колонку ключа (service_columns); платформа делает то же самое — замерено на 8.3.27: она кладёт ключи во временную таблицу pg_temp.ttN и читает секцию соединением с ней; Состав и Состав.* дают ссылку, номер строки и реквизиты, Состав.(…) — ровно перечисленные колонки (псевдонимы внутри списка принимаются и отбрасываются); вместе с ИТОГИ, в объединении и во вложенном запросе — диагностика; ПУСТАЯТАБЛИЦА.(…) / EMPTYTABLE не поддержана
✅ ПОМЕСТИТЬ <ВТ> / INTO, УНИЧТОЖИТЬ <ВТ> / DROP базы-копии только на чтение, поэтому таблица эмулируется CTE vt1, vt2, …: ПОМЕСТИТЬ определяет CTE и возвращает строку Количество, УНИЧТОЖИТЬ SQL не порождает и скрывает имя (можно определить заново); определения хранит TempTablesManager, в WITH попадают только достижимые; правила определения — как у вложенного запроса (*, отложенные представления и УПОРЯДОЧИТЬ ПО без ПЕРВЫЕ запрещены); неизвестное или дублирующее имя — TemporaryTable
✅ ДОБАВИТЬ <ВТ> / ADD (добавление строк в существующую ВТ) новая CTE SELECT … FROM vtK UNION ALL <оператор>, имя переключается на неё; структура сверяется строго (число колонок, виды, цели и ширина ссылок), расширения типа нет; метки колонок остаются от первого определения; поле перед ДОБАВИТЬ не обязано иметь псевдоним, в отличие от 1С
🟡 ИНДЕКСИРОВАТЬ ПО … / INDEX BY, ИНДЕКСИРОВАТЬ ПО НАБОРАМ ((…),(…)) / INDEX BY SETS, модификатор УНИКАЛЬНО / UNIQUE разбирается и проверяется (поля обязаны быть в списке выборки, иначе TemporaryTable; поле может быть уточнено псевдонимом источника — ИНДЕКСИРОВАТЬ ПО Т.Поле называет метку Поле, как принимает платформа), SQL не порождает: у CTE индексов нет
✅ ИЗ КритерийОтбора.<Имя>(<значение>) / FilterCriterion объединение UNION ALL по одному выбору на каждое поле состава критерия; единственное поле Ссылка несёт найденный объект как payload RTRef ‖ RRRef, поэтому разыменовывается, группируется и соединяется как ссылка производного источника; ссылочное значение сравнивается своим 16-байтовым идентификатором; критерий, состав которого не достаёт ни одного живого поля, — диагностика
✅ ИЗ ЖурналДокументов.<Имя> / DocumentJournal таблица журнала со стандартными полями Ссылка, Тип, Дата, Номер, ПометкаУдаления, Проведен и собственными графами по именам метаданных; Ссылка — ссылка зарегистрированного документа: одна колонка, если журнал регистрирует один вид документа, и пара RTRef ‖ RRRef, если несколько, поэтому разыменование и соединение работают как у любой ссылки; Тип — значение типа этой ссылки
🟡 <Источник>.<ТабличнаяЧасть>.<Поле> в условии компилируется в коррелированный EXISTS по таблице части: строка владельца отвечает один раз, сколько бы её строк ни подошло — замерено на 8.3.27 (документ с двумя подходящими строками пришёл один раз, КОЛИЧЕСТВО(*) = 4, а не 5); секция называется через владельца (Д.Товары.Количество), потому что голое <Состав>.<Поле> — это обращение к своим колонкам у запроса, читающего секцию источником; колонка секции, хранимая парой ссылки, сравнивается по payload RTRef ‖ RRRef, другая сторона расширяется так же, как в обычном сравнении составной ссылки; прочие составные колонки секции — диагностика; вне сравнения путь не поддержан
✅ ИЗ <Вид>.<Объект>.<ТабличнаяЧасть> табличная часть читается как источник у всех видов, которые её имеют: справочники, документы, планы видов характеристик, планы счетов, планы видов расчёта, бизнес-процессы, задачи и планы обмена; у прочих видов — диагностика
✅ ИЗ <ВТ> [КАК Псевдоним] (чтение временной таблицы) имя без точки читается как временная таблица, в том числе в соединениях, вложенных запросах и В (…); с псевдонимом источник адресуется только им, без псевдонима квалификатором служит имя таблицы (платформа голое имя объекта не принимает вовсе — это наше послабление); колонки приходят с видами из определения; разыменование — как у вложенного источника
❌ ИЗ &ВнешнийИсточник (ВТ из таблицы значений) внешние источники данных в компиляторе отсутствуют
✅ ИЗ / FROM: несколько источников через запятую каждый элемент списка — источник со своими соединениями; рендерится цепочкой CROSS JOIN в порядке записи; условие соединения видит только источники своего элемента, как в 1С (иначе UnknownField); разделители у таких источников ставятся как у базового; элемент со своими соединениями заключается в скобки и присоединяется целиком — платформа отвечает Товары, Смешанные ПОЛНОЕ СОЕДИНЕНИЕ Клиенты 26 строками, то есть 13 × (0 ⟗ 2), а не 2 (замерено); * при нескольких источниках — диагностика
✅ ИЗ (вложенный запрос) КАК Псевдоним, в том числе в соединениях псевдоним обязателен; колонки подзапроса становятся полями источника с их ColumnKind; внутри допустимы объединения, группировка, соединения, ПЕРВЫЕ, РАЗЛИЧНЫЕ, inline-представления, УПОРЯДОЧИТЬ ПО только когда у каждой ветки есть ПЕРВЫЕ (у объединения порядок ни на что не влияет и отбрасывается); запрещены * и отложенные представления; разыменование — только через колонку-ссылку с одной фиксированной целью; коррелированные ссылки на внешние источники — диагностика; глубина вложенности ≤ 16
🟡 ИЗ &Таблица [КАК Т] и СОЕДИНЕНИЕ &Таблица (таблица значений как параметр) параметр ParameterValue::Table { columns, rows } с типизированными колонками ParameterColumn { name, kind } (строка, число, булево, дата, двоичные, ссылка на объект или на несколько, ЛюбаяСсылка — ссылка без целей); строки встраиваются в CTE оператора SELECT 1 AS "__row", CAST(значение AS тип) … UNION ALL SELECT 2, … (первая строка приводится к типу колонки, пустая таблица — SELECT … WHERE 1 = 0 из типизированных NULL), источник читает CTE по имени; значения проверяются по виду колонки, ссылка обязана указывать на одну из целей; ссылки на несколько объектов или ЛюбаяСсылка — payload RTRef ‖ RRRef; даты в домене хранения; в операторе с ПОМЕСТИТЬ CTE уезжает к определению таблицы; кривая таблица (разная длина строк, значение не того вида, повтор имени колонки, вид NULL/Неопределено/тип, список внутри) и скаляр вместо таблицы — диагностика Parameter; несвязанный проход подготовки видит колонки, названные в тексте; в консоли — литерал ТАБЛИЦА(Код КАК СТРОКА, Ссылка КАК Справочник.Номенклатура)((строка), …)
🟡 [ВНУТРЕННЕЕ] СОЕДИНЕНИЕ, ЛЕВОЕ/ПРАВОЕ/ПОЛНОЕ [ВНЕШНЕЕ] СОЕДИНЕНИЕ … ПО / [INNER] JOIN, LEFT/RIGHT/FULL [OUTER] JOIN … ON источник соединения может нести свои соединения до собственного ПО (условия закрываются в обратном порядке), такая группа компилируется в равносильную плоскую цепочку, внешнее соединение первым — замерено на платформе; группа, у которой внешнее соединение ЛЕВОЕ/ПРАВОЕ/ПОЛНОЕ, а вложенное не ЛЕВОЕ, — диагностика, потому что плоская цепочка отвечает иначе (замерено: 21 строка против 13); отличие: платформа не видит из вложенного условия внешние источники, мы их допускаем; цепочка любого числа соединений в порядке записи; ссылки разной ширины в равенстве приводятся к RTRef ‖ RRRef (фиксированная получает номер типа цели, составная конкатенируется, payload остаётся как есть), две составные сравниваются почленно; ПО внутреннего, левого и правого соединения — любое условие над присоединяемым и более ранними источниками (ИСТИНА, сравнение с параметром, неравенство, МЕЖДУ, разыменование, в том числе через ВЫРАЗИТЬ), как принимают платформа и серверы; ПО полного соединения содержит хотя бы одно равенство прямых полей или одношаговых разыменований присоединяемого и любого более раннего источника (иначе сервер не спланирует FULL JOIN), дополнительно — скалярные фильтры через И; при разыменовании в ПО соединения разыменования выводятся группой рядом со своим источником; ссылка на источник, присоединяемый позже, — диагностика; путь глубже одного шага в ПО — диагностика; ПОЛНОЕ компилируется в нативный FULL JOIN и ведёт себя как остальные соединения: допустимо в цепочке, под агрегатами и с группировкой, разыменование в его ПО выносится внутрь своей стороны; платформа вместо FULL JOIN шлёт разложение — UNION ALL внутреннего соединения и двух антисоединений через НЕ СУЩЕСТВУЕТ (замерено на 8.3.27), но на равенстве оба отвечают одинаково, что сверено пробами построчно; условие ПО остаётся цепочкой равенств через И, иначе сервер откажется планировать соединение
✅ ГДЕ / WHERE
✅ СГРУППИРОВАТЬ ПО / GROUP BY, ИМЕЮЩИЕ / HAVING ключи — путь поля (одно разыменование), псевдоним проекции или выражение, совпадающее с проекцией; проекция, которая не читает ни одного поля источника, — константа набора строк: её не требуется ни группировать, ни ставить рядом с агрегатом (как отвечает платформа); каждая неагрегатная проекция обязана быть ключом, разыменованием ключа (Сотрудник.Наименование при ключе Сотрудник — присоединённая колонка добавляется в GROUP BY) или выражением над ключами (-Сумма, ЕСТЬNULL(Ключ, &П) + 1); ссылочный ключ группируется по всем физическим членам; ИМЕЮЩИЕ — предикат с агрегатами; сортировка сгруппированной ветви — по ключам (и без их проекции), разыменованиям ключей, псевдонимам и выражениям с агрегатом (МАКСИМУМ(Период) УБЫВ); с ПОЛНОЕ СОЕДИНЕНИЕ группировка разрешена и отвечает как платформа
❌ СГРУППИРОВАТЬ [ВСЕ] ПО ГРУППИРУЮЩИМ НАБОРАМ ((…),(…)) / GROUP BY GROUPING SETS
✅ ОБЪЕДИНИТЬ [ВСЕ] / UNION [ALL] ветви должны совпадать по числу значений; значения разных типов образуют составное значение, как на платформе — замерено на 8.3.27: каждая ветвь пишет член своего типа, ноль остальных членов и тег своего типа, и все члены остаются NULL, пока значение ветви NULL; ветвь, которая уже выдаёт члены, сохраняет свой порядок, остальные подстраиваются под неё; ссылки разной ширины по-прежнему приводятся к RTRef ‖ RRRef; колонки, не являющиеся членами одного значения, — диагностика. Отличие: у объединения только скалярных ветвей порядок членов наш (значение первым, _TYPE последним, как у ВЫБОР), у платформы _TYPE первым — на результат это не влияет, обе стороны объединения согласованы между собой
🟡 УПОРЯДОЧИТЬ ПО … ВОЗР/УБЫВ / ORDER BY … ASC/DESC только в конце запроса; ключ — поле, псевдоним проекции или любое выражение (ВЫБОР, арифметика, ЕСТЬNULL, ТИПЗНАЧЕНИЯ), порядковые номера не поддержаны; при JOIN, группировке и ОБЪЕДИНИТЬ порядок задаётся по колонкам результата, поэтому ключ обязан быть полем проекции или псевдонимом, а выражение отклоняется; с ИТОГИ ключ может отсутствовать в проекции — он выводится скрытой колонкой __order_<n>; упорядочивание по типу идёт в порядке кодировки (Неопределено, примитивы, ссылки по номеру таблицы), как на платформе; у оператора с соединениями (без объединения, группировки и РАЗЛИЧНЫЕ) можно сортировать и по непроецируемому полю — оно сортируется своей колонкой, проецируемое — по позиции
❌ УПОРЯДОЧИТЬ ПО … [ВОЗР/УБЫВ] ИЕРАРХИЯ / HIERARCHY
🟡 АВТОУПОРЯДОЧИВАНИЕ / AUTOORDER принимается после УПОРЯДОЧИТЬ ПО (и без него) и ничего не добавляет: платформа досортировывает по представлениям ссылок, компилятор сортирует только по написанным ключам
🟡 ИТОГИ [поля] ПО [ОБЩИЕ] точки [[ТОЛЬКО] ИЕРАРХИЯ] [ПЕРИОДАМИ(…)] / TOTALS … BY [OVERALL] … [[ONLY] HIERARCHY] [PERIODS] результат — строки обхода Прямой: общий итог, затем итог каждой группы перед её строками, группы в порядке первого появления в упорядоченной выборке; итоговые поля — агрегаты по колонкам результата (агрегат пишется в свою колонку, выражение — в колонку из КАК), в прочих колонках NULL; контрольная точка — колонка результата (точка вне списка выборки — диагностика, платформа допускает); ПЕРИОДАМИ разбирается и проверяется, но строк не добавляет (платформа дополняет периоды только в обходе по группировкам); CompileOptions::totals_level добавляет колонку __level = Уровень(), консоль её включает; ИЕРАРХИЯ/ТОЛЬКО ИЕРАРХИЯ — одна контрольная точка (вторая — UnsupportedFeature) с одноцелевой ссылкой на иерархический справочник (иначе Syntax): строка итога по иерархии для каждой папки-предка через рекурсивные CTE по _ParentIDRRef (WITH RECURSIVE на PostgreSQL; на SQL Server действует MAXRECURSION 100), она суммирует строки самой папки и всех потомков; уровень папки — её глубина, итог группы на уровень ниже строки над ним (у папки-ключа — ниже её собственной строки иерархии), детальная запись ещё ниже, при ОБЩИЕ всё на единицу глубже; при ТОЛЬКО группировка по родителю значения; ПО X, X ИЕРАРХИЯ равносильно ПО X ИЕРАРХИЯ; родители ищутся по базовой таблице и таблицам расширений справочника; сверено с платформой на четырёх пробах построчно; отличие: папки-соседи идут в порядке первого появления строк под ними, тогда как платформа сортирует их по полям УПОРЯДОЧИТЬ ПО, вычисленным для самих папок; с ПОМЕСТИТЬ — Syntax, во вложенных запросах — UnsupportedFeature
❌ ДЛЯ ИЗМЕНЕНИЯ [OF таблицы] / FOR UPDATE [OF] компилятор только для чтения
✅ [НЕ] В (вложенный запрос) подзапрос с одной колонкой совместимого вида либо с колонками-членами одного составного значения: замерено на 8.3.27, платформа сравнивает члены рядом ((TYPE, S, RTRef, RRRef) IN (SELECT …)), раскладывая вторую сторону по тем же членам — свой член несёт значение, дискриминатор — тег, остальные — ноль своего типа, и все они остаются NULL, пока значение NULL; на SQL Server строкового сравнения нет, поэтому составная форма там отклоняется диагностикой; составное значение с внешней стороны отвечает своими членами, а если его членов не хватает — диагностика; строковый член сравнивается как текст с обеих сторон; колонки, не являющиеся членами одного значения, — диагностика, как раньше; источники внешнего оператора видны в подзапросе по своему псевдониму (коррелированный подзапрос), безымянное поле по-прежнему ищется только среди собственных источников, а производный источник ИЗ (…) внешние псевдонимы не видит — SQL вычисляет его до внешней строки; ссылки сравниваются на одной ширине (fixed сторона расширяется до RTRef ‖ RRRef) — и в кортеже (А, Б) В (…) тоже: элемент-ссылка нескольких типов сравнивается как payload, составное поле (субконто) — по своим членам с колонками Имя_TYPE/Имя подзапроса; подзапросы в списке выбора — ❌ (их нет и в 1С)
✅ (А, Б) [НЕ] В (вложенный запрос) кортеж полей против подзапроса с тем же числом колонок совместимых видов; рендерится как EXISTS по подзапросу с равенством на каждую колонку на обоих диалектах, в том числе в условии виртуальной таблицы; ссылка нескольких типов с любой стороны и кортеж вне такого условия — диагностика
🟡 Пакет запросов ; операторы пакета компилируются последовательно (не более 64) и собираются в один SQL-оператор: результат даёт последний, как Запрос.Выполнить(); промежуточные запросы без ПОМЕСТИТЬ только проверяются; массива результатов, как у ВыполнитьПакет(), нет; пакет из одного УНИЧТОЖИТЬ строк не возвращает
🟡 Разыменование Поле.Реквизит[.Реквизит…] сколько угодно шагов: каждый шаг присоединяет цель предыдущего, одинаковые шаги ветви делят одно соединение; допустимо в проекции, ГДЕ, СГРУППИРОВАТЬ ПО, УПОРЯДОЧИТЬ ПО, а в ПО соединения — только один шаг, в том числе у ПОЛНОЕ; имя таблицы можно опускать, если поле уникально среди источников; продолжать путь через составную ссылку нельзя — диагностика, платформа так умеет
✅ Поле-пара RTRef ‖ RRRef (Регистратор, Ссылка журнала, payload критерия) как значение такая пара — всегда ссылка, _TYPE у неё нет; агрегат над парой (МАКСИМУМ(Регистратор)) — тот же payload с тем же видом, ЕСТЬNULL над ним расширения не требует; замерено на 8.3.27 на регистре с двумя видами регистратора: платформа принимает её значением везде — в проекции, ВЫБОР, ЕСТЬNULL, сравнении (почленном), ЕСТЬ NULL (оба члена), ССЫЛКА (по _RTRef), группировке и упорядочивании (оба члена) и в агрегате (по склейке членов). Здесь пара в выражении рендерится своим payload RTRef ‖ RRRef с видом runtime-typed ссылки, ТИПЗНАЧЕНИЯ от неё — тег ссылки рядом с номером таблицы из _RTRef, агрегат берётся от payload
✅ Разыменование составного поля (ЛюбаяСсылка, Регистратор, payload подзапроса или ВТ) цели берутся из SchemaStorage, из описания типа в Config, из вида колонки подзапроса либо перебором ссылочных объектов; SchemaStorage не называет цели ссылки, допускающей несколько таблиц (["R",0,0,"",4] против ["R",0,0,"Reference53",3]), но их называет Config: у объекта третий идентификатор его класса — это ссылочный тип, которым его называют другие, а у реквизита есть описание {"Pattern", {"#", <ссылочный тип>}, …} (и то и другое замерено на 8.3.27 на пробной конфигурации); описание типа может называть целый вид, а не объект («любой справочник», «любой бизнес-процесс», «любая ссылка») — это десять платформенных констант, замеренных на 8.3.27, и такой тип раскрывается во все объекты своего вида; если же описание называет не хранимый объект (определяемый тип, характеристику), список остаётся пустым и работает перебор, и стандартные поля в нём распознаются по имени, так что Т.Регистратор.Дата и Т.Объект.Родитель разыменовываются; если присоединяемых целей больше 256 (столько таблиц принимает в одном операторе SQL Server), нужна ВЫРАЗИТЬ; предел считает цели, которые действительно дают соединение, а не кандидатов перебора: корпусный запрос перебирает больше 256 объектов и соединяет 94, давая 65 КБ SQL со 188 LEFT JOIN, который живой сервер планирует и выполняет; на каждую цель LEFT JOIN с охраной по типу, значение — ВЫБОР по _RTRef, для типов без реквизита NULL; цели, которые типизируют реквизит по-разному, дают одно составное значение: каждая пишет член своего типа, ноль остальных членов и тег своего типа, и все они остаются NULL, пока значение этой цели NULL (замерено на 8.3.27, форма та же, что у ВЫБОР разнотипных ветвей); ссылки расширяются до RTRef ‖ RRRef; путь продолжается за составной шаг — замерено на 8.3.27: остаток пути проходится внутри каждой цели (соединения после составного шага идут без охраны, потому что цель уже фиксирована), ветви выбираются тем же CASE по типу, а цель, в которой остаток пути не разрешается, в результат не попадает; составной шаг глубже вкладывает ещё один CASE; больше 256 целей и представление результата — диагностика; значение, разыменованное через многотипную ссылку (Регистратор.Организация), в выражении — его член-значение (CASE по целям), сравнение со ссылочной константой — через её payload RTRef ‖ RRRef
✅ .Представление / .Presentation через callback-план приложения (см. README «Callback ABI представлений»)

2. Операторы

Грамматика логических выражений по страницам «Логические выражения в языке запросов» и «Логические операторы»: сравнение > < = >= <= <>, [НЕ] В [ИЕРАРХИИ] (список | подзапрос), [НЕ] МЕЖДУ … И …, ЕСТЬ [НЕ] NULL, ССЫЛКА <Имя таблицы> (операнд — поле или ВЫРАЗИТЬ(поле КАК та же таблица)), [НЕ] ПОДОБНО … [СПЕЦСИМВОЛ …], связки И ИЛИ НЕ.

Статус Оператор Примечание / реакция
✅ + - * / % — ❌ (в справке не описан)
✅ + как конкатенация строк замерено на 8.3.27: платформа склеивает строки и отказывает, если рядом со строкой стоит другой тип («Неверные параметры "+"»), — здесь так же; операнды приводятся к тексту, вид выражения — String
✅ = <> < > <= >=
🟡 Сравнение составного поля со значением (=, <>, В) предикат собирается по физическим членам, как это делает платформа: _TYPE сравнивается с тегом типа значения, а член этого типа — со значением; ссылка сравнивает ещё и _RTRef, а поле с единственным ссылочным типом хранит _RTRef не отдельной колонкой, и он синтезируется из _TYPE; значение типа, который поле хранить не может, даёт пустую выборку, а параметр без значения — сравнение с NULL; сравнение двух составных полей, >/< (платформа упорядочивает по тегу типа) и ЕСТЬNULL над составным полем не поддержаны — диагностика
✅ Логическое выражение как значение сравнение, И/ИЛИ/НЕ, ЕСТЬ NULL, ПОДОБНО, МЕЖДУ, ССЫЛКА и В отвечают булевым значением в проекции, ветви ВЫБОР и упорядочивании; NULL в операнде даёт NULL — замерено на 8.3.27. На PostgreSQL это само предикатное выражение, на SQL Server булевых значений нет, поэтому значение рендерится трёхветочным CASE WHEN p THEN 0x01 WHEN NOT p THEN 0x00 END (сохраняет NULL), а предикатная позиция остаётся обычным предикатом
✅ И / ИЛИ / НЕ (AND / OR / NOT) приоритет замерен на платформе: НЕ слабее любого сравнения и сильнее И, поэтому НЕ Т.Цена = 10 отрицает сравнение, а НЕ А > 10 И Б < 30 отрицает только первое; НЕ покрывает также ПОДОБНО, В, В ИЕРАРХИИ, ССЫЛКА и ЕСТЬ NULL; унарные + и - по-прежнему относятся к своему операнду; отличие: НЕ х МЕЖДУ а И б платформа не принимает (нужно х НЕ МЕЖДУ а И б), мы разбираем как отрицание сравнения; на MSSQL булевы поля в предикатах приводятся к = 0x01
✅ В (список) / IN (...) непустой список скалярных выражений, в том числе ЗНАЧЕНИЕ(...)
✅ НЕ В (список) / NOT IN
✅ [НЕ] В ИЕРАРХИИ (…) / IN HIERARCHY значение совпадает с элементом списка или лежит под ним по цепочке _ParentIDRRef; спуск — рекурсивная CTE на каждый предикат (WITH RECURSIVE на PostgreSQL, WITH на SQL Server), проверка через EXISTS, поэтому NULL в списке ничего не портит; пустая ссылка охватывает весь справочник, а справочник без колонки родителя вырождается в обычное вхождение — как на платформе; слева — поле с единственной ссылочной целью либо составная ссылка: у составной сравнивается идентификатор, а тип обязан совпасть с типом семян, потому что значение другого типа ни под каким семенем не лежит (замерено на 8.3.27); если тип семян неизвестен при компиляции — например, параметр связан NULL — спуск не строится и остаётся сравнение идентификаторов, которые уникальны; справа — вложенный запрос или константы (поле в списке — диагностика, CTE не видит внешнюю строку); в операторе с ПОМЕСТИТЬ/ДОБАВИТЬ рекурсивные CTE переезжают к определению таблицы под именами __hier_t<id>_<n> и объявляются перед её CTE в каждом читающем её операторе (WITH RECURSIVE на PostgreSQL)
✅ [НЕ] МЕЖДУ … И … / BETWEEN границы включаются, обратные границы дают пустую выборку, NULL не совпадает — как на платформе; значение и границы — любые скалярные выражения
✅ [НЕ] ПОДОБНО … [СПЕЦСИМВОЛ …] / [NOT] LIKE … [ESCAPE …] шаблон передаётся в LIKE без переписывания на обоих провайдерах (на PostgreSQL классы […] обеспечивает mchar); операнды — строки; принимается и как значение (проекция, ВЫБОР, упорядочивание), как на платформе
✅ ЕСТЬ NULL / ЕСТЬ НЕ NULL (IS [NOT] NULL) составное поле и универсальная ссылка проверяются по одному члену — _TYPE, иначе RRRef: он NULL ровно тогда, когда строки нет, поэтому у собственных строк таблицы ответ всегда ЛОЖЬ, а у непопавшей строки внешнего соединения — ИСТИНА, как на платформе
✅ ССЫЛКА Справочник.X / REFS операнд — прямое поле или одношаговое разыменование; составное поле сравнивает _RTRef с номером типа, payload вложенного запроса — первые четыре байта; поле с единственной целью даёт ИСТИНА и для пустой ссылки, как платформа; чужой тип и нессылочное поле — Syntax (в 1С «Несовместимые типы»)
✅ ВЫБОР [выражение] КОГДА … ТОГДА … [ИНАЧЕ …] КОНЕЦ / CASE [expr] WHEN … THEN … [ELSE …] END простая форма сравнивает каждую альтернативу с выражением после ВЫБОР по тем же правилам, что и сравнение в ГДЕ (ссылки, составные поля, значения типа); NULL в выражении не совпадает ни с одной альтернативой, как на платформе; ветки разных типов дают значение составного типа: в проекции оно раскладывается по членам (<имя> — payload ссылки, <имя>_S, <имя>_N, <имя>_T, <имя>_L и <имя>_TYPE), каждая ветка пишет своё значение в свой член и нули в остальные — так же хранит и возвращает платформа; ветка, состоящая из одних NULL (например вложенный ВЫБОР по несвязанным параметрам), получает тип альтернативы: без этого PostgreSQL читает её как text и отвергает соседство с payload ссылки; двоичные данные и УникальныйИдентификатор члена в раскладке 1С не имеют (такое значение не попадает в таблицу), поэтому получают собственные члены <имя>_B и <имя>_U с тегом NULL — платформа отвечает на такую ветвь двоичными данными, а ТИПЗНАЧЕНИЯ от неё даёт Null (замерено на 8.3.27); ТИПЗНАЧЕНИЯ от самого разнотипного ВЫБОР пока не компилируется; вне проекции разнотипные ветки — диагностика, кроме сравнения и ПРЕДСТАВЛЕНИЕ: в сравнении со значением ветвь другого вида отдаёт NULL и потому не совпадает (как на платформе; <> с такой ветвью даёт NULL, а не платформенную истину), при сравнении с NULL или параметром без значения ветви меряются по первой типизированной; ПРЕДСТАВЛЕНИЕ оно проталкивается в ветви и даёт одну строковую колонку (строковая ветвь — сама строка, ссылочная — представление по плану приложения), как отвечает платформа (замерено на 8.3.27); ветвь, представимая только отложенным протоколом, — диагностика; вид результата — первая не-NULL ветвь, остальные должны быть совместимы; ссылки на разные объекты расширяются до runtime-typed payload; агрегаты внутри ВЫБОР допустимы в сгруппированных ветвях и в ветвях из одних агрегатов

3. Функции

Полный перечень функций языка запросов даёт страница «Функции языка запросов», агрегатные перечислены на странице «Агрегатные функции языка запросов». Английские написания взяты из двуязычной таблицы «Двуязычное представление ключевых слов» и заголовков страниц функций.

Агрегатные

Статус Функция Примечание
✅ КОЛИЧЕСТВО(*), КОЛИЧЕСТВО(x), КОЛИЧЕСТВО(РАЗЛИЧНЫЕ x) / COUNT([DISTINCT] …) ColumnKind::Number; РАЗЛИЧНЫЕ в 1С тоже допустимо только у КОЛИЧЕСТВО
✅ СУММА / SUM аргумент — любое скалярное выражение (СУММА(ВЫБОР … КОНЕЦ))
✅ МИНИМУМ / MIN, МАКСИМУМ / MAX аргумент — любое скалярное выражение; тип результата — тип аргумента; ссылочное выражение агрегируется как payload
✅ СРЕДНЕЕ / AVG аргумент — любое скалярное выражение, РАЗЛИЧНЫЕ и * не допускаются; результат — Number; на SQL Server среднее целочисленных литералов целое, у numeric колонок шесть знаков после запятой, PostgreSQL возвращает полную точность
❌ СГРУППИРОВАНОПО(x) / GROUPEDBY имеет смысл только с группирующими наборами

Типы и значения

Статус Функция Примечание
✅ ВЫРАЗИТЬ(x КАК БУЛЕВО | ЧИСЛО [(Длина[, Точность])] | СТРОКА [(Длина)] | ДАТА) / CAST … AS BOOLEAN | NUMBER | STRING | DATE ЧИСЛО без параметров на MSSQL — numeric(38, 10); в 1С длина СТРОКА ограничена 1024
✅ ВЫРАЗИТЬ(x КАК Справочник.X)[.Реквизит] сужается не только поле, но и выражение: ссылка того же типа сохраняет значение, payload сужается по префиксу типа, значение, которое NULL при любом типе (в том числе несвязанный параметр), даёт NULL названного типа, прочие виды — диагностика, как их отвергает платформа; значение — RRRef под guard RTRef, чужие типы → NULL (как в 1С); одно разыменование через LEFT JOIN; в ПО допустимо само сужение, но не .Реквизит после него («JOIN condition supports direct fields only»)
✅ ЗНАЧЕНИЕ(Перечисление.X.Y), ЗНАЧЕНИЕ(Справочник.X.Предопределенный), ЗНАЧЕНИЕ(ПланСчетов.X.Счет), ЗНАЧЕНИЕ(ПланВидовХарактеристик.X.Вид) / VALUE справочники, перечисления, планы счетов и планы видов характеристик (предопределённые элементы лежат в ресурсах <guid>.1c, .9 и .7 соответственно, замерено на УНФ и демо-бухгалтерии; планы видов расчёта — после замера); имена внутри скобок принимаются и тогда, когда совпадают с ключевым словом (в реальных конфигурациях есть значение перечисления НеОпределено)
🟡 ЗНАЧЕНИЕ(ВидДвиженияНакопления.Приход), ЗНАЧЕНИЕ(ВидДвиженияБухгалтерии.Дебет), ЗНАЧЕНИЕ(ВидСчета.АктивноПассивный) / AccumulationRecordType, AccountingRecordType, AccountType системные перечисления компилируются в число, которое хранит платформа: Приход 0, Расход 1 (колонка _RecordKind), Дебет 0, Кредит 1 (_Correspond), Активный 0, Пассивный 1, АктивноПассивный 2 (_Kind плана счетов, замерено на плане счетов УНФ по предопределённым счетам); принимаются везде, где принимается числовой литерал, в том числе в условиях виртуальных таблиц; ТИПЗНАЧЕНИЯ от такого значения отвечает числом, а платформа — типом перечисления
✅ ЗНАЧЕНИЕ(<Вид>.<Объект>.ПустаяСсылка) / EmptyRef 16 нулевых байт с видом Reference{targets: [объект]} для всех ссылочных видов; сравнение с runtime-typed полем проверяет _RTRef и _RRRef
✅ Литерал ТИП(Строка), ТИП(Справочник.X) / TYPE аргумент — Строка, Число, Дата, Булево (String, Number, Date, Boolean) или объект метаданных с номером типа; прочее — диагностика Syntax, как в 1С («Таблица не найдена»)
✅ ТИПЗНАЧЕНИЯ(x) / VALUETYPE вид колонки — Type, значение — 5 байт: тег _TYPE платформы (0x01 Неопределено, 0x02 Булево, 0x03 Число, 0x04 Дата, 0x05 Строка, 0x08 ссылка, 0x00 тип NULL — замерено на платформе) и номер таблицы ссылки; составное поле читает _TYPE и _RTRef, поле из вложенного запроса — колонку <имя>_TYPE рядом с payload, универсальная ссылка — префикс payload, прочие выражения дают константу своего вида под охраной IS NULL; NULL и несвязанный параметр дают тип NULL, так что результат никогда не NULL; двоичные поля, УникальныйИдентификатор и неклассифицированные типы — UnsupportedFeature; группировка и упорядочивание по типу не поддержаны; консоль печатает имя типа (Справочник.Товары, Строка)
✅ ЕСТЬNULL(x, y) / ISNULL COALESCE(x, y); вид — вид x (или y, если x — NULL); ссылки расширяются как в ВЫБОР; строковый результат на PostgreSQL приводится к text, как и у ВЫБОР и агрегатов, иначе тип-расширение mvarchar не читается драйвером
✅ ПРЕДСТАВЛЕНИЕ(x) / PRESENTATION, ПРЕДСТАВЛЕНИЕССЫЛКИ(x) / REFPRESENTATION аргументом принимается любое выражение — замерено на 8.3.27: значение, которое не ссылка, само себе представление (строка отвечает собой, склейка — результатом, число — цифрами); ссылочное выражение несёт саму ссылку отложенной колонкой представления — так же, как универсальная ссылка поля, и приложение разрешает её вторым проходом (сверено: консоль разрешает пробу в те же имена, что печатает платформа); универсальные ссылки полей резолвятся отложенно пакетами; аргументом может быть агрегат — такая проекция считается агрегатной, и ветвь агрегирует (замерено на 8.3.27: ПРЕДСТАВЛЕНИЕ(МАКСИМУМ(Т.Клиент)) даёт представление наибольшей ссылки, ПРЕДСТАВЛЕНИЕ(КОЛИЧЕСТВО(*)) — число текстом, с группировкой — по каждой группе)
✅ УНИКАЛЬНЫЙИДЕНТИФИКАТОР(x) / UUID нативный uuid / uniqueidentifier; аргумент — ссылочное поле; NULL → NULL как в 1С; нессылочный аргумент — ошибка компиляции (в 1С — ошибка выполнения)
✅ АВТОНОМЕРЗАПИСИ() / RECORDAUTONUMBER ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) — уникальный номер строки без определённого порядка; в 1С допустима только в запросе с ПОМЕСТИТЬ, компилятор принимает её в любом операторе
❌ РАЗМЕРХРАНИМЫХДАННЫХ английское написание в справке не приведено

Строковые

Статус Функция Примечание
✅ ПОДСТРОКА(x, нач, длина) / SUBSTRING позиции с единицы, длина за концом обрезается, нулевая длина даёт пустую строку
❌ СТРОКА(x) / STRING, как цель ВЫРАЗИТЬ — ✅ платформа возвращает локализованное представление (10,00, 15.01.2024 00:00:00, Да), воспроизвести это в SQL точно нельзя; используйте ВЫРАЗИТЬ(x КАК СТРОКА)
✅ ДлинаСтроки(x) / StringLength считает и концевые пробелы, поэтому на SQL Server не LEN, а LEN(x + '.') - 1
✅ СокрЛП / TrimAll, СокрЛ / TrimL, СокрП / TrimR убирают пробелы
✅ ВРег / Upper, НРег / Lower
✅ Лев(x, n) / Left, Прав(x, n) / Right английские имена совпадают с ключевыми словами соединений, поэтому распознаются только в выражении; на PostgreSQL выводятся через substring, так как left/right появились в 9.1
✅ СтрНайти(x, подстрока) / StrFind, СтрЗаменить / StrReplace СтрНайти возвращает позицию с единицы и 0, если подстроки нет; СтрЗаменить заменяет все вхождения

НСтр в Синтакс-помощнике как функция языка запросов не значится (предыдущая редакция таблицы ошибочно включала её).

Математические

Статус Функция Примечание
✅ Окр(x[, разрядность]) / Round, Цел(x) / Int Окр округляет от нуля и принимает отрицательную разрядность, разрядность по умолчанию 0; Цел отсекает к нулю; на SQL Server результат сохраняет масштаб аргумента
✅ ACos, ASin, ATan, Cos, Sin, Tan, Exp, Log, Log10, Pow, Sqrt Log — натуральный логарифм (на PostgreSQL это ln, а log — десятичный), Log10 — десятичный; тригонометрические на PostgreSQL приводят аргумент к double precision

Даты

Статус Функция Примечание
✅ ДАТАВРЕМЯ(г, м, д[, ч, мин, с]) / DATETIME только целочисленные литералы; на MSSQL учитывается _YearOffset
✅ НАЧАЛОПЕРИОДА(x, МИНУТА | ЧАС | ДЕНЬ | НЕДЕЛЯ | МЕСЯЦ | КВАРТАЛ | ГОД | ДЕКАДА | ПОЛУГОДИЕ) / BEGINOFPERIOD все девять периодов; неделя с понедельника; на SQL Server 2008 — эмуляция DATEADD/DATEDIFF
✅ КОНЕЦПЕРИОДА(x, период) / ENDOFPERIOD те же девять периодов; последняя секунда периода, декада заканчивается 10-м, 20-м или последним днём месяца; СЕКУНДА — диагностика Syntax, как в 1С
✅ ДОБАВИТЬКДАТЕ(x, период, n) / DATEADD десять периодов, включая СЕКУНДА; n — любое числовое выражение, поле или параметр; конец месяца «прижимается»; дробное n округляется для СЕКУНДА…МЕСЯЦ и усекается для ДЕКАДА, КВАРТАЛ, ПОЛУГОДИЕ, ГОД — так считает платформа
✅ РАЗНОСТЬДАТ(a, b, СЕКУНДА | МИНУТА | ЧАС | ДЕНЬ | МЕСЯЦ | КВАРТАЛ | ГОД) / DATEDIFF считает пересечённые границы единицы (31.12 23:59:59 → 01.01 в днях даёт 1), как DATEDIFF SQL Server и платформа; НЕДЕЛЯ, ДЕКАДА, ПОЛУГОДИЕ — диагностика Syntax; секунды не переполняются на всём диапазоне дат
✅ ГОД, КВАРТАЛ, МЕСЯЦ, ДЕНЬГОДА, ДЕНЬ, НЕДЕЛЯ, ДЕНЬНЕДЕЛИ, ЧАС, МИНУТА, СЕКУНДА / YEAR, QUARTER, MONTH, DAYOFYEAR, DAY, WEEK, WEEKDAY, HOUR, MINUTE, SECOND результат — целое число; ДЕНЬНЕДЕЛИ — 1 (понедельник) … 7 (воскресенье) независимо от DATEFIRST; НЕДЕЛЯ — нумерация платформы, не ISO 8601: неделя, в которую попадает 1 января, — первая, недели начинаются с понедельника, нумерация начинается заново 1 января; имена функций остаются допустимыми псевдонимами (ГОД(Дата) КАК Год); на MSSQL части берутся от логической даты с учётом _YearOffset

4. Источники и виртуальные таблицы

Списки параметров ниже — в порядке, заданном страницами таблиц Синтакс- помощника; в 1С любой параметр можно опустить, оставив запятую. Страница справки у виртуальной таблицы называется так же, как сама таблица.

Статус Источник Примечание
✅ Справочник, Документ, Перечисление, ПланВидовХарактеристик, ПланСчетов, ПланВидовРасчета, ПланОбмена, РегистрСведений, РегистрНакопления, РегистрБухгалтерии, РегистрРасчета, БизнесПроцесс, Задача, Константа, Последовательность русские, английские и короткие имена видов (Catalog/Reference, InfoRg, AccumRg, …); объект должен иметь живую таблицу
✅ Табличные части Документ.X.ТЧ, Справочник.X.ТЧ стандартные поля строки Ссылка, НомерСтроки; таблицы расширений X/X1 объединяются UNION ALL
✅ Константы / Constants (как одна таблица) поля — имена констант, * допускается; в SQL — UNION ALL только по константам, которые упоминает запрос, свёрнутый MAX в одну строку; незаписанная константа даёт NULL; разделители применяются в каждой ветви
✅ Константа.<Имя> / Constant.<Name> (как отдельная таблица) одно поле Значение / Value; имя самой константы полем не является — замерено на 8.3.27: ВЫБРАТЬ * ИЗ Константа.ОсновнойТовар даёт колонку Значение, а К.ОсновнойТовар — «Поле не найдено»; поле проецируется, фильтруется, группируется, упорядочивается и разыменовывается как любое другое; разделители таблицы применяются как у обычного источника; состав * пока расходится с платформой (мы показываем независимый разделитель и RecordKey, платформа — нет)
❌ ВнешнийИсточникДанных внешние источники данных в компиляторе отсутствуют; КритерийОтбора и ЖурналДокументов поддерживаются — см. их строки выше
✅ Главная таблица РегистрБухгалтерии.X: СчетДт/СчетКт (AccountDr/AccountCr; Счет без корреспонденции), балансовые измерения и ресурсы по имени, небалансовые — <Имя>Дт/<Имя>Кт (<Имя>Dr/<Имя>Cr), реквизиты, Период, Регистратор, НомерСтроки, Активность назначения полей, флаг «Балансовый» и план счетов регистра читаются из Config (коллекции и флаг замерены на 8.3.27 по регистру Управленческий УНФ); колонки _Fld<N>Dt/_Fld<N>Ct относятся к полю N; УточнениеПериода не отвечается
✅ Служебные части: Изменения (ПланОбмена/регистрация изменений; поля Узел/Node и НомерСообщения/MessageNo), БазовыеВидыРасчета, ВедущиеВидыРасчета, ВытесняющиеВидыРасчета, ВидыСубконто остальные служебные таблицы видны в \dt, но во FROM дают UnsupportedFeature
✅ РегистрСведений.X.СрезПоследних(Период, Условие) / SliceLast оба аргумента необязательны; условие — по прямым измерениям и разделителям; только активные записи (как в 1С с 8.3.18)
✅ РегистрСведений.X.СрезПервых(Период, Условие) / SliceFirst
✅ РегистрНакопления.X.Остатки(Период, Условие) / Balance только регистры остатков; ресурсы суммируются по измерениям, которые запрос не читает, как на платформе (измерение из условия самой виртуальной таблицы группировки не добавляет); условие принимает разыменование (Номенклатура.Родитель = &Р) — цель присоединяется к ветке итогов и к ветке движений; список аргументов можно опустить
🟡 РегистрНакопления.X.Обороты(НачалоПериода, КонецПериода, Периодичность, Условие) / Turnovers у регистра остатков на каждый ресурс отвечаются <Ресурс>Оборот, <Ресурс>Приход и <Ресурс>Расход (суммы по виду записи), у оборотного — только <Ресурс>Оборот; периодичность — календарная единица от Секунда до Год, пишется именем периода; Период (документированное умолчание: «только за период, не разворачивать») равносильна опущенной периодичности; Авто («определяется по используемым в запросе полям периодов») даёт поля Период, ПериодСекунда…ПериодГод (начало соответствующего периода записи), Регистратор и НомерСтроки как измерения: прочитанные разворачивают таблицу, непрочитанные суммируются, без них — весь интервал; таблица получает поле Период (начало периода записи) и группируется по нему даже тогда, когда запрос Период не читает, как на платформе; Регистратор группирует по периоду и регистратору записи и выдаёт поля Период и Регистратор, Запись добавляет НомерСтроки и даёт строку на каждую запись регистра; НомерСтроки при Регистратор недоступен, как на платформе; поля ПериодГод…ПериодСекунда недоступны; ресурсы суммируются по непрочитанным измерениям
🟡 РегистрНакопления.X.ОстаткиИОбороты(НачалоПериода, КонецПериода, Периодичность, МетодДополненияПериодов, Условие) / BalanceAndTurnovers на каждый ресурс выдаются НачальныйОстаток, Приход, Расход, Оборот, КонечныйОстаток; значения считаются по движениям: начальный остаток — знаковое движение до начала, приход и расход — движения [начало, конец) по виду записи, конечный — их сумма; суммируются по непрочитанным измерениям, как у прочих таблиц регистра; календарная периодичность группирует движения интервала по периодам и даёт поле Период — ровно то, что отвечает платформа, пока не читается колонка остатка; метод дополнения периодов принимается и без периодичности (там ему нечего дополнять, платформа его допускает); оба метода дают одни и те же строки там, где остаток не читается; под Авто те же поля разворота, что у Обороты, а остатки развёрнутой таблицы — бегущие суммы, как у регистра накопления (части Дт/Кт — от бегущей суммы), на SQL Server 2008 — диагностика; колонки остатка развёрнутой таблицы — бегущие суммы оконной функцией (SUM(SUM(…)) OVER (PARTITION BY измерения ORDER BY корзина ROWS BETWEEN …)) над движениями до Конец, разложенными по корзинам гранулярности — календарный период, регистратор, запись, — где движения до Начало образуют первую корзину, отбрасываемую после окна; под Авто гранулярность — то, что читает запрос (запись при НомерСтроки, регистратор при Регистратор/Период, иначе самый мелкий прочитанный уровень периода), запрос без колонок остатка получает отношение без окон; на SQL Server 2008 остатки развёрнутой таблицы отклоняются (нет рамки окна); метод ДвиженияИГраницыПериода пограничных строк не добавляет; Регистратор и Запись как периодичность — разворот по периоду записи и регистратору (и номеру строки), остатки — бегущие суммы по тем же корзинам, на SQL Server 2008 — диагностика (сверено на живой демо-бухгалтерии: начальный остаток плюс оборот равен конечному в каждой строке); только регистр остатков
🟡 РегистрБухгалтерии.X.Остатки(Период, УсловиеСчета, Субконто, Условие) / Balance только регистр с корреспонденцией, по движениям на той же свёртке сторон, что Обороты: <Ресурс>Остаток — дебет минус кредит по активным записям до Период (без него — все), <Ресурс>ОстатокДт/<Ресурс>ОстатокКт — положительная и взятая с минусом отрицательная часть остатка на том уровне, который читает запрос (пересчитываются после суммирования непрочитанных измерений, а не суммируются); комбинации с нулевыми остатками отбрасываются; <Ресурс>РазвернутыйОстатокДт/Кт — положительная и взятая с обратным знаком отрицательная части остатка по счёту, измерениям и субконто, суммируемые снаружи по непрочитанным измерениям (сверено на живой демо-бухгалтерии: разность частей равна свёрнутому остатку); у регистра без субконто аргумент «Субконто» отсутствует (Остатки(Период, УсловиеСчета, Условие)); SQL выполнен на живой базе УНФ субконто: поля Субконто<k> (составное значение) и ВидСубконто<k> по числу уровней регистра читаются из встроенных колонок стороны (_ValueDt<k>_*, _KindDt<k>RRef, замерено на демо-бухгалтерии) и суммируются, если не прочитаны; без аргумента «Субконто» позиции — порядок видов самого счёта; аргумент — один вид (ЗНАЧЕНИЕ(ПланВидовХарактеристик.…) или параметр-ссылка) либо список в скобках, тогда Субконто<j> берёт значение уровня с j-м указанным видом, а записи, у чьего счёта вида нет, отбрасываются; параметр без привязанной ссылки (не привязан либо массив, которого компилятор не видит) оставляет позиции как без аргумента; в условии видны позиционные Субконто<k>
🟡 РегистрБухгалтерии.X.Обороты(НачалоПериода, КонецПериода, Периодичность, УсловиеСчета, Субконто, Условие, УсловиеКорСчета, КорСубконто) / Turnovers только регистр с корреспонденцией: каждая активная запись [Начало, Конец) даёт строку дебета и строку кредита, группировка по Счет, прочитанным измерениям и календарному периоду; небалансовое измерение или ресурс читается из колонки своей стороны под общим именем; на ресурс — <Ресурс>Оборот (Дт минус Кт), <Ресурс>ОборотДт, <Ресурс>ОборотКт; непрочитанные измерения суммируются; УсловиеСчета — предикат на Счет стороны, Условие видит запись глазами стороны; у регистра без субконто платформа опускает аргументы «Субконто» (замерено на УНФ: Обороты(&Н, &К, МЕСЯЦ, , Условие)), раскладка аргументов следует наличию таблицы AccRgED; Регистратор и Запись разворачивают как у регистра накопления; корреспонденция: КорСчет, <Измерение>Кор небалансовых измерений, КорСубконто<k>/ВидКорСубконто<k> — ветка дебета читает их из кредитовых колонок, ветка кредита из дебетовых; КорСубконто перечисляет виды как Субконто, проверка на противоположной стороне; УсловиеКорСчета компилируется вместе с условием счёта; сверено на живой демо-бухгалтерии; регистр без корреспонденции — позже
🟡 РегистрБухгалтерии.X.ОстаткиИОбороты(НачалоПериода, КонецПериода, Периодичность, МетодДополненияПериодов, УсловиеСчета, Субконто, Условие) / BalanceAndTurnovers на ресурс: НачальныйОстаток (записи до Начало), Оборот/ОборотДт/ОборотКт за [Начало, Конец), КонечныйОстаток, части Дт/Кт обоих остатков — производные на итоговом уровне; календарная периодичность, Регистратор, Запись и Авто разворачивают, остатки при этом — бегущие суммы оконной функцией (SQL Server 2008 — диагностика); метод дополнения периодов — по правилам регистра накопления; у регистра без субконто аргумент «Субконто» отсутствует; SQL выполнен на живой базе УНФ субконто — как у Остатки; <Ресурс>НачальныйРазвернутыйОстатокДт/Кт и <Ресурс>КонечныйРазвернутыйОстатокДт/Кт — только без периодичности (под разворотом — диагностика); метод дополнения периодов принимается и без периодичности
🟡 РегистрБухгалтерии.X.ОборотыДтКт(НачалоПериода, КонецПериода, Периодичность, УсловиеСчетаДт, СубконтоДт, УсловиеСчетаКт, СубконтоКт, Условие) / DrCrTurnovers без свёртки: одна строка на пару СчетДт/СчетКт, балансовые измерения, стороны небалансовых, СубконтоДт<k>/СубконтоКт<k> (и их виды) обеих сторон, разворот периодичности; на балансовый ресурс — <Ресурс>Оборот, на небалансовый — <Ресурс>ОборотДт/<Ресурс>ОборотКт; непрочитанные измерения суммируются; списки видов субконто каждой стороны — как у Остатки; условия видят поля записи; без субконто аргументы «СубконтоДт»/«СубконтоКт» отсутствуют; Авто, Регистратор, Запись разворачивают; SQL выполнен на живой демо-бухгалтерии
🟡 РегистрБухгалтерии.X.ДвиженияССубконто(НачалоПериода, КонецПериода, Условие, Порядок, Первые) / RecordsWithExtDimensions записи [Начало, Конец) с полями главной таблицы и СубконтоДт<k>, ВидСубконтоДт<k>, СубконтоКт<k>, ВидСубконтоКт<k> из встроенных колонок; условие видит те же поля и безсторонние имена Счет, Субконто<k>, ВидСубконто<k>, небалансовые измерения и ресурсы — такое условие выполняется, если верно для дебета или для кредита (по синтакс-помощнику, на платформе не замерено); Первые — число или параметр-число: LIMIT/TOP (N) в порядке Порядок (поля записи по возрастанию, одно или кортеж; параметр NULL — без порядка) или в порядке записи (период, регистратор, номер строки); Порядок без Первые ничего не меняет (у источника нет порядка, SQL Server не принимает ORDER BY в подзапросе)
✅ РегистрБухгалтерии.X.Субконто / ExtDimensions (без параметров) таблица _AccRgED: Период, Регистратор, НомерСтроки, УточнениеПериода, ВидДвижения (Correspond, сторона записи), Вид (ссылка на план видов характеристик), Значение (составное значение); замерено на демо-бухгалтерии: строка на запись, сторону и уровень
❌ РегистрРасчета.X.ФактическийПериодДействия(Условие) / AdjustedEffectivePeriod
❌ РегистрРасчета.X.ДанныеГрафика(Условие) / ScheduleData
❌ РегистрРасчета.X.База<Регистр>(ИзмеренияОсновногоРегистра, ИзмеренияБазовогоРегистра, Разрезы, Условие) / Base<Register>
🟡 Периоды и условия виртуальных таблиц период — литерал, ДАТАВРЕМЯ, параметр-дата, а также НАЧАЛОПЕРИОДА, КОНЕЦПЕРИОДА, ДОБАВИТЬКДАТЕ над ними (Обороты(НАЧАЛОПЕРИОДА(&П, МЕСЯЦ), КОНЕЦПЕРИОДА(&П, МЕСЯЦ))); условие агрегирующих таблиц (Остатки, Обороты, ОстаткиИОбороты, условие счёта) принимает разыменование: цель присоединяется LEFT JOIN к той ветке, которую условие фильтрует (у свёртки регистра бухгалтерии — по счёту своей стороны, у остатков регистра накопления — к итогам и к движениям порознь); условие срезов — прямые поля

5. Стандартные поля

В скобках — написание, которое принимает open-sdbl, если оно отличается от имени 1С. Английские имена платформы Ref, DeletionMark и LineNumber не распознаются: пишите ID, Marked, LineNo или русский синоним.

Статус Поле (RU / EN) Примечание
✅ Ссылка / Ref (ID), Код / Code, Наименование / Description, ПометкаУдаления / DeletionMark (Marked), ВерсияДанных / Version, Номер / Number, Дата / Date, Проведен / Posted, Регистратор / Recorder, НомерСтроки / LineNumber (LineNo), Период / Period, Активность / Active, Родитель / Parent (ParentID), Владелец / Owner (OwnerID) у каждого из четырнадцати полей принимаются оба синонима — русский и схемный
🟡 Предопределенный / Predefined, ЭтоГруппа / IsFolder вычисляются, как на платформе: ЭтоГруппа — отрицание колонки Folder (она хранит ИСТИНУ у элемента), Предопределенный — непустой PredefinedID; отвечают в проекции, ГДЕ, группировке, упорядочивании и через ссылку, вид колонки — Boolean; в * не попадают, там остаются схемные колонки
✅ Стандартные поля плана счетов: Вид/Kind, Забалансовый/OffBalance, Порядок/Order (OrderField) колонки _Kind, _OffBalance, _OrderField таблицы _Acc; Вид сравнивается с ЗНАЧЕНИЕ(ВидСчета.…), работает и через разыменование (Т.СчетДт.Вид)
✅ Стандартные поля бизнес-процессов и задач: Завершен/Completed, Стартован/Started, ВедущаяЗадача/HeadTask, Наименование/Name, Выполнена/Executed, БизнесПроцесс/BusinessProcess, ТочкаМаршрута/Point имена проверены на платформе на пробной конфигурации с бизнес-процессом и его задачей
🟡 ИмяПредопределенныхДанных / PredefinedDataName сопоставляется с именем предопределённого элемента, объявленным в конфигурации: строка с именем, пустая строка у непредопределённой записи, NULL у непопавшей строки соединения; вид колонки — String. Платформа хранит идентификатор и переводит его в имя вне SQL, поэтому упорядочивание и сравнения </> идут по имени, а не по идентификатору, ПОДОБНО и строковые функции над полем принимаются (платформа их запрещает), а имя, которого нет, даёт пустую выборку, а не ошибку
✅ ВидДвижения / RecordType принимается и схемное имя из SchemaStorage (RecordKind); имя запроса проверено на платформе
🟡 МоментВремени / PointInTime пара «дата + ссылка», физической колонки за ней нет: у документа это Дата и Ссылка, у записи регистра, подчинённого регистратору, — Период и Регистратор. Замерено на 8.3.27: платформа раскладывает пару на две колонки выборки (<имя>_T — дата, <имя> — ссылка), на два члена в УПОРЯДОЧИТЬ ПО, СГРУППИРОВАТЬ ПО и РАЗЛИЧНЫЕ; так же поступает и компилятор. У справочника и у независимого регистра сведений поля нет — диагностика, как на платформе; агрегат и разыменование платформа тоже запрещает. Отличие: сравнение двух моментов времени платформа раскрывает лексикографически (дата >, при равенстве — ссылка), здесь пара в выражениях отклоняется диагностикой
✅ Источник.Представление / Presentation представление собственной ссылки источника; путь тот же, что у ПРЕДСТАВЛЕНИЕССЫЛКИ(Источник.Ссылка) — план представления запрашивается у приложения; источник без собственной ссылки — диагностика
✅ ТипЗначения / ValueType у плана видов характеристик колонка Type объекта
✅ Порядок / Order у перечисления колонка EnumOrder: порядок объявления значения, начиная с нуля (замерено на платформе)
✅ Реквизиты, добавленные расширениями по _ExtensionsRestruct

6. Литералы, параметры, комментарии

По странице «Константы и параметры в языке запросов» литералами являются ИСТИНА, ЛОЖЬ, число, строка, ДАТАВРЕМЯ(…), ТИП(…), параметр &Имя, НЕОПРЕДЕЛЕНО, NULL.

Статус Элемент Примечание
✅ Строки "…" с удвоением "" многострочные литералы с | — ❌
✅ Числа
✅ ИСТИНА / ЛОЖЬ / NULL (TRUE / FALSE)
🟡 НЕОПРЕДЕЛЕНО / UNDEFINED компилируется в NULL, вид колонки — Undefined; сравнение с литералом сравнивает тип значения с типом «Неопределено»: составное поле совпадает только при теге 0x01, значение вида, который не может хранить Неопределено (двоичное, УникальныйИдентификатор, тип), даёт константный предикат ЛОЖЬ (<> — ИСТИНА), как платформа возвращает пустую выборку вместо ошибки; в ВЫБОР, ЕСТЬNULL и ОБЪЕДИНИТЬ совместим с любым видом, как NULL; отличие от 1С: в результате Неопределено неотличимо от NULL
✅ ТИП(…) / TYPE см. раздел 3
✅ Бинарные литералы 0x… расширение open-sdbl (нет в 1С)
🟡 Даты только через ДАТАВРЕМЯ; строковые даты допускаются лишь в аргументах виртуальных таблиц
✅ Параметры &Имя значения передаются через CompileOptions::parameters и инлайнятся типизированными литералами (Null, Boolean, Number, String, Date, Reference, Binary, List только в В (…)); в консоли — \set, \params, \unset
✅ Параметры сеанса &Имя расширение open-sdbl: CompileOptions::session (SessionParameters) видны всем запросам и ограничениям доступа сеанса; параметр запроса с тем же именем имеет приоритет; неиспользованный параметр сеанса — не ошибка; в консоли — \session
✅ Разделители данных (общие реквизиты Разделять) как в 1С: каждая разделённая таблица получает _Fld<N> = <значение>, значение — из параметра сеанса, привязанного к разделителю в Config (иначе по имени реквизита); без значения Независимо и совместно фильтруется пустым значением, Независимо — диагностика Parameter; параметр использования ЛОЖЬ отключает предикат
✅ Бинарный литерал в формате вывода консоли против ссылочного поля 16 байт для одночленной ссылки, 20 байт RTRef ‖ RRRef для runtime-typed поля (=, <>, В); иная длина — диагностика
✅ Комментарии //

7. Что open-sdbl добавляет сверх языка 1С

  • Бинарные литералы 0x….
  • Ключевое слово ON вместо ПО в условии соединения; короткие английские имена видов метаданных (Reference, InfoRg, AccumRg, …) и физические имена стандартных полей (Folder, ParentID, RecordKind, …).
  • ColumnKind для каждой колонки результата и нативные типы вместо текста.
  • Колонка __level у результата с ИТОГИ (по опции CompileOptions::totals_level, в консоли включена): уровень строки, как Уровень() у выборки по группировкам, потому что результат — плоский набор строк, а не дерево.
  • Параметры сеанса: SessionParameters видны каждому запросу и каждому ограничению доступа, в отличие от параметров одного Запроса.
  • Разделители данных без значения в сеансе фильтруются пустым значением (общие данные), а не читаются целиком; платформа в этом случае не фильтрует.
  • Прикладная политика вместо ролей конфигурации: представления значений (PresentationPlan) и построчные ограничения РАЗРЕШЕННЫЕ (AccessRestriction) приходят от приложения через callback, потому что ядро не выполняет ввод-вывод и не читает роли.
  • Уровень диалекта MSSQL (2008/2012), поддержка PostgreSQL 9.0+ и баз платформы 8.2 без PartNo.

Источники

Основной источник — Синтакс-помощник платформы 1С:Предприятие 8.3.27.2342 (/opt/1cv8/x86_64/8.3.27.2342): раздел «Язык запросов» с корневой страницей «Синтаксис текста запросов» и страницы таблиц. Названия страниц приведены так, как их показывает сам Синтакс-помощник. Программно те же страницы читает MCP-сервер unica (unica.documentation.search / unica.documentation.get, корпус platform-help, authority: vendor): страница находится поиском по названию.

Дополнительные источники (для истории; при расхождениях приоритет у Синтакс-помощника):