Skip to content

Add finder params in Value Stream Analytics

Adam Hegyi requested to merge 217973-accept-filter-params-in-vsa-v2 into master

What does this MR do?

This MR adds extra finder params in Value Stream Analytics. The finder params are already supported by the underlying Issuable filters. Here we just make sure that we validate and pass the params correctly.

  • label_name
  • author_username
  • assignee_username
  • milestone_title

Notes

  • Note 1: This change is not user facing. FE implementation is not there yet.
  • Note 2: Finders are already tested at other places so I only have a few test cases to make sure filters are working correctly.
  • Note 3: There is a minor refactor in the controllers to remove code duplication related to strong params and params validation.
  • Note 4: We do some params transformation (created_after -> from, created_before -> to) which is currently needed to ensure compatibility with the old VSA implementation. I hope we can clean it up in #33580 (closed)

Database Queries

Preliminary performance analysis with various options: #12525 (comment 340109218)

Note: there can be several different query combinations, the performance characteristics are similar in all cases.

Complex filter: assignee + label + milestone

Issue Query
SELECT EXTRACT(EPOCH
               FROM percentile_cont(0.5) WITHIN GROUP(
                                                      ORDER BY COALESCE("issue_metrics"."first_associated_with_milestone_at", "issue_metrics"."first_added_to_board_at") - "issues"."created_at")) AS median
FROM "issues"
INNER JOIN "projects" ON "projects"."id" = "issues"."project_id"
INNER JOIN "label_links" ON "label_links"."target_type" = 'Issue'
AND "label_links"."target_id" = "issues"."id"
INNER JOIN "labels" ON "labels"."id" = "label_links"."label_id"
INNER JOIN "issue_metrics" ON "issue_metrics"."issue_id" = "issues"."id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE "projects"."namespace_id" IN
    (WITH RECURSIVE "base_and_descendants" AS (
                                                 (SELECT "namespaces".*
                                                  FROM "namespaces"
                                                  WHERE "namespaces"."type" = 'Group'
                                                    AND "namespaces"."id" = 9970)
                                               UNION
                                                 (SELECT "namespaces".*
                                                  FROM "namespaces",
                                                       "base_and_descendants"
                                                  WHERE "namespaces"."type" = 'Group'
                                                    AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT "namespaces"."id"
     FROM "base_and_descendants" AS "namespaces")
  AND (EXISTS
         (SELECT 1
          FROM "project_authorizations"
          WHERE "project_authorizations"."user_id" = 4156052
            AND (project_authorizations.project_id = projects.id))
       OR projects.visibility_level IN (0,
                                        10,
                                        20))
  AND ("project_features"."issues_access_level" > 0
       OR "project_features"."issues_access_level" IS NULL)
  AND "issues"."created_at" <= '2020-06-04 23:59:59.999999'
  AND "issues"."created_at" >= '2020-02-06 00:00:00'
  AND (EXISTS
         (SELECT TRUE
          FROM "issue_assignees"
          WHERE "issue_assignees"."user_id" IN (4156052)
            AND issue_id = issues.id))
  AND "milestones"."title" = '13.1'
  AND "labels"."title" = 'feature'
  AND ("issue_metrics"."first_added_to_board_at" IS NOT NULL
       OR "issue_metrics"."first_associated_with_milestone_at" IS NOT NULL)
  AND COALESCE("issue_metrics"."first_associated_with_milestone_at", "issue_metrics"."first_added_to_board_at") >= "issues"."created_at"

Plan

MR Query
SELECT EXTRACT(EPOCH
               FROM percentile_cont(0.5) WITHIN GROUP(
                                                      ORDER BY "merge_request_metrics"."merged_at" - "merge_requests"."created_at")) AS median
FROM "merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
INNER JOIN "label_links" ON "label_links"."target_type" = 'MergeRequest'
AND "label_links"."target_id" = "merge_requests"."id"
INNER JOIN "labels" ON "labels"."id" = "label_links"."label_id"
INNER JOIN "merge_request_metrics" ON "merge_request_metrics"."merge_request_id" = "merge_requests"."id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE "projects"."namespace_id" IN
    (WITH RECURSIVE "base_and_descendants" AS (
                                                 (SELECT "namespaces".*
                                                  FROM "namespaces"
                                                  WHERE "namespaces"."type" = 'Group'
                                                    AND "namespaces"."id" = 9970)
                                               UNION
                                                 (SELECT "namespaces".*
                                                  FROM "namespaces",
                                                       "base_and_descendants"
                                                  WHERE "namespaces"."type" = 'Group'
                                                    AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT "namespaces"."id"
     FROM "base_and_descendants" AS "namespaces")
  AND (EXISTS
         (SELECT 1
          FROM "project_authorizations"
          WHERE "project_authorizations"."user_id" = 4156052
            AND (project_authorizations.project_id = projects.id))
       OR projects.visibility_level IN (0,
                                        10,
                                        20))
  AND ("project_features"."merge_requests_access_level" > 0
       OR "project_features"."merge_requests_access_level" IS NULL)
  AND "merge_requests"."created_at" <= '2020-06-04 23:59:59.999999'
  AND "merge_requests"."created_at" >= '2020-05-06 00:00:00'
  AND (EXISTS
         (SELECT TRUE
          FROM "merge_request_assignees"
          WHERE "merge_request_assignees"."user_id" IN (4156052)
            AND merge_request_id = merge_requests.id))
  AND "milestones"."title" = '13.1'
  AND "labels"."title" = 'database'
  AND "merge_request_metrics"."merged_at" >= "merge_requests"."created_at"

Plan

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

#217973 (closed)

Edited by Markus Koller

Merge request reports