ID |
|
|---|---|
Status |
Spec |
Theme |
classification-model |
Created |
2026-05-19 |
Updated |
2026-07-15 |
Resolved accessors for record-parent column reads
Re-specced 2026-07-13 against the current model; the original spec (see git history of this file) was written against a surface that no longer exists and had shrunk to one live concern. What changed under it:
-
ResultTypeis a four-arm seal (GraphitronType.java:94): R276 deletedPojoResultType.NoBacking, andPojoResultTypepermits onlyBacked. Every five-arm switch the old spec designed for is gone. -
FetcherEmitter.propertyOrRecordValue, the old spec’s primary migration target, no longer exists. The fetcher path resolves accessors at classification time. -
The multi-site duplication that motivated a shared
ColumnReadShapedispatcher is gone. Exactly one column-read switch overResultTypesurvives:GeneratorUtils.recordColumnReadArgs(generators/GeneratorUtils.java:290, javadoc’d as the shared per-column reader), consumed bybuildFkRowKey(:274) andbuildProducedRecordsKeyMany(both reached viabuildRecordParentKeyExtraction,:238).
With one site, a cross-site dispatcher is pointless. What survives of R180 is the old spec’s "second asymmetry", previously deferred to a non-goal, now the whole item:
The live problem
recordColumnReadArgs synthesizes accessor names by convention instead of using a resolved accessor:
-
JavaRecordTypearm emits((Backing) expr).<camelCase(sqlName)>(). -
PojoResultType.Backedarm emits((Backing) expr).get<CamelCase(sqlName)>().
Both ride on the unverified assumption that the backing class’s accessor names follow the camel-case convention derived from the column’s SQL name. A backing class whose accessor deviates (renamed component, non-conventional getter, @field(name:)-style remaps once those reach this path) produces generated code that fails to compile, with no classify-time diagnostic. The fetcher path already does this right: it reflects on the backing class at classification time and threads a resolved accessor to the emitter.
R461 (unify-sdl-field-accessor-resolution, Done as of 2026-07-14; its file self-deleted, see the changelog) consolidated accessor-candidate enumeration behind ClassAccessorResolver.enumerate with a probe entry point for the discovery direction and a sealed AccessorProbe (Grounded | NoMatch) result. That is precisely the machinery this item should consume: resolve the per-column accessor at classification time via the R461 surface, carry it to the key-extraction emitter, and fail at classify time (typed rejection with candidates) instead of emitting uncompilable code.
Direction for the revised plan
-
Resolve the accessor for each FK/key column of a record-backed parent at classification time (where the backing class is already reflected on), using
ClassAccessorResolverrather than a parallel name-synthesis rule. -
Carry the resolution to the emitter. The natural carrier is
SourceKey(the old spec’s non-goal 1); noteSourceKey.Reader.AccessorCallalready carries a resolved accessor for the auto-lift path, so the shape has precedent. R431 (decompose-sourcekey, now In Progress; this item’sdepends-onrecords the edge) is reworking that record; sequence this after R431 or land it as part of R431’s reshaping rather than widening the current record independently. R431’s own body flags that the implementer may fold this resolved-accessor carry into the lift fact’s member-read arm; if it does, R180 closes as absorbed rather than following as a separate item. -
recordColumnReadArgs’s jOOQ arms (.get(Tables.X.COL)` /.get(sqlName)) are correct as-is and stay. -
The
ClassName.bestGuess(fqClassName())re-parses in the same arms are R412’s concern (nested-backing-class-emitter-lift); do not fold that here, but do not make it worse.
Non-goals (unchanged from the original spec)
-
backingClassOf(GeneratorUtils.java) andSourceRowDirectiveResolver.parentBackingClassanswer a different question ("give me the parent’s backing class") and stay out of scope. -
No per-dispatcher unit tests asserting
CodeBlockstring equality; pipeline tier verifies emission by compiling generated code against the sakila catalog, perdevelopment-principles.adoc.
Status note
This item is in Spec; the revision above replaces a plan whose reviewer-visible shape changed materially, so the next Spec to Ready transition needs a fresh independent sign-off per the workflow’s reviewer rule.