@@ -229,7 +229,103 @@ CREATE INDEX dependents_by_dependency ON dependents_index (
229229CREATE INDEX dependencies_by_dependent ON dependents_index (
230230 dependent_object_id,
231231 dependent_component_index
232- )
232+ );
233+
234+
235+ -- This table allows us to look up which branch hashes have a name lookup.
236+ CREATE TABLE name_lookups (
237+ root_branch_hash_id INTEGER PRIMARY KEY REFERENCES hash(id) ON DELETE CASCADE
238+ );
239+
240+ CREATE TABLE scoped_term_name_lookup (
241+ root_branch_hash_id INTEGER NOT NULL REFERENCES hash(id) ON DELETE CASCADE ,
242+
243+ -- The name of the term in reversed form, with a trailing '.':
244+ -- E.g. map.List.base.
245+ --
246+ -- The trailing '.' is helpful when performing suffix queries where we may not know
247+ -- whether the suffix is complete or not, e.g. we could suffix search using any of the
248+ -- following globs and it would still find 'map.List.base.':
249+ -- map.List.base.*
250+ -- map.List.*
251+ -- map.*
252+ reversed_name TEXT NOT NULL ,
253+
254+ -- The last name segment of the name. This is used when looking up names for
255+ -- suffixification when building PPEs.
256+ -- E.g. for the name 'base.List.map' this would be 'map'
257+ last_name_segment TEXT NOT NULL ,
258+
259+ -- The namespace containing this definition, not reversed, with a trailing '.'
260+ -- The trailing '.' simplifies GLOB queries, so that 'base.*' matches both things in
261+ -- 'base' and 'base.List', but not 'base1', which allows us to avoid an OR in our where
262+ -- clauses which in turn helps the sqlite query planner use indexes more effectively.
263+ --
264+ -- example value: 'base.List.'
265+ namespace TEXT NOT NULL ,
266+ referent_builtin TEXT NULL ,
267+ referent_component_hash TEXT NULL ,
268+ referent_component_index INTEGER NULL ,
269+ referent_constructor_index INTEGER NULL ,
270+ referent_constructor_type INTEGER NULL ,
271+ PRIMARY KEY (root_branch_hash_id, reversed_name, referent_builtin, referent_component_hash, referent_component_index, referent_constructor_index)
272+ );
273+
274+ -- This index allows finding all names we need to consider within a given namespace for
275+ -- suffixification of a name.
276+ -- It may seem strange to use last_name_segment rather than a suffix search over reversed_name name here;
277+ -- but SQLite will only optimize for a single prefix-glob at once, so we can't glob search
278+ -- over both namespace and reversed_name, but we can EXACT match on last_name_segment and
279+ -- then glob search on the namespace prefix, and have SQLite do the final glob search on
280+ -- reversed_name over rows with a matching last segment without using an index and should be plenty fast.
281+ CREATE INDEX scoped_term_names_by_namespace_and_last_name_segment ON scoped_term_name_lookup(root_branch_hash_id, last_name_segment, namespace);
282+
283+ -- This index allows us to find all names with a given ref within a specific namespace
284+ CREATE INDEX scoped_term_name_by_referent_lookup ON scoped_term_name_lookup(root_branch_hash_id, referent_builtin, referent_component_hash, referent_component_index, referent_constructor_index, namespace);
285+
286+ -- Allows fetching ALL names within a specific namespace prefix. We currently use this to
287+ -- pretty-print on share, but will be replaced with a more precise set of queries soon.
288+ CREATE INDEX scoped_term_names_by_namespace ON scoped_term_name_lookup(root_branch_hash_id, namespace);
289+
290+
291+ CREATE TABLE scoped_type_name_lookup (
292+ root_branch_hash_id INTEGER NOT NULL REFERENCES hash(id),
293+ -- The name of the term: E.g. List.base
294+ reversed_name TEXT NOT NULL ,
295+ -- The last name segment of the name. This is used when looking up names for
296+ -- suffixification when building PPEs.
297+ -- E.g. for the name 'base.List.map' this would be 'map'
298+ last_name_segment TEXT NOT NULL ,
299+ -- The namespace containing this definition, not reversed, with a trailing '.'
300+ -- The trailing '.' simplifies GLOB queries, so that 'base.*' matches both things in
301+ -- 'base' and 'base.List', but not 'base1', which allows us to avoid an OR in our where
302+ -- clauses which in turn helps the sqlite query planner use indexes more effectively.
303+ --
304+ -- example value: 'base.List.'
305+ namespace TEXT NOT NULL ,
306+ reference_builtin TEXT NULL ,
307+ reference_component_hash INTEGER NULL ,
308+ reference_component_index INTEGER NULL ,
309+ PRIMARY KEY (reversed_name, reference_builtin, reference_component_hash, reference_component_index)
310+ );
311+
312+ -- This index allows finding all names we need to consider within a given namespace for
313+ -- suffixification of a name.
314+ -- It may seem strange to use last_name_segment rather than a suffix search over reversed_name name here;
315+ -- but SQLite will only optimize for a single prefix-glob at once, so we can't glob search
316+ -- over both namespace and reversed_name, but we can EXACT match on last_name_segment and
317+ -- then glob search on the namespace prefix, and have SQLite do the final glob search on
318+ -- reversed_name over rows with a matching last segment without using an index and should be plenty fast.
319+ CREATE INDEX scoped_type_names_by_namespace_and_last_name_segment ON scoped_type_name_lookup(root_branch_hash_id, last_name_segment, namespace)
320+
321+
322+ -- This index allows us to find all names with a given ref within a specific namespace.
323+ CREATE INDEX scoped_type_name_by_reference_lookup ON scoped_type_name_lookup(root_branch_hash_id, reference_builtin, reference_component_hash, reference_component_index, namespace)
324+
325+
326+ -- Allows fetching ALL names within a specific namespace prefix. We currently use this to
327+ -- pretty-print on share, but will be replaced with a more precise set of queries soon.
328+ CREATE INDEX scoped_type_names_by_namespace ON scoped_type_name_lookup(root_branch_hash_id, namespace)
233329
234330-- Semicolon intentionally omitted, for the same reason
235331-- semicolons in comments will blow up codebase initialization.
0 commit comments