@@ -466,17 +466,36 @@ def _get_thread_summaries_txn(
466
466
) -> Tuple [Dict [str , int ], Dict [str , str ]]:
467
467
# Fetch the count of threaded events and the latest event ID.
468
468
# TODO Should this only allow m.room.message events.
469
- sql = """
470
- SELECT parent.event_id, child.event_id FROM events AS child
471
- INNER JOIN event_relations USING (event_id)
472
- INNER JOIN events AS parent ON
473
- parent.event_id = relates_to_id
474
- AND parent.room_id = child.room_id
475
- WHERE
476
- %s
477
- AND relation_type = ?
478
- ORDER BY child.topological_ordering DESC, child.stream_ordering DESC
479
- """
469
+ if isinstance (self .database_engine , PostgresEngine ):
470
+ # The `DISTINCT ON` clause will pick the *first* row it encounters,
471
+ # so ordering by topologica ordering + stream ordering desc will
472
+ # ensure we get the latest event in the thread.
473
+ sql = """
474
+ SELECT DISTINCT ON (parent.event_id) parent.event_id, child.event_id FROM events AS child
475
+ INNER JOIN event_relations USING (event_id)
476
+ INNER JOIN events AS parent ON
477
+ parent.event_id = relates_to_id
478
+ AND parent.room_id = child.room_id
479
+ WHERE
480
+ %s
481
+ AND relation_type = ?
482
+ ORDER BY parent.event_id, child.topological_ordering DESC, child.stream_ordering DESC
483
+ """
484
+ else :
485
+ # SQLite uses a simplified query which returns all entries for a
486
+ # thread. The first result for each thread is chosen to and subsequent
487
+ # results for a thread are ignored.
488
+ sql = """
489
+ SELECT parent.event_id, child.event_id FROM events AS child
490
+ INNER JOIN event_relations USING (event_id)
491
+ INNER JOIN events AS parent ON
492
+ parent.event_id = relates_to_id
493
+ AND parent.room_id = child.room_id
494
+ WHERE
495
+ %s
496
+ AND relation_type = ?
497
+ ORDER BY child.topological_ordering DESC, child.stream_ordering DESC
498
+ """
480
499
481
500
clause , args = make_in_list_sql_clause (
482
501
txn .database_engine , "relates_to_id" , event_ids
0 commit comments