Files
llm/docs/1c-sql-format-spec.md
T
2026-08-14 09:40:51 +03:00

33 KiB
Raw Blame History

1C SQL Format Specification Draft

Date: 2026-06-20

The maintained evidence log for saved-state encoding, extension overlays, Configurator reload behaviour, and failed protocol paths is split by topic in docs/1c-sql-protocol/. This specification keeps only universal format rules.

This document describes universal 1C SQL storage rules observed and verified so far. It must not contain knowledge about a particular infobase object such as АвансовыйОтчет, except as test evidence in a separate report.

Scope

The goal is a parser that understands 1C metadata storage, then applies that understanding to any concrete infobase.

The parser should know:

  • where metadata containers live in SQL;
  • how to decode metadata payloads;
  • how to read DBNames storage records;
  • how to follow extension CAS manifests;
  • how to map metadata objects and attributes to physical data tables/columns.

The parser should not hardcode:

  • concrete configuration object names;
  • concrete GUIDs from one customer base;
  • physical table numbers from one infobase.

SQL Containers

Observed top-level SQL containers:

  • Config
  • ConfigSave
  • ConfigCAS
  • ConfigCASSave
  • Params
  • _ExtensionsInfo

Current interpretation:

  • Config stores direct metadata payloads for the main configuration.
  • ConfigSave stores saved-but-not-applied configuration state when present.
  • ConfigCAS stores content-addressed payload files.
  • ConfigCASSave is the saved-state counterpart when present.
  • Params stores platform metadata maps such as DBNames.
  • _ExtensionsInfo stores extension registry rows and extension root package pointers.

Payload Encoding

Observed direct metadata payloads:

SQL BinaryData -> raw deflate -> UTF-8 text with optional BOM -> brace tree

Known compression envelopes to try:

  1. raw deflate
  2. zlib
  3. gzip
  4. none

Known text encodings to try after decompression:

  1. UTF-8 with BOM
  2. UTF-8
  3. UTF-16LE
  4. UTF-16BE
  5. CP1251

If UTF-8 BOM is present, it must take priority over heuristic encoding scores.

Brace Tree Grammar

The decoded metadata text is a nested brace format:

value    = list | string | atom
list     = "{" [value ("," value)*] "}"
string   = '"' text-with-doubled-quotes '"'
atom     = non-space text until one of "{", "}", ",", ":"
sequence = value+

The parser must preserve generic structure before assigning semantic names.

Generic node examples:

{"type": "atom", "value": "1"}
{"type": "string", "value": "ru"}
{"type": "list", "items": [...]}

DBNames

Params/DBNames* is the platform-maintained map from metadata/storage GUIDs to storage roles and SQL numeric suffixes.

Observed decoded shape:

{ root_number,
  { declared_count,
    { guid, storage_role, sql_number },
    ...
  }
}

Parser output:

{
  "guid": "84e4c0c3-2a21-4aba-a7b0-f92b3f2878ec",
  "storage_role": "Document",
  "sql_number": 563,
  "source": "DBNames"
}

Important rule: preserve storage_role exactly as stored by the platform. Do not infer object kind from physical SQL table names.

Observed storage role families:

  • table-like roles: Document, Reference, Enum, InfoRg, AccumRg, Const, Node, ScheduledJobs;
  • structural roles: Fld, VT, LineNo, ByDims, ByField, ByResource, ByProperty.

Physical table/column names are derived after reading DBNames, for example:

Document + 563 -> _Document563
Fld + 1234     -> _Fld1234

This mapping is a storage route, not a metadata object model by itself.

Base Config Object Route

For main configuration metadata objects:

Config.FileName = metadata_object_guid
Config.BinaryData = object payload

Observed object payload:

root marker = 1
root list length = 8 or 9 for tested top-level objects

Object identity is inside the object body. Verified pattern:

{1,0,<object_guid>}, "<name>", {1,"ru","<synonym>"}

This pattern has been observed for tested Document, Catalog, and InformationRegister objects. The exact object-body position must be derived from the tree and validated per object kind, not hardcoded from one sample.

Extension Route

Extension metadata is not retrieved by Config.FileName = object_guid in the tested cases. It is reached through the extension package path:

_ExtensionsInfo
  -> _ExtensionZippedInfo
  -> root_cas_key
  -> ConfigCAS[root_cas_key]
  -> root manifest
  -> object_id
  -> cas_key
  -> ConfigCAS[cas_key]

Observed _ExtensionZippedInfo binary structure:

bytes 0..3   : marker
bytes 4..23  : root CAS SHA1 key
bytes 24..   : small extension metadata fragment

ConfigCAS.FileName equals SHA1(BinaryData) for the stored compressed bytes.

The root CAS file contains manifest pairs:

object_id -> base64(20-byte sha1)

The decoded 20-byte SHA1 is the target ConfigCAS key.

object_id may be:

<guid>
<guid>.0
<guid>.1
<guid>.2
<guid>.3
...

Suffix is only a part key. It is not a semantic label by itself.

Extension/Object Part Payloads

Observed payload signatures:

  • root=1: metadata object or child metadata object description;
  • root=4: form payload structure;
  • root=5 with #base64: embedded help/text payload;
  • root=8 with MOXCEL: spreadsheet/template payload;
  • stream_headers: binary/text stream container, often containing BSL module payloads;
  • #base64: embedded base64 data inside a brace tree.

Semantic assignment requires direct evidence:

  • root shape;
  • payload markers;
  • declared stream sizes;
  • exact SHA1 match with exported XML/BSL/HTML;
  • normalized text match when byte-level line endings differ.

Metadata Object Model

The universal parser should expose a model like:

{
  "guid": "...",
  "kind": "Document",
  "name": "...",
  "synonyms": {"ru": "..."},
  "attributes": [],
  "tabular_sections": [],
  "forms": [],
  "templates": [],
  "modules": [],
  "storage": []
}

At the current stage only the following are accepted as proven fields:

  • GUID;
  • name;
  • localized synonym where the identity block is found;
  • generic root marker and root length;
  • raw parsed tree;
  • DBNames storage records;
  • payload route.

Attributes, tabular sections, commands, forms, templates, and modules must be added only after position-by-position validation against XML exports and SQL routes.

Position Validation Against XML

The parser must not globally assign section semantics from a single object sample. The observed root=1 payload shape is shared by multiple object kinds, but section coordinates differ by kind.

Historical mechanical validation compared brace-tree positions with XML exports. Those per-sample reports were removed from the current workspace; the stable conclusions are kept here as format notes.

Observed examples:

  • Document, 4 samples: XML-heavy top paths include 3, 5, and 1.
  • Catalog, 4 samples: XML-heavy top paths include 5, 6, and 1.
  • InformationRegister, 4 samples: XML-heavy top paths include 1, 4, and 3; path 7 appears in one tested sample.
  • ExchangePlan extension sample: XML-heavy top paths include 3 and 5.

These are evidence points, not final semantic names. A future object-kind parser must attach names such as attributes or tabular sections only when the mapping is confirmed across enough samples and matches XML structure.

Historical observed profiles with min_support_ratio = 0.75:

  • Document: paths 3, 5, 1.
  • Catalog: paths 5, 1, 6.
  • InformationRegister: paths 1, 4, 3.

The profile format keeps semantic_status = unassigned. It is a compact, evidence-based section selector, not yet a semantic object-kind parser.

XML Category Mapping

The next validation layer compares each observed profile section with structured XML metadata categories. The XML extractor reads only stable metadata elements:

  • the root object category, name, synonym, and UUID;
  • generated types;
  • standard attributes;
  • child objects such as Attribute, TabularSection, Form, Template, Dimension, and Resource.

The mapper scores a Config tree section against each XML category by exact name, synonym, and UUID matches. This keeps the process mechanical: a section receives a candidate semantic category only from direct evidence found in the XML export.

Historical evidence from 12 base objects, 4 per kind:

Catalog path 1              -> Catalog             4/4
Catalog path 5              -> TabularSection      3/4 candidate
Catalog path 6              -> Attribute           4/4
Document path 1             -> Document            4/4
Document path 3             -> TabularSection      4/4
Document path 5             -> Attribute           4/4
InformationRegister path 1  -> InformationRegister 4/4
InformationRegister path 3  -> Resource            3/4 candidate
InformationRegister path 4  -> Dimension           4/4

Only 4/4 mappings are currently strong candidates for object-kind parser rules. The 3/4 mappings remain candidate semantics until the missing or conflicting sample is explained by object shape, optional sections, or a deeper path rule.

Follow-up parser projection reports:

  • strict, only support_ratio = 1.0: reports/1c-sql/upo/structured-metadata-summary.json
  • candidate, support_ratio >= 0.75: reports/1c-sql/upo/structured-metadata-candidates-summary.json

Strict projection currently extracts:

  • Document: tabular sections from path 3, attributes from path 5;
  • Catalog: attributes from path 6;
  • InformationRegister: dimensions from path 4.

Candidate projection adds:

  • Catalog: tabular sections from path 5;
  • InformationRegister: resources from path 3.

The Catalog path 5 3/4 conflict is explained by nested content: the section contains the tabular section object and may also contain attributes belonging to that tabular section. A category scorer can therefore see more Attribute matches than TabularSection matches, but the tabular section UUID is still present in the section.

The InformationRegister path 3 3/4 result is explained by optional resources: one tested register has no resource matches, while the other tested registers map resources from the same path.

This means the next semantic parser step is not to add arbitrary conditions. It is to represent section nesting explicitly:

object section
  -> child object list
     -> child object identity
     -> child attributes/properties

Until that nesting is decoded, the structured projection must keep evidence on each item: source path, name hit, synonym hit, and UUID hit.

All-kind expansion was validated on 112 samples across 44 XML top object kinds. The current retained summary used by SQL-read enrichment is reports/1c-sql/upo/structured-metadata-all-kinds-dbnames-summary.json.

Examples of confirmed all-kind mappings:

AccumulationRegister path 5 -> Resource
AccumulationRegister path 6 -> Attribute
AccumulationRegister path 7 -> Dimension
AccountingRegister path 3   -> Dimension
AccountingRegister path 5   -> Resource
AccountingRegister path 7   -> Attribute
BusinessProcess path 6      -> Attribute
Enum path 6                 -> EnumValue
DocumentJournal path 4      -> Column
HTTPService path 3          -> URLTemplate
IntegrationService path 3   -> IntegrationServiceChannel
Report path 4               -> Attribute
Task path 5                 -> Attribute
Task path 6                 -> AddressingAttribute
Task path 8                 -> Command
WebService path 3           -> Operation

For many metadata kinds, path 1 currently maps to the root object identity and main properties. These mappings are useful for object identification but do not yet expose child objects. Kinds with only root-object evidence still need deeper payload analysis or related ConfigCAS/module payload routing.

Child Record Boundaries

Many child-object sections use the same mechanical container shape:

{ section_marker_guid, declared_count, record_0, record_1, ... }

The parser now detects these boundaries without assigning business semantics. Semantic assignment is still evidence-based through XML category matching.

All 474 structured child items from the 112-sample batch are now attached to a specific record_path:

section_path = top-level section container
record_path  = concrete child record inside that container
record_index = zero-based child record index

Examples:

Enum value "Требуется"                         -> section 6, record 6.2
AccumulationRegister resource "Сумма"          -> section 5, record 5.2
AccumulationRegister attribute "Подразделение" -> section 6, record 6.2
Document attribute "Автор"                     -> section 5, record 5.2

DBNames Route Enrichment

Structured metadata reports can be enriched with DBNames routes:

  • enrichment summary: reports/1c-sql/upo/structured-metadata-all-kinds-dbnames-summary.json
  • enriched reports: reports/1c-sql/upo/structured-metadata-all-kinds-dbnames/

Current all-kind enrichment coverage:

metadata items total:        474
items with DBNames routes:   420
object storage route count:   88

Observed child route coverage:

attributes                  338/341
tabular_sections             29/29
dimensions                   19/19
resources                     8/8
columns                      17/17
addressing_attributes         4/4
accounting_flags              1/1
integration_service_channels  4/4
commands                      0/4
enum_values                   0/15
operations                    0/15
url_templates                 0/17

This is expected: persisted data fields have DBNames routes, while logical metadata-only children such as enum values, web-service operations, commands, and HTTP URL templates do not necessarily have independent SQL storage routes.

Known route families now classified:

Fld                         -> field/column base name `_FldN`
Document, Reference, ...    -> table names such as `_DocumentN`
AccumRg*, AccRg*            -> register table families
VT, LineNo, ByField, ...    -> structural routes needing parent context
IntegService*/IntegChannel* -> integration service tables
TurnoverDt/Ct/Turnover      -> structural accounting-register routes

Column suffixes such as _RRef, _TYPE, _RTRef, and numeric/string value columns are not inferred here. They require type decoding from the child record and verification against the physical SQL table schema.

Value Types And Simple Columns

The XML validation oracle now extracts value type information for child metadata items:

types       = XML Type entries, for example xs:string or cfg:CatalogRef.Users
qualifiers  = string length, number precision/scale, date fractions, etc.
is_composite = true when multiple Type entries are present

Validated simple column rules:

single primitive type xs:string/xs:decimal/xs:boolean/xs:dateTime
  + DBNames Fld N
  -> SQL column _FldN

single 1C reference type cfg:*Ref.Name
  + DBNames Fld N
  -> SQL column _FldNRRef

Composite types are deliberately not guessed yet:

multiple XML Type entries -> needs_composite_type_mapping

Validated composite column rules:

multiple value types
  -> _FldN_TYPE

multiple reference-capable value types
  -> _FldN_TYPE
  -> _FldN_RTRef
  -> _FldN_RRRef

mixed string + reference value types
  -> _FldN_TYPE
  -> _FldN_S
  -> _FldN_RRRef

_RTRef is present when the composite field needs to distinguish multiple reference metadata types. When the composite type is a primitive/reference mix with a single reference metadata type, _TYPE is enough to distinguish the primitive vs reference branch, so _RTRef is not emitted.

Validated composite reference read rule:

_FldN_TYPE  -> branch marker
_FldN_RTRef -> DBNames SQL number of the selected reference target
_FldN_RRRef -> _IDRRef in the selected target table

For the current Document.АвансовыйОтчет smoke sample:

Запасы.ЕдиницаИзмерения:
  value types: cfg:CatalogRef.КлассификаторЕдиницИзмерения,
               cfg:CatalogRef.ЕдиницыИзмерения
  _TYPE:  08
  _RTRef: 000000a6 -> decimal 166 -> DBNames Reference 166
  target: Catalog.ЕдиницыИзмерения -> _Reference166
  _RRRef: value _IDRRef in _Reference166

Composite reference smoke result:

  • tool: scripts/resolve_1c_sql_composite_references.ps1;
  • report: reports/1c-sql/upo/sql-composite-reference-resolution-document-avansovy-otchet.json;
  • composite groups: 6;
  • resolved: 6;
  • target misses: 0;
  • row misses: 0.

SQL Composite Values

Composite value resolution is broader than composite reference resolution. A single metadata field can have several physical columns:

_FldN_TYPE  -> type/branch marker
_FldN_S     -> string branch
_FldN_N     -> number branch
_FldN_L     -> boolean branch
_FldN_T     -> datetime branch
_FldN_RTRef -> reference target SQL number when multiple reference targets exist
_FldN_RRRef -> reference value id

The adapter currently selects the branch by observed physical values:

non-zero RRRef        -> reference
non-empty S/N/L/T     -> primitive
otherwise             -> empty_or_unknown

This intentionally avoids overclaiming the meaning of _TYPE until enough non-empty examples are collected for every primitive/reference combination.

Current composite-value smoke result for Document.АвансовыйОтчет:

  • tool: scripts/resolve_1c_sql_composite_values.py;
  • report: reports/1c-sql/upo/sql-composite-value-resolution-document-avansovy-otchet.json;
  • composite values: 11;
  • branch counts: reference=6, empty_or_unknown=5.

The only currently observed mixed primitive/reference metadata field in the sample set is:

BusinessProcess.ЗаявкаСотрудникаИзменитьЛичныеДанные.ДокументВид:
  value types: xs:string, cfg:CatalogRef.ВидыДокументовФизическихЛиц
  physical columns: _Fld46687_TYPE, _Fld46687_RRRef, _Fld46687_S

The target table has no rows in the current UPO SQL snapshot, so this remains a structural rule without non-empty value observations.

SQL Read View

onec_sql_read_view.v1 is the first agent-facing read result. It combines:

onec_sql_read_result.v1
  + onec_sql_reference_resolution.v1
  + onec_sql_composite_reference_resolution.v1
  + onec_sql_composite_value_resolution.v1
  -> onec_sql_read_view.v1

The view keeps two row shapes:

cells:
  original physical-cell map from SQL aliases/columns, with resolved evidence
  attached to the exact source cell when available

fields:
  logical metadata_path groups, where multi-column fields such as composite
  references are represented as one field with column evidence underneath

The view does not erase raw SQL evidence. It attaches presentations next to the raw values:

attributes.ВалютаДокумента -> resolved.presentation = "руб."
attributes.Организация     -> resolved.presentation = "АЙЭФСИЭМ ГРУПП ООО"
Запасы.ЕдиницаИзмерения    -> resolved.presentation = "шт" or "кг"

Every logical field also gets display_value, selected in this order:

resolved.presentation
resolved.selected_presentation
composite primitive value
raw single-column value
null

For SQL date/time strings with the 1C SQL year offset, raw cell values are preserved unchanged and only display_value is normalized by subtracting 2000 years from years >= 3000. Example: raw 4025-09-16T08:00:00.0000000 is displayed as 2025-09-16T08:00:00.0000000.

For one-byte SQL binary boolean values, raw cell values are also preserved unchanged. display_value maps 00 to false and 01 to true only when the field is a known standard boolean (_Marked, _Posted, _Active) or the metadata value type contains xs:boolean.

Enum Presentation

SQL enum tables store _EnumOrder, but agent-facing output needs enum value names. The adapter builds:

onec_enum_presentation_map.v1

from enum XML routes in the unified object route index:

Enum.<Name>.ChildObjects.EnumValue order
  -> value uuid
  -> value name
  -> ru synonym

When the same enum name exists in the base configuration and extensions, base configuration XML has priority for the presentation map. Extension evidence is not discarded from the route index; it is only not allowed to overwrite the base enum presentation by name.

Current smoke examples:

EnumRef.ТипыНалогообложенияНДС, _EnumOrder = 0
  -> Облагается (с НДС)

EnumRef.ПоложениеРеквизитаНаФорме, _EnumOrder = 0
  -> В шапке

Read views expose enum presentations as agent-facing display values. Example shape:

attributes.НалогообложениеНДС.display_value = Облагается (с НДС)
attributes.ПоложениеПроекта.display_value = В шапке

For declared-target misses with extension table hits, the view keeps both:

resolved.found = false
resolved.selected_alternate = _Reference348X1 / other observed hit
resolved.selected_presentation = ...

The full read pipeline is available as one orchestrated command:

scripts/read_1c_object_view.py
  --kind <Kind>
  --name <Name>
  --summary <structured metadata DBNames batch summary>
  --validation <predicted column validation>
  --route-index <unified object route index>
  --output-dir <run output directory>

For shells with uncertain Unicode handling, pass object names as UTF-8 base64:

--name-b64 0JDQstCw0L3RgdC+0LLRi9C50J7RgtGH0LXRgg==

The orchestrator intentionally writes ASCII-only artifact file names. Russian metadata names remain inside JSON payloads as data.

Current orchestrated smoke result:

  • tool: scripts/read_1c_object_view.py;
  • output directory: reports/1c-sql/upo/object-read-runs;
  • object: Document.АвансовыйОтчет;
  • final schema: onec_sql_read_view.v1;
  • main rows: 5;
  • table parts: 5;
  • simple reference cells: 55;
  • composite reference groups: 6;
  • sample presentations: attributes.Автор = Evgeniya.Matyushina, Запасы.ЕдиницаИзмерения = шт.

Validated tabular-section table rule:

object primary table + DBNames VT N -> <object_table>_VTN

Only primary object tables are used for this prediction. Change tables and auxiliary tables such as ChngR, SInf, BPrPoints, totals/options tables, and similar companions are excluded from tabular-section table prediction.

Validated tabular-section attribute rule:

TabularSection XML ChildObjects/Attribute
  -> parent TabularSection UUID
  -> nested SQL child record under the tabular section record
  -> DBNames Fld N
  -> parent tabular-section table column

The parser keeps both levels:

tabular section:
  section_path, record_path, VT/LineNo routes, physical table

tabular section attribute:
  parent tabular section UUID/name
  nested record_path
  value type
  Fld route
  physical column in the parent tabular-section table

Physical column validation against the live SQL schema:

  • script: scripts/validate_1c_predicted_columns.ps1
  • report: reports/1c-sql/upo/predicted-column-validation.json

Current result:

predicted columns: 695
found in SQL schema: 695

predicted tabular-section tables: 29
found in SQL schema:              29

Validated by kind:

AccountingRegister        columns   9/9
AccumulationRegister      columns  25/25
BusinessProcess           columns 136/136
Catalog                   columns  81/81, table parts 9/9
ChartOfAccounts           columns   7/7,  table parts 1/1
ChartOfCalculationTypes   columns  27/27, table parts 2/2
Document                  columns 388/388, table parts 17/17
InformationRegister       columns   3/3
Task                      columns  19/19

Validated by metadata field:

attributes                  361/361
tabular_section_attributes  304/304
dimensions                   17/17
resources                     8/8
addressing_attributes         4/4
accounting_flags              1/1

This gives a proven read route for simple persisted fields:

metadata object GUID
  -> Config payload
  -> child section
  -> child record
  -> XML value type
  -> DBNames Fld route
  -> object DBNames table route
  -> physical SQL column

SQL Read Projection

The adapter can now build a read projection from enriched metadata:

  • tool: plugins/1c/tools/build_sql_read_projection.py
  • sample report: reports/1c-sql/upo/sql-read-projection-document-avansovy-otchet.json

The projection contains:

main_table
main_columns[]:
  metadata_path
  metadata_uuid
  value_type
  physical column
  SQL type
  stable SQL select alias

table_parts[]:
  tabular section name/uuid
  physical table
  owner/line columns
  nested tabular-section attribute columns
  SELECT statement

SQL aliases are ASCII-only (c001, c002, ...). Human-readable Russian names stay in JSON metadata fields. This avoids client encoding problems while keeping the query result mechanically mappable back to metadata.

Smoke-tested generated SQL:

Document.АвансовыйОтчет main table
  SELECT FROM _Document563
  result: 37 columns, 5 rows

Document.АвансовыйОтчет.Запасы tabular section
  SELECT FROM _Document563_VT1614
  result: 33 columns, 5 rows

This is the first end-to-end read chain:

task asks for object data
  -> metadata object identity
  -> SQL storage table
  -> metadata fields and tabular-section fields
  -> physical SQL columns/tables
  -> generated SELECT
  -> result columns mapped back through projection JSON

Examples:

Document.АвансовыйОтчет.Автор
  cfg:CatalogRef.Пользователи + Fld 1584 -> _Document563._Fld1584RRef

Document.АвансовыйОтчет.Комментарий
  xs:string + Fld 1587 -> _Document563._Fld1587

Document.АвансовыйОтчет.ДокументОснование
  composite DocumentRef + Fld 1586
  -> _Document563._Fld1586_TYPE
  -> _Document563._Fld1586_RTRef
  -> _Document563._Fld1586_RRRef

Document.АвансовыйОтчет.ВыданныеАвансы
  VT 1610 -> _Document563_VT1610

Document.АвансовыйОтчет.ВыданныеАвансы.Документ
  composite DocumentRef + Fld 1612
  -> _Document563_VT1610._Fld1612_TYPE
  -> _Document563_VT1610._Fld1612_RTRef
  -> _Document563_VT1610._Fld1612_RRRef

Document.АвансовыйОтчет.ВыданныеАвансы.Сумма
  xs:decimal(15,2) + Fld 1613
  -> _Document563_VT1610._Fld1613

AccumulationRegister.АвансовыеПлатежиИностранцевПоНДФЛ.Сумма
  xs:decimal(15,2) + Fld 45848 -> _AccumRg45843._Fld45848

Metadata To Data Mapping

The target runtime chain is:

metadata object -> DBNames storage role -> physical table
metadata field  -> DBNames Fld/VT/LineNo records -> physical column/table part

Example shape, without hardcoded concrete values:

Document object GUID
  -> DBNames role Document, sql_number N
  -> _DocumentN

Attribute GUID
  -> DBNames role Fld, sql_number M
  -> _FldM or _FldMRRef depending on stored value type

Implemented mechanical route helpers:

Document + N       -> _DocumentN
DocumentChngR + N -> _DocumentChngRN
Reference + N      -> _ReferenceN
InfoRg + N         -> _InfoRgN
Node + N           -> _NodeN
Fld + N            -> _FldN base column candidate

Structural roles such as VT, LineNo, and ByDims are not standalone physical names in the parser core. They require parent object/section context.

The suffixes such as RRef, _TYPE, _RTRef, and version/deletion columns must be specified from observed SQL schema and value type evidence before write support is allowed.

Safety Boundary

SQL Read Result

The read path has three separate layers:

structured metadata + DBNames + SQL schema
  -> onec_sql_read_projection.v1
  -> SQL SELECT execution
  -> onec_sql_read_result.v1

onec_sql_read_projection.v1 is the deterministic query plan. It contains the main physical table, table-part physical tables, selected physical columns, SQL aliases, and the metadata evidence for every selected column.

onec_sql_read_result.v1 is the executed result. It must not add new metadata guesses. Each returned cell is keyed as:

<metadata_path>::<physical_column>

The cell body keeps:

  • alias: generated SQL alias, for example c006;
  • column: physical SQL column, for example _Fld1584RRef;
  • metadata_path: logical metadata path, for example attributes.Автор;
  • metadata_name, metadata_uuid, metadata_field;
  • value_type: value type evidence from metadata;
  • sql_type: SQL schema evidence;
  • value: serialized SQL value.

Binary SQL values are serialized as:

{"kind": "binary", "length": 16, "hex": "..."}

This keeps 1C references stable without pretending that a raw RRef is already a resolved presentation. Reference resolution is a later layer that must use metadata/DBNames type evidence to choose the target table and presentation fields.

SQL Reference Resolution

Reference resolution starts from value_type, not from the physical SQL column name.

Observed single-reference mapping:

cfg:CatalogRef.<Name>  -> XML kind Catalog  -> DBNames role Reference -> _ReferenceN
cfg:DocumentRef.<Name> -> XML kind Document -> DBNames role Document  -> _DocumentN
cfg:EnumRef.<Name>     -> XML kind Enum     -> DBNames role Enum      -> _EnumN

The declared target is selected through the unified object route index:

value_type name -> XML top object -> object GUID -> DBNames storage role

The resolver then reads _IDRRef in the declared target table and returns only available presentation columns, for example _Code, _Description, _Number, _Date_Time, _Posted, _Marked, or _EnumOrder.

Extension-aware databases can contain physical table variants such as _Reference348X1. Therefore a failed lookup in the declared target table is not enough evidence that the value is invalid. The resolver records alternate_hits across the same table family:

Catalog  -> _Reference%
Document -> _Document%
Enum     -> _Enum%

The current smoke test found attributes.Автор declared as cfg:CatalogRef.Пользователи with target _Reference348, while the same _IDRRef also exists in _Reference348X1. The adapter must keep this evidence explicit instead of silently replacing the declared target.

Current read support is implemented through scripts/read_1c_object_view.py. The command must keep declared metadata targets, selected effective physical tables, alternate extension hits, raw SQL values, and resolved presentations as separate evidence fields.

SQL write support is out of scope until all of the following are proven:

  • round-trip decode/encode for target payload type;
  • validation against 1C Designer/Enterprise;
  • backup and rollback workflow;
  • saved-state handling for ConfigSave/ConfigCASSave;
  • extension package rebuild validation.

Implementation Status

This document is the SQL-format reference for the current adapter. The active agent API is documented in docs/1c-adapter-api-contract.md, and the active tool list is in plugins/1c/tools/README.md.

Current parser/library core:

  • plugins/1c/parser/payload.py
  • plugins/1c/parser/dbnames.py
  • plugins/1c/parser/extensions.py
  • plugins/1c/parser/config_object.py
  • plugins/1c/parser/storage.py
  • plugins/1c/parser/config_sections.py
  • plugins/1c/parser/xml_metadata.py
  • plugins/1c/parser/structured_metadata.py
  • plugins/1c/parser/child_records.py

Current adapter-facing build/read tools:

  • scripts/extract_1c_dbnames.py
  • scripts/build_1c_xml_guid_index.py
  • scripts/compare_1c_sql_xml_guids.py
  • scripts/build_1c_unified_object_route_index.py
  • scripts/build_1c_metadata_from_resolved_object.py
  • plugins/1c/tools/build_sql_read_projection.py
  • scripts/validate_1c_predicted_columns.ps1
  • scripts/execute_1c_sql_read_projection.ps1
  • scripts/resolve_1c_sql_read_references.ps1
  • scripts/resolve_1c_sql_composite_references.ps1
  • scripts/resolve_1c_sql_composite_values.py
  • scripts/build_1c_enum_presentation_map.py
  • scripts/build_1c_sql_read_view.py
  • scripts/read_1c_object_view.py

Current required evidence artifacts:

  • reports/1c-sql/upo/dbnames.json
  • reports/1c-sql/upo/xml-guid-index-combined.json
  • reports/1c-sql/upo/sql-xml-guid-compare-combined.json
  • reports/1c-sql/upo/unified-object-route-index.json
  • reports/1c-sql/upo/structured-metadata-all-kinds-dbnames-summary.json
  • reports/1c-sql/upo/predicted-column-validation.json
  • reports/1c-sql/upo/enum-presentation-map.json

The current adapter confirms:

  • DBNames records are the authoritative bridge from metadata/storage GUIDs to physical SQL table and column roles.
  • XML and extension manifest evidence provide configurator-visible Russian names, forms, modules, templates, and object relationships.
  • effective metadata must apply active extension overlays before returning attributes, forms, modules, or data views.
  • SQL reads are allowed only through generated projections plus live table-column validation.
  • SQL writes to configuration/data storage remain outside the safe workflow.