diff --git a/sql/2025-09-17_optional_transitive_names.sql b/sql/2025-09-17_optional_transitive_names.sql new file mode 100644 index 00000000..79ddbf25 --- /dev/null +++ b/sql/2025-09-17_optional_transitive_names.sql @@ -0,0 +1,196 @@ +-- Add an additional argument for whether to include dependencies or transitive dependencies. +CREATE FUNCTION term_names_for_ref( + arg_bh_id integer, + arg_namespace_prefix text, + arg_reversed_name_prefix text, + arg_should_suffixify boolean, + arg_referent_builtin text, + arg_referent_component_hash_id integer, + arg_referent_component_index bigint, + arg_referent_constructor_index bigint, + arg_include_dependencies boolean, + arg_include_transitive_dependencies boolean +) RETURNS TABLE ( + reversed_name text, + suffixified_name text +) AS $$ +DECLARE + names name_with_suffix[]; +BEGIN + SELECT array_agg(ROW(names.reversed_name, names.suffixified_name)::name_with_suffix) INTO names + FROM ( + SELECT stnl.reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, '', ROW(stnl.*)) + ELSE stnl.reversed_name + END AS suffixified_name + FROM scoped_term_name_lookup stnl + WHERE root_branch_hash_id = arg_bh_id + -- This may seem overly verbose, but it nudges the query planner to use the + -- correct partial index, which is keyed on whether the refBuiltin is null or not. + AND ( + (arg_referent_builtin IS NULL + AND referent_builtin IS NULL + AND referent_component_hash_id = arg_referent_component_hash_id + AND referent_component_index = arg_referent_component_index + AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index + ) + OR + ( arg_referent_builtin IS NOT NULL + AND referent_builtin = arg_referent_builtin + ) + ) + AND (arg_namespace_prefix = '' OR namespace LIKE like_escape(arg_namespace_prefix) || '%') + AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + UNION ALL + SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, mount.reversed_mount_path, ROW(names.*)) + ELSE names.reversed_name || mount.reversed_mount_path + END AS suffixified_name + FROM name_lookup_mounts mount + INNER JOIN scoped_term_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id + WHERE arg_include_dependencies + AND mount.parent_root_branch_hash_id = arg_bh_id + AND (arg_namespace_prefix = '' OR mount.mount_path LIKE like_escape(arg_namespace_prefix) || '%') + AND ( + (arg_referent_builtin IS NULL + AND referent_builtin IS NULL + AND referent_component_hash_id = arg_referent_component_hash_id + AND referent_component_index = arg_referent_component_index + AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index + ) + OR + ( arg_referent_builtin IS NOT NULL + AND referent_builtin = arg_referent_builtin + ) + ) + AND (arg_reversed_name_prefix = '' OR names.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + ) AS names; + + IF NOT arg_include_transitive_dependencies OR (names IS NOT NULL AND array_length(names, 1) > 0) THEN + RETURN QUERY + SELECT n.reversed_name, n.suffixified_name + FROM unnest(names) AS n(reversed_name, suffixified_name); + ELSE + RETURN QUERY + SELECT (stnl.reversed_name || reversed_mount_path) AS reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_term_fqn(arg_bh_id, arg_namespace_prefix, reversed_mount_path, ROW(stnl.*)) + ELSE stnl.reversed_name || reversed_mount_path + END AS suffixified_name + FROM transitive_dependency_mounts(arg_bh_id) + INNER JOIN scoped_term_name_lookup stnl + ON stnl.root_branch_hash_id = transitive_dependency_mounts.root_branch_hash_id + WHERE ( + (arg_referent_builtin IS NULL + AND referent_builtin IS NULL + AND referent_component_hash_id = arg_referent_component_hash_id + AND referent_component_index = arg_referent_component_index + AND referent_constructor_index IS NOT DISTINCT FROM arg_referent_constructor_index + ) + OR + ( arg_referent_builtin IS NOT NULL + AND referent_builtin = arg_referent_builtin + ) + ) AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + LIMIT 1; + END IF; +END; +$$ LANGUAGE plpgsql STABLE; + + +CREATE FUNCTION type_names_for_ref( + arg_bh_id integer, + arg_namespace_prefix text, + arg_reversed_name_prefix text, + arg_should_suffixify boolean, + arg_reference_builtin text, + arg_reference_component_hash_id integer, + arg_reference_component_index bigint, + arg_include_dependencies boolean, + arg_include_transitive_dependencies boolean +) RETURNS TABLE ( + reversed_name text, + suffixified_name text +) AS $$ +DECLARE + names name_with_suffix[]; +BEGIN + SELECT array_agg(ROW(names.reversed_name, names.suffixified_name)::name_with_suffix) INTO names + FROM ( + SELECT stnl.reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, '', ROW(stnl.*)) + ELSE stnl.reversed_name + END AS suffixified_name + FROM scoped_type_name_lookup stnl + WHERE root_branch_hash_id = arg_bh_id + -- This may seem overly verbose, but it nudges the query planner to use the + -- correct partial index, which is keyed on whether the refBuiltin is null or not. + AND ( + (arg_reference_builtin IS NULL + AND reference_builtin IS NULL + AND reference_component_hash_id = arg_reference_component_hash_id + AND reference_component_index = arg_reference_component_index + ) + OR + ( arg_reference_builtin IS NOT NULL + AND reference_builtin = arg_reference_builtin + ) + ) + AND (arg_namespace_prefix = '' OR namespace LIKE like_escape(arg_namespace_prefix) || '%') + AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + UNION ALL + SELECT (names.reversed_name || mount.reversed_mount_path) AS reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, mount.reversed_mount_path, ROW(names.*)) + ELSE names.reversed_name || mount.reversed_mount_path + END AS suffixified_name + FROM name_lookup_mounts mount + INNER JOIN scoped_type_name_lookup names ON names.root_branch_hash_id = mount.mounted_root_branch_hash_id + WHERE arg_include_dependencies + AND mount.parent_root_branch_hash_id = arg_bh_id + AND (arg_namespace_prefix = '' OR mount.mount_path LIKE like_escape(arg_namespace_prefix) || '%') + AND ( + (arg_reference_builtin IS NULL + AND reference_builtin IS NULL + AND reference_component_hash_id = arg_reference_component_hash_id + AND reference_component_index = arg_reference_component_index + ) + OR + ( arg_reference_builtin IS NOT NULL + AND reference_builtin = arg_reference_builtin + ) + ) AND (arg_reversed_name_prefix = '' OR names.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + ) AS names; + + IF NOT arg_include_transitive_dependencies OR (names IS NOT NULL AND array_length(names, 1) > 0) THEN + RETURN QUERY + SELECT n.reversed_name, n.suffixified_name + FROM unnest(names) AS n(reversed_name, suffixified_name); + ELSE + RETURN QUERY + SELECT (stnl.reversed_name || reversed_mount_path) AS reversed_name, + CASE + WHEN arg_should_suffixify THEN suffixify_type_fqn(arg_bh_id, arg_namespace_prefix, reversed_mount_path, ROW(stnl.*)) + ELSE stnl.reversed_name || reversed_mount_path + END AS suffixified_name + FROM transitive_dependency_mounts(arg_bh_id) + INNER JOIN scoped_type_name_lookup stnl + ON stnl.root_branch_hash_id = transitive_dependency_mounts.root_branch_hash_id + WHERE ( + (arg_reference_builtin IS NULL + AND reference_builtin IS NULL + AND reference_component_hash_id = arg_reference_component_hash_id + AND reference_component_index = arg_reference_component_index + ) + OR + ( arg_reference_builtin IS NOT NULL + AND reference_builtin = arg_reference_builtin + ) + ) AND (arg_reversed_name_prefix = '' OR stnl.reversed_name LIKE like_escape(arg_reversed_name_prefix) || '%') + LIMIT 1; + END IF; +END; +$$ LANGUAGE plpgsql STABLE; diff --git a/src/Share/BackgroundJobs/Search/DefinitionSync.hs b/src/Share/BackgroundJobs/Search/DefinitionSync.hs index da52e5fb..153ebc9f 100644 --- a/src/Share/BackgroundJobs/Search/DefinitionSync.hs +++ b/src/Share/BackgroundJobs/Search/DefinitionSync.hs @@ -30,6 +30,7 @@ import Share.Postgres qualified as PG import Share.Postgres.Cursors qualified as Cursors import Share.Postgres.IDs (BranchHashId) import Share.Postgres.NameLookups.Ops qualified as NLOps +import Share.Postgres.NameLookups.Queries (NameSearchScope (..)) import Share.Postgres.NamesPerspective.Ops qualified as NPOps import Share.Postgres.NamesPerspective.Types (NamesPerspective (..)) import Share.Postgres.Notifications qualified as Notif @@ -243,7 +244,7 @@ syncTerms codebase namesPerspective rootBranchHashId termsCursor = do -- It's much more efficient to build only one PPE per batch. let allDeps = setOf (folded . folding tokens . folded . to LD.TypeReference) refDocs - pped <- PG.timeTransaction "Build PPED" $ PPEPostgres.ppedForReferences namesPerspective allDeps + pped <- PG.timeTransaction "Build PPED" $ PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective allDeps let ppe = PPED.unsuffixifiedPPE pped let namedDocs :: [DefinitionDocument Name (Name, ShortHash)] namedDocs = @@ -426,7 +427,7 @@ syncTypes codebase codeCache namesPerspective rootBranchHashId typesCursor = do } -- It's much more efficient to build only one PPE per batch. let allDeps = setOf (folded . folding tokens . folded . to LD.TypeReference) defDocuments - pped <- PPEPostgres.ppedForReferences namesPerspective allDeps + pped <- PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective allDeps let ppe = PPED.unsuffixifiedPPE pped let namedDocs :: V.Vector (DefinitionDocument Name (Name, ShortHash)) namedDocs = diff --git a/src/Share/Names/Postgres.hs b/src/Share/Names/Postgres.hs index 2e52e4c4..50fb802e 100644 --- a/src/Share/Names/Postgres.hs +++ b/src/Share/Names/Postgres.hs @@ -7,7 +7,7 @@ import Data.Set qualified as Set import Share.Postgres qualified as PG import Share.Postgres.NameLookups.Conversions qualified as CV import Share.Postgres.NameLookups.Ops qualified as NameLookupOps -import Share.Postgres.NameLookups.Queries (ShouldSuffixify (NoSuffixify)) +import Share.Postgres.NameLookups.Queries (NameSearchScope, ShouldSuffixify (NoSuffixify)) import Share.Postgres.NameLookups.Types qualified as NameLookups import Share.Postgres.NamesPerspective.Types (NamesPerspective) import Share.Postgres.Refs.Types @@ -19,8 +19,8 @@ import Unison.Names qualified as Names import Unison.Reference qualified as V1 import Unison.Referent qualified as V1 -namesForReferences :: forall m. (PG.QueryM m) => NamesPerspective m -> Set LabeledDependency -> m Names -namesForReferences namesPerspective refs = do +namesForReferences :: forall m. (PG.QueryM m) => NameSearchScope -> NamesPerspective m -> Set LabeledDependency -> m Names +namesForReferences namesScope namesPerspective refs = do (pgRefTerms, pgRefTypes) <- Set.toList refs & CV.labeledDependencies1ToPG @@ -38,7 +38,7 @@ namesForReferences namesPerspective refs = do & asListOf trav %%~ \refs -> do let pgRefs = snd <$> refs typeNames :: [[(NameLookups.ReversedName, NameLookups.ReversedName)]] <- - NameLookupOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify traversed pgRefs + NameLookupOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify namesScope traversed pgRefs pure $ do ((ref, _pgRef), names) <- zip refs typeNames pure $ do @@ -51,7 +51,7 @@ namesForReferences namesPerspective refs = do & asListOf trav %%~ \refs -> do let pgRefs = snd <$> refs termNames :: [[(NameLookups.ReversedName, NameLookups.ReversedName)]] <- - NameLookupOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify traversed pgRefs + NameLookupOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify namesScope traversed pgRefs pure $ do ((ref, _pgRef), names) <- zip refs termNames pure $ do diff --git a/src/Share/NamespaceDiffs.hs b/src/Share/NamespaceDiffs.hs index d5e4dc17..f2813ef0 100644 --- a/src/Share/NamespaceDiffs.hs +++ b/src/Share/NamespaceDiffs.hs @@ -53,6 +53,7 @@ import Share.Postgres qualified as PG import Share.Postgres.Definitions.Queries qualified as DefnsQ import Share.Postgres.IDs (BranchHashId) import Share.Postgres.NameLookups.Ops qualified as NL +import Share.Postgres.NameLookups.Queries (NameSearchScope (TransitiveDependencies)) import Share.Postgres.NameLookups.Types (NameLookupReceipt) import Share.Postgres.NameLookups.Types qualified as NL import Share.Postgres.NamesPerspective.Ops qualified as NPOps @@ -298,7 +299,7 @@ computeThreeWayNamespaceDiff codebaseEnvs2 aliceCodeCache bobCodeCache branchHas traverse NPOps.namesPerspectiveForRoot branchHashIds names <- PG.transactionSpan "load names" mempty do - sequence (PGNames.namesForReferences <$> perspectives <*> ThreeWay.toTwoOrThreeWay dependencies) + sequence (PGNames.namesForReferences TransitiveDependencies <$> perspectives <*> ThreeWay.toTwoOrThreeWay dependencies) pure (TwoOrThreeWay.toThreeWay Names.empty names) Merge.makeDiffblob diff --git a/src/Share/Postgres/NameLookups/Ops.hs b/src/Share/Postgres/NameLookups/Ops.hs index 4de466dc..d6570e55 100644 --- a/src/Share/Postgres/NameLookups/Ops.hs +++ b/src/Share/Postgres/NameLookups/Ops.hs @@ -74,20 +74,20 @@ fuzzySearchDefinitions includeDependencies namesPerspective@NamesPerspective {re -- | Get the list of (fqn, suffixified) names for a given Referent. -- If 'shouldSuffixify' is 'NoSuffixify', the suffixified name will be the same as the fqn. -termNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Traversal s t PGReferent [(ReversedName, ReversedName)] -> s -> m t -termNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify trav s = do +termNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Q.NameSearchScope -> Traversal s t PGReferent [(ReversedName, ReversedName)] -> s -> m t +termNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify nameScope trav s = do s & asListOf trav %%~ \refs -> do - NameLookupQ.termNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify traversed refs + NameLookupQ.termNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify nameScope traversed refs <&> (fmap . fmap) \(NameWithSuffix {reversedName, suffixifiedName}) -> (reversedName, suffixifiedName) -- | Get the list of (fqn, suffixified) names for a given Reference. -- If 'shouldSuffixify' is 'NoSuffixify', the suffixified name will be the same as the fqn. -typeNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Traversal s t PGReference [(ReversedName, ReversedName)] -> s -> m t -typeNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify trav s = do +typeNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Q.NameSearchScope -> Traversal s t PGReference [(ReversedName, ReversedName)] -> s -> m t +typeNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify nameScope trav s = do s & asListOf trav %%~ \refs -> do - NameLookupQ.typeNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify traversed refs + NameLookupQ.typeNamesForRefsWithinNamespaceOf namesPerspective maySuffix shouldSuffixify nameScope traversed refs <&> (fmap . fmap) \(NameWithSuffix {reversedName, suffixifiedName}) -> (reversedName, suffixifiedName) termRefsForExactNamesOf :: (PG.QueryM m) => NamesPerspective m -> Traversal s t ReversedName [NamedRef V1.Referent] -> s -> m t diff --git a/src/Share/Postgres/NameLookups/Queries.hs b/src/Share/Postgres/NameLookups/Queries.hs index dd204dd9..b1399a8a 100644 --- a/src/Share/Postgres/NameLookups/Queries.hs +++ b/src/Share/Postgres/NameLookups/Queries.hs @@ -4,6 +4,7 @@ module Share.Postgres.NameLookups.Queries ( termNamesForRefsWithinNamespaceOf, typeNamesForRefsWithinNamespaceOf, + NameSearchScope (..), ShouldSuffixify (..), termRefsForExactNamesOf, typeRefsForExactNamesOf, @@ -52,13 +53,19 @@ import Unison.Util.Monoid qualified as Monoid data ShouldSuffixify = Suffixify | NoSuffixify +data NameSearchScope + = ProjectDefinitions + | Dependencies + | TransitiveDependencies + deriving (Show, Eq, Ord) + -- | Get the list of term names and suffixifications for a given Referent within a given root namespace perspective. -- Considers one level of dependencies, but not transitive dependencies. -- -- If NoSuffixify is provided, the suffixified name will be the same as the fqn. termNamesForRefsWithinNamespaceOf :: - (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Traversal s t PGReferent [NameWithSuffix] -> s -> m t -termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do + (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> NameSearchScope -> Traversal s t PGReferent [NameWithSuffix] -> s -> m t +termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify nameScope trav s = do s & asListOf trav \refs -> do let refsTable :: [(Int32, Maybe Text, Maybe ComponentHashId, Maybe Int64, Maybe Int64)] refsTable = @@ -74,7 +81,7 @@ termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do -- Need COALESCE because array_agg will return NULL rather than the empty array -- if there are no results. SELECT COALESCE(array_agg((names.reversed_name, names.suffixified_name) ORDER BY length(names.reversed_name) ASC), '{}') - FROM term_names_for_ref_within_namespace( + FROM term_names_for_ref( #{bhId}, #{namespacePrefix}, #{reversedNamePrefix}, @@ -82,7 +89,9 @@ termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do refs.referent_builtin, refs.referent_component_hash_id, refs.referent_component_index, - refs.referent_constructor_index + refs.referent_constructor_index, + #{includeDependencies}, + #{includeTransitiveDependencies} ) AS names(reversed_name, suffixified_name) ) AS ref_names FROM refs @@ -90,6 +99,10 @@ termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do |] <&> over (traversed . traversed . field @"reversedName") (qualifyNameToPerspective np) where + (includeDependencies, includeTransitiveDependencies) = case nameScope of + ProjectDefinitions -> (False, False) + Dependencies -> (True, False) + TransitiveDependencies -> (True, True) -- Look in the current mount. bhId = perspectiveCurrentMountBranchHashId np shouldSuffixifyArg = case shouldSuffixify of @@ -104,8 +117,8 @@ termNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do -- Considers one level of dependencies, but not transitive dependencies. -- -- If NoSuffixify is provided, the suffixified name will be the same as the fqn. -typeNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> Traversal s t PGReference [NameWithSuffix] -> s -> m t -typeNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do +typeNamesForRefsWithinNamespaceOf :: (PG.QueryM m) => NamesPerspective m -> Maybe ReversedName -> ShouldSuffixify -> NameSearchScope -> Traversal s t PGReference [NameWithSuffix] -> s -> m t +typeNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify nameScope trav s = do s & asListOf trav \refs -> do let refsTable :: [(Int32, Maybe Text, Maybe ComponentHashId, Maybe Int64)] refsTable = @@ -121,14 +134,16 @@ typeNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do -- Need COALESCE because array_agg will return NULL rather than the empty array -- if there are no results. SELECT COALESCE(array_agg((names.reversed_name, names.suffixified_name) ORDER BY length(names.reversed_name) ASC), '{}') - FROM type_names_for_ref_within_namespace( + FROM type_names_for_ref( #{bhId}, #{namespacePrefix}, #{reversedNamePrefix}, #{shouldSuffixifyArg}, refs.reference_builtin, refs.reference_component_hash_id, - refs.reference_component_index + refs.reference_component_index, + #{includeDependencies}, + #{includeTransitiveDependencies} ) AS names(reversed_name, suffixified_name) ) AS ref_names FROM refs @@ -136,6 +151,10 @@ typeNamesForRefsWithinNamespaceOf np maySuffix shouldSuffixify trav s = do |] <&> over (traversed . traversed . field @"reversedName") (qualifyNameToPerspective np) where + (includeDependencies, includeTransitiveDependencies) = case nameScope of + ProjectDefinitions -> (False, False) + Dependencies -> (True, False) + TransitiveDependencies -> (True, True) bhId = perspectiveCurrentMountBranchHashId np shouldSuffixifyArg = case shouldSuffixify of Suffixify -> True diff --git a/src/Share/PrettyPrintEnvDecl/Postgres.hs b/src/Share/PrettyPrintEnvDecl/Postgres.hs index 5da324ad..d72b4418 100644 --- a/src/Share/PrettyPrintEnvDecl/Postgres.hs +++ b/src/Share/PrettyPrintEnvDecl/Postgres.hs @@ -7,7 +7,7 @@ import Data.Set qualified as Set import Share.Postgres qualified as PG import Share.Postgres.NameLookups.Conversions qualified as CV import Share.Postgres.NameLookups.Ops qualified as NameLookupOps -import Share.Postgres.NameLookups.Queries (ShouldSuffixify (..)) +import Share.Postgres.NameLookups.Queries (NameSearchScope, ShouldSuffixify (..)) import Share.Postgres.NameLookups.Types qualified as NameLookups import Share.Postgres.NamesPerspective.Types (NamesPerspective) import Share.Postgres.Refs.Types @@ -20,8 +20,8 @@ import Unison.PrettyPrintEnvDecl qualified as PPED import Unison.Reference qualified as V1 import Unison.Referent qualified as V1 -ppedForReferences :: forall m. (PG.QueryM m) => NamesPerspective m -> Set LabeledDependency -> m PPED.PrettyPrintEnvDecl -ppedForReferences namesPerspective refs = do +ppedForReferences :: forall m. (PG.QueryM m) => NameSearchScope -> NamesPerspective m -> Set LabeledDependency -> m PPED.PrettyPrintEnvDecl +ppedForReferences nameScope namesPerspective refs = do (pgRefTerms, pgRefTypes) <- Set.toList refs & CV.labeledDependencies1ToPG @@ -38,7 +38,7 @@ ppedForReferences namesPerspective refs = do & asListOf trav %%~ \refs -> do let pgRefs = snd <$> refs termNames :: [[(NameLookups.ReversedName, NameLookups.ReversedName)]] <- - NameLookupOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing Suffixify traversed pgRefs + NameLookupOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing Suffixify nameScope traversed pgRefs pure $ do ((ref, _pgRef), names) <- zip refs termNames pure $ do @@ -50,7 +50,7 @@ ppedForReferences namesPerspective refs = do & asListOf trav %%~ \refs -> do let pgRefs = snd <$> refs typeNames :: [[(NameLookups.ReversedName, NameLookups.ReversedName)]] <- - NameLookupOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing Suffixify traversed pgRefs + NameLookupOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing Suffixify nameScope traversed pgRefs pure $ do ((ref, _pgRef), names) <- zip refs typeNames pure $ do diff --git a/src/Share/Web/Share/Diffs/Impl.hs b/src/Share/Web/Share/Diffs/Impl.hs index 02fba7db..dd8da510 100644 --- a/src/Share/Web/Share/Diffs/Impl.hs +++ b/src/Share/Web/Share/Diffs/Impl.hs @@ -23,6 +23,7 @@ import Share.Postgres.Causal.Queries qualified as CausalQ import Share.Postgres.Contributions.Queries qualified as ContributionQ import Share.Postgres.Hashes.Queries qualified as HashQ import Share.Postgres.IDs (BranchHash, BranchHashId, CausalId) +import Share.Postgres.NameLookups.Queries (NameSearchScope (TransitiveDependencies)) import Share.Postgres.NameLookups.Types (NameLookupReceipt) import Share.Postgres.NamesPerspective.Ops qualified as NLOps import Share.Postgres.NamesPerspective.Types (NamesPerspective (..)) @@ -294,7 +295,7 @@ getTermDefinitionsOf codebase rt namesPerspective trav s = do Definitions.termDefinitionByNamesOf codebase ppedBuilder namesPerspective renderWidth rt includeDocs traversed names where includeDocs = False - ppedBuilder deps = PPEPostgres.ppedForReferences namesPerspective deps + ppedBuilder deps = PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective deps renderWidth :: Width renderWidth = 80 @@ -336,7 +337,7 @@ expectTermDefinitionsByNamedRefsOf codebase rt namesPerspective toReferent trav (map (\name -> (name, toReferent name)) names) where includeDocs = False - ppedBuilder deps = PPEPostgres.ppedForReferences namesPerspective deps + ppedBuilder deps = PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective deps renderWidth :: Width renderWidth = 80 @@ -371,7 +372,7 @@ getTypeDefinitionsOf codebase rt namesPerspective trav s = do Definitions.typeDefinitionsByNamesOf codebase ppedBuilder namesPerspective renderWidth rt includeDocs traversed names where includeDocs = False - ppedBuilder = PPEPostgres.ppedForReferences namesPerspective + ppedBuilder = PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective renderWidth :: Width renderWidth = 80 @@ -398,7 +399,7 @@ expectTypeDefinitionsByNamedRefsOf codebase rt namesPerspective toReference trav (map (\name -> (name, toReference name)) names) where includeDocs = False - ppedBuilder = PPEPostgres.ppedForReferences namesPerspective + ppedBuilder = PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective renderWidth :: Width renderWidth = 80 diff --git a/src/Unison/Server/NameSearch/Postgres.hs b/src/Unison/Server/NameSearch/Postgres.hs index a65263f2..4856faf7 100644 --- a/src/Unison/Server/NameSearch/Postgres.hs +++ b/src/Unison/Server/NameSearch/Postgres.hs @@ -14,7 +14,7 @@ import Share.Postgres (QueryM) import Share.Postgres qualified as PG import Share.Postgres.NameLookups.Conversions qualified as CV import Share.Postgres.NameLookups.Ops as NLOps -import Share.Postgres.NameLookups.Queries (ShouldSuffixify (NoSuffixify)) +import Share.Postgres.NameLookups.Queries (NameSearchScope, ShouldSuffixify (NoSuffixify)) import Share.Postgres.NameLookups.Types import Share.Postgres.NamesPerspective.Types (NamesPerspective, perspectiveCurrentMountPathPrefix) import Share.Prelude @@ -30,8 +30,8 @@ import Unison.Server.NameSearch (NameSearch (..), Search (..)) import Unison.Server.SearchResult qualified as SR import Unison.ShortHash qualified as V1ShortHash -nameSearchForPerspective :: forall m. (PG.QueryM m) => NamesPerspective m -> NameSearch m -nameSearchForPerspective namesPerspective = +nameSearchForPerspective :: forall m. (PG.QueryM m) => NameSearchScope -> NamesPerspective m -> NameSearch m +nameSearchForPerspective nameSearchScope namesPerspective = NameSearch {typeSearch, termSearch} where -- Some searches will provide a fully-qualified name, so we need to strip off the @@ -64,7 +64,7 @@ nameSearchForPerspective namesPerspective = lookupNamesForTypes :: V1.Reference -> m (Set (HQ'.HashQualified Name)) lookupNamesForTypes ref = fromMaybeT (pure mempty) $ do pgRef <- MaybeT $ CV.references1ToPGOf id ref - names <- lift $ NLOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify id pgRef + names <- lift $ NLOps.typeNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify nameSearchScope id pgRef names & fmap (\(fqnSegments, _suffixSegments) -> HQ'.HashQualified (reversedSegmentsToName fqnSegments) (V1Reference.toShortHash ref)) & Set.fromList @@ -72,7 +72,7 @@ nameSearchForPerspective namesPerspective = lookupNamesForTerms :: V1Referent.Referent -> m (Set (HQ'.HashQualified Name)) lookupNamesForTerms ref = fromMaybeT (pure mempty) $ do pgRef <- MaybeT $ CV.referents1ToPGOf id ref - names <- lift $ NLOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify id pgRef + names <- lift $ NLOps.termNamesForRefsWithinNamespaceOf namesPerspective Nothing NoSuffixify nameSearchScope id pgRef names & fmap (\(fqnSegments, _suffixSegments) -> HQ'.HashQualified (reversedSegmentsToName fqnSegments) (V1Referent.toShortHash ref)) & Set.fromList diff --git a/src/Unison/Server/Share/DefinitionSummary.hs b/src/Unison/Server/Share/DefinitionSummary.hs index 2d4ec48e..11c65425 100644 --- a/src/Unison/Server/Share/DefinitionSummary.hs +++ b/src/Unison/Server/Share/DefinitionSummary.hs @@ -22,6 +22,7 @@ import Share.Backend qualified as Backend import Share.Codebase qualified as Codebase import Share.Codebase.Types (CodeCache) import Share.Postgres (QueryM, unrecoverableError) +import Share.Postgres.NameLookups.Queries (NameSearchScope (TransitiveDependencies)) import Share.Postgres.NamesPerspective.Types (NamesPerspective) import Share.Prelude import Share.PrettyPrintEnvDecl.Postgres qualified as PPEPostgres @@ -68,7 +69,7 @@ termSummariesForReferentsOf namesPerspective mayWidth trav s = do & asListOf trav %%~ \inputs -> do let (refs, typeSigs, mayNames) = unzip3 inputs let allDeps = foldMap Type.labeledDependencies typeSigs - pped <- PPEPostgres.ppedForReferences namesPerspective allDeps + pped <- PPEPostgres.ppedForReferences TransitiveDependencies namesPerspective allDeps let shortHashes = V2Referent.toShortHash <$> refs let displayNames = zipWith (\mayName shortHash -> maybe (HQ.HashOnly shortHash) HQ.NameOnly mayName) mayNames shortHashes let termReferences = V2Referent.toReference <$> refs diff --git a/src/Unison/Server/Share/Definitions.hs b/src/Unison/Server/Share/Definitions.hs index a5188bd7..79adc79d 100644 --- a/src/Unison/Server/Share/Definitions.hs +++ b/src/Unison/Server/Share/Definitions.hs @@ -29,6 +29,7 @@ import Share.Postgres (QueryM, transactionSpan) import Share.Postgres qualified as PG import Share.Postgres.Causal.Queries qualified as CausalQ import Share.Postgres.IDs (CausalId, ComponentHash (..)) +import Share.Postgres.NameLookups.Queries (NameSearchScope (..)) import Share.Postgres.NameLookups.Types (pathToPathSegments) import Share.Postgres.NamesPerspective.Ops qualified as NPOps import Share.Postgres.NamesPerspective.Types (NamesPerspective) @@ -147,9 +148,9 @@ definitionDependencyResults :: Maybe Width -> m [DefinitionSearchResult] definitionDependencyResults codebase codeCache hqName project branchRef np mayWidth = do - let nameSearch = PGNameSearch.nameSearchForPerspective np + let nameSearch = PGNameSearch.nameSearchForPerspective ProjectDefinitions np deps <- definitionDependencies codebase hqName nameSearch - ppe <- PPED.unsuffixifiedPPE <$> PPEPostgres.ppedForReferences np deps + ppe <- PPED.unsuffixifiedPPE <$> PPEPostgres.ppedForReferences TransitiveDependencies np deps -- TODO: batchify this forMaybe (Set.toList $ dependenciesToReferences deps) \dep -> runMaybeT $ case dep of Left termRef -> do @@ -231,9 +232,9 @@ definitionDependentResults :: Maybe Width -> m [DefinitionSearchResult] definitionDependentResults codebase codeCache hqName project branchRef np mayWidth = do - let nameSearch = PGNameSearch.nameSearchForPerspective np + let nameSearch = PGNameSearch.nameSearchForPerspective ProjectDefinitions np deps <- definitionDependents codebase hqName nameSearch - ppe <- PPED.unsuffixifiedPPE <$> PPEPostgres.ppedForReferences np deps + ppe <- PPED.unsuffixifiedPPE <$> PPEPostgres.ppedForReferences ProjectDefinitions np deps let allRefs = Set.toList $ dependenciesToReferences deps let (allTerms, allTypes) = partitionEithers allRefs liftA2 (<>) (doTerms ppe allTerms) (doTypes ppe allTypes) @@ -316,8 +317,8 @@ displayDefinitionByHQName codebase@(CodebaseEnv {codebaseOwner}) perspective roo -- `trunk` over those in other releases. -- ppe which returns names fully qualified to the current namesRoot, not to the codebase root. let biases = maybeToList $ HQ.toName query - let ppedBuilder deps = (PPED.biasTo biases) <$> (PPEPostgres.ppedForReferences perspectiveNP deps) - let nameSearch = PGNameSearch.nameSearchForPerspective perspectiveNP + let ppedBuilder deps = (PPED.biasTo biases) <$> (PPEPostgres.ppedForReferences TransitiveDependencies perspectiveNP deps) + let nameSearch = PGNameSearch.nameSearchForPerspective TransitiveDependencies perspectiveNP dr@(Backend.DefinitionResults terms types misses) <- mkDefinitionsForQuery rt.codeCache nameSearch [query] let width = mayDefaultWidth renderWidth let docResultsOf :: forall s t. Traversal s t Name [(HashQualifiedName, UnisonHash, Doc.Doc)] -> s -> m t diff --git a/src/Unison/Server/Share/FuzzyFind.hs b/src/Unison/Server/Share/FuzzyFind.hs index 10ab8c02..5802ba48 100644 --- a/src/Unison/Server/Share/FuzzyFind.hs +++ b/src/Unison/Server/Share/FuzzyFind.hs @@ -30,6 +30,7 @@ import Share.Postgres (QueryM) import Share.Postgres.Causal.Queries qualified as CausalQ import Share.Postgres.IDs (BranchHashId, CausalId) import Share.Postgres.NameLookups.Ops qualified as NameLookupOps +import Share.Postgres.NameLookups.Queries (NameSearchScope (TransitiveDependencies)) import Share.Postgres.NameLookups.Queries qualified as Q import Share.Postgres.NameLookups.Types (NamedRef (..), PathSegments (..)) import Share.Postgres.NameLookups.Types qualified as NameLookups @@ -232,7 +233,7 @@ serveFuzzyFind codebase inScratch searchDependencies rootCausal perspective mayL (r,) <$> Backend.typeListEntry (ExactName (NameSegment n) r) ) let allLabeledDependencies = foldMap (either (termEntryLabeledDependencies . snd) (typeEntryLabeledDependencies . snd)) entries - pped <- PPED.ppedForReferences namesPerspective allLabeledDependencies + pped <- PPED.ppedForReferences TransitiveDependencies namesPerspective allLabeledDependencies let ppe = PPED.suffixifiedPPE pped for entries \case Left (_r, termEntry) -> diff --git a/src/Unison/Server/Share/RenderDoc.hs b/src/Unison/Server/Share/RenderDoc.hs index ff41caae..2ae2ddb9 100644 --- a/src/Unison/Server/Share/RenderDoc.hs +++ b/src/Unison/Server/Share/RenderDoc.hs @@ -17,6 +17,7 @@ import Share.Codebase.Types (CodebaseEnv (..), CodebaseRuntime) import Share.Postgres (QueryM) import Share.Postgres.Causal.Queries qualified as CausalQ import Share.Postgres.IDs (CausalId) +import Share.Postgres.NameLookups.Queries (NameSearchScope (TransitiveDependencies)) import Share.Postgres.NameLookups.Types (PathSegments (..)) import Share.Postgres.NamesPerspective.Ops qualified as NPOps import Share.Prelude @@ -62,5 +63,5 @@ findAndRenderDoc codebase@(CodebaseEnv {codebaseOwner}) docNames runtime namespa namesPerspective <- NPOps.namesPerspectiveForRootAndPath rootNamespaceHashId (coerce $ Path.toList namespacePath) eDoc <- Backend.evalDocRef codebase runtime docRef let docDeps = Doc.dependencies eDoc <> Set.singleton (LD.TermReference docRef) - docPPE <- PostgresPPE.ppedForReferences namesPerspective docDeps + docPPE <- PostgresPPE.ppedForReferences TransitiveDependencies namesPerspective docDeps pure $ Doc.renderDoc docPPE eDoc