Skip to content

Comments

[DMS-938] Emit Project Schemas + Resource/Extension Tables + Abstract Identity Tables/Views#840

Open
simpat-adam wants to merge 28 commits intomainfrom
DMS-938-rebased
Open

[DMS-938] Emit Project Schemas + Resource/Extension Tables + Abstract Identity Tables/Views#840
simpat-adam wants to merge 28 commits intomainfrom
DMS-938-rebased

Conversation

@simpat-adam
Copy link
Contributor

Summary

This PR implements the DDL emission infrastructure for the relational model backend redesign, enabling generation of database schemas for PostgreSQL and MSSQL dialects.

Key Features

  • Schema Emission: Generates CREATE SCHEMA statements for Ed-Fi project schemas (e.g., edfi, sample, tpdm)
  • Resource/Extension Table Emission: Emits CREATE TABLE statements for resource root tables and extension tables with proper column types, constraints, and foreign keys
  • Abstract Identity Tables/Views: Generates abstract identity tables and union views for polymorphic resource references
  • Trigger Infrastructure: Implements discriminated union pattern (TriggerKindParameters) for trigger variants:
    • DocumentStamping - timestamp maintenance triggers
    • ReferentialIdentityMaintenance - referential identity sync triggers
    • AbstractIdentityMaintenance - abstract identity table maintenance
    • IdentityPropagationFallback - fallback propagation triggers
  • Index Inventory: Derives and emits indexes for foreign key support and query optimization
  • Key Unification Pass: Implements key unification for merged identity columns across resource hierarchies
  • Constraint Derivation: Adds descriptor foreign key constraints and reference constraints with proper CHECK constraints

Technical Changes

  • RelationalModelDdlEmitter - Main DDL emitter using SqlWriter for phased emission
  • DeriveTriggerInventoryPass - Derives trigger inventory with proper reverse reference tracking
  • KeyUnificationPass - Implements column aliasing and identity propagation
  • DerivedModelSetManifestEmitter - JSON manifest emission for derived model set
  • Extensive golden tests for both PostgreSQL and MSSQL DDL output
  • PageDocumentIdSqlCompiler - SQL compiler for paginated document queries

Testing

  • DDL emission golden tests comparing expected vs actual SQL for both dialects
  • Authoritative relational model golden tests updated for new schema structure
  • Unit tests for all new passes and emitters

Test plan

  • Verify unit tests pass: dotnet test in backend projects
  • Review golden test outputs for correctness
  • Verify DDL emission produces valid SQL for both PostgreSQL and MSSQL

🤖 Generated with Claude Code

simpat-adam added a commit that referenced this pull request Feb 19, 2026
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the big guy. Emit schemas, tables, indexes, views, triggers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why these didn't get alphabetized until my branch. Same goes for all the files under Old.Postgresql

/// nullable optional parameters.
/// </summary>
public enum DbTriggerKind
public abstract record TriggerKindParameters
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yay Discriminated union

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lots of changes in this file. Summary of DeriveTriggerInventoryPass changes:

The major change here is correcting the IdentityPropagationFallback trigger placement to align with the design specification in reference/design/backend-redesign/epics/01-relational-model/07-index-and-trigger-inventory.md (lines 97-102):

"For eligible targets (abstract targets and concrete targets with allowIdentityUpdates=true), inventory emits one propagation trigger per referenced table (TriggerTable) with deterministic referrer fan-out actions."

Before (incorrect): Triggers were placed on the referrer table (e.g., TR_Enrollment_Propagation_School on Enrollment). This resulted in N triggers for N referrers pointing to the same target.

After (per design): A single trigger is placed on the referenced table (e.g., TR_School_PropagateIdentity on School) that fans out to update all referrer tables. This is more efficient and matches where identity changes originate.

Other changes:

  • Replaced DbTriggerKind enum with TriggerKindParameters discriminated union to carry trigger-specific metadata (identity elements, column mappings, referrer updates) needed for DDL emission
  • Added BuildReverseReferenceIndex to collect all referrers per target resource
  • Enhanced ReferentialIdentityMaintenance and AbstractIdentityMaintenance triggers with UUIDv5 computation metadata (resource key IDs, identity element mappings, superclass alias info)

The test changes reflect the corrected trigger placement — assertions now expect triggers on the referenced table with ReferrerUpdates containing the fan-out targets.

simpat-adam added a commit that referenced this pull request Feb 19, 2026
simpat-adam added a commit that referenced this pull request Feb 19, 2026
simpat-adam and others added 23 commits February 20, 2026 16:22
…Identity Tables/Views

- Emit schemas, tables, indexes, views, and triggers from derived relational model
- Support abstract identity tables and union views
- Implement all four trigger kinds: DocumentStamping, ReferentialIdentityMaintenance,
  AbstractIdentityMaintenance, and IdentityPropagationFallback
- Add FK-support index emission
- Add comprehensive golden file tests for DDL emission
- Use ISqlDialect.RenderColumnType for type rendering
- Apply dialect-specific identifier shortening

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…rentialIdentity and AbstractIdentity triggers
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.

1 participant