1111from data_rentgen .db .models import Operation , OperationStatus , OperationType
1212from data_rentgen .db .repositories .base import Repository
1313from data_rentgen .dto import OperationDTO , PaginationDTO
14- from data_rentgen .utils .uuid import extract_timestamp_from_uuid
14+ from data_rentgen .utils .uuid import extract_timestamp_from_uuid , get_max_uuid , get_min_uuid
1515
1616insert_statement = insert (Operation ).on_conflict_do_nothing ()
1717update_statement = update (Operation )
1818
1919get_list_by_run_ids_query = select (Operation ).where (
20+ Operation .id >= bindparam ("min_id" ),
2021 Operation .created_at >= bindparam ("since" ),
2122 Operation .run_id == any_ (bindparam ("run_ids" )),
2223)
3637 func .count (Operation .id .distinct ()).label ("total_operations" ),
3738 )
3839 .where (
40+ Operation .id >= bindparam ("min_id" ),
3941 Operation .created_at >= bindparam ("since" ),
4042 Operation .run_id == any_ (bindparam ("run_ids" )),
4143 )
@@ -101,25 +103,43 @@ async def paginate(
101103 # do not use `tuple_(Operation.created_at, Operation.id).in_(...),
102104 # as this is too complex filter for Postgres to make an optimal query plan
103105 where = []
106+
107+ # created_at and id are always correlated,
108+ # and primary key starts with id, so we need to apply filter on both
109+ # to get the most optimal query plan
104110 if operation_ids :
105111 min_operation_created_at = extract_timestamp_from_uuid (min (operation_ids ))
106112 max_operation_created_at = extract_timestamp_from_uuid (max (operation_ids ))
107- min_created_at = max (since , min_operation_created_at ) if since else min_operation_created_at
108- max_created_at = min (until , max_operation_created_at ) if until else max_operation_created_at
113+ # narrow created_at range
114+ min_created_at = max (filter (None , [since , min_operation_created_at ]))
115+ max_created_at = min (filter (None , [until , max_operation_created_at ]))
109116 where = [
110117 Operation .created_at >= min_created_at ,
111118 Operation .created_at <= max_created_at ,
119+ Operation .id == any_ (list (operation_ids )), # type: ignore[arg-type]
120+ ]
121+
122+ elif run_id :
123+ run_created_at = extract_timestamp_from_uuid (run_id )
124+ # narrow created_at range
125+ min_created_at = max (filter (None , [since , run_created_at ]))
126+ where = [
127+ Operation .run_id == run_id ,
128+ Operation .created_at >= min_created_at ,
129+ Operation .id >= get_min_uuid (min_created_at ),
130+ ]
131+
132+ elif since :
133+ where = [
134+ Operation .created_at >= since ,
135+ Operation .id >= get_min_uuid (since ),
136+ ]
137+
138+ if until and not operation_ids :
139+ where += [
140+ Operation .created_at <= until ,
141+ Operation .id <= get_max_uuid (until ),
112142 ]
113- else :
114- if since :
115- where .append (Operation .created_at >= since )
116- if until :
117- where .append (Operation .created_at <= until )
118-
119- if run_id :
120- where .append (Operation .run_id == run_id )
121- if operation_ids :
122- where .append (Operation .id == any_ (list (operation_ids ))) # type: ignore[arg-type]
123143
124144 query = select (Operation ).where (* where )
125145 order_by : list [UnaryExpression ] = [Operation .created_at .desc (), Operation .id .desc ()]
@@ -151,6 +171,7 @@ async def list_by_run_ids(
151171 result = await self ._session .scalars (
152172 query ,
153173 {
174+ "min_id" : get_min_uuid (min_operation_created_at ),
154175 "since" : min_operation_created_at ,
155176 "run_ids" : list (run_ids ),
156177 },
@@ -175,11 +196,13 @@ async def get_stats_by_run_ids(self, run_ids: Collection[UUID]) -> dict[UUID, Ro
175196 if not run_ids :
176197 return {}
177198
199+ # All operations are created after run
200+ since = extract_timestamp_from_uuid (min (run_ids ))
178201 query_result = await self ._session .execute (
179202 get_stats_by_run_ids ,
180203 {
181- # All operations are created after run
182- "since " : extract_timestamp_from_uuid ( min ( run_ids ) ),
204+ "since" : since ,
205+ "min_id " : get_min_uuid ( since ),
183206 "run_ids" : list (run_ids ),
184207 },
185208 )
0 commit comments