mirror of
https://github.com/element-hq/synapse
synced 2024-06-30 14:53:29 +00:00
Add actual guranteed order for UNION
We use `union all` because we don't need any of the deduplication logic (`union` is really a union + distinct). `UNION ALL`` does preserve the ordering of the operand queries but there is no actual gurantee that it has this behavior in all scenarios so we need the extra `ORDER BY` at the bottom. See https://dba.stackexchange.com/questions/316818/are-results-from-union-all-clauses-always-appended-in-order/316835#316835
This commit is contained in:
parent
87ad458d77
commit
431b31e0f2
|
@ -920,6 +920,13 @@ class StreamWorkerStore(EventsWorkerStore, SQLBaseStore):
|
||||||
# minimum stream ordering. We then filter the results against the
|
# minimum stream ordering. We then filter the results against the
|
||||||
# token and return the first row that matches.
|
# token and return the first row that matches.
|
||||||
|
|
||||||
|
# We use `union all` because we don't need any of the deduplication logic
|
||||||
|
# (`union` is really a union + distinct). `UNION ALL`` does preserve the
|
||||||
|
# ordering of the operand queries but there is no actual gurantee that it
|
||||||
|
# has this behavior in all scenarios so we need the extra `ORDER BY` at the
|
||||||
|
# bottom.
|
||||||
|
#
|
||||||
|
# We're using the subquery syntax for SQLite compatibility.
|
||||||
sql = """
|
sql = """
|
||||||
SELECT * FROM (
|
SELECT * FROM (
|
||||||
SELECT instance_name, stream_ordering, topological_ordering, event_id
|
SELECT instance_name, stream_ordering, topological_ordering, event_id
|
||||||
|
@ -943,6 +950,7 @@ class StreamWorkerStore(EventsWorkerStore, SQLBaseStore):
|
||||||
ORDER BY stream_ordering DESC
|
ORDER BY stream_ordering DESC
|
||||||
LIMIT 1
|
LIMIT 1
|
||||||
) AS b
|
) AS b
|
||||||
|
ORDER BY stream_ordering DESC
|
||||||
"""
|
"""
|
||||||
txn.execute(
|
txn.execute(
|
||||||
sql,
|
sql,
|
||||||
|
|
|
@ -449,7 +449,7 @@ class GetLastEventInRoomBeforeStreamOrderingTestCase(HomeserverTestCase):
|
||||||
|
|
||||||
# Assemble a token that encompasses event1 -> event4 on worker1
|
# Assemble a token that encompasses event1 -> event4 on worker1
|
||||||
end_token = RoomStreamToken(
|
end_token = RoomStreamToken(
|
||||||
stream=event_pos1.stream,
|
stream=event_pos2.stream,
|
||||||
instance_map=immutabledict({"worker1": event_pos4.stream}),
|
instance_map=immutabledict({"worker1": event_pos4.stream}),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue