
# 架构验证

当快照之间的架构发生变化（列被添加、删除或重命名）时，merql 会检测并报告这些差异。架构不匹配不会阻止合并，但会被明确指出，供调用方决定如何处理。

## 检测

`SchemaValidator::validate()` 会比较各表在 base、ours 和 theirs 快照中的列集合，并报告：

- 在 ours 中添加的列（存在于 ours，但不存在于 base）
- 在 ours 中删除的列（存在于 base，但不存在于 ours）
- 在 theirs 中添加的列
- 在 theirs 中删除的列

```php
use Merql\Merge\ThreeWayMerge;

$merge = new ThreeWayMerge();
$result = $merge->merge($base, $ours, $theirs);

if ($result->hasSchemaMismatches()) {
    foreach ($result->schemaMismatches() as $mismatch) {
        echo $mismatch->getMessage() . "\n";
        // "Schema mismatch on table 'posts': columns added in theirs: subtitle"
    }
}
```

## 检测内容

| 变更 | 是否检测 | 备注 |
|---|---|---|
| 添加列 | 是 | 按每一侧报告（ours/theirs） |
| 删除列 | 是 | 按每一侧报告 |
| 列类型变更 | 否 | 类型会存储，但不会比较 |
| 列重命名 | 否 | 会表现为添加列和删除列 |
| 主键变更 | 否 | 标识在快照时固定 |

## 合并期间的行为

当某列存在于一个快照中而不存在于另一个快照时，合并会将缺失的列值视为 `null`。这意味着：

- 在 theirs 中添加且值非空的列会显示为 `null -> value`（接受 theirs 的变更）
- 在 theirs 中删除的列会显示为 theirs 中所有行均具有 `null`

合并会继续执行并生成结果。架构不匹配仅提供信息。调用方应在应用之前确认目标数据库架构与合并后的数据相符。

## 访问不匹配信息

架构不匹配信息可在 `ThreeWayMerge` 上获取（通过 `schemaMismatches()`），也可在 `MergeResult` 上获取（通过 `schemaMismatches()` 和 `hasSchemaMismatches()`）。这些信息会在 `ConflictResolver::resolve()` 过程中保留。

```php
// On the merge result directly
$result->hasSchemaMismatches(); // bool
$result->schemaMismatches();    // list<SchemaException>

// Each mismatch is a SchemaException with a descriptive message
foreach ($result->schemaMismatches() as $e) {
    // $e->getMessage() includes table name and column details
}
```
