
# 스키마 검증

스냅샷 간에 스키마가 변경되면(열 추가, 삭제 또는 이름 변경) merql이 그 차이를 감지해 보고합니다. 스키마 불일치가 병합을 막지는 않지만, 호출자가 진행 방법을 결정할 수 있도록 해당 내용을 표시합니다.

## 감지

`SchemaValidator::validate()`은 base, ours, theirs 스냅샷에서 각 테이블의 열 집합을 비교합니다. 다음 항목을 보고합니다:

- ours에 추가된 열(base에는 없고 ours에는 있음)
- 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`으로 처리됩니다. 따라서 다음과 같이 동작합니다:

- 값이 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
}
```
