Allow filtering Duo workflows by status group and goal/title
What does this MR do and why?
Allow filtering Duo workflows by their status_group
or through a fuzzy search against their goal
or definition
(aka title
).
This is needed so users are able to choose how they want to see in the sessions page.
References
Related to #571931
GraphQL details
GraphQL Query
query getAgentFlows(
$projectPath: ID!,
$sort: DuoWorkflowsWorkflowSort,
$statusGroup: DuoWorkflowStatusGroup,
$type: String
) {
project(fullPath: $projectPath) {
id
duoWorkflowWorkflows(
projectPath: $projectPath
sort: $sort
statusGroup: $statusGroup
type: $type
) {
pageInfo {
startCursor
endCursor
hasNextPage
hasPreviousPage
}
edges {
node {
id
goal
workflowDefinition
status
statusName
statusGroup
}
}
}
}
}
Variables
{
"projectPath": "gitlab-duo/test",
"sort": "STATUS_DESC",
"statusGroup": null,
"type": "code_review/experimental"
}
SQL query plans
title
or goal
When fuzzy searching by Raw SQL
SELECT
"duo_workflows_workflows".*
FROM "duo_workflows_workflows"
WHERE
"duo_workflows_workflows"."project_id" = 278964
AND "duo_workflows_workflows"."workflow_definition" != 'chat'
AND "duo_workflows_workflows"."environment" = 2
AND (
"duo_workflows_workflows"."workflow_definition" ILIKE '%code%'
AND "duo_workflows_workflows"."workflow_definition" ILIKE '%review%' OR "duo_workflows_workflows"."goal" ILIKE '%code%'
AND "duo_workflows_workflows"."goal" ILIKE '%review%'
)
ORDER BY
"duo_workflows_workflows"."created_at" DESC
SQL plan without new index
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44288/commands/135743
Sort (cost=9441.74..9441.76 rows=8 width=338) (actual time=2466.257..2466.261 rows=19 loops=1)
Sort Key: duo_workflows_workflows.created_at DESC
Sort Method: quicksort Memory: 28kB
Buffers: shared hit=7 read=5765 dirtied=648
WAL: records=699 fpi=648 bytes=5146939
I/O Timings: read=2398.086 write=0.000
-> Index Scan using index_duo_workflows_workflows_on_project_id on public.duo_workflows_workflows (cost=0.29..9441.62 rows=8 width=338) (actual time=1063.636..2466.153 rows=19 loops=1)
Index Cond: (duo_workflows_workflows.project_id = 278964)
Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.environment = 2) AND (((duo_workflows_workflows.workflow_definition ~~* '%code%'::text) AND (duo_workflows_workflows.workflow_definition ~~* '%review%'::text)) OR ((duo_workflows_workflows.goal ~~* '%code%'::text) AND (duo_workflows_workflows.goal ~~* '%review%'::text))))
Rows Removed by Filter: 21350
Buffers: shared hit=4 read=5765 dirtied=648
WAL: records=699 fpi=648 bytes=5146939
I/O Timings: read=2398.086 write=0.000
Settings: effective_cache_size = '472585MB', jit = 'off', random_page_cost = '1.5', seq_page_cost = '4', work_mem = '100MB'
SQL plan with new index
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44420/commands/136146
Index Scan using index_duo_workflows_workflows_project_environment_created_at on public.duo_workflows_workflows (cost=0.42..7753.65 rows=10 width=338) (actual time=0.294..20.398 rows=269 loops=1)
Index Cond: ((duo_workflows_workflows.project_id = 278964) AND (duo_workflows_workflows.environment = 2))
Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (((duo_workflows_workflows.workflow_definition ~~* '%code%'::text) AND (duo_workflows_workflows.workflow_definition ~~* '%review%'::text)) OR ((duo_workflows_workflows.goal ~~* '%code%'::text) AND (duo_workflows_workflows.goal ~~* '%review%'::text))))
Rows Removed by Filter: 8438
Buffers: shared hit=8599 read=46 dirtied=489
WAL: records=526 fpi=489 bytes=3877346
I/O Timings: read=1.322 write=0.000
Settings: random_page_cost = '1.5', seq_page_cost = '4', effective_cache_size = '472585MB', jit = 'off', work_mem = '100MB'
status_group
When filtering by Raw SQL
SELECT
"duo_workflows_workflows".*
FROM "duo_workflows_workflows"
WHERE
"duo_workflows_workflows"."project_id" = 278964
AND "duo_workflows_workflows"."workflow_definition" != 'chat'
AND "duo_workflows_workflows"."environment" = 2
AND "duo_workflows_workflows"."status" = 5
ORDER BY
"duo_workflows_workflows"."created_at" DESC
SQL plan
https://postgres.ai/console/gitlab/gitlab-production-main/sessions/44288/commands/135745
Sort (cost=1257.65..1257.74 rows=39 width=338) (actual time=21.865..21.869 rows=0 loops=1)
Sort Key: duo_workflows_workflows.created_at DESC
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=470 read=29
I/O Timings: read=17.774 write=0.000
-> Bitmap Heap Scan on public.duo_workflows_workflows (cost=303.71..1256.62 rows=39 width=338) (actual time=21.847..21.851 rows=0 loops=1)
Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.environment = 2))
Rows Removed by Filter: 484
Buffers: shared hit=467 read=29
I/O Timings: read=17.774 write=0.000
-> BitmapAnd (cost=303.71..303.71 rows=450 width=0) (actual time=20.151..20.154 rows=0 loops=1)
Buffers: shared hit=34 read=29
I/O Timings: read=17.774 write=0.000
-> Bitmap Index Scan using idx_workflows_status_updated_at_id (cost=0.00..90.71 rows=3039 width=0) (actual time=18.479..18.479 rows=3045 loops=1)
Index Cond: (duo_workflows_workflows.status = 5)
Buffers: shared hit=3 read=29
I/O Timings: read=17.774 write=0.000
-> Bitmap Index Scan using index_duo_workflows_workflows_on_project_id (cost=0.00..212.72 rows=21324 width=0) (actual time=1.498..1.498 rows=21369 loops=1)
Index Cond: (duo_workflows_workflows.project_id = 278964)
Buffers: shared hit=31
I/O Timings: read=0.000 write=0.000
Settings: jit = 'off', random_page_cost = '1.5', seq_page_cost = '4', work_mem = '100MB', effective_cache_size = '472585MB'
SQL plan with new index
https://console.postgres.ai/gitlab/gitlab-production-main/sessions/44420/commands/136148
Sort (cost=29.37..29.38 rows=1 width=338) (actual time=27.859..27.861 rows=0 loops=1)
Sort Key: duo_workflows_workflows.created_at DESC
Sort Method: quicksort Memory: 25kB
Buffers: shared hit=286 read=12 dirtied=9
WAL: records=15 fpi=9 bytes=43767
I/O Timings: read=26.094 write=0.000
-> Index Scan using idx_workflows_status_updated_at_id on public.duo_workflows_workflows (cost=0.42..29.36 rows=1 width=338) (actual time=27.846..27.846 rows=0 loops=1)
Index Cond: (duo_workflows_workflows.status = 1)
Filter: ((duo_workflows_workflows.workflow_definition <> 'chat'::text) AND (duo_workflows_workflows.project_id = 278964) AND (duo_workflows_workflows.environment = 2))
Rows Removed by Filter: 26
Buffers: shared hit=283 read=12 dirtied=9
WAL: records=15 fpi=9 bytes=43767
I/O Timings: read=26.094 write=0.000
Settings: effective_cache_size = '472585MB', jit = 'off', work_mem = '100MB', random_page_cost = '1.5', seq_page_cost = '4'
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.
Edited by Wanderson Policarpo