Update started / upcoming logic for milestone filters
What does this MR do and why?
This change updates the logic for the milestones filters "started" and "upcoming", according to the changes outlined in this table. The summary of these changes are:
- Upcoming
- Use the
start_dateinstead of thedue_dateto determine if a milestone is upcoming (and apply the reverse logic to the inverse scope) - Returns all upcoming milestones, not just the next for a given group / project
- Use the
- Started
- Use an open-ended overlap check with the current date, and exclude milestones which do not have at least one of
start_dateanddue_date, to avoid cluttering the view
- Use an open-ended overlap check with the current date, and exclude milestones which do not have at least one of
These changes are behind the new_milestone_filtering_logic feature flag. Note that this flag will only apply the new filter logic for views within a single group / project. Cross-group queries, such as the dashboards page will continue to use the existing filtering logic regardless of the state of the flag, as the feature flag is scoped to a specific namespace. The feature flag rollout issue is available here.
References
Screenshots or screen recordings
| Filter | Before | After |
|---|---|---|
|
|
Shows items in the current milestone (first milestone with |
Shows items in upcoming milestones (milestones with a |
|
|
Shows items whose milestone start date is on or before the current date. Does not include work items whose associated milestone does not have a start date |
Shows items whose milestone start date is |
How to set up and validate locally
Prerequisites
- Enable the
new_milestone_filtering_logicfeature flag (i.e. by visiting http://localhost:3000/rails/features with the GDK running)
Started filter
- Create an issue and assign it to a milestone with a
nullstart date, and a due date in the future - Create an issue and assign it to a milestone with a start date in the past, and a
nulldue date - Create an issue and assign it to a milestone with a
nullstart date and anulldue date - On the Group > Issues page, Project > Issues page, or an Issue board, filter for issues by
Milestone is %Started - Observe that only the issues with a start or due date are returned
Upcoming filter
- Create an issue and assign it to a milestone with a start date in the past
- Create an issue and assign it to a milestone with a start date in the future
- On the Group > Issues page, Project > Issues page, or an Issue board, filter for issues by
Milestone is %Upcoming - Observe that only the issue with a milestone starting in future is returned
Not upcoming filter
- Create an issue and assign it to a milestone with a start date in the past
- Create an issue and assign it to a milestone with a start date in the future
- On the Group > Issues page, Project > Issues page, or an Issue board, filter for issues by
Milestone != %Upcoming - Observe that only the issue with a milestone starting in the past is returned
- Note that the logic for the
!= %Startedfilter has not changed
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.
Database
Raw SQL before changes
Boards Query Raw SQL Before (With Upcoming Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "issues"."project_id" = 278964
AND "issues"."state_id" = 1
AND "issues"."milestone_id" IN (SELECT DISTINCT ON (project_id, group_id) id
FROM ((SELECT "milestones".*
FROM "milestones"
WHERE "milestones"."project_id" = 278964)
UNION ALL
(SELECT "milestones".*
FROM "milestones"
WHERE "milestones"."group_id" IN (SELECT "namespaces"."id"
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND "namespaces"."id" = 9970))) milestones
WHERE ("milestones"."state" IN ('active'))
AND (milestones.due_date > CURRENT_DATE)
ORDER BY "milestones"."project_id" ASC, "milestones"."group_id" ASC,
"milestones"."due_date" ASC)
AND "issues"."work_item_type_id" IN (1, 2, 5)
ORDER BY "issues"."relative_position" ASC NULLS LAST, "issues"."id" ASC
LIMIT 11
Boards Query Raw SQL Before (With Started Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "issues"."project_id" = 278964
AND "issues"."state_id" = 2
AND ("milestones"."state" IN ('active'))
AND (milestones.start_date <= CURRENT_DATE)
AND "issues"."work_item_type_id" IN (1, 2, 5)
ORDER BY "issues"."closed_at" DESC NULLS LAST, "issues"."id" DESC
LIMIT 11
Group > Issues Query Raw SQL Before (With Upcoming Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
INNER JOIN "projects" ON "projects"."id" = "issues"."project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "projects"."namespace_id" IN (SELECT "namespaces"."id"
FROM UNNEST(COALESCE((SELECT ids
FROM (SELECT "namespace_descendants"."self_and_descendant_group_ids" AS ids
FROM "namespace_descendants"
WHERE "namespace_descendants"."outdated_at" IS NULL
AND "namespace_descendants"."namespace_id" = 9970) cached_query),
(SELECT ids
FROM (SELECT ARRAY_AGG("namespaces"."id") AS ids
FROM (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}'))) namespaces) consistent_query))) AS namespaces(id))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 25345642
AND (project_authorizations.project_id = projects.id)
AND (project_authorizations.access_level >= 10)) OR projects.visibility_level IN (10, 20))
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" = 25345642
AND (project_authorizations.project_id = project_features.project_id)
AND (project_authorizations.access_level >= 10))))
AND "issues"."state_id" = 1
AND ("issues"."project_id" IS NULL OR "projects"."archived" = FALSE)
AND "issues"."milestone_id" IN (SELECT DISTINCT ON (project_id, group_id) 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
(SELECT "namespaces"."id"
FROM UNNEST(COALESCE((SELECT ids
FROM (SELECT "namespace_descendants"."self_and_descendant_group_ids" AS ids
FROM "namespace_descendants"
WHERE "namespace_descendants"."outdated_at" IS NULL
AND "namespace_descendants"."namespace_id" = 9970) cached_query),
(SELECT ids
FROM (SELECT ARRAY_AGG("namespaces"."id") AS ids
FROM (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}'))) namespaces) consistent_query))) AS namespaces(id))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 25345642
AND (project_authorizations.project_id = projects.id)
AND (project_authorizations.access_level >= 10)) OR
projects.visibility_level IN (10,
20))
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" = 25345642
AND (project_authorizations.project_id = project_features.project_id)
AND (project_authorizations.access_level >= 10))))))
UNION ALL
(SELECT "milestones".*
FROM "milestones"
WHERE "milestones"."group_id" = 9970)) milestones
WHERE ("milestones"."state" IN ('active'))
AND (milestones.due_date > CURRENT_DATE)
ORDER BY "milestones"."project_id" ASC, "milestones"."group_id" ASC,
"milestones"."due_date" ASC)
AND "issues"."work_item_type_id" IN (1, 2, 5, 7, 6, 3)
ORDER BY "issues"."created_at" ASC, "issues"."id" DESC
LIMIT 21
Group > Issues Query Raw SQL Before (With Started Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
INNER JOIN "projects" ON "projects"."id" = "issues"."project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "projects"."namespace_id" IN (SELECT "namespaces"."id"
FROM UNNEST(COALESCE((SELECT ids
FROM (SELECT "namespace_descendants"."self_and_descendant_group_ids" AS ids
FROM "namespace_descendants"
WHERE "namespace_descendants"."outdated_at" IS NULL
AND "namespace_descendants"."namespace_id" = 9970) cached_query),
(SELECT ids
FROM (SELECT ARRAY_AGG("namespaces"."id") AS ids
FROM (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}'))) namespaces) consistent_query))) AS namespaces(id))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 25345642
AND (project_authorizations.project_id = projects.id)
AND (project_authorizations.access_level >= 10)) OR projects.visibility_level IN (10, 20))
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" = 25345642
AND (project_authorizations.project_id = project_features.project_id)
AND (project_authorizations.access_level >= 10))))
AND "issues"."state_id" = 1
AND ("issues"."project_id" IS NULL OR "projects"."archived" = FALSE)
AND ("milestones"."state" IN ('active'))
AND (milestones.start_date <= CURRENT_DATE)
AND "issues"."work_item_type_id" IN (1, 2, 5, 7, 6, 3)
ORDER BY "issues"."created_at" ASC, "issues"."id" DESC
LIMIT 21
Raw SQL after changes
Boards Query Raw SQL After (With Upcoming Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."due_date",
"issues"."moved_to_id",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "issues"."project_id" = 278964
AND "issues"."state_id" = 1
AND "issues"."milestone_id" IN (SELECT "milestones"."id"
FROM ((SELECT "milestones".* FROM "milestones" WHERE "milestones"."project_id" = 278964)
UNION ALL
(SELECT "milestones".*
FROM "milestones"
WHERE "milestones"."group_id" IN (SELECT "namespaces"."id"
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND "namespaces"."id" = 9970))) milestones
WHERE ("milestones"."state" IN ('active'))
AND (milestones.start_date > CURRENT_DATE)
ORDER BY "milestones"."project_id" ASC, "milestones"."group_id" ASC,
"milestones"."start_date" ASC)
AND "issues"."work_item_type_id" IN (1, 2, 5)
ORDER BY "issues"."relative_position" ASC NULLS LAST, "issues"."id" ASC
LIMIT 11
Boards Query Raw SQL After (With Started Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "issues"."project_id" = 278964
AND "issues"."state_id" = 2
AND ("milestones"."state" IN ('active'))
AND ((milestones.start_date <= CURRENT_DATE OR milestones.start_date IS NULL) AND
(milestones.due_date IS NULL OR milestones.due_date > CURRENT_DATE) AND
NOT (milestones.start_date IS NULL AND milestones.due_date IS NULL))
AND "issues"."work_item_type_id" IN (1, 2, 5)
ORDER BY "issues"."closed_at" DESC NULLS LAST, "issues"."id" DESC
LIMIT 11
Group > Issues Query Raw SQL After (With Upcoming Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."due_date",
"issues"."moved_to_id",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
INNER JOIN "projects" ON "projects"."id" = "issues"."project_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 (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}')))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 1
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"."state_id" = 1
AND ("issues"."project_id" IS NULL OR "projects"."archived" = FALSE)
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
(SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}')))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 1
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)))
UNION ALL
(SELECT "milestones".*
FROM "milestones"
WHERE "milestones"."group_id" = 9970)) milestones
WHERE ("milestones"."state" IN ('active'))
AND (milestones.start_date > CURRENT_DATE)
ORDER BY "milestones"."project_id" ASC, "milestones"."group_id" ASC,
"milestones"."start_date" ASC)
AND "issues"."work_item_type_id" IN (1, 2, 5, 7, 6, 3)
ORDER BY "issues"."created_at" DESC, "issues"."id" DESC
LIMIT 51
Group > Issues Query Raw SQL After (With Started Filter)
SELECT "issues"."id",
"issues"."title",
"issues"."author_id",
"issues"."project_id",
"issues"."created_at",
"issues"."updated_at",
"issues"."description",
"issues"."milestone_id",
"issues"."iid",
"issues"."updated_by_id",
"issues"."weight",
"issues"."confidential",
"issues"."moved_to_id",
"issues"."due_date",
"issues"."lock_version",
"issues"."title_html",
"issues"."description_html",
"issues"."time_estimate",
"issues"."relative_position",
"issues"."service_desk_reply_to",
"issues"."cached_markdown_version",
"issues"."last_edited_at",
"issues"."last_edited_by_id",
"issues"."discussion_locked",
"issues"."closed_at",
"issues"."closed_by_id",
"issues"."state_id",
"issues"."duplicated_to_id",
"issues"."promoted_to_epic_id",
"issues"."health_status",
"issues"."external_key",
"issues"."sprint_id",
"issues"."blocking_issues_count",
"issues"."upvotes_count",
"issues"."work_item_type_id",
"issues"."namespace_id",
"issues"."start_date",
"issues"."imported_from"
FROM "issues"
INNER JOIN "projects" ON "projects"."id" = "issues"."project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON issues.milestone_id = milestones.id
WHERE (NOT EXISTS (SELECT 1 FROM "banned_users" WHERE (issues.author_id = banned_users.user_id)))
AND "projects"."namespace_id" IN (SELECT "namespaces"."id"
FROM UNNEST(COALESCE((SELECT ids
FROM (SELECT "namespace_descendants"."self_and_descendant_group_ids" AS ids
FROM "namespace_descendants"
WHERE "namespace_descendants"."outdated_at" IS NULL
AND "namespace_descendants"."namespace_id" = 9970) cached_query),
(SELECT ids
FROM (SELECT ARRAY_AGG("namespaces"."id") AS ids
FROM (SELECT namespaces.traversal_ids[array_length(namespaces.traversal_ids, 1)] AS id
FROM "namespaces"
WHERE "namespaces"."type" = 'Group'
AND (traversal_ids @> ('{9970}'))) namespaces) consistent_query))) AS namespaces(id))
AND (EXISTS (SELECT 1
FROM "project_authorizations"
WHERE "project_authorizations"."user_id" = 25345642
AND (project_authorizations.project_id = projects.id)
AND (project_authorizations.access_level >= 10)) OR projects.visibility_level IN (10, 20))
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" = 25345642
AND (project_authorizations.project_id = project_features.project_id)
AND (project_authorizations.access_level >= 10))))
AND "issues"."state_id" = 1
AND ("issues"."project_id" IS NULL OR "projects"."archived" = FALSE)
AND ("milestones"."state" IN ('active'))
AND ((milestones.start_date <= CURRENT_DATE OR milestones.start_date IS NULL) AND
(milestones.due_date IS NULL OR milestones.due_date > CURRENT_DATE) AND
NOT (milestones.start_date IS NULL AND milestones.due_date IS NULL))
AND "issues"."work_item_type_id" IN (1, 2, 5, 7, 6, 3)
ORDER BY "issues"."created_at" ASC, "issues"."id" DESC
LIMIT 21
Query Plans
Before:
| Query Type | Query Plan |
|---|---|
Board with Milestone = %Upcoming (link) |
pg.ai |
Board with Milestone = %Started
|
pg.ai |
Group (9970) > Issues page with Milestone = %Upcoming
|
pg.ai |
Group (9970) > Issues page with Milestone = %Started
|
pg.ai |
Project (278964) > Issues page with Milestone = %Started
|
pg.ai |
After:
| Query Type | Query Plan |
|---|---|
Board with Milestone = %Upcoming
|
pg.ai |
Board with Milestone = %Started
|
pg.ai |
Group (9970) > Issues page with Milestone = %Upcoming
|
pg.ai |
Group (9970) > Issues page with Milestone = %Started
|
pg.ai |
Project (278964) > Issues page with Milestone = %Started
|
pg.ai |
Related to #429728 (closed)



