Skip to content

templates: one mechanism owns the numbering partition default (#7147) - #7200

Merged
delchev merged 1 commit into
masterfrom
issue-7147-numbering-partition-default
Sep 9, 2026
Merged

templates: one mechanism owns the numbering partition default (#7147)#7200
delchev merged 1 commit into
masterfrom
issue-7147-numbering-partition-default

Conversation

@delchev

@delchev delchev commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Fixes #7147

What was wrong

#7101's create-path allocator resolved a null per: FK to its own copy of the relation's init: (numberPerDefault), on the premise that "a partition FK the caller left unset is still null here even when the relation carries an init: default (the database applies that on insert)". Since #7104/#7115 the applyDefaults macro is the first statement of save() and assigns exactly that FK from exactly that value — so by the time the numbering block runs the FK is already set and the == null arm is unreachable.

Both arms resolved the same partition, so nothing was wrong at run time. What was wrong is the documentation: the comment stated a premise that no longer holds, and a reader would take a dead fallback for the load-bearing guarantee.

What changed

  • The dead arm and its marker are gone. The create-time allocator reads the FK the write has already defaulted, and a null FK now means what it says: a relation that declares no init: at all, i.e. the tenant-wide base row. The comment now points at the mechanism that actually owns the value.
  • numberPerDefault had exactly one consumer, so EdmIntentGenerator.putNumberPartitionDefaults goes with it. (Side benefit: it had been inserted between the ProcessIds javadoc and processIdsProperty; removing it reunites them.)
  • The stampOn: issue stamp keeps its own perDefault fallback. That path reads a row loaded from the database, where the column can genuinely hold null — an explicit null write into a nullable column carrying a DEFAULT stores null — so its fallback is live, not dead.

On the second half of the issue

The issue asked for the partition default to be unquoted like #defaultLiteral, so an init: 'ACME' could not allocate in partition 'ACME' beside ACME. It cannot happen, and not only because intent PKs are integer-only today: unlike a field default:, a relation's init: is resolved by StatusSymbolResolver against the target's own seeds, and anything that is neither a seeded name nor a numeric id is refused at parse. So the quoted authoring shape never reaches a generator, and adding the unquoting would have been a second piece of dead code beside the one this PR removes.

The invariant is therefore stated where a reader would otherwise wonder (NumberingSupport.partitionDefault's javadoc) and pinned by a test asserting the parse refusal, rather than defended by unreachable code. Happy to add the unquoting anyway if you'd rather have the belt.

Verification

  • The rendered repository defaults the FK before the allocation and carries no second copy of the init value — IntentEngineIT#numbering_partitions_the_default_company_by_the_relations_init rewritten to assert that ORDER rather than the old ternary constant, run end to end (green).
  • engine-intent: 1182 unit tests green. EdmPartitionedNumberInitTest now asserts the .model half of the guarantee (the FK's own dataDefaultValue, and that the number carries no duplicate).
  • formatter:validate clean, javadoc clean under -P release.

Generated output for an existing model is unchanged except for the removed branch, which was never taken.

🤖 Generated with Claude Code

#7101's create-path allocator resolved a null `per:` FK to its own copy of the
relation's `init:` (`numberPerDefault`), on the premise that "the database
applies that on insert". Since #7104/#7115 the applyDefaults macro is the FIRST
statement of `save()` and assigns exactly that FK from exactly that value, so
by the time the numbering block runs the FK is already set and the `== null`
arm is unreachable. Both arms resolved the same partition, so nothing was
wrong at run time - but the comment documented a premise that no longer holds,
and a reader would take a dead fallback for the load-bearing guarantee.

The arm and the marker are gone: the allocator reads the FK the write has
already defaulted, and a null FK now means what it says - a relation that
declares no `init:` at all, i.e. the tenant-wide base row. `numberPerDefault`
had exactly one consumer, so `EdmIntentGenerator.putNumberPartitionDefaults`
goes with it (which also reunites the `ProcessIds` javadoc it had been
inserted in front of with `processIdsProperty`).

The issue's second half asked for the partition default to be unquoted like
`#defaultLiteral`, so an `init: 'ACME'` could not allocate in partition
`'ACME'` beside `ACME`. It cannot: unlike a field `default:`, a relation's
`init:` is resolved by `StatusSymbolResolver` against the target's own seeds
and anything that is neither a seeded name nor a numeric id is refused at
parse - so the quoted shape never reaches a generator. Adding the unquoting
would have been a second piece of dead code beside the one being removed, so
the invariant is stated where a reader would otherwise wonder and pinned by a
test instead.

The `stampOn: issue` stamp keeps its own `perDefault` fallback: it reads a row
loaded from the database, where the column can genuinely hold null (an
explicit null write into a nullable column with a DEFAULT stores null).

Verified: the rendered repository defaults the FK before the allocation and
carries no second copy of the init value (IntentEngineIT's numbering case,
rewritten to assert that ORDER rather than the old ternary constant, green
end to end); engine-intent's 1182 unit tests green.

Fixes #7147

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@delchev
delchev merged commit 932ffb2 into master Sep 9, 2026
10 checks passed
@delchev
delchev deleted the issue-7147-numbering-partition-default branch September 9, 2026 06:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

templates: the numbering per: null-FK fallback is dead since applyDefaults - its comment states a premise that no longer holds

1 participant