diff --git a/migration/src/lib.rs b/migration/src/lib.rs index 24a223ed..c18aa082 100644 --- a/migration/src/lib.rs +++ b/migration/src/lib.rs @@ -99,6 +99,7 @@ mod m0000790_alter_sbom_alter_document_id; mod m0000800_alter_product_version_range_scheme; mod m0000810_fix_get_purl; mod m0000820_create_conversation; +mod m0000830_perf_indexes; pub struct Migrator; @@ -205,6 +206,7 @@ impl MigratorTrait for Migrator { Box::new(m0000800_alter_product_version_range_scheme::Migration), Box::new(m0000810_fix_get_purl::Migration), Box::new(m0000820_create_conversation::Migration), + Box::new(m0000830_perf_indexes::Migration), ] } } diff --git a/migration/src/m0000830_perf_indexes.rs b/migration/src/m0000830_perf_indexes.rs new file mode 100644 index 00000000..2890ab83 --- /dev/null +++ b/migration/src/m0000830_perf_indexes.rs @@ -0,0 +1,116 @@ +use sea_orm_migration::prelude::*; + +#[derive(DeriveMigrationName)] +pub struct Migration; + +#[async_trait::async_trait] +#[allow(deprecated)] +impl MigrationTrait for Migration { + async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .create_index( + Index::create() + .table(PurlStatus::Table) + .name(Indexes::PurlStatusBasePurlIdIDX.to_string()) + .col(PurlStatus::BasePurlId) + .to_owned(), + ) + .await?; + manager + .create_index( + Index::create() + .table(Status::Table) + .name(Indexes::StatusSlugPartialIDX.to_string()) + .col(Status::Slug) + .to_owned(), + ) + .await?; + manager + .create_index( + Index::create() + .table(SbomPackagePurlRef::Table) + .name(Indexes::SbomPackagePurlRefSbomIdIDX.to_string()) + .col(SbomPackagePurlRef::SbomId) + .to_owned(), + ) + .await?; + manager + .create_index( + Index::create() + .table(SbomPackagePurlRef::Table) + .name(Indexes::SbomPackagePurlRefNodeIdIDX.to_string()) + .col(SbomPackagePurlRef::NodeId) + .to_owned(), + ) + .await?; + Ok(()) + } + + async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> { + manager + .drop_index( + Index::drop() + .if_exists() + .table(SbomPackagePurlRef::Table) + .name(Indexes::SbomPackagePurlRefNodeIdIDX.to_string()) + .to_owned(), + ) + .await?; + manager + .drop_index( + Index::drop() + .if_exists() + .table(SbomPackagePurlRef::Table) + .name(Indexes::SbomPackagePurlRefSbomIdIDX.to_string()) + .to_owned(), + ) + .await?; + manager + .drop_index( + Index::drop() + .if_exists() + .table(Status::Table) + .name(Indexes::StatusSlugPartialIDX.to_string()) + .to_owned(), + ) + .await?; + manager + .drop_index( + Index::drop() + .if_exists() + .table(PurlStatus::Table) + .name(Indexes::PurlStatusBasePurlIdIDX.to_string()) + .to_owned(), + ) + .await?; + Ok(()) + } +} + +#[allow(clippy::enum_variant_names)] +#[derive(DeriveIden)] +enum Indexes { + PurlStatusBasePurlIdIDX, + StatusSlugPartialIDX, + SbomPackagePurlRefSbomIdIDX, + SbomPackagePurlRefNodeIdIDX, +} + +#[derive(DeriveIden)] +enum PurlStatus { + Table, + BasePurlId, +} + +#[derive(DeriveIden)] +enum Status { + Table, + Slug, +} + +#[derive(DeriveIden)] +enum SbomPackagePurlRef { + Table, + SbomId, + NodeId, +} diff --git a/modules/fundamental/src/sbom/model/details.rs b/modules/fundamental/src/sbom/model/details.rs index fcaa8086..c5ef2208 100644 --- a/modules/fundamental/src/sbom/model/details.rs +++ b/modules/fundamental/src/sbom/model/details.rs @@ -60,6 +60,14 @@ impl SbomDetails { JoinType::LeftJoin, qualified_purl::Relation::VersionedPurl.def(), ) + .join(JoinType::LeftJoin, versioned_purl::Relation::BasePurl.def()) + .join(JoinType::Join, base_purl::Relation::PurlStatus.def()) + .join(JoinType::Join, purl_status::Relation::Status.def()) + .filter(Expr::col((status::Entity, status::Column::Slug)).eq("affected")) + .join( + JoinType::LeftJoin, + purl_status::Relation::VersionRange.def(), + ) .filter(SimpleExpr::FunctionCall( Func::cust(VersionMatches) .arg(Expr::col(( @@ -68,13 +76,6 @@ impl SbomDetails { ))) .arg(Expr::col((version_range::Entity, Asterisk))), )) - .join(JoinType::LeftJoin, versioned_purl::Relation::BasePurl.def()) - .join(JoinType::Join, base_purl::Relation::PurlStatus.def()) - .join(JoinType::Join, purl_status::Relation::Status.def()) - .join( - JoinType::LeftJoin, - purl_status::Relation::VersionRange.def(), - ) .join(JoinType::LeftJoin, purl_status::Relation::ContextCpe.def()) .join(JoinType::Join, purl_status::Relation::Advisory.def()) .join(JoinType::Join, purl_status::Relation::Vulnerability.def()) @@ -162,6 +163,7 @@ impl SbomDetails { JOIN "vulnerability" ON "product_status"."vulnerability_id" = "vulnerability"."id" WHERE "sbom"."sbom_id" = $1 + AND "status"."slug" = 'affected' "#; let result: Vec = tx