Skip to content

Commit ec56e0e

Browse files
committed
Alter syncv2 to expand causals but not history, and skip child causals via except_causal
1 parent f0183c7 commit ec56e0e

2 files changed

Lines changed: 130 additions & 177 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
-- Takes a causal_id and returns a table of ALL hashes which are dependencies of that causal, EXCEPT for the
2+
-- ancestors of the causal.
3+
CREATE OR REPLACE FUNCTION dependencies_of_causals_without_ancestors(the_causal_ids INTEGER[]) RETURNS TABLE (hash TEXT) AS $$
4+
WITH RECURSIVE all_causals(causal_id, causal_hash, causal_namespace_hash_id) AS (
5+
-- Base causal
6+
SELECT DISTINCT causal.id, causal.hash, causal.namespace_hash_id
7+
FROM UNNEST(the_causal_ids) AS causal_id
8+
JOIN causals causal ON causal.id = causal_id
9+
UNION
10+
-- This nested CTE is required because RECURSIVE CTEs can't refer
11+
-- to the recursive table more than once.
12+
-- I don't fully understand why or how this works, but it does
13+
( WITH rec AS (
14+
SELECT tc.causal_id, tc.causal_namespace_hash_id
15+
FROM all_causals tc
16+
)
17+
SELECT child_causal.id, child_causal.hash, child_causal.namespace_hash_id
18+
FROM rec tc
19+
JOIN namespace_children nc ON tc.causal_namespace_hash_id = nc.parent_namespace_hash_id
20+
JOIN causals child_causal ON nc.child_causal_id = child_causal.id
21+
)
22+
), all_namespaces(namespace_hash_id, namespace_hash) AS (
23+
SELECT DISTINCT tc.causal_namespace_hash_id AS namespace_hash_id, bh.base32 as namespace_hash
24+
FROM all_causals tc
25+
JOIN branch_hashes bh ON tc.causal_namespace_hash_id = bh.id
26+
), all_patches(patch_id, patch_hash) AS (
27+
SELECT DISTINCT patch.id, patch.hash
28+
FROM all_namespaces an
29+
JOIN namespace_patches np ON an.namespace_hash_id = np.namespace_hash_id
30+
JOIN patches patch ON np.patch_id = patch.id
31+
),
32+
-- term components to start transitively joining dependencies to
33+
base_term_components(component_hash_id) AS (
34+
SELECT DISTINCT term.component_hash_id
35+
FROM all_namespaces an
36+
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
37+
JOIN terms term ON nt.term_id = term.id
38+
UNION
39+
SELECT DISTINCT term.component_hash_id
40+
FROM all_patches ap
41+
JOIN patch_term_mappings ptm ON ap.patch_id = ptm.patch_id
42+
JOIN terms term ON ptm.to_term_id = term.id
43+
UNION
44+
-- term metadata
45+
SELECT DISTINCT term.component_hash_id
46+
FROM all_namespaces an
47+
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
48+
JOIN namespace_term_metadata meta ON nt.id = meta.named_term
49+
JOIN terms term ON meta.metadata_term_id = term.id
50+
UNION
51+
-- type metadata
52+
SELECT DISTINCT term.component_hash_id
53+
FROM all_namespaces an
54+
JOIN namespace_types nt ON an.namespace_hash_id = nt.namespace_hash_id
55+
JOIN namespace_type_metadata meta ON nt.id = meta.named_type
56+
JOIN terms term ON meta.metadata_term_id = term.id
57+
),
58+
-- type components to start transitively joining dependencies to
59+
base_type_components(component_hash_id) AS (
60+
SELECT DISTINCT typ.component_hash_id
61+
FROM all_namespaces an
62+
JOIN namespace_types nt ON an.namespace_hash_id = nt.namespace_hash_id
63+
JOIN types typ ON nt.type_id = typ.id
64+
UNION
65+
SELECT DISTINCT typ.component_hash_id
66+
FROM all_namespaces an
67+
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
68+
JOIN constructors con ON nt.constructor_id = con.id
69+
JOIN types typ ON con.type_id = typ.id
70+
UNION
71+
SELECT DISTINCT typ.component_hash_id
72+
FROM all_patches ap
73+
JOIN patch_type_mappings ptm ON ap.patch_id = ptm.patch_id
74+
JOIN types typ ON ptm.to_type_id = typ.id
75+
UNION
76+
SELECT DISTINCT typ.component_hash_id
77+
FROM all_patches ap
78+
JOIN patch_constructor_mappings pcm ON ap.patch_id = pcm.patch_id
79+
JOIN constructors con ON pcm.to_constructor_id = con.id
80+
JOIN types typ ON con.type_id = typ.id
81+
),
82+
-- All the dependencies we join in transitively from the known term & type components we depend on.
83+
all_components(component_hash_id) AS (
84+
SELECT DISTINCT btc.component_hash_id
85+
FROM base_term_components btc
86+
UNION
87+
SELECT DISTINCT btc.component_hash_id
88+
FROM base_type_components btc
89+
UNION
90+
( WITH rec AS (
91+
SELECT DISTINCT ac.component_hash_id
92+
FROM all_components ac
93+
)
94+
-- recursively union in term dependencies
95+
SELECT DISTINCT ref.component_hash_id
96+
FROM rec atc
97+
-- This joins in ALL the terms from the component, not just the one that caused the dependency on the
98+
-- component
99+
JOIN terms term ON atc.component_hash_id = term.component_hash_id
100+
JOIN term_local_component_references ref ON term.id = ref.term_id
101+
UNION
102+
-- recursively union in type dependencies
103+
SELECT DISTINCT ref.component_hash_id
104+
FROM rec atc
105+
-- This joins in ALL the types from the component, not just the one that caused the dependency on the
106+
-- component
107+
JOIN types typ ON atc.component_hash_id = typ.component_hash_id
108+
JOIN type_local_component_references ref ON typ.id = ref.type_id
109+
)
110+
)
111+
(SELECT ch.base32 AS hash
112+
FROM all_components ac
113+
JOIN component_hashes ch ON ac.component_hash_id = ch.id
114+
)
115+
UNION ALL
116+
(SELECT ap.patch_hash AS hash
117+
FROM all_patches ap
118+
)
119+
UNION ALL
120+
(SELECT an.namespace_hash AS hash
121+
FROM all_namespaces an
122+
)
123+
UNION ALL
124+
(SELECT ac.causal_hash AS hash
125+
FROM all_causals ac
126+
)
127+
$$ LANGUAGE SQL;

src/Share/Web/UCM/SyncV2/Queries.hs

Lines changed: 3 additions & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -18,180 +18,6 @@ import Unison.SyncV2.Types (CBORBytes)
1818

1919
allSerializedDependenciesOfCausalCursor :: CausalId -> Set CausalHash -> CodebaseM e (PGCursor (CBORBytes TempEntity, Hash32))
2020
allSerializedDependenciesOfCausalCursor cid exceptCausalHashes = do
21-
ownerUserId <- asks codebaseOwner
22-
-- Create a temp table for storing the dependencies we know the calling client already has.
23-
execute_ [sql| CREATE TEMP TABLE except_causals (causal_id INTEGER PRIMARY KEY ) ON COMMIT DROP |]
24-
execute_
25-
[sql|
26-
WITH the_causal_hashes(hash) AS (
27-
SELECT * FROM ^{singleColumnTable (toList exceptCausalHashes)}
28-
) INSERT INTO except_causals(causal_id)
29-
SELECT DISTINCT c.id
30-
FROM the_causal_hashes tch
31-
JOIN causals c ON tch.hash = c.hash
32-
ON CONFLICT DO NOTHING
33-
|]
34-
cursor <-
35-
PGCursor.newRowCursor @(CBORBytes TempEntity, Hash32, Maybe Int32)
36-
"serialized_entities"
37-
[sql|
38-
WITH RECURSIVE transitive_causals(causal_id, causal_hash, causal_namespace_hash_id) AS (
39-
SELECT causal.id, causal.hash, causal.namespace_hash_id
40-
FROM causals causal
41-
WHERE causal.id = #{cid}
42-
AND EXISTS (SELECT FROM causal_ownership co WHERE co.user_id = #{ownerUserId} AND co.causal_id = causal.id)
43-
AND NOT EXISTS (SELECT FROM except_causals ec WHERE ec.causal_id = causal.id)
44-
UNION
45-
-- This nested CTE is required because RECURSIVE CTEs can't refer
46-
-- to the recursive table more than once.
47-
( WITH rec AS (
48-
SELECT tc.causal_id, tc.causal_namespace_hash_id
49-
FROM transitive_causals tc
50-
)
51-
SELECT ancestor_causal.id, ancestor_causal.hash, ancestor_causal.namespace_hash_id
52-
FROM causal_ancestors ca
53-
JOIN rec tc ON ca.causal_id = tc.causal_id
54-
JOIN causals ancestor_causal ON ca.ancestor_id = ancestor_causal.id
55-
WHERE NOT EXISTS (SELECT FROM except_causals ec WHERE ec.causal_id = ancestor_causal.id)
56-
UNION
57-
SELECT child_causal.id, child_causal.hash, child_causal.namespace_hash_id
58-
FROM rec tc
59-
JOIN namespace_children nc ON tc.causal_namespace_hash_id = nc.parent_namespace_hash_id
60-
JOIN causals child_causal ON nc.child_causal_id = child_causal.id
61-
WHERE NOT EXISTS (SELECT FROM except_causals ec WHERE ec.causal_id = child_causal.id)
62-
)
63-
), all_namespaces(namespace_hash_id, namespace_hash) AS (
64-
SELECT DISTINCT tc.causal_namespace_hash_id AS namespace_hash_id, bh.base32 as namespace_hash
65-
FROM transitive_causals tc
66-
JOIN branch_hashes bh ON tc.causal_namespace_hash_id = bh.id
67-
), all_patches(patch_id, patch_hash) AS (
68-
SELECT DISTINCT patch.id, patch.hash
69-
FROM all_namespaces an
70-
JOIN namespace_patches np ON an.namespace_hash_id = np.namespace_hash_id
71-
JOIN patches patch ON np.patch_id = patch.id
72-
),
73-
-- term components to start transitively joining dependencies to
74-
base_term_components(component_hash_id) AS (
75-
SELECT DISTINCT term.component_hash_id
76-
FROM all_namespaces an
77-
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
78-
JOIN terms term ON nt.term_id = term.id
79-
UNION
80-
SELECT DISTINCT term.component_hash_id
81-
FROM all_patches ap
82-
JOIN patch_term_mappings ptm ON ap.patch_id = ptm.patch_id
83-
JOIN terms term ON ptm.to_term_id = term.id
84-
UNION
85-
-- term metadata
86-
SELECT DISTINCT term.component_hash_id
87-
FROM all_namespaces an
88-
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
89-
JOIN namespace_term_metadata meta ON nt.id = meta.named_term
90-
JOIN terms term ON meta.metadata_term_id = term.id
91-
UNION
92-
-- type metadata
93-
SELECT DISTINCT term.component_hash_id
94-
FROM all_namespaces an
95-
JOIN namespace_types nt ON an.namespace_hash_id = nt.namespace_hash_id
96-
JOIN namespace_type_metadata meta ON nt.id = meta.named_type
97-
JOIN terms term ON meta.metadata_term_id = term.id
98-
),
99-
-- type components to start transitively joining dependencies to
100-
base_type_components(component_hash_id) AS (
101-
SELECT DISTINCT typ.component_hash_id
102-
FROM all_namespaces an
103-
JOIN namespace_types nt ON an.namespace_hash_id = nt.namespace_hash_id
104-
JOIN types typ ON nt.type_id = typ.id
105-
UNION
106-
SELECT DISTINCT typ.component_hash_id
107-
FROM all_namespaces an
108-
JOIN namespace_terms nt ON an.namespace_hash_id = nt.namespace_hash_id
109-
JOIN constructors con ON nt.constructor_id = con.id
110-
JOIN types typ ON con.type_id = typ.id
111-
UNION
112-
SELECT DISTINCT typ.component_hash_id
113-
FROM all_patches ap
114-
JOIN patch_type_mappings ptm ON ap.patch_id = ptm.patch_id
115-
JOIN types typ ON ptm.to_type_id = typ.id
116-
UNION
117-
SELECT DISTINCT typ.component_hash_id
118-
FROM all_patches ap
119-
JOIN patch_constructor_mappings pcm ON ap.patch_id = pcm.patch_id
120-
JOIN constructors con ON pcm.to_constructor_id = con.id
121-
JOIN types typ ON con.type_id = typ.id
122-
),
123-
-- All the dependencies we join in transitively from the known term & type components we depend on.
124-
-- Unfortunately it's not possible to know which hashes are terms vs types :'(
125-
transitive_components(component_hash_id) AS (
126-
SELECT DISTINCT btc.component_hash_id
127-
FROM base_term_components btc
128-
UNION
129-
SELECT DISTINCT btc.component_hash_id
130-
FROM base_type_components btc
131-
UNION
132-
( WITH rec AS (
133-
SELECT component_hash_id
134-
FROM transitive_components tc
135-
)
136-
-- recursively union in term dependencies
137-
SELECT DISTINCT ref.component_hash_id
138-
FROM rec atc
139-
-- This joins in ALL the terms from the component, not just the one that caused the dependency on the
140-
-- component
141-
JOIN terms term ON atc.component_hash_id = term.component_hash_id
142-
JOIN term_local_component_references ref ON term.id = ref.term_id
143-
UNION
144-
-- recursively union in type dependencies
145-
SELECT DISTINCT ref.component_hash_id
146-
FROM rec atc
147-
-- This joins in ALL the types from the component, not just the one that caused the dependency on the
148-
-- component
149-
JOIN types typ ON atc.component_hash_id = typ.component_hash_id
150-
JOIN type_local_component_references ref ON typ.id = ref.type_id
151-
)
152-
)
153-
(SELECT bytes.bytes, ch.base32, cd.depth
154-
FROM transitive_components tc
155-
JOIN serialized_components sc ON sc.user_id = #{ownerUserId} AND tc.component_hash_id = sc.component_hash_id
156-
JOIN bytes ON sc.bytes_id = bytes.id
157-
JOIN component_hashes ch ON tc.component_hash_id = ch.id
158-
LEFT JOIN component_depth cd ON ch.id = cd.component_hash_id
159-
)
160-
UNION ALL
161-
(SELECT bytes.bytes, ap.patch_hash, pd.depth
162-
FROM all_patches ap
163-
JOIN serialized_patches sp ON ap.patch_id = sp.patch_id
164-
JOIN bytes ON sp.bytes_id = bytes.id
165-
LEFT JOIN patch_depth pd ON ap.patch_id = pd.patch_id
166-
)
167-
UNION ALL
168-
(SELECT bytes.bytes, an.namespace_hash, nd.depth
169-
FROM all_namespaces an
170-
JOIN serialized_namespaces sn ON an.namespace_hash_id = sn.namespace_hash_id
171-
JOIN bytes ON sn.bytes_id = bytes.id
172-
LEFT JOIN namespace_depth nd ON an.namespace_hash_id = nd.namespace_hash_id
173-
)
174-
UNION ALL
175-
(SELECT bytes.bytes, tc.causal_hash, cd.depth
176-
FROM transitive_causals tc
177-
JOIN serialized_causals sc ON tc.causal_id = sc.causal_id
178-
JOIN bytes ON sc.bytes_id = bytes.id
179-
LEFT JOIN causal_depth cd ON tc.causal_id = cd.causal_id
180-
)
181-
-- Put them in dependency order, nulls come first because we want to bail and
182-
-- report an error if we are somehow missing a depth.
183-
ORDER BY depth ASC NULLS FIRST
184-
|]
185-
pure
186-
( cursor <&> \(bytes, hash, depth) -> case depth of
187-
-- This should never happen, but is a sanity check in case we're missing a depth.
188-
-- Better than silently omitting a required result.
189-
Nothing -> error $ "allSerializedDependenciesOfCausalCursor: Missing depth for entity: " <> show hash
190-
Just _ -> (bytes, hash)
191-
)
192-
193-
_allSerializedDependenciesOfCausalCursorOld :: CausalId -> Set CausalHash -> CodebaseM e (PGCursor (CBORBytes TempEntity, Hash32))
194-
_allSerializedDependenciesOfCausalCursorOld cid exceptCausalHashes = do
19521
ownerUserId <- asks codebaseOwner
19622
-- Create a temp table for storing the dependencies we know the calling client already has.
19723
execute_ [sql| CREATE TEMP TABLE except_causals (causal_id INTEGER PRIMARY KEY ) ON COMMIT DROP |]
@@ -207,12 +33,12 @@ _allSerializedDependenciesOfCausalCursorOld cid exceptCausalHashes = do
20733
JOIN causals c ON tch.hash = c.hash
20834
), dependency_hashes(hash) AS (
20935
SELECT DISTINCT deps.hash
210-
FROM dependencies_of_causals((SELECT ARRAY_AGG(kci.causal_id) FROM known_causal_ids kci)) AS deps
36+
FROM dependencies_of_causals_without_ancestors((SELECT ARRAY_AGG(kci.causal_id) FROM known_causal_ids kci)) AS deps
21137
), do_causals AS (
21238
INSERT INTO except_causals(causal_id)
21339
SELECT DISTINCT causal.id
214-
FROM the_causal_hashes tch
215-
JOIN causals causal ON tch.hash = causal.hash
40+
FROM dependency_hashes dh
41+
JOIN causals causal ON dh.hash = causal.hash
21642
ON CONFLICT DO NOTHING
21743
), do_namespaces AS (
21844
INSERT INTO except_namespaces(branch_hash_ids)

0 commit comments

Comments
 (0)