
# Συγχώνευση σε επίπεδο στήλης

Η συγχώνευση σε επίπεδο στήλης είναι το κύριο πλεονέκτημα του merql έναντι της απλοϊκής σύγκρισης σε επίπεδο γραμμής. Όταν και οι δύο πλευρές τροποποιούν την ίδια γραμμή, το merql συγκρίνει κάθε στήλη ξεχωριστά αντί να επισημαίνει ολόκληρη τη γραμμή ως σύγκρουση.

## Το πρόβλημα της συγχώνευσης σε επίπεδο γραμμής

Σκεφτείτε έναν πίνακα `posts` όπου δύο άτομα επεξεργάζονται την ίδια γραμμή:

```
Base:    post #42  { title: "Hello",     content: "Body",    status: "draft"   }
Ours:    post #42  { title: "Hello",     content: "Body v2", status: "draft"   }
Theirs:  post #42  { title: "New Title", content: "Body",    status: "publish" }
```

Μια συγχώνευση σε επίπεδο γραμμής βλέπει ότι και οι δύο πλευρές άλλαξαν τη γραμμή και δηλώνει σύγκρουση. Όμως οι αλλαγές δεν αλληλεπικαλύπτονται καθόλου. Το ours επεξεργάστηκε το `content`, ενώ το theirs επεξεργάστηκε τα `title` και `status`.

## Πώς την επιλύει η συγχώνευση σε επίπεδο στήλης

Το merql εφαρμόζει τους ίδιους κανόνες συγχώνευσης τριών κατευθύνσεων ξεχωριστά σε κάθε στήλη:

```
title:   base="Hello", ours="Hello",  theirs="New Title"  -> accept theirs
content: base="Body",  ours="Body v2", theirs="Body"      -> accept ours
status:  base="draft", ours="draft",  theirs="publish"    -> accept theirs
```

Αποτέλεσμα: `{ title: "New Title", content: "Body v2", status: "publish" }`. Καθαρή συγχώνευση, χωρίς σύγκρουση.

## Πώς λειτουργεί

Όταν το `ThreeWayMerge` εντοπίζει ότι και οι δύο πλευρές ενημέρωσαν την ίδια γραμμή, αναθέτει τη συγχώνευση στο `ColumnMerge::merge()`:

```php
use Merql\Merge\ColumnMerge;

$result = ColumnMerge::merge(
    table: 'posts',
    rowKey: '42',
    base: ['title' => 'Hello', 'content' => 'Body', 'status' => 'draft'],
    ours: ['title' => 'Hello', 'content' => 'Body v2', 'status' => 'draft'],
    theirs: ['title' => 'New Title', 'content' => 'Body', 'status' => 'publish'],
);

// $result['values']    -> merged column values
// $result['conflicts'] -> list of Conflict objects (empty if clean)
```

Για κάθε στήλη ισχύουν οι ίδιοι κανόνες:

| Βάση | Ours | Theirs | Αποτέλεσμα |
|---|---|---|---|
| A | A | A | Διατήρηση βάσης (χωρίς αλλαγή) |
| A | A | B | Αποδοχή του theirs |
| A | B | A | Αποδοχή του ours |
| A | B | B | Αποδοχή (συμφωνούν και οι δύο) |
| A | B | C | **Σύγκρουση** (διαφορετικές τιμές) |

## Πότε εξακολουθούν να προκύπτουν συγκρούσεις

Σύγκρουση σε επίπεδο στήλης προκύπτει όταν και οι δύο πλευρές αλλάξουν την ίδια στήλη σε διαφορετικές τιμές:

```
Base:    post #42  { title: "Hello" }
Ours:    post #42  { title: "Welcome" }
Theirs:  post #42  { title: "Greetings" }
```

Και οι δύο άλλαξαν το `title` σε διαφορετικές τιμές. Πρόκειται για πραγματική σύγκρουση που απαιτεί επίλυση.

```php
$result = ColumnMerge::merge(
    'posts', '42',
    ['title' => 'Hello'],
    ['title' => 'Welcome'],
    ['title' => 'Greetings'],
);

// $result['conflicts'] contains one Conflict:
//   table: "posts", column: "title"
//   oursValue: "Welcome", theirsValue: "Greetings", baseValue: "Hello"
```

## Μερικές συγκρούσεις

Μια γραμμή μπορεί να περιέχει τόσο καθαρές συγχωνεύσεις όσο και συγκρούσεις. Αν μία στήλη συγχωνευθεί ομαλά αλλά μια άλλη έχει σύγκρουση, το `MergeOperation` της γραμμής περιέχει τις συγχωνευμένες τιμές για τις στήλες που συγχωνεύθηκαν ομαλά και την τιμή ours (από προεπιλογή) για τις στήλες με σύγκρουση. Η σύγκρουση εξακολουθεί να αναφέρεται ξεχωριστά.

```
Base:    { title: "Hello", content: "Body",    status: "draft" }
Ours:    { title: "Welcome", content: "Body v2", status: "draft" }
Theirs:  { title: "Greetings", content: "Body",    status: "publish" }
```

Εδώ, το `title` έχει σύγκρουση (και οι δύο πλευρές το άλλαξαν διαφορετικά), το `content` συγχωνεύεται ομαλά (άλλαξε μόνο το ours) και το `status` συγχωνεύεται ομαλά (άλλαξε μόνο το theirs). Η λειτουργία περιλαμβάνει:

```php
// values: { title: "Welcome", content: "Body v2", status: "publish" }
// One conflict on the "title" column.
```

## Σύγκριση τιμών

Οι τιμές στηλών συγκρίνονται ως συμβολοσειρές μετά τη μετατροπή τύπου. Το `NULL` είναι διακριτή τιμή:

- `NULL` σε `NULL` = καμία αλλαγή.
- `NULL` σε `"hello"` = ενημέρωση.
- `"hello"` σε `NULL` = ενημέρωση.
- `"1"` σε `1` = καμία αλλαγή (και τα δύο μετατρέπονται στη συμβολοσειρά `"1"`).

Αυτό συμφωνεί με τη σημασιολογία λήψης δεδομένων του προσαρμογέα σύνδεσης MerQL: όλες οι τιμές της βάσης δεδομένων επιστρέφονται ως συμβολοσειρές (ή NULL).

## Συγχώνευση σε επίπεδο κελιού

Όταν η συγχώνευση σε επίπεδο στήλης εξακολουθεί να οδηγεί σε σύγκρουση (και οι δύο πλευρές άλλαξαν την ίδια στήλη σε διαφορετικές τιμές), το merql μπορεί να προχωρήσει ένα επίπεδο βαθύτερα με [συγχώνευση σε επίπεδο κελιού](https://merql.inline0.dev/el/docs/merge/cell-level). Αυτό εφαρμόζεται σε στήλες TEXT (διαφορές ανά γραμμή) και στήλες JSON (διαφορές ανά κλειδί), επιλύοντας περιπτώσεις όπου και οι δύο πλευρές επεξεργάστηκαν διαφορετικά μέρη της τιμής της ίδιας στήλης.
