Merge silently picks one expression when branches add the same generated column with different AS(...) definitions
- Dominant language
- Go
- Stars
- 24.4k
- Forks
- 873
- Avg merge
- 1d 5h
- Merged PRs (30d)
- 108
Description
### Description
When both branches add the **same-named generated column** with **different expressions**, a three-way merge succeeds with zero conflicts and silently keeps **ours**. The final table uses one expression only; the other is discarded with no schema conflict.
That means computed query results can change after a “clean” merge without any signal that the branches disagreed about the formula. For merge purposes, the generated expression should participate in schema conflict detection (same as any other divergent column definition), not only the column name / type prefix.
Related: #11362 (generated expression left invalid after rename), #11363 (plain vs generated same-name panic).
### Reproduction
```sh
dolt init --name oracle --email oracle@test
dolt sql <<'SQL'
CREATE TABLE t(id INTEGER PRIMARY KEY, a INT);
INSERT INTO t VALUES (1, 10);
CALL dolt_commit('-Am', 'ancestor');
CALL dolt_branch('feat');
CALL dolt_checkout('feat');
ALTER TABLE t ADD COLUMN computed INT AS (a * 2) VIRTUAL;
CALL dolt_commit('-Am', 'feat_expr');
CALL dolt_checkout('main');
ALTER TABLE t ADD COLUMN computed INT AS (a * 3) VIRTUAL;
CALL dolt_commit('-Am', 'main_expr');
CALL dolt_merge('feat');
SELECT * FROM dolt_schema_conflicts;
SELECT * FROM dolt_merge_status;
SHOW CREATE TABLE t;
SELECT id, a, computed FROM t;
SQL
```
### Observed
- Merge returns success (`conflicts = 0`).
- `dolt_schema_conflicts` is empty; merge status is not active.
- Final definition keeps **main’s** expression, e.g. `GENERATED ALWAYS AS ((a * 3))`.
- `SELECT` yields `computed = 30` for `a = 10`.
Same outcome if one side uses short `AS (...)` form and the other uses `GENERATED ALWAYS AS (...)` with a different body.
### Expected
A **schema conflict** on `t` / `computed` (or equivalent refusal to auto-merge), so the user must choose which expression wins. Divergent formulas should not be treated as merge-equivalent solely because both columns are generated with the same name/type.
### Notes
- Syntax variants that are **semantically identical** (e.g. `AS (a * 2) VIRTUAL` vs `GENERATED ALWAYS AS (a * 2) VIRTUAL`) can still auto-merge.
- DoltLite currently mirrors this silent ours-wins behavior for Dolt oracle parity (`generated_both_add_different_expression_ours_wins` in doltlite). Fixing Dolt first would let DoltLite follow.
### Impact
Silent selection of one formula after a clean merge can make merged data look valid while producing incorrect computed values; the chosen schema is committed and history looks conflict-free.
Contributor guide
No contributing guide indexed for this repository
Research direction
Reproduce the merge with the provided SQL, then trace Dolt's schema-merge handling for generated columns and schema conflicts. Use DoltLite's generated_both_add_different_expression_ours_wins test as a parity reference. Done means divergent generated expressions produce a schema conflict, while semantically identical syntax variants still auto-merge.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go, sql
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100