feat: Implements foreign key handling (#68)

This commit is contained in:
Marcelo Mendonça Soares 2026-06-10 17:31:05 -03:00 • committed by GitHub
commit 4580326956
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 6630 additions and 189 deletions

View file

@ -1,10 +1,9 @@
### Why a CRDT row entered its current visibility generation.
### Why a synced user tombstone changed row visibility.
enum: CrdtDataDeletedReason
serialized: byIndex
values:
- userInsert
- userDelete
- userReinsert
- restrictRestore
- cascadeDelete
- userDelete
- userCascadeDelete
- uniqueLoser

View file

@ -16,6 +16,10 @@ fields:
### The node that updated the field.
node: CrdtNode?, relation
### The foreign key information for the field, if this field holds a
### reference to another row.
foreignKey: CrdtDataForeignKey?, relation(optional, name=field_foreign_key)
indexes:
crdt_data_fields_row_column_idx:
fields: rowId, columnId

View file

@ -0,0 +1,40 @@
### CRDT field foreign key value and projection table.
###
### This table stores the user/attempted foreign key value for a CRDT field and
### the materialized foreign key projection for that value. CrdtDataField stores
### only HLC metadata, so FK columns store their durable attempted value here.
###
### Repairs must be recomputable from merged CRDT row, field, and tombstone
### facts plus this attempted FK value. The projection columns record what was
### materialized into the domain row; they do not decide business semantics or
### create user field updates during merge.
class: CrdtDataForeignKey
table: crdt_data_foreign_key
database: all
fields:
### The field that the foreign key belongs to.
field: CrdtDataField?, relation(name=field_foreign_key, field=fieldId, onDelete=Cascade)
fieldId: int
### The user-attempted foreign key value that the CRDT field currently carries.
###
### This may be null for nullable foreign keys. This is durable FK field-value
### storage for CRDT columns whose CrdtDataField row stores only HLC metadata.
attemptedValue: UuidValue?, required
### The foreign key value that is currently visible in the actual data row
### when an override is active (overrideReason is non-null).
visibleValue: UuidValue?
### The authoritative indicator and reason for an active projection override.
###
### This is the single source of truth for whether an override is active:
### non-null means an override is active; null means no override. It also
### names the cause of the override. The FK resolver recomputes it from merged
### row, field, and tombstone facts.
overrideReason: CrdtForeignKeyOverrideReason?
indexes:
crdt_data_foreign_key_field_idx:
fields: fieldId
unique: true

View file

@ -0,0 +1,15 @@
### Why a foreign key projection override is active.
enum: CrdtForeignKeyOverrideReason
serialized: byIndex
values:
### The attempted parent target is hidden or missing and the FK projection
### set the column to null.
- setNull
### The attempted parent target is hidden or missing and the FK projection
### set the column to the default value.
- setDefault
### The attempted parent target is hidden or missing and the FK projection
### cannot repair the value (restrict, no action, cascade, or the column is
### non-nullable), so the row is hidden by projection while the attempt is
### preserved.
- missingParent

View file

@ -22,10 +22,16 @@ fields:
### The node that inserted the row with the HLC timestamp.
node: CrdtNode?, relation
### The visibility CLFlag for this row.
### Materialized visibility state for domain queries.
###
### Only present after the first visibility change event has been recorded.
### If null, the row is visible and has never been deleted/hidden.
### Updated by user tombstone writes and foreign key projection. Visible
### states are listed before hidden states in CrdtDataRowVisibility.
visibility: CrdtDataRowVisibility, default=userInsert
### The synced user tombstone for this row.
###
### Only present after the first user visibility change event has been recorded.
### Projection may keep a visible [visibility] while a user delete tombstone exists.
deleted: CrdtDataDeleted?, relation(name=row_deleted, optional)
### The fields for this row.

View file

@ -0,0 +1,13 @@
### Materialized visibility state for a CRDT row.
###
### Visible states are listed first, hidden states last. A row is visible when
### its serialized index is less than or equal to [foreignKeyRestrictRestore].
enum: CrdtDataRowVisibility
serialized: byIndex
values:
- userInsert
- userReinsert
- foreignKeyRestrictRestore
- userDelete
- userCascadeDelete
- foreignKeyCascade