Skip to content

Commit e78b54d

Browse files
committed
Don't consider lib names when suffixifying local identifiers
1 parent ad2ec5d commit e78b54d

File tree

1 file changed

+302
-0
lines changed

1 file changed

+302
-0
lines changed
Lines changed: 302 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,302 @@
1+
-- If the name we're using for a term is in the project,
2+
-- don't suffixify it against things in lib.
3+
4+
CREATE OR REPLACE FUNCTION term_names_for_ref(
5+
arg_bh_id integer,
6+
arg_namespace_prefix text,
7+
arg_reversed_name_prefix text,
8+
arg_should_suffixify boolean,
9+
arg_referent_builtin text,
10+
arg_referent_component_hash_id integer,
11+
arg_referent_component_index bigint,
12+
arg_referent_constructor_index bigint,
13+
arg_include_dependencies boolean,
14+
arg_include_transitive_dependencies boolean
15+
) RETURNS TABLE (
16+
reversed_name text,
17+
suffixified_name text
18+
) AS $$
19+
DECLARE
20+
names name_with_suffix[];
21+
BEGIN
22+
SELECT array_agg(ROW(names.reversed_name, names.suffixified_name)::name_with_suffix) INTO names
23+
FROM (
24+
SELECT stnl.reversed_name,
25+
CASE
26+
WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, '', ROW(stnl.*), false)
27+
ELSE stnl.reversed_name
28+
END AS suffixified_name
29+
FROM scoped_term_name_lookup stnl
30+
WHERE root_branch_hash_id = arg_bh_id
31+
-- This may seem overly verbose, but it nudges the query planner to use the
32+
-- correct partial index, which is keyed on whether the refBuiltin is null or not.
33+
AND (
34+
(arg_referent_builtin IS NULL
35+
AND referent_builtin IS NULL
36+
AND referent_component_hash_id = arg_referent_component_hash_id
37+
AND referent_component_index = arg_referent_component_index
38+
AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index
39+
)
40+
OR
41+
( arg_referent_builtin IS NOT NULL
42+
AND referent_builtin = arg_referent_builtin
43+
)
44+
)
45+
AND (arg_namespace_prefix = '' OR namespace LIKE like_escape(arg_namespace_prefix) || '%')
46+
AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
47+
UNION ALL
48+
SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name,
49+
CASE
50+
WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, mount.reversed_mount_path, ROW(names.*), true)
51+
ELSE names.reversed_name || mount.reversed_mount_path
52+
END AS suffixified_name
53+
FROM name_lookup_mounts mount
54+
INNER JOIN scoped_term_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id
55+
WHERE arg_include_dependencies
56+
AND mount.parent_root_branch_hash_id = arg_bh_id
57+
AND (arg_namespace_prefix = '' OR mount.mount_path LIKE like_escape(arg_namespace_prefix) || '%')
58+
AND (
59+
(arg_referent_builtin IS NULL
60+
AND referent_builtin IS NULL
61+
AND referent_component_hash_id = arg_referent_component_hash_id
62+
AND referent_component_index = arg_referent_component_index
63+
AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index
64+
)
65+
OR
66+
( arg_referent_builtin IS NOT NULL
67+
AND referent_builtin = arg_referent_builtin
68+
)
69+
)
70+
AND (arg_reversed_name_prefix = '' OR names.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
71+
) AS names;
72+
73+
IF NOT arg_include_transitive_dependencies OR (names IS NOT NULL AND array_length(names, 1) > 0) THEN
74+
RETURN QUERY
75+
SELECT n.reversed_name, n.suffixified_name
76+
FROM unnest(names) AS n(reversed_name, suffixified_name);
77+
ELSE
78+
RETURN QUERY
79+
SELECT (stnl.reversed_name || reversed_mount_path) AS reversed_name,
80+
CASE
81+
WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, reversed_mount_path, ROW(stnl.*), true)
82+
ELSE stnl.reversed_name || reversed_mount_path
83+
END AS suffixified_name
84+
FROM transitive_dependency_mounts(arg_bh_id)
85+
INNER JOIN scoped_term_name_lookup stnl
86+
ON stnl.root_branch_hash_id = transitive_dependency_mounts.root_branch_hash_id
87+
WHERE (
88+
(arg_referent_builtin IS NULL
89+
AND referent_builtin IS NULL
90+
AND referent_component_hash_id = arg_referent_component_hash_id
91+
AND referent_component_index = arg_referent_component_index
92+
AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index
93+
)
94+
OR
95+
( arg_referent_builtin IS NOT NULL
96+
AND referent_builtin = arg_referent_builtin
97+
)
98+
) AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
99+
LIMIT 1;
100+
END IF;
101+
END;
102+
$$ LANGUAGE plpgsql STABLE;
103+
104+
105+
CREATE OR REPLACE FUNCTION type_names_for_ref(
106+
arg_bh_id integer,
107+
arg_namespace_prefix text,
108+
arg_reversed_name_prefix text,
109+
arg_should_suffixify boolean,
110+
arg_reference_builtin text,
111+
arg_reference_component_hash_id integer,
112+
arg_reference_component_index bigint,
113+
arg_include_dependencies boolean,
114+
arg_include_transitive_dependencies boolean
115+
) RETURNS TABLE (
116+
reversed_name text,
117+
suffixified_name text
118+
) AS $$
119+
DECLARE
120+
names name_with_suffix[];
121+
BEGIN
122+
SELECT array_agg(ROW(names.reversed_name, names.suffixified_name)::name_with_suffix) INTO names
123+
FROM (
124+
SELECT stnl.reversed_name,
125+
CASE
126+
WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, '', ROW(stnl.*), false)
127+
ELSE stnl.reversed_name
128+
END AS suffixified_name
129+
FROM scoped_type_name_lookup stnl
130+
WHERE root_branch_hash_id = arg_bh_id
131+
-- This may seem overly verbose, but it nudges the query planner to use the
132+
-- correct partial index, which is keyed on whether the refBuiltin is null or not.
133+
AND (
134+
(arg_reference_builtin IS NULL
135+
AND reference_builtin IS NULL
136+
AND reference_component_hash_id = arg_reference_component_hash_id
137+
AND reference_component_index = arg_reference_component_index
138+
)
139+
OR
140+
( arg_reference_builtin IS NOT NULL
141+
AND reference_builtin = arg_reference_builtin
142+
)
143+
)
144+
AND (arg_namespace_prefix = '' OR namespace LIKE like_escape(arg_namespace_prefix) || '%')
145+
AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
146+
UNION ALL
147+
SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name,
148+
CASE
149+
WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, mount.reversed_mount_path, ROW(names.*), true)
150+
ELSE names.reversed_name || mount.reversed_mount_path
151+
END AS suffixified_name
152+
FROM name_lookup_mounts mount
153+
INNER JOIN scoped_type_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id
154+
WHERE arg_include_dependencies
155+
AND mount.parent_root_branch_hash_id = arg_bh_id
156+
AND (arg_namespace_prefix = '' OR mount.mount_path LIKE like_escape(arg_namespace_prefix) || '%')
157+
AND (
158+
(arg_reference_builtin IS NULL
159+
AND reference_builtin IS NULL
160+
AND reference_component_hash_id = arg_reference_component_hash_id
161+
AND reference_component_index = arg_reference_component_index
162+
)
163+
OR
164+
( arg_reference_builtin IS NOT NULL
165+
AND reference_builtin = arg_reference_builtin
166+
)
167+
) AND (arg_reversed_name_prefix = '' OR names.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
168+
) AS names;
169+
170+
IF NOT arg_include_transitive_dependencies OR (names IS NOT NULL AND array_length(names, 1) > 0) THEN
171+
RETURN QUERY
172+
SELECT n.reversed_name, n.suffixified_name
173+
FROM unnest(names) AS n(reversed_name, suffixified_name);
174+
ELSE
175+
RETURN QUERY
176+
SELECT (stnl.reversed_name || reversed_mount_path) AS reversed_name,
177+
CASE
178+
WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, reversed_mount_path, ROW(stnl.*), true)
179+
ELSE stnl.reversed_name || reversed_mount_path
180+
END AS suffixified_name
181+
FROM transitive_dependency_mounts(arg_bh_id)
182+
INNER JOIN scoped_type_name_lookup stnl
183+
ON stnl.root_branch_hash_id = transitive_dependency_mounts.root_branch_hash_id
184+
WHERE (
185+
(arg_reference_builtin IS NULL
186+
AND reference_builtin IS NULL
187+
AND reference_component_hash_id = arg_reference_component_hash_id
188+
AND reference_component_index = arg_reference_component_index
189+
)
190+
OR
191+
( arg_reference_builtin IS NOT NULL
192+
AND reference_builtin = arg_reference_builtin
193+
)
194+
) AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%')
195+
LIMIT 1;
196+
END IF;
197+
END;
198+
$$ LANGUAGE plpgsql STABLE;
199+
200+
CREATE OR REPLACE FUNCTION suffixify_term_fqn(root_bh_id integer, namespace_prefix text, arg_reversed_mount_path text, term_name scoped_term_name_lookup, include_deps boolean)
201+
RETURNS text AS $$
202+
DECLARE
203+
suffixes text[];
204+
current_suffix text;
205+
fallback_suffix text := NULL;
206+
BEGIN
207+
suffixes := generate_valid_suffixifications(term_name.reversed_name || coalesce(arg_reversed_mount_path, ''));
208+
FOREACH current_suffix IN ARRAY suffixes
209+
LOOP
210+
IF NOT has_name_matching_term_suffixification(root_bh_id, namespace_prefix, current_suffix, term_name, include_deps)
211+
THEN
212+
RETURN current_suffix;
213+
ELSE
214+
fallback_suffix := current_suffix;
215+
END IF;
216+
END LOOP;
217+
218+
RETURN fallback_suffix;
219+
END;
220+
$$ LANGUAGE plpgsql;
221+
222+
CREATE OR REPLACE FUNCTION suffixify_type_fqn(root_bh_id integer, namespace_prefix text, mount_path text, type_name scoped_type_name_lookup, include_deps boolean)
223+
RETURNS text AS $$
224+
DECLARE
225+
suffixes text[];
226+
current_suffix text;
227+
fallback_suffix text := NULL;
228+
BEGIN
229+
suffixes := generate_valid_suffixifications(type_name.reversed_name || coalesce(mount_path, ''));
230+
FOREACH current_suffix IN ARRAY suffixes
231+
LOOP
232+
IF NOT has_name_matching_type_suffixification(root_bh_id, namespace_prefix, current_suffix, type_name, include_deps)
233+
THEN
234+
RETURN current_suffix;
235+
ELSE
236+
fallback_suffix := current_suffix;
237+
END IF;
238+
END LOOP;
239+
240+
RETURN fallback_suffix;
241+
END;
242+
$$ LANGUAGE plpgsql;
243+
244+
CREATE OR REPLACE FUNCTION has_name_matching_term_suffixification(root_bh_id integer, namespace_prefix text, reversed_name_prefix text, term_name scoped_term_name_lookup, include_deps boolean)
245+
RETURNS boolean AS $$
246+
BEGIN
247+
RETURN EXISTS (
248+
SELECT scoped_term_name_lookup.reversed_name, scoped_term_name_lookup.referent_builtin, scoped_term_name_lookup.referent_component_hash_id, scoped_term_name_lookup.referent_component_index, scoped_term_name_lookup.referent_constructor_index, scoped_term_name_lookup.referent_constructor_type
249+
FROM scoped_term_name_lookup
250+
WHERE scoped_term_name_lookup.root_branch_hash_id = root_bh_id
251+
AND scoped_term_name_lookup.last_name_segment = term_name.last_name_segment
252+
AND scoped_term_name_lookup.namespace LIKE like_escape(namespace_prefix) || '%'
253+
AND scoped_term_name_lookup.reversed_name LIKE like_escape(reversed_name_prefix) || '%'
254+
-- We don't need to consider names for the same definition when suffixifying, so
255+
-- we filter those out. Importantly this also avoids matching the name we're trying to suffixify.
256+
AND NOT is_same_term_hash(scoped_term_name_lookup, term_name)
257+
-- pull in names from mounted dependencies
258+
UNION ALL
259+
SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name, names.referent_builtin, referent_component_hash_id, names.referent_component_index, names.referent_constructor_index, names.referent_constructor_type
260+
FROM name_lookup_mounts mount
261+
INNER JOIN scoped_term_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id
262+
WHERE mount.parent_root_branch_hash_id = root_bh_id
263+
AND mount.mount_path LIKE like_escape(namespace_prefix) || '%'
264+
AND names.last_name_segment = term_name.last_name_segment
265+
AND (names.reversed_name || mount.reversed_mount_path) LIKE like_escape(reversed_name_prefix) || '%'
266+
-- We don't need to consider names for the same definition when suffixifying, so
267+
-- we filter those out. Importantly this also avoids matching the name we're trying to suffixify.
268+
AND NOT is_same_term_hash(names, term_name)
269+
AND include_deps
270+
);
271+
END;
272+
$$ LANGUAGE plpgsql;
273+
274+
CREATE OR REPLACE FUNCTION has_name_matching_type_suffixification(root_bh_id integer, namespace_prefix text, reversed_name_prefix text, type_name scoped_type_name_lookup, include_deps boolean)
275+
RETURNS boolean AS $$
276+
BEGIN
277+
RETURN EXISTS (
278+
SELECT reversed_name, reference_builtin, reference_component_hash_id, reference_component_index
279+
FROM scoped_type_name_lookup
280+
WHERE root_branch_hash_id = root_bh_id
281+
AND last_name_segment = type_name.last_name_segment
282+
AND namespace LIKE like_escape(namespace_prefix) || '%'
283+
AND reversed_name LIKE like_escape(reversed_name_prefix) || '%'
284+
-- We don't need to consider names for the same definition when suffixifying, so
285+
-- we filter those out. Importantly this also avoids matching the name we're trying to suffixify.
286+
AND NOT is_same_type_hash(scoped_type_name_lookup, type_name)
287+
UNION ALL
288+
SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name, names.reference_builtin, reference_component_hash_id, names.reference_component_index
289+
FROM name_lookup_mounts mount
290+
INNER JOIN scoped_type_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id
291+
WHERE mount.parent_root_branch_hash_id = root_bh_id
292+
AND mount.mount_path LIKE like_escape(namespace_prefix) || '%'
293+
AND last_name_segment = type_name.last_name_segment
294+
AND (names.reversed_name || mount.reversed_mount_path) LIKE like_escape(reversed_name_prefix) || '%'
295+
-- We don't need to consider names for the same definition when suffixifying, so
296+
-- we filter those out. Importantly this also avoids matching the name we're trying to suffixify.
297+
AND NOT is_same_type_hash(names, type_name)
298+
AND include_deps
299+
);
300+
END;
301+
$$ LANGUAGE plpgsql;
302+

0 commit comments

Comments
 (0)