@@ -166,7 +166,8 @@ module U.Codebase.Sqlite.Queries
166
166
getDependencyIdsForDependent ,
167
167
getDependenciesBetweenTerms ,
168
168
getDirectDependenciesOfScope ,
169
- getDependentsWithinScope ,
169
+ getDirectDependentsWithinScope ,
170
+ getTransitiveDependentsWithinScope ,
170
171
171
172
-- ** type index
172
173
addToTypeIndex ,
@@ -1913,28 +1914,68 @@ getDirectDependenciesOfScope scope = do
1913
1914
1914
1915
pure dependencies1
1915
1916
1916
- {- ORMOLU_DISABLE -}
1917
+ -- | `getDirectDependentsWithinScope scope query` returns all direct dependents of `query` that are in `scope` (not
1918
+ -- including `query` itself).
1919
+ getDirectDependentsWithinScope ::
1920
+ Set S.Reference. Id ->
1921
+ Set S. Reference ->
1922
+ Transaction (DefnsF Set S. TermReferenceId S. TypeReferenceId )
1923
+ getDirectDependentsWithinScope scope query = do
1924
+ -- Populate a temporary table with all of the references in `scope`
1925
+ let scopeTableName = [sql | dependents_search_scope |]
1926
+ createTemporaryTableOfReferenceIds scopeTableName scope
1927
+
1928
+ -- Populate a temporary table with all of the references in `query`
1929
+ let queryTableName = [sql | dependencies_query |]
1930
+ createTemporaryTableOfReferences queryTableName query
1931
+
1932
+ -- Get their direct dependents (tagged with object type)
1933
+ dependents0 <-
1934
+ queryListRow @ (S.Reference. Id :. Only ObjectType )
1935
+ [sql |
1936
+ SELECT s.object_id, s.component_index, o.type_id
1937
+ FROM $queryTableName q
1938
+ JOIN dependents_index d
1939
+ ON q.builtin IS d.dependency_builtin
1940
+ AND q.object_id IS d.dependency_object_id
1941
+ AND q.component_index IS d.dependency_component_index
1942
+ JOIN $scopeTableName s
1943
+ ON d.dependent_object_id = s.object_id
1944
+ AND d.dependent_component_index = s.component_index
1945
+ JOIN object o ON s.object_id = o.id
1946
+ |]
1947
+
1948
+ -- Drop the temporary tables
1949
+ execute [sql | DROP TABLE $scopeTableName |]
1950
+ execute [sql | DROP TABLE $queryTableName |]
1951
+
1952
+ -- Post-process the query result
1953
+ let dependents1 =
1954
+ List. foldl'
1955
+ ( \ deps -> \ case
1956
+ dep :. Only TermComponent -> Defns (Set. insert dep deps. terms) deps. types
1957
+ dep :. Only DeclComponent -> Defns deps. terms (Set. insert dep deps. types)
1958
+ _ -> deps -- impossible; could error here
1959
+ )
1960
+ (Defns Set. empty Set. empty)
1961
+ dependents0
1962
+
1963
+ pure dependents1
1917
1964
1918
- -- | `getDependentsWithinScope scope query` returns all of transitive dependents of `query` that are in `scope` (not
1919
- -- including `query` itself). Each dependent is also tagged with whether it is a term or decl.
1920
- getDependentsWithinScope :: Set S.Reference. Id -> Set S. Reference -> Transaction (Map S.Reference. Id ObjectType )
1921
- getDependentsWithinScope scope query = do
1965
+ -- | `getTransitiveDependentsWithinScope scope query` returns all transitive dependents of `query` that are in `scope`
1966
+ -- (not including `query` itself).
1967
+ getTransitiveDependentsWithinScope ::
1968
+ Set S.Reference. Id ->
1969
+ Set S. Reference ->
1970
+ Transaction (DefnsF Set S. TermReferenceId S. TypeReferenceId )
1971
+ getTransitiveDependentsWithinScope scope query = do
1922
1972
-- Populate a temporary table with all of the references in `scope`
1923
- createTemporaryTableOfReferenceIds [sql | dependents_search_scope |] scope
1973
+ let scopeTableName = [sql | dependents_search_scope |]
1974
+ createTemporaryTableOfReferenceIds scopeTableName scope
1924
1975
1925
1976
-- Populate a temporary table with all of the references in `query`
1926
- execute
1927
- [sql |
1928
- CREATE TEMPORARY TABLE dependencies_query (
1929
- dependency_builtin INTEGER NULL,
1930
- dependency_object_id INTEGER NULL,
1931
- dependency_component_index INTEGER NULL,
1932
- CHECK ((dependency_builtin IS NULL) = (dependency_object_id IS NOT NULL)),
1933
- CHECK ((dependency_object_id IS NULL) = (dependency_component_index IS NULL))
1934
- )
1935
- |]
1936
- for_ query \ r ->
1937
- execute [sql |INSERT INTO dependencies_query VALUES (@r, @, @)|]
1977
+ let queryTableName = [sql | dependencies_query |]
1978
+ createTemporaryTableOfReferences queryTableName query
1938
1979
1939
1980
-- Say the query set is { #foo, #bar }, and the scope set is { #foo, #bar, #baz, #qux, #honk }.
1940
1981
--
@@ -1954,34 +1995,65 @@ getDependentsWithinScope scope query = do
1954
1995
-- We use `UNION` rather than `UNION ALL` so as to not track down the transitive dependents of any particular
1955
1996
-- reference more than once.
1956
1997
1957
- result :: [S.Reference. Id :. Only ObjectType ] <- queryListRow [sql |
1958
- WITH RECURSIVE transitive_dependents (dependent_object_id, dependent_component_index, type_id) AS (
1959
- SELECT d.dependent_object_id, d.dependent_component_index, object.type_id
1960
- FROM dependents_index d
1961
- JOIN object ON d.dependent_object_id = object.id
1962
- JOIN dependencies_query q
1963
- ON q.dependency_builtin IS d.dependency_builtin
1964
- AND q.dependency_object_id IS d.dependency_object_id
1965
- AND q.dependency_component_index IS d.dependency_component_index
1966
- JOIN dependents_search_scope s
1967
- ON s.object_id = d.dependent_object_id
1968
- AND s.component_index = d.dependent_component_index
1969
-
1970
- UNION SELECT d.dependent_object_id, d.dependent_component_index, object.type_id
1971
- FROM dependents_index d
1972
- JOIN object ON d.dependent_object_id = object.id
1973
- JOIN transitive_dependents t
1974
- ON t.dependent_object_id = d.dependency_object_id
1975
- AND t.dependent_component_index = d.dependency_component_index
1976
- JOIN dependents_search_scope s
1977
- ON s.object_id = d.dependent_object_id
1978
- AND s.component_index = d.dependent_component_index
1979
- )
1980
- SELECT * FROM transitive_dependents
1981
- |]
1982
- execute [sql | DROP TABLE dependents_search_scope |]
1983
- execute [sql | DROP TABLE dependencies_query |]
1984
- pure . Map. fromList $ [(r, t) | r :. Only t <- result]
1998
+ result0 :: [S.Reference. Id :. Only ObjectType ] <-
1999
+ queryListRow
2000
+ [sql |
2001
+ WITH RECURSIVE transitive_dependents (dependent_object_id, dependent_component_index, type_id) AS (
2002
+ SELECT d.dependent_object_id, d.dependent_component_index, object.type_id
2003
+ FROM dependents_index d
2004
+ JOIN object ON d.dependent_object_id = object.id
2005
+ JOIN $queryTableName q
2006
+ ON q.builtin IS d.dependency_builtin
2007
+ AND q.object_id IS d.dependency_object_id
2008
+ AND q.component_index IS d.dependency_component_index
2009
+ JOIN $scopeTableName s
2010
+ ON s.object_id = d.dependent_object_id
2011
+ AND s.component_index = d.dependent_component_index
2012
+
2013
+ UNION SELECT d.dependent_object_id, d.dependent_component_index, object.type_id
2014
+ FROM dependents_index d
2015
+ JOIN object ON d.dependent_object_id = object.id
2016
+ JOIN transitive_dependents t
2017
+ ON t.dependent_object_id = d.dependency_object_id
2018
+ AND t.dependent_component_index = d.dependency_component_index
2019
+ JOIN $scopeTableName s
2020
+ ON s.object_id = d.dependent_object_id
2021
+ AND s.component_index = d.dependent_component_index
2022
+ )
2023
+ SELECT * FROM transitive_dependents
2024
+ |]
2025
+
2026
+ execute [sql | DROP TABLE $scopeTableName |]
2027
+ execute [sql | DROP TABLE $queryTableName |]
2028
+
2029
+ -- Post-process the query result
2030
+ let result1 =
2031
+ List. foldl'
2032
+ ( \ deps -> \ case
2033
+ dep :. Only TermComponent -> Defns (Set. insert dep deps. terms) deps. types
2034
+ dep :. Only DeclComponent -> Defns deps. terms (Set. insert dep deps. types)
2035
+ _ -> deps -- impossible; could error here
2036
+ )
2037
+ (Defns Set. empty Set. empty)
2038
+ result0
2039
+
2040
+ pure result1
2041
+
2042
+ createTemporaryTableOfReferences :: Sql -> Set S. Reference -> Transaction ()
2043
+ createTemporaryTableOfReferences tableName refs = do
2044
+ execute
2045
+ [sql |
2046
+ CREATE TEMPORARY TABLE $tableName (
2047
+ builtin INTEGER NULL,
2048
+ object_id INTEGER NULL,
2049
+ component_index INTEGER NULL
2050
+ CHECK ((builtin IS NULL) = (object_id IS NOT NULL)),
2051
+ CHECK ((object_id IS NULL) = (component_index IS NULL))
2052
+ )
2053
+ |]
2054
+
2055
+ for_ refs \ ref ->
2056
+ execute [sql | INSERT INTO $tableName VALUES (@ref, @, @) |]
1985
2057
1986
2058
createTemporaryTableOfReferenceIds :: Sql -> Set S.Reference. Id -> Transaction ()
1987
2059
createTemporaryTableOfReferenceIds tableName refs = do
@@ -1996,6 +2068,8 @@ createTemporaryTableOfReferenceIds tableName refs = do
1996
2068
for_ refs \ ref ->
1997
2069
execute [sql | INSERT INTO $tableName VALUES (@ref, @) |]
1998
2070
2071
+ {- ORMOLU_DISABLE -}
2072
+
1999
2073
objectIdByBase32Prefix :: ObjectType -> Text -> Transaction [ObjectId ]
2000
2074
objectIdByBase32Prefix objType prefix =
2001
2075
queryListCol
0 commit comments