Skip to content

Fix duplicit epics when filtering by milestone

Jan Provaznik requested to merge fix_duplicit_epics_on_roadmap into master

What does this MR do?

When epics are filtered by milestone, this is done through join issues table. If an epic has multiple issues from the same milestone, then there are duplicit Epic instances returned - we should use distinct list in this case.

DB query plan:

Query plan for query which uses `DISTINCT`: https://explain.depesz.com/s/EnAr
SELECT DISTINCT "epics".*
FROM "epics"
INNER JOIN "epic_issues" ON "epic_issues"."epic_id" = "epics"."id"
INNER JOIN "issues" ON "issues"."id" = "epic_issues"."issue_id"
WHERE "epics"."group_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 (start_date IS NOT NULL
       OR end_date IS NOT NULL)
  AND (start_date IS NULL
       OR start_date <= '2021-09-30')
  AND (end_date IS NULL
       OR end_date >= '2020-09-01')
  AND "epics"."state_id" = 1
  AND (EXISTS
         (SELECT "label_links".*
          FROM "label_links"
          WHERE "label_links"."target_type" = 'Epic'
            AND "label_links"."target_id" = "epics"."id"
            AND "label_links"."label_id" = 3103451
          LIMIT 1))
  AND "issues"."milestone_id" IN
    (SELECT "milestones"."id"
     FROM (
             (SELECT "milestones".*
              FROM "milestones"
              WHERE "milestones"."project_id" IN
                  (SELECT "projects"."id"
                   FROM "projects"
                   LEFT JOIN project_features ON projects.id = project_features.project_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 ("project_features"."issues_access_level" IS NULL
                          OR "project_features"."issues_access_level" IN (20,
                                                                          30)
                          OR ("project_features"."issues_access_level" = 10
                              AND EXISTS
                                (SELECT 1
                                 FROM "project_authorizations"
                                 WHERE "project_authorizations"."user_id" = 1642716
                                   AND (project_authorizations.project_id = projects.id)
                                   AND (project_authorizations.access_level >= 10))))))
           UNION ALL
             (SELECT "milestones".*
              FROM "milestones"
              WHERE "milestones"."group_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"))) milestones
     WHERE "milestones"."title" = '13.8')
ORDER BY end_date ASC NULLS LAST,
                      id DESC,
                      "epics"."id" DESC
LIMIT 2000;
Screenshots (strongly suggested)

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

Related to #294428 (closed)

Edited by Jan Provaznik

Merge request reports

Loading