Skip to content

Improve timelog graphQL functionality

Lee Tickett requested to merge remove-group-timelog-mandatory-arguments into master

What does this MR do?

As graphQL enforces pagination (with a maximum of 100 records, we do not need to enforce the use of start/end arguments).

This is a pre-cursor to exposing timelogs against projects. See the discussion that led to this mr: !59588 (comment 575019111)

Similarly, anyone with access to an issuable can view timelogs through the web UI, so it seems odd that we've introduced a different permission for the graphQL endpoint. This MR removes that additional check.

Execution Plans etc

query {
  group(fullPath: "twitter") {
    timelogs(startDate: "2021-04-01" endDate: "2021-05-30") { nodes { 
        timeSpent
    } }
  }
}

Before

SELECT "timelogs".* FROM "timelogs" INNER JOIN "projects" ON "projects"."id" = "timelogs"."project_id" WHERE (spent_at BETWEEN '2021-03-31 23:00:00' AND '2021-05-30 22:59:59.999999') AND "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 id FROM "base_and_descendants" AS "namespaces") ORDER BY "timelogs"."id" DESC LIMIT 100
 Limit  (cost=4174.55..4174.61 rows=24 width=52) (actual time=10.291..10.298 rows=11 loops=1)
   Buffers: shared hit=7397
   I/O Timings: read=0.000 write=0.000
   ->  Sort  (cost=4174.55..4174.61 rows=24 width=52) (actual time=10.289..10.295 rows=11 loops=1)
         Sort Key: timelogs.id DESC
         Sort Method: quicksort  Memory: 26kB
         Buffers: shared hit=7397
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=1591.61..4174.00 rows=24 width=52) (actual time=7.571..10.249 rows=11 loops=1)
               Buffers: shared hit=7394
               I/O Timings: read=0.000 write=0.000
               ->  Nested Loop  (cost=1591.18..2155.36 rows=3790 width=4) (actual time=2.773..5.008 rows=1379 loops=1)
                     Buffers: shared hit=3249
                     I/O Timings: read=0.000 write=0.000
                     ->  HashAggregate  (cost=1590.74..1592.65 rows=191 width=4) (actual time=2.748..2.823 rows=236 loops=1)
                           Group Key: namespaces.id
                           Buffers: shared hit=1182
                           I/O Timings: read=0.000 write=0.000
                           ->  CTE Scan on base_and_descendants namespaces  (cost=1584.53..1588.35 rows=191 width=4) (actual time=0.031..2.630 rows=236 loops=1)
                                 Buffers: shared hit=1182
                                 I/O Timings: read=0.000 write=0.000
                                 CTE base_and_descendants
                                   ->  Recursive Union  (cost=0.43..1584.53 rows=191 width=349) (actual time=0.025..2.256 rows=236 loops=1)
                                         Buffers: shared hit=1182
                                         I/O Timings: read=0.000 write=0.000
                                         ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=349) (actual time=0.017..0.018 rows=1 loops=1)
                                               Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 9970))
                                               Buffers: shared hit=4
                                               I/O Timings: read=0.000 write=0.000
                                         ->  Nested Loop  (cost=0.56..157.73 rows=19 width=349) (actual time=0.019..0.265 rows=39 loops=6)
                                               Buffers: shared hit=1178
                                               I/O Timings: read=0.000 write=0.000
                                               ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.000..0.004 rows=39 loops=6)
                                                     I/O Timings: read=0.000 write=0.000
                                               ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.73 rows=2 width=349) (actual time=0.004..0.006 rows=1 loops=236)
                                                     Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                                     Filter: ((namespaces_2.type)::text = 'Group'::text)
                                                     Rows Removed by Filter: 0
                                                     Buffers: shared hit=1178
                                                     I/O Timings: read=0.000 write=0.000
                     ->  Index Only Scan using index_projects_on_namespace_id_and_id on public.projects  (cost=0.44..2.75 rows=20 width=8) (actual time=0.005..0.008 rows=6 loops=236)
                           Index Cond: (projects.namespace_id = namespaces.id)
                           Heap Fetches: 97
                           Buffers: shared hit=2067
                           I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_timelogs_on_project_id_and_spent_at on public.timelogs  (cost=0.43..0.50 rows=3 width=52) (actual time=0.004..0.004 rows=0 loops=1379)
                     Index Cond: ((timelogs.project_id = projects.id) AND (timelogs.spent_at >= '2021-03-31 23:00:00+00'::timestamp with time zone) AND (timelogs.spent_at <= '2021-05-30 22:59:59.999999+00'::timestamp with time zone))
                     Buffers: shared hit=4145
                     I/O Timings: read=0.000 write=0.000

Time: 12.585 ms
  - planning: 1.976 ms
  - execution: 10.609 ms
    - I/O read: 0.000 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 7397 (~57.80 MiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/4242/commands/14787

After

SELECT "timelogs".* FROM "timelogs" INNER JOIN "projects" ON "projects"."id" = "timelogs"."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 id FROM "base_and_descendants" AS "namespaces") AND (spent_at BETWEEN '2021-03-31 23:00:00' AND '2021-05-30 22:59:59.999999') ORDER BY "timelogs"."id" DESC LIMIT 100
Limit  (cost=4174.55..4174.61 rows=24 width=52) (actual time=9.010..9.017 rows=11 loops=1)
   Buffers: shared hit=7397
   I/O Timings: read=0.000 write=0.000
   ->  Sort  (cost=4174.55..4174.61 rows=24 width=52) (actual time=9.009..9.013 rows=11 loops=1)
         Sort Key: timelogs.id DESC
         Sort Method: quicksort  Memory: 26kB
         Buffers: shared hit=7397
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=1591.61..4174.00 rows=24 width=52) (actual time=6.498..8.966 rows=11 loops=1)
               Buffers: shared hit=7394
               I/O Timings: read=0.000 write=0.000
               ->  Nested Loop  (cost=1591.18..2155.36 rows=3790 width=4) (actual time=2.616..4.516 rows=1379 loops=1)
                     Buffers: shared hit=3249
                     I/O Timings: read=0.000 write=0.000
                     ->  HashAggregate  (cost=1590.74..1592.65 rows=191 width=4) (actual time=2.593..2.648 rows=236 loops=1)
                           Group Key: namespaces.id
                           Buffers: shared hit=1182
                           I/O Timings: read=0.000 write=0.000
                           ->  CTE Scan on base_and_descendants namespaces  (cost=1584.53..1588.35 rows=191 width=4) (actual time=0.034..2.488 rows=236 loops=1)
                                 Buffers: shared hit=1182
                                 I/O Timings: read=0.000 write=0.000
                                 CTE base_and_descendants
                                   ->  Recursive Union  (cost=0.43..1584.53 rows=191 width=349) (actual time=0.028..2.106 rows=236 loops=1)
                                         Buffers: shared hit=1182
                                         I/O Timings: read=0.000 write=0.000
                                         ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=349) (actual time=0.020..0.021 rows=1 loops=1)
                                               Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 9970))
                                               Buffers: shared hit=4
                                               I/O Timings: read=0.000 write=0.000
                                         ->  Nested Loop  (cost=0.56..157.73 rows=19 width=349) (actual time=0.017..0.249 rows=39 loops=6)
                                               Buffers: shared hit=1178
                                               I/O Timings: read=0.000 write=0.000
                                               ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.000..0.004 rows=39 loops=6)
                                                     I/O Timings: read=0.000 write=0.000
                                               ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.73 rows=2 width=349) (actual time=0.004..0.006 rows=1 loops=236)
                                                     Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                                     Filter: ((namespaces_2.type)::text = 'Group'::text)
                                                     Rows Removed by Filter: 0
                                                     Buffers: shared hit=1178
                                                     I/O Timings: read=0.000 write=0.000
                     ->  Index Only Scan using index_projects_on_namespace_id_and_id on public.projects  (cost=0.44..2.75 rows=20 width=8) (actual time=0.005..0.007 rows=6 loops=236)
                           Index Cond: (projects.namespace_id = namespaces.id)
                           Heap Fetches: 97
                           Buffers: shared hit=2067
                           I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_timelogs_on_project_id_and_spent_at on public.timelogs  (cost=0.43..0.50 rows=3 width=52) (actual time=0.003..0.003 rows=0 loops=1379)
                     Index Cond: ((timelogs.project_id = projects.id) AND (timelogs.spent_at >= '2021-03-31 23:00:00+00'::timestamp with time zone) AND (timelogs.spent_at <= '2021-05-30 22:59:59.999999+00'::timestamp with time zone))
                     Buffers: shared hit=4145
                     I/O Timings: read=0.000 write=0.000

Time: 11.195 ms
  - planning: 1.883 ms
  - execution: 9.312 ms
    - I/O read: 0.000 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 7397 (~57.80 MiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/4242/commands/14782
query {
  group(fullPath: "twitter") {
    timelogs(startDate: "2021-04-01") { nodes { 
        timeSpent
    } }
  }
}
SELECT "timelogs".* FROM "timelogs" INNER JOIN "projects" ON "projects"."id" = "timelogs"."project_id" WHERE "projects"."namespace_id" IN (WITH RECURSIVE "base_and_descendants" AS ((SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 27)
UNION
(SELECT "namespaces".* FROM "namespaces", "base_and_descendants" WHERE "namespaces"."type" = 'Group' AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT id FROM "base_and_descendants" AS "namespaces") AND (spent_at >= '2021-03-31 23:00:00') ORDER BY "timelogs"."id" DESC LIMIT 100
Limit  (cost=4146.12..4146.18 rows=24 width=52) (actual time=1.184..1.192 rows=0 loops=1)
   Buffers: shared hit=5 read=1
   I/O Timings: read=1.028 write=0.000
   ->  Sort  (cost=4146.12..4146.18 rows=24 width=52) (actual time=1.181..1.188 rows=0 loops=1)
         Sort Key: timelogs.id DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=5 read=1
         I/O Timings: read=1.028 write=0.000
         ->  Nested Loop  (cost=1591.61..4145.57 rows=24 width=52) (actual time=1.123..1.130 rows=0 loops=1)
               Buffers: shared hit=2 read=1
               I/O Timings: read=1.028 write=0.000
               ->  Nested Loop  (cost=1591.18..2155.36 rows=3790 width=4) (actual time=1.122..1.128 rows=0 loops=1)
                     Buffers: shared hit=2 read=1
                     I/O Timings: read=1.028 write=0.000
                     ->  HashAggregate  (cost=1590.74..1592.65 rows=191 width=4) (actual time=1.121..1.125 rows=0 loops=1)
                           Group Key: namespaces.id
                           Buffers: shared hit=2 read=1
                           I/O Timings: read=1.028 write=0.000
                           ->  CTE Scan on base_and_descendants namespaces  (cost=1584.53..1588.35 rows=191 width=4) (actual time=1.115..1.120 rows=0 loops=1)
                                 Buffers: shared hit=2 read=1
                                 I/O Timings: read=1.028 write=0.000
                                 CTE base_and_descendants
                                   ->  Recursive Union  (cost=0.43..1584.53 rows=191 width=349) (actual time=1.113..1.116 rows=0 loops=1)
                                         Buffers: shared hit=2 read=1
                                         I/O Timings: read=1.028 write=0.000
                                         ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=349) (actual time=1.100..1.101 rows=0 loops=1)
                                               Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 27))
                                               Buffers: shared hit=2 read=1
                                               I/O Timings: read=1.028 write=0.000
                                         ->  Nested Loop  (cost=0.56..157.73 rows=19 width=349) (actual time=0.011..0.012 rows=0 loops=1)
                                               I/O Timings: read=0.000 write=0.000
                                               ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.009..0.010 rows=0 loops=1)
                                                     I/O Timings: read=0.000 write=0.000
                                               ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.73 rows=2 width=349) (actual time=0.000..0.000 rows=0 loops=0)
                                                     Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                                     Filter: ((namespaces_2.type)::text = 'Group'::text)
                                                     Rows Removed by Filter: 0
                                                     I/O Timings: read=0.000 write=0.000
                     ->  Index Only Scan using index_projects_on_namespace_id_and_id on public.projects  (cost=0.44..2.75 rows=20 width=8) (actual time=0.000..0.000 rows=0 loops=0)
                           Index Cond: (projects.namespace_id = namespaces.id)
                           Heap Fetches: 0
                           I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_timelogs_on_project_id_and_spent_at on public.timelogs  (cost=0.43..0.50 rows=3 width=52) (actual time=0.000..0.000 rows=0 loops=0)
                     Index Cond: ((timelogs.project_id = projects.id) AND (timelogs.spent_at >= '2021-03-31 23:00:00+00'::timestamp with time zone))
                     I/O Timings: read=0.000 write=0.000

Time: 3.860 ms
  - planning: 2.293 ms
  - execution: 1.567 ms
    - I/O read: 1.028 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 5 (~40.00 KiB) from the buffer pool
  - reads: 1 (~8.00 KiB) from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/4242/commands/14784
query {
  group(fullPath: "twitter") {
    timelogs(endDate: "2021-05-30") { nodes { 
        timeSpent
    } }
  }
}
SELECT "timelogs".* FROM "timelogs" INNER JOIN "projects" ON "projects"."id" = "timelogs"."project_id" WHERE "projects"."namespace_id" IN (WITH RECURSIVE "base_and_descendants" AS ((SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 27)
UNION
(SELECT "namespaces".* FROM "namespaces", "base_and_descendants" WHERE "namespaces"."type" = 'Group' AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT id FROM "base_and_descendants" AS "namespaces") AND (spent_at <= '2021-05-30 22:59:59.999999') ORDER BY "timelogs"."id" DESC LIMIT 100
 Limit  (cost=10414.78..10415.03 rows=100 width=52) (actual time=0.111..0.113 rows=0 loops=1)
   Buffers: shared hit=6
   I/O Timings: read=0.000 write=0.000
   ->  Sort  (cost=10414.78..10415.81 rows=411 width=52) (actual time=0.109..0.111 rows=0 loops=1)
         Sort Key: timelogs.id DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=6
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=1591.61..10399.07 rows=411 width=52) (actual time=0.031..0.033 rows=0 loops=1)
               Buffers: shared hit=3
               I/O Timings: read=0.000 write=0.000
               ->  Nested Loop  (cost=1591.18..2155.36 rows=3790 width=4) (actual time=0.031..0.033 rows=0 loops=1)
                     Buffers: shared hit=3
                     I/O Timings: read=0.000 write=0.000
                     ->  HashAggregate  (cost=1590.74..1592.65 rows=191 width=4) (actual time=0.031..0.032 rows=0 loops=1)
                           Group Key: namespaces.id
                           Buffers: shared hit=3
                           I/O Timings: read=0.000 write=0.000
                           ->  CTE Scan on base_and_descendants namespaces  (cost=1584.53..1588.35 rows=191 width=4) (actual time=0.029..0.030 rows=0 loops=1)
                                 Buffers: shared hit=3
                                 I/O Timings: read=0.000 write=0.000
                                 CTE base_and_descendants
                                   ->  Recursive Union  (cost=0.43..1584.53 rows=191 width=349) (actual time=0.027..0.029 rows=0 loops=1)
                                         Buffers: shared hit=3
                                         I/O Timings: read=0.000 write=0.000
                                         ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=349) (actual time=0.025..0.026 rows=0 loops=1)
                                               Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 27))
                                               Buffers: shared hit=3
                                               I/O Timings: read=0.000 write=0.000
                                         ->  Nested Loop  (cost=0.56..157.73 rows=19 width=349) (actual time=0.001..0.002 rows=0 loops=1)
                                               I/O Timings: read=0.000 write=0.000
                                               ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.001..0.001 rows=0 loops=1)
                                                     I/O Timings: read=0.000 write=0.000
                                               ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.73 rows=2 width=349) (actual time=0.000..0.000 rows=0 loops=0)
                                                     Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                                     Filter: ((namespaces_2.type)::text = 'Group'::text)
                                                     Rows Removed by Filter: 0
                                                     I/O Timings: read=0.000 write=0.000
                     ->  Index Only Scan using index_projects_on_namespace_id_and_id on public.projects  (cost=0.44..2.75 rows=20 width=8) (actual time=0.000..0.000 rows=0 loops=0)
                           Index Cond: (projects.namespace_id = namespaces.id)
                           Heap Fetches: 0
                           I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_timelogs_on_project_id_and_spent_at on public.timelogs  (cost=0.43..1.60 rows=58 width=52) (actual time=0.000..0.000 rows=0 loops=0)
                     Index Cond: ((timelogs.project_id = projects.id) AND (timelogs.spent_at <= '2021-05-30 22:59:59.999999+00'::timestamp with time zone))
                     I/O Timings: read=0.000 write=0.000

Time: 2.781 ms
  - planning: 2.350 ms
  - execution: 0.431 ms
    - I/O read: 0.000 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 6 (~48.00 KiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/4242/commands/14785
query {
  group(fullPath: "twitter") {
    timelogs { nodes { 
        timeSpent
    } }
  }
}
SELECT "timelogs".* FROM "timelogs" INNER JOIN "projects" ON "projects"."id" = "timelogs"."project_id" WHERE "projects"."namespace_id" IN (WITH RECURSIVE "base_and_descendants" AS ((SELECT "namespaces".* FROM "namespaces" WHERE "namespaces"."type" = 'Group' AND "namespaces"."id" = 27)
UNION
(SELECT "namespaces".* FROM "namespaces", "base_and_descendants" WHERE "namespaces"."type" = 'Group' AND "namespaces"."parent_id" = "base_and_descendants"."id")) SELECT id FROM "base_and_descendants" AS "namespaces") ORDER BY "timelogs"."id" DESC LIMIT 100
 Limit  (cost=12791.21..12791.46 rows=100 width=52) (actual time=0.067..0.069 rows=0 loops=1)
   Buffers: shared hit=6
   I/O Timings: read=0.000 write=0.000
   ->  Sort  (cost=12791.21..12792.74 rows=612 width=52) (actual time=0.066..0.067 rows=0 loops=1)
         Sort Key: timelogs.id DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=6
         I/O Timings: read=0.000 write=0.000
         ->  Nested Loop  (cost=1591.61..12767.82 rows=612 width=52) (actual time=0.023..0.025 rows=0 loops=1)
               Buffers: shared hit=3
               I/O Timings: read=0.000 write=0.000
               ->  Nested Loop  (cost=1591.18..2155.36 rows=3790 width=4) (actual time=0.023..0.024 rows=0 loops=1)
                     Buffers: shared hit=3
                     I/O Timings: read=0.000 write=0.000
                     ->  HashAggregate  (cost=1590.74..1592.65 rows=191 width=4) (actual time=0.023..0.024 rows=0 loops=1)
                           Group Key: namespaces.id
                           Buffers: shared hit=3
                           I/O Timings: read=0.000 write=0.000
                           ->  CTE Scan on base_and_descendants namespaces  (cost=1584.53..1588.35 rows=191 width=4) (actual time=0.021..0.022 rows=0 loops=1)
                                 Buffers: shared hit=3
                                 I/O Timings: read=0.000 write=0.000
                                 CTE base_and_descendants
                                   ->  Recursive Union  (cost=0.43..1584.53 rows=191 width=349) (actual time=0.020..0.021 rows=0 loops=1)
                                         Buffers: shared hit=3
                                         I/O Timings: read=0.000 write=0.000
                                         ->  Index Scan using index_namespaces_on_type_and_id_partial on public.namespaces namespaces_1  (cost=0.43..3.45 rows=1 width=349) (actual time=0.018..0.018 rows=0 loops=1)
                                               Index Cond: (((namespaces_1.type)::text = 'Group'::text) AND (namespaces_1.id = 27))
                                               Buffers: shared hit=3
                                               I/O Timings: read=0.000 write=0.000
                                         ->  Nested Loop  (cost=0.56..157.73 rows=19 width=349) (actual time=0.001..0.002 rows=0 loops=1)
                                               I/O Timings: read=0.000 write=0.000
                                               ->  WorkTable Scan on base_and_descendants  (cost=0.00..0.20 rows=10 width=4) (actual time=0.001..0.001 rows=0 loops=1)
                                                     I/O Timings: read=0.000 write=0.000
                                               ->  Index Scan using index_namespaces_on_parent_id_and_id on public.namespaces namespaces_2  (cost=0.56..15.73 rows=2 width=349) (actual time=0.000..0.000 rows=0 loops=0)
                                                     Index Cond: (namespaces_2.parent_id = base_and_descendants.id)
                                                     Filter: ((namespaces_2.type)::text = 'Group'::text)
                                                     Rows Removed by Filter: 0
                                                     I/O Timings: read=0.000 write=0.000
                     ->  Index Only Scan using index_projects_on_namespace_id_and_id on public.projects  (cost=0.44..2.75 rows=20 width=8) (actual time=0.000..0.000 rows=0 loops=0)
                           Index Cond: (projects.namespace_id = namespaces.id)
                           Heap Fetches: 0
                           I/O Timings: read=0.000 write=0.000
               ->  Index Scan using index_timelogs_on_project_id_and_spent_at on public.timelogs  (cost=0.43..1.94 rows=86 width=52) (actual time=0.000..0.000 rows=0 loops=0)
                     Index Cond: (timelogs.project_id = projects.id)
                     I/O Timings: read=0.000 write=0.000

Time: 2.494 ms
  - planning: 2.158 ms
  - execution: 0.336 ms
    - I/O read: 0.000 ms
    - I/O write: 0.000 ms

Shared buffers:
  - hits: 6 (~48.00 KiB) from the buffer pool
  - reads: 0 from the OS file cache, including disk I/O
  - dirtied: 0
  - writes: 0

https://postgres.ai/console/gitlab/gitlab-production-tunnel-pg12/sessions/4242/commands/14788

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.

  • 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
Edited by Lee Tickett

Merge request reports