feat(ogar-adapter-surrealql): emit array<record> for to-many associations (#2 Stage A)#136
Merged
Merged
Conversation
…ions (#2 Stage A) W3.3's "One2many/Many2many array<record>" emitter gap: the shared SurrealQL emitter rendered only the owning side (BelongsTo → record<X>) and dropped to-many associations to a comment marker. Now that the lift carries the association (OGAR #132 `relation_kind` → HasMany/HasAndBelongsToMany + comodel), `emit_field_assoc` renders both as `array<record<comodel>>`: - BelongsTo (Many2one) -> record<X> / option<record<X>> (unchanged) - HasMany (One2many) -> array<record<X>> (NEW) - HasAndBelongsToMany (Many2many) -> array<record<X>> (NEW) - HasOne (Rails-only, non-owning) -> comment marker (unchanged) Target handling mirrors the owning-side record<X> exactly (dotted Odoo comodels are quoted), so no new normalization. The One2many *computed* `VALUE <-comodel.<inverse> READONLY` reverse-link is the separate W3.3 "computed VALUE" gap and is deferred; this lands the structural array TYPE. Parse-back of `array<record<…>>` is the companion `surrealdb-parser` follow-up — today's `walk` recovers the owning-side record<X> only (same emit-richer-than-parse asymmetry the prior comment-marker had; the gated round-trip tests cover BelongsTo + primitives, unaffected). This is #2 Stage A from odoo-rs #19 — it unblocks deleting od-ontology's native emit fork (W3.3) once the shared emitter covers the schema. Verified via probe (default features, no surrealdb): 22 tests pass (3 new: has_many/has_and_belongs_to_many → array<record>, has_one → comment), clippy -D warnings clean. The emit side is pure string-gen (no surrealdb); the OGAR workspace's surrealdb-parser leg builds on CI. Co-Authored-By: Claude <noreply@anthropic.com>
AdaWorldAPI
pushed a commit
that referenced
this pull request
Jun 29, 2026
…§1.5)
Operator correction (2026-06-29): the facet "versions" are useless because one
compiled ClassView recombines all the carvings while sinking into OGAR and
getting COMPILED into the binary — NOT parsed from SurrealQL (slow even with
JIT). Captures the load-bearing architecture so future sessions invest in the
spine, not the membrane:
- New §1.5 — the compiled ClassView spine:
a. recombines the facet layout (6×(1:2) / 4×(1:2:3) / 3×(1:2:3:4)) — no
hardcoded V1/V2/V3 facet "versions"; one compiled reader subsumes them.
b. sub-range hierarchy mapping (e.g. 1..3 of 12) + NESTED ClassViews stacked
into compiled CONSTRUCTORS (composition of compiled readers, not a runtime
interpreter).
c. lazy + lazy-lock-reused materialization of the 32×GUID SoA (build once on
first touch; the key prerenders nodes with zero value-decode).
+ why compiled beats parsed, and where SurrealQL sits (storage membrane,
never the hot path — ADR-022/023).
- §1 pull-back reframed: modes are NOT co-equal — (a) compiled ClassView =
spine/hot-path; (b) SurrealQL emit = storage-membrane adapter.
- §6 re-prioritised: the compiled ClassView spine is THE priority; #136 Stage A
(array<record>) and the od-ontology fork-deletion are membrane work,
secondary. Tier-byte arithmetic of each carving to be pinned against
FacetCascade before coding — not guessed.
Co-Authored-By: Claude <noreply@anthropic.com>
AdaWorldAPI
pushed a commit
that referenced
this pull request
Jun 30, 2026
…sembler
Adds the keystone gap named in E-KEEP-AR-REMOVE-ORM / the OP convergence
assessment: a Rails-correct sibling of compile_graph_python. Identical
shape (mint_graph::<P> + per-class facet resolution) but routes through
the existing lift_model_graph (Language::Ruby) instead of
lift_model_graph_python — pure operator-reuse, no new lift, and
project_odoo_fields is correctly never invoked for Rails (it would
double-count; lift_model_graph_python's own doc-comment says so).
Proves the convergence claim in code: compile_graph_ruby::<OpenProjectPort>
on a WorkPackage graph and compile_graph_ruby::<RedminePort> on an Issue
graph mint to the SAME low-u16 concept (0x0102 project_work_item) and
DIFFERENT high-u16 render prefixes (0x0001 vs 0x0007) — one canonical
concept, two render skins, machine-checked rather than asserted.
Drive-by fix: 3 pre-existing Function{...} literal constructions
(emit.rs, mint.rs's account_move fixture, lib.rs) broke against the
already-merged ruff#38 (writes/calls fields) because this crate's
ruff_spo_triplet dep floats on branch=main. Added ..Default::default()
to each — no behavior change, restores compilation.
Verification: standalone probe workspace (path-dep ogar-vocab +
ogar-from-ruff, git-dep ruff branch=main) — the OGAR workspace itself
can't resolve in-sandbox (ogar-adapter-surrealql's surrealdb-ast git dep
403s), the same pattern prior PRs (#131/#132/#136/#138/#141) used.
44/44 tests pass (3 new + 41 pre-existing unbroken); clippy --no-deps
-D warnings clean at the pinned 1.95.0 toolchain (ogar-vocab itself has
pre-existing unrelated clippy debt from never being --workspace-gated,
out of scope here); doc-links resolve.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#2 Stage A (from the odoo-rs #19 thinning roadmap): close W3.3's
"One2many/Many2many
array<record>" emitter gap so the shared SurrealQL emittercovers to-many relations — the prerequisite for deleting od-ontology's native
emit fork.
Before,
emit_field_assocrendered only the owning side and dropped to-manyassociations to a comment. Now that the lift carries the association (OGAR #132
relation_kind→ HasMany/HasAndBelongsToMany + comodel), it renders:BelongsTorecord<X>/option<record<X>>(unchanged)HasManyarray<record<X>>HasAndBelongsToManyarray<record<X>>HasOneTarget handling mirrors the owning-side
record<X>exactly (dotted Odoocomodels quoted) — no new normalization.
Scoped deferrals (documented, not silent):
VALUE <-comodel.<inverse> READONLYreverse-link isthe separate W3.3 "computed VALUE" gap — deferred; this lands the structural
array TYPE.
array<record<…>>is the companionsurrealdb-parserfollow-up; today's
walkrecovers the owning-siderecord<X>only (the sameemit-richer-than-parse asymmetry the prior comment-marker had). The gated
round-trip tests cover BelongsTo + primitives and are unaffected.
Test Plan
Probe-verified (default features, no surrealdb — the emit side is pure
string-gen): 22 tests pass, 3 new (
emit_class_with_has_many_renders_array_of_record,..._has_and_belongs_to_many_...,..._has_one_keeps_non_owning_comment),clippy -D warningsclean. The OGAR workspace'ssurrealdb-parserleg buildson CI.
🤖 Generated with Claude Code
Generated by Claude Code