Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bugfix: fix lca query #5327

Merged
merged 2 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 39 additions & 26 deletions codebase2/codebase-sqlite/U/Codebase/Sqlite/Queries.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2863,32 +2863,45 @@ before x y =
selectAncestorsOfY = ancestorSql y

lca :: CausalHashId -> CausalHashId -> Transaction (Maybe CausalHashId)
lca x y =
queryStreamCol (ancestorSql x) \nextX ->
queryStreamCol (ancestorSql y) \nextY -> do
let getNext = (,) <$> nextX <*> nextY
loop2 seenX seenY =
getNext >>= \case
(Just px, Just py) ->
let seenX' = Set.insert px seenX
seenY' = Set.insert py seenY
in if Set.member px seenY'
then pure (Just px)
else
if Set.member py seenX'
then pure (Just py)
else loop2 seenX' seenY'
(Nothing, Nothing) -> pure Nothing
(Just px, Nothing) -> loop1 nextX seenY px
(Nothing, Just py) -> loop1 nextY seenX py
loop1 getNext matches v =
if Set.member v matches
then pure (Just v)
else
getNext >>= \case
Just v -> loop1 getNext matches v
Nothing -> pure Nothing
loop2 (Set.singleton x) (Set.singleton y)
lca alice bob =
queryMaybeCol
[sql|
WITH RECURSIVE history_one (causal_id) AS (
SELECT :alice
UNION
SELECT causal_parent.parent_id
FROM history_one
JOIN causal_parent ON history_one.causal_id = causal_parent.causal_id
),
history_two (causal_id) AS (
SELECT :bob
UNION
SELECT causal_parent.parent_id
FROM history_two
JOIN causal_parent ON history_two.causal_id = causal_parent.causal_id
),
common_ancestors (causal_id) AS (
SELECT causal_id
FROM history_one
INTERSECT
SELECT causal_id
FROM history_two
ORDER BY causal_id DESC
)
SELECT causal_id
FROM common_ancestors
WHERE NOT EXISTS (
SELECT 1
FROM causal_parent
WHERE causal_parent.parent_id = common_ancestors.causal_id
AND EXISTS (
SELECT 1
FROM common_ancestors c
WHERE c.causal_id = causal_parent.causal_id
)
)
LIMIT 1
|]

ancestorSql :: CausalHashId -> Sql
ancestorSql h =
Expand Down
125 changes: 125 additions & 0 deletions unison-src/transcripts/fix-5326.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
```ucm
scratch/main> builtins.merge lib.builtin
```

```unison
x = 1
```

```ucm
scratch/main> update
scratch/main> branch foo
scratch/main>
```

```
main, foo
|
A
```

```unison
x = 2
```

```ucm
scratch/main> update
scratch/main> branch bar
scratch/main>
```

```
main, bar
|
| foo
| |
B - A
```

```unison
x = 3
```

```ucm
scratch/main> update
```

```
main
|
| bar foo
| | |
C - B - A
```

```unison
x = 4
```

```ucm
scratch/main> update
scratch/foo>
```

```
main
|
| bar foo
| | |
D - C - B - A
```

```unison
y = 5
```

```ucm
scratch/foo> update
```

```
main
|
| bar
| |
D - C - B - A
/
E
|
foo
```

```ucm
scratch/main> merge /foo
```

```
main
|
| bar
| |
F - D - C - B - A
\ /
----------- E
|
foo
```

```ucm
scratch/main> merge /bar
```

This should be a fast-forward, but we used to get this shape instead (which fails due to conflicts), because we
incorrectly computed `LCA(main, bar)` as `A`, not `B`.

```
main
|
| ------------ bar
| / \|
G - F - D - C - B - A
\ /
----------- E
|
foo
```
Loading