refactor: relationship model to column lists for compound FK (ADR-0043)

Move the FK column fields String->Vec<String> through all six
layers (AddRelationship/SqlForeignKey AST, RelationshipSchema,
metadata, project.yaml, ReadForeignKey, RelationshipEnd). Metadata
stores comma-joined lists in the existing TEXT cells; project.yaml
endpoints now columns: [a, b] (house style). Executor logic is
multi-column ready: resolve_fk_parent_columns (full-PK F-A +
auto-expand F-D), per-pair type-compat, schema_to_ddl multi-column
emission, pragma FK read grouped by id, auto-name + --create-fk
per-column, multi-column teaching echo. Single-column behaviour
preserved (one-element vecs); all 2181 tests green. The grammar to
parse multi-column input lands next.
This commit is contained in:
claude@clouddev1
2026-06-09 18:25:40 +00:00
parent b688592b4c
commit b14f0199e9
23 changed files with 721 additions and 507 deletions
@@ -159,9 +159,14 @@ convention `project.yaml` already uses for `primary_key` and index
- **Metadata** (`__rdbms_playground_relationships`): no
`CREATE TABLE` change (the `TEXT` columns and
`PRIMARY KEY (child_table, child_column)` are untouched).
`parent_column` / `child_column` store the list as a JSON array
string — uniformly, including `["id"]` for a single column
(SQLite has no array type, so a text cell is where a list lives).
`parent_column` / `child_column` store the list **comma-joined**
in the same text cell (`a,b`; a single column is just its bare
name). *As-built note:* the ADR first said "JSON array"; the
implementation uses a comma delimiter, which is safe because
column identifiers are `[A-Za-z0-9_]+` (no commas — `parser.rs`)
and simpler (no `serde_json` dependency). This is an internal
encoding detail below fork F-B — the user-visible `project.yaml`
is still the `columns: [a, b]` list.
The actual enforced FK lives on the rebuilt child table's DDL
(`FOREIGN KEY (a, b) REFERENCES P(x, y)`), emitted by
`schema_to_ddl`, exactly as the single-column FK is today via the