
# Validação do esquema

Quando os esquemas evoluem entre snapshots (com colunas adicionadas, removidas ou renomeadas), merql detecta e relata essas diferenças. Incompatibilidades de esquema não bloqueiam a mesclagem, mas são sinalizadas para que quem chamou possa decidir como prosseguir.

## Detecção

`SchemaValidator::validate()` compara os conjuntos de colunas de cada tabela nos snapshots base, ours e theirs. Ele relata:

- Colunas adicionadas em ours (presentes em ours, mas não em base)
- Colunas removidas de ours (presentes em base, mas não em ours)
- Colunas adicionadas em theirs
- Colunas removidas de 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"
    }
}
```

## O que é detectado

| Alteração | Detectada | Observações |
|---|---|---|
| Coluna adicionada | Sim | Relatada por lado (ours/theirs) |
| Coluna removida | Sim | Relatada por lado |
| Tipo de coluna alterado | Não | Os tipos são armazenados, mas não comparados |
| Coluna renomeada | Não | Aparece como adição + remoção |
| Chave primária alterada | Não | A identidade é definida no momento do snapshot |

## Comportamento durante a mesclagem

Quando uma coluna existe em um snapshot, mas não em outro, a mesclagem trata o valor da coluna ausente como `null`. Isso significa:

- Uma coluna adicionada em theirs com um valor não nulo aparece como `null -> value` (aceita como alteração de theirs)
- Uma coluna removida de theirs aparece como tendo `null` em todas as linhas de theirs

A mesclagem prossegue e gera um resultado. As incompatibilidades de esquema são informativas. Quem chamou deve verificar se o esquema do banco de dados de destino corresponde aos dados mesclados antes de aplicá-los.

## Acesso às incompatibilidades

As incompatibilidades de esquema estão disponíveis tanto em `ThreeWayMerge` (via `schemaMismatches()`) quanto em `MergeResult` (via `schemaMismatches()` e `hasSchemaMismatches()`). Elas são preservadas por `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
}
```
