Skip to content

Commit 3fc8271

Browse files
authored
Merge pull request #5327 from unisonweb/fix-lca-query
bugfix: fix lca query
2 parents b08cbb0 + 728f1b9 commit 3fc8271

File tree

3 files changed

+400
-26
lines changed

3 files changed

+400
-26
lines changed

codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2863,32 +2863,45 @@ before x y =
28632863
selectAncestorsOfY = ancestorSql y
28642864

28652865
lca :: CausalHashId -> CausalHashId -> Transaction (Maybe CausalHashId)
2866-
lca x y =
2867-
queryStreamCol (ancestorSql x) \nextX ->
2868-
queryStreamCol (ancestorSql y) \nextY -> do
2869-
let getNext = (,) <$> nextX <*> nextY
2870-
loop2 seenX seenY =
2871-
getNext >>= \case
2872-
(Just px, Just py) ->
2873-
let seenX' = Set.insert px seenX
2874-
seenY' = Set.insert py seenY
2875-
in if Set.member px seenY'
2876-
then pure (Just px)
2877-
else
2878-
if Set.member py seenX'
2879-
then pure (Just py)
2880-
else loop2 seenX' seenY'
2881-
(Nothing, Nothing) -> pure Nothing
2882-
(Just px, Nothing) -> loop1 nextX seenY px
2883-
(Nothing, Just py) -> loop1 nextY seenX py
2884-
loop1 getNext matches v =
2885-
if Set.member v matches
2886-
then pure (Just v)
2887-
else
2888-
getNext >>= \case
2889-
Just v -> loop1 getNext matches v
2890-
Nothing -> pure Nothing
2891-
loop2 (Set.singleton x) (Set.singleton y)
2866+
lca alice bob =
2867+
queryMaybeCol
2868+
[sql|
2869+
WITH RECURSIVE history_one (causal_id) AS (
2870+
SELECT :alice
2871+
UNION
2872+
SELECT causal_parent.parent_id
2873+
FROM history_one
2874+
JOIN causal_parent ON history_one.causal_id = causal_parent.causal_id
2875+
),
2876+
history_two (causal_id) AS (
2877+
SELECT :bob
2878+
UNION
2879+
SELECT causal_parent.parent_id
2880+
FROM history_two
2881+
JOIN causal_parent ON history_two.causal_id = causal_parent.causal_id
2882+
),
2883+
common_ancestors (causal_id) AS (
2884+
SELECT causal_id
2885+
FROM history_one
2886+
INTERSECT
2887+
SELECT causal_id
2888+
FROM history_two
2889+
ORDER BY causal_id DESC
2890+
)
2891+
SELECT causal_id
2892+
FROM common_ancestors
2893+
WHERE NOT EXISTS (
2894+
SELECT 1
2895+
FROM causal_parent
2896+
WHERE causal_parent.parent_id = common_ancestors.causal_id
2897+
AND EXISTS (
2898+
SELECT 1
2899+
FROM common_ancestors c
2900+
WHERE c.causal_id = causal_parent.causal_id
2901+
)
2902+
)
2903+
LIMIT 1
2904+
|]
28922905

28932906
ancestorSql :: CausalHashId -> Sql
28942907
ancestorSql h =

unison-src/transcripts/fix-5326.md

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
```ucm
2+
scratch/main> builtins.merge lib.builtin
3+
```
4+
5+
```unison
6+
x = 1
7+
```
8+
9+
```ucm
10+
scratch/main> update
11+
scratch/main> branch foo
12+
scratch/main>
13+
```
14+
15+
```
16+
main, foo
17+
|
18+
A
19+
```
20+
21+
```unison
22+
x = 2
23+
```
24+
25+
```ucm
26+
scratch/main> update
27+
scratch/main> branch bar
28+
scratch/main>
29+
```
30+
31+
```
32+
main, bar
33+
|
34+
| foo
35+
| |
36+
B - A
37+
```
38+
39+
```unison
40+
x = 3
41+
```
42+
43+
```ucm
44+
scratch/main> update
45+
```
46+
47+
```
48+
main
49+
|
50+
| bar foo
51+
| | |
52+
C - B - A
53+
```
54+
55+
```unison
56+
x = 4
57+
```
58+
59+
```ucm
60+
scratch/main> update
61+
scratch/foo>
62+
```
63+
64+
```
65+
main
66+
|
67+
| bar foo
68+
| | |
69+
D - C - B - A
70+
```
71+
72+
```unison
73+
y = 5
74+
```
75+
76+
```ucm
77+
scratch/foo> update
78+
```
79+
80+
```
81+
main
82+
|
83+
| bar
84+
| |
85+
D - C - B - A
86+
/
87+
E
88+
|
89+
foo
90+
```
91+
92+
```ucm
93+
scratch/main> merge /foo
94+
```
95+
96+
```
97+
main
98+
|
99+
| bar
100+
| |
101+
F - D - C - B - A
102+
\ /
103+
----------- E
104+
|
105+
foo
106+
```
107+
108+
```ucm
109+
scratch/main> merge /bar
110+
```
111+
112+
This should be a fast-forward, but we used to get this shape instead (which fails due to conflicts), because we
113+
incorrectly computed `LCA(main, bar)` as `A`, not `B`.
114+
115+
```
116+
main
117+
|
118+
| ------------ bar
119+
| / \|
120+
G - F - D - C - B - A
121+
\ /
122+
----------- E
123+
|
124+
foo
125+
```

0 commit comments

Comments
 (0)