Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Fix skipping items when paginating /relations forward. #13840

Merged
merged 11 commits into from
Sep 22, 2022
35 changes: 19 additions & 16 deletions synapse/storage/databases/main/relations.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ class _RelatedEvent:
event_id: str
# The sender of the related event.
sender: str
topological_ordering: Optional[int]
stream_ordering: int


class RelationsWorkerStore(SQLBaseStore):
Expand Down Expand Up @@ -142,31 +144,32 @@ def _get_recent_references_for_event_txn(
) -> Tuple[List[_RelatedEvent], Optional[StreamToken]]:
txn.execute(sql, where_args + [limit + 1])

last_topo_id = None
last_stream_id = None
events = []
for event_id, relation_type, sender, topo_ordering, stream_ordering in txn:
# Do not include edits for redacted events as they leak event
# content.
if not is_redacted or relation_type != RelationTypes.REPLACE:
events.append(_RelatedEvent(event_id, sender))
last_topo_id = topo_ordering
last_stream_id = stream_ordering
events.append(
_RelatedEvent(event_id, sender, topo_ordering, stream_ordering)
)

# If there are more events, generate the next pagination key.
# If there are more events, generate the next pagination key from the
# last event returned.
next_token = None
if len(events) > limit:
# If there are events we must have pulled at least one row.
assert last_topo_id is not None
assert last_stream_id is not None

# Due to how the pagination clause is generated, the stream ID is
# handled as an exclusive range when paginating forward. Correct
# for that here.
if direction == "f":
last_stream_id -= 1
events = events[:limit]

topo = events[-1].topological_ordering
toke = events[-1].stream_ordering
clokep marked this conversation as resolved.
Show resolved Hide resolved
if direction == "b":
# Tokens are positions between events.
# This token points *after* the last event in the chunk.
# We need it to point to the event before it in the chunk
# when we are going backwards so we subtract one from the
# stream part.
toke -= 1
next_key = RoomStreamToken(topo, toke)
clokep marked this conversation as resolved.
Show resolved Hide resolved

next_key = RoomStreamToken(last_topo_id, last_stream_id)
if from_token:
next_token = from_token.copy_and_replace(
StreamKeyType.ROOM, next_key
Expand Down