2828
2929from synapse .api .constants import EventTypes
3030from synapse .api .errors import NotFoundError
31- from synapse .api .room_versions import EventFormatVersions
32- from synapse .events import FrozenEvent , event_type_from_format_version # noqa: F401
33- from synapse .events .snapshot import EventContext # noqa: F401
31+ from synapse .api .room_versions import (
32+ KNOWN_ROOM_VERSIONS ,
33+ EventFormatVersions ,
34+ RoomVersions ,
35+ )
36+ from synapse .events import make_event_from_dict
3437from synapse .events .utils import prune_event
3538from synapse .logging .context import LoggingContext , PreserveLoggingContext
3639from synapse .metrics .background_process_metrics import run_as_background_process
@@ -580,8 +583,49 @@ def _get_events_from_db(self, event_ids, allow_rejected=False):
580583 # of a event format version, so it must be a V1 event.
581584 format_version = EventFormatVersions .V1
582585
583- original_ev = event_type_from_format_version (format_version )(
586+ room_version_id = row ["room_version_id" ]
587+
588+ if not room_version_id :
589+ # this should only happen for out-of-band membership events
590+ if not internal_metadata .get ("out_of_band_membership" ):
591+ logger .warning (
592+ "Room %s for event %s is unknown" , d ["room_id" ], event_id
593+ )
594+ continue
595+
596+ # take a wild stab at the room version based on the event format
597+ if format_version == EventFormatVersions .V1 :
598+ room_version = RoomVersions .V1
599+ elif format_version == EventFormatVersions .V2 :
600+ room_version = RoomVersions .V3
601+ else :
602+ room_version = RoomVersions .V5
603+ else :
604+ room_version = KNOWN_ROOM_VERSIONS .get (room_version_id )
605+ if not room_version :
606+ logger .error (
607+ "Event %s in room %s has unknown room version %s" ,
608+ event_id ,
609+ d ["room_id" ],
610+ room_version_id ,
611+ )
612+ continue
613+
614+ if room_version .event_format != format_version :
615+ logger .error (
616+ "Event %s in room %s with version %s has wrong format: "
617+ "expected %s, was %s" ,
618+ event_id ,
619+ d ["room_id" ],
620+ room_version_id ,
621+ room_version .event_format ,
622+ format_version ,
623+ )
624+ continue
625+
626+ original_ev = make_event_from_dict (
584627 event_dict = d ,
628+ room_version = room_version ,
585629 internal_metadata_dict = internal_metadata ,
586630 rejected_reason = rejected_reason ,
587631 )
@@ -661,6 +705,12 @@ def _fetch_event_rows(self, txn, event_ids):
661705 of EventFormatVersions. 'None' means the event predates
662706 EventFormatVersions (so the event is format V1).
663707
708+ * room_version_id (str|None): The version of the room which contains the event.
709+ Hopefully one of RoomVersions.
710+
711+ Due to historical reasons, there may be a few events in the database which
712+ do not have an associated room; in this case None will be returned here.
713+
664714 * rejected_reason (str|None): if the event was rejected, the reason
665715 why.
666716
@@ -676,17 +726,18 @@ def _fetch_event_rows(self, txn, event_ids):
676726 """
677727 event_dict = {}
678728 for evs in batch_iter (event_ids , 200 ):
679- sql = (
680- "SELECT "
681- " e.event_id, "
682- " e.internal_metadata,"
683- " e.json,"
684- " e.format_version, "
685- " rej.reason "
686- " FROM event_json as e"
687- " LEFT JOIN rejections as rej USING (event_id)"
688- " WHERE "
689- )
729+ sql = """\
730+ SELECT
731+ e.event_id,
732+ e.internal_metadata,
733+ e.json,
734+ e.format_version,
735+ r.room_version,
736+ rej.reason
737+ FROM event_json as e
738+ LEFT JOIN rooms r USING (room_id)
739+ LEFT JOIN rejections as rej USING (event_id)
740+ WHERE """
690741
691742 clause , args = make_in_list_sql_clause (
692743 txn .database_engine , "e.event_id" , evs
@@ -701,7 +752,8 @@ def _fetch_event_rows(self, txn, event_ids):
701752 "internal_metadata" : row [1 ],
702753 "json" : row [2 ],
703754 "format_version" : row [3 ],
704- "rejected_reason" : row [4 ],
755+ "room_version_id" : row [4 ],
756+ "rejected_reason" : row [5 ],
705757 "redactions" : [],
706758 }
707759
0 commit comments