@@ -466,17 +466,36 @@ def _get_thread_summaries_txn(
466466 ) -> Tuple [Dict [str , int ], Dict [str , str ]]:
467467 # Fetch the count of threaded events and the latest event ID.
468468 # 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+ """
480499
481500 clause , args = make_in_list_sql_clause (
482501 txn .database_engine , "relates_to_id" , event_ids
0 commit comments