Add reviewer_id and reviewer_username filters to MergeRequest
What does this MR do?
This MR adds ability to filter MergeRequest by reviewer_id
and reviewer_username
the same as assignee_id
and assignee_username
does except the negated multiple assignees as that doesn't seem to be in use as far as I can tell.
frontend work is required to make it accessible to the users.
We originally attempted to merge Assignee and Reviewer in !45738 (merged) and !43497 (merged), but we encountered performance issues.
This is compromised option to get Reviewer feature out the door and we'll be iterating on it.
Related to #237922 (closed)
Database
@dskim_gitlab AND Reviewer = @dskim_gitlab
Filter: Assignee =EXPLAIN
SELECT
merge_requests.*,
(
SELECT
MIN("label_priorities"."priority")
FROM
"labels"
LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id"
INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id"
WHERE (label_priorities.project_id = merge_requests.target_project_id)
AND (label_links.target_id = merge_requests.id)
AND "label_links"."target_type" = 'MergeRequest') AS highest_priority,
MIN(milestones.due_date)
FROM
"merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE (EXISTS (
SELECT
1
FROM
"project_authorizations"
WHERE
"project_authorizations"."user_id" = 4901936
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"."state_id" IN (1))
AND (EXISTS (
SELECT
TRUE
FROM
"merge_request_assignees"
WHERE
"merge_request_assignees"."user_id" IN (4901936)
AND merge_request_id = merge_requests.id))
AND "projects"."archived" = FALSE
AND EXISTS (
SELECT
TRUE
FROM
"merge_request_reviewers"
WHERE
"merge_request_reviewers"."user_id" = 4901936
AND merge_request_id = merge_requests.id)
GROUP BY
"merge_requests"."id"
ORDER BY
MIN(milestones.due_date) ASC NULLS LAST,
highest_priority ASC NULLS LAST,
"merge_requests"."id" DESC
LIMIT 20
Explain: https://explain.depesz.com/s/HfS6
@dskim_gitlab AND Reviewer != @dskim_gitlab
Filter: Assignee =EXPLAIN
SELECT
merge_requests.*,
(
SELECT
MIN("label_priorities"."priority")
FROM
"labels"
LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id"
INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id"
WHERE (label_priorities.project_id = merge_requests.target_project_id)
AND (label_links.target_id = merge_requests.id)
AND "label_links"."target_type" = 'MergeRequest') AS highest_priority,
MIN(milestones.due_date)
FROM
"merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE (EXISTS (
SELECT
1
FROM
"project_authorizations"
WHERE
"project_authorizations"."user_id" = 4901936
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"."state_id" IN (1))
AND (EXISTS (
SELECT
TRUE
FROM
"merge_request_assignees"
WHERE
"merge_request_assignees"."user_id" IN (4901936)
AND merge_request_id = merge_requests.id))
AND "projects"."archived" = false
AND NOT (EXISTS (
SELECT
TRUE
FROM
"merge_request_reviewers"
WHERE
"merge_request_reviewers"."user_id" = 4901936
AND merge_request_id = merge_requests.id))
GROUP BY
"merge_requests"."id"
ORDER BY
MIN(milestones.due_date) ASC NULLS LAST,
highest_priority ASC NULLS LAST,
"merge_requests"."id" DESC
LIMIT 20
Explain: https://explain.depesz.com/s/K1FL
@dskim_gitlab AND Reviewer = Any
Filter: Assignee =EXPLAIN
SELECT
merge_requests.*,
(
SELECT
MIN("label_priorities"."priority")
FROM
"labels"
LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id"
INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id"
WHERE (label_priorities.project_id = merge_requests.target_project_id)
AND (label_links.target_id = merge_requests.id)
AND "label_links"."target_type" = 'MergeRequest') AS highest_priority,
MIN(milestones.due_date)
FROM
"merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE (EXISTS (
SELECT
1
FROM
"project_authorizations"
WHERE
"project_authorizations"."user_id" = 4901936
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"."state_id" IN (1))
AND (EXISTS (
SELECT
TRUE
FROM
"merge_request_assignees"
WHERE
"merge_request_assignees"."user_id" IN (4901936)
AND merge_request_id = merge_requests.id))
AND "projects"."archived" = false
AND EXISTS (
SELECT
TRUE
FROM
"merge_request_reviewers"
WHERE
merge_request_id = merge_requests.id)
GROUP BY
"merge_requests"."id"
ORDER BY
MIN(milestones.due_date) ASC NULLS LAST,
highest_priority ASC NULLS LAST,
"merge_requests"."id" DESC
LIMIT 20
Explain: https://explain.depesz.com/s/BAQ8
@dskim_gitlab AND Reviewer = None
Filter: Assignee =EXPLAIN
SELECT
merge_requests.*,
(
SELECT
MIN("label_priorities"."priority")
FROM
"labels"
LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id"
INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id"
WHERE (label_priorities.project_id = merge_requests.target_project_id)
AND (label_links.target_id = merge_requests.id)
AND "label_links"."target_type" = 'MergeRequest') AS highest_priority,
MIN(milestones.due_date)
FROM
"merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE (EXISTS (
SELECT
1
FROM
"project_authorizations"
WHERE
"project_authorizations"."user_id" = 4901936
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"."state_id" IN (1))
AND (EXISTS (
SELECT
TRUE
FROM
"merge_request_assignees"
WHERE
"merge_request_assignees"."user_id" IN (4901936)
AND merge_request_id = merge_requests.id))
AND "projects"."archived" = false
AND NOT (EXISTS (
SELECT
TRUE
FROM
"merge_request_reviewers"
WHERE
merge_request_id = merge_requests.id))
GROUP BY
"merge_requests"."id"
ORDER BY
MIN(milestones.due_date) ASC NULLS LAST,
highest_priority ASC NULLS LAST,
"merge_requests"."id" DESC
LIMIT 20
Explain: https://explain.depesz.com/s/qc3Z
@dskim_gitlab AND Reviewer = @dskim_gitlab AND Approved-By = @dskim_gitlab
Filter: Assignee =EXPLAIN
SELECT
merge_requests.*,
(
SELECT
MIN("label_priorities"."priority")
FROM
"labels"
LEFT OUTER JOIN "label_priorities" ON "labels"."id" = "label_priorities"."label_id"
INNER JOIN "label_links" ON "label_links"."label_id" = "labels"."id"
WHERE (label_priorities.project_id = merge_requests.target_project_id)
AND (label_links.target_id = merge_requests.id)
AND "label_links"."target_type" = 'MergeRequest') AS highest_priority,
MIN(milestones.due_date)
FROM
"merge_requests"
INNER JOIN "projects" ON "projects"."id" = "merge_requests"."target_project_id"
INNER JOIN "approvals" ON "approvals"."merge_request_id" = "merge_requests"."id"
INNER JOIN "users" ON "users"."id" = "approvals"."user_id"
LEFT JOIN project_features ON projects.id = project_features.project_id
LEFT OUTER JOIN milestones ON merge_requests.milestone_id = milestones.id
WHERE (EXISTS (
SELECT
1
FROM
"project_authorizations"
WHERE
"project_authorizations"."user_id" = 4901936
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"."state_id" IN (1))
AND (EXISTS (
SELECT
TRUE
FROM
"merge_request_assignees"
WHERE
"merge_request_assignees"."user_id" IN (4901936)
AND merge_request_id = merge_requests.id))
AND "projects"."archived" = FALSE
AND "users"."username" = 'dskim_gitlab'
AND EXISTS (
SELECT
TRUE
FROM
"merge_request_reviewers"
WHERE
"merge_request_reviewers"."user_id" = 4901936
AND merge_request_id = merge_requests.id)
GROUP BY
"merge_requests"."id",
"merge_requests"."id"
HAVING (COUNT(users.id) = 1)
ORDER BY
MIN(milestones.due_date) ASC NULLS LAST,
highest_priority ASC NULLS LAST,
"merge_requests"."id" DESC
LIMIT 20
Explain: https://explain.depesz.com/s/ykcQ
Screenshots (strongly suggested)
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation (if required) -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Availability and Testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers -
Informed Infrastructure department of a default or new setting change, if applicable per definition of done
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