@@ -184,6 +184,7 @@ module U.Codebase.Sqlite.Queries
184184 getDirectDependenciesOfScope ,
185185 getDirectDependentsWithinScope ,
186186 getTransitiveDependentsWithinScope ,
187+ getTransitiveDependentsGraphWithinScope ,
187188
188189 -- ** type index
189190 addToTypeIndex ,
@@ -2018,13 +2019,13 @@ getTransitiveDependentsWithinScope scope query = do
20182019 WITH RECURSIVE
20192020 dependents_index_in_scope AS (
20202021 SELECT *
2021- FROM dependents_index d
2022- WHERE (d. dependent_object_id, d. dependent_component_index) IN (
2022+ FROM dependents_index
2023+ WHERE (dependent_object_id, dependent_component_index) IN (
20232024 SELECT object_id, component_index
20242025 FROM $scopeTableName
20252026 )
20262027 -- Ignore self-dependents
2027- AND ((d. dependency_object_id, d. dependency_component_index) IS DISTINCT FROM (d. dependent_object_id, d. dependent_component_index))
2028+ AND ((dependency_object_id, dependency_component_index) IS DISTINCT FROM (dependent_object_id, dependent_component_index))
20282029 ),
20292030 transitive_dependents (object_id, component_index, type_id) AS (
20302031 SELECT d.dependent_object_id, d.dependent_component_index, o.type_id
@@ -2043,7 +2044,7 @@ getTransitiveDependentsWithinScope scope query = do
20432044 JOIN object o ON d.dependent_object_id = o.id
20442045 )
20452046 SELECT *
2046- FROM transitive_dependents t
2047+ FROM transitive_dependents
20472048 |]
20482049
20492050 execute [sql | DROP TABLE $scopeTableName |]
@@ -2062,6 +2063,86 @@ getTransitiveDependentsWithinScope scope query = do
20622063
20632064 pure result1
20642065
2066+ -- | Like 'getTransitiveDependentsWithinScope', but returns the dependents as a searchable adjacency matrix rather than
2067+ -- just a set of references.
2068+ --
2069+ -- Returns (dependent ref, dependent type, dependency, dependency type)
2070+ getTransitiveDependentsGraphWithinScope ::
2071+ DefnsF Set S. TermReferenceId S. TypeReferenceId ->
2072+ DefnsF Set S. TermReference S. TypeReference ->
2073+ Transaction [S.Reference. Id :. Only ObjectType :. S. Reference :. Only (Maybe ObjectType )]
2074+ getTransitiveDependentsGraphWithinScope scope query = do
2075+ -- Populate a temporary table with all of the references in `scope`
2076+ let scopeTableName = [sql | dependents_search_scope |]
2077+ createTemporaryTableOfReferenceIds scopeTableName
2078+ for_ scope. terms \ ref -> execute [sql | INSERT INTO $scopeTableName VALUES (@ref, @) |]
2079+ for_ scope. types \ ref -> execute [sql | INSERT INTO $scopeTableName VALUES (@ref, @) |]
2080+
2081+ -- Populate a temporary table with all of the references in `query`
2082+ let queryTableName = [sql | dependencies_query |]
2083+ createTemporaryTableOfReferences queryTableName
2084+ for_ query. terms \ ref -> execute [sql | INSERT INTO $queryTableName VALUES (@ref, @, @) |]
2085+ for_ query. types \ ref -> execute [sql | INSERT INTO $queryTableName VALUES (@ref, @, @) |]
2086+
2087+ result :: [S.Reference. Id :. Only ObjectType :. S. Reference :. Only (Maybe ObjectType )] <-
2088+ queryListRow
2089+ [sql |
2090+ WITH RECURSIVE
2091+ dependents_index_in_scope AS (
2092+ SELECT *
2093+ FROM dependents_index
2094+ WHERE
2095+ (dependent_object_id, dependent_component_index) IN (
2096+ SELECT object_id, component_index
2097+ FROM $scopeTableName
2098+ )
2099+ AND (dependency_object_id, dependency_component_index)
2100+ IS DISTINCT FROM (dependent_object_id, dependent_component_index)
2101+ ),
2102+ transitive_dependents AS (
2103+ SELECT *
2104+ FROM dependents_index_in_scope
2105+ WHERE
2106+ (dependency_builtin IS NULL AND
2107+ (dependency_object_id, dependency_component_index) IN (
2108+ SELECT dependency_object_id, dependency_component_index
2109+ FROM $queryTableName
2110+ WHERE dependency_builtin IS NULL
2111+ )
2112+ )
2113+ OR
2114+ (dependency_builtin IS NOT NULL AND
2115+ dependency_builtin IN (
2116+ SELECT dependency_builtin
2117+ FROM $queryTableName
2118+ WHERE dependency_builtin IS NOT NULL
2119+ )
2120+ )
2121+ UNION
2122+ SELECT d.*
2123+ FROM transitive_dependents t
2124+ JOIN dependents_index_in_scope d
2125+ ON t.dependent_object_id = d.dependency_object_id
2126+ AND t.dependent_component_index = d.dependency_component_index
2127+ )
2128+ SELECT
2129+ t.dependent_object_id,
2130+ t.dependent_component_index,
2131+ o1.type_id,
2132+ t.dependency_builtin,
2133+ t.dependency_object_id,
2134+ t.dependency_component_index,
2135+ o2.type_id
2136+ FROM transitive_dependents t
2137+ JOIN object o1 ON t.dependent_object_id = o1.id
2138+ LEFT JOIN object o2 ON t.dependency_object_id = o2.id
2139+ |]
2140+
2141+ execute [sql | DROP TABLE $scopeTableName |]
2142+ execute [sql | DROP TABLE $queryTableName |]
2143+
2144+ pure result
2145+
20652146createTemporaryTableOfReferences :: Sql -> Transaction ()
20662147createTemporaryTableOfReferences tableName = do
20672148 execute
0 commit comments