mirror of
https://github.com/element-hq/synapse.git
synced 2024-11-21 17:15:38 +03:00
Fix downgrading to previous version of Synapse (#15907)
We do this by marking the constraint as deferrable.
This commit is contained in:
parent
6774f265b4
commit
e55a9b3e41
5 changed files with 24 additions and 6 deletions
1
changelog.d/15907.misc
Normal file
1
changelog.d/15907.misc
Normal file
|
@ -0,0 +1 @@
|
|||
Add foreign key constraint to `event_forward_extremities`.
|
|
@ -80,10 +80,14 @@ class ForeignKeyConstraint(Constraint):
|
|||
Attributes:
|
||||
referenced_table: The "parent" table name.
|
||||
columns: The list of mappings of columns from table to referenced table
|
||||
deferred: Whether to defer checking of the constraint to the end of the
|
||||
transaction. This is useful for e.g. backwards compatibility where
|
||||
an older version inserted data in the wrong order.
|
||||
"""
|
||||
|
||||
referenced_table: str
|
||||
columns: Sequence[Tuple[str, str]]
|
||||
deferred: bool
|
||||
|
||||
def make_check_clause(self, table: str) -> str:
|
||||
join_clause = " AND ".join(
|
||||
|
@ -94,7 +98,8 @@ class ForeignKeyConstraint(Constraint):
|
|||
def make_constraint_clause_postgres(self) -> str:
|
||||
column1_list = ", ".join(col1 for col1, col2 in self.columns)
|
||||
column2_list = ", ".join(col2 for col1, col2 in self.columns)
|
||||
return f"FOREIGN KEY ({column1_list}) REFERENCES {self.referenced_table} ({column2_list})"
|
||||
defer_clause = " DEFERRABLE INITIALLY DEFERRED" if self.deferred else ""
|
||||
return f"FOREIGN KEY ({column1_list}) REFERENCES {self.referenced_table} ({column2_list}) {defer_clause}"
|
||||
|
||||
|
||||
@attr.s(auto_attribs=True)
|
||||
|
|
|
@ -146,7 +146,9 @@ class EventFederationWorkerStore(SignatureWorkerStore, EventsWorkerStore, SQLBas
|
|||
update_name="event_forward_extremities_event_id_foreign_key_constraint_update",
|
||||
table="event_forward_extremities",
|
||||
constraint_name="event_forward_extremities_event_id",
|
||||
constraint=ForeignKeyConstraint("events", [("event_id", "event_id")]),
|
||||
constraint=ForeignKeyConstraint(
|
||||
"events", [("event_id", "event_id")], deferred=True
|
||||
),
|
||||
unique_columns=("event_id", "room_id"),
|
||||
)
|
||||
|
||||
|
|
|
@ -28,19 +28,25 @@ FORWARD_EXTREMITIES_TABLE_SCHEMA = """
|
|||
event_id TEXT NOT NULL,
|
||||
room_id TEXT NOT NULL,
|
||||
UNIQUE (event_id, room_id),
|
||||
CONSTRAINT event_forward_extremities_event_id FOREIGN KEY (event_id) REFERENCES events (event_id)
|
||||
CONSTRAINT event_forward_extremities_event_id FOREIGN KEY (event_id) REFERENCES events (event_id) DEFERRABLE INITIALLY DEFERRED
|
||||
)
|
||||
"""
|
||||
|
||||
|
||||
def run_create(cur: LoggingTransaction, database_engine: BaseDatabaseEngine) -> None:
|
||||
# We mark this as a deferred constraint, as the previous version of Synapse
|
||||
# inserted the event into the forward extremities *before* the events table.
|
||||
# By marking as deferred we ensure that downgrading to the previous version
|
||||
# will continue to work.
|
||||
run_validate_constraint_and_delete_rows_schema_delta(
|
||||
cur,
|
||||
ordering=7803,
|
||||
update_name="event_forward_extremities_event_id_foreign_key_constraint_update",
|
||||
table="event_forward_extremities",
|
||||
constraint_name="event_forward_extremities_event_id",
|
||||
constraint=ForeignKeyConstraint("events", [("event_id", "event_id")]),
|
||||
constraint=ForeignKeyConstraint(
|
||||
"events", [("event_id", "event_id")], deferred=True
|
||||
),
|
||||
sqlite_table_name="event_forward_extremities2",
|
||||
sqlite_table_schema=FORWARD_EXTREMITIES_TABLE_SCHEMA,
|
||||
)
|
||||
|
|
|
@ -586,7 +586,9 @@ class BackgroundUpdateValidateConstraintTestCase(unittest.HomeserverTestCase):
|
|||
update_name="test_bg_update",
|
||||
table="test_constraint",
|
||||
constraint_name="test_constraint_name",
|
||||
constraint=ForeignKeyConstraint("base_table", [("b", "b")]),
|
||||
constraint=ForeignKeyConstraint(
|
||||
"base_table", [("b", "b")], deferred=False
|
||||
),
|
||||
sqlite_table_name="test_constraint2",
|
||||
sqlite_table_schema=table2_sqlite,
|
||||
)
|
||||
|
@ -604,7 +606,9 @@ class BackgroundUpdateValidateConstraintTestCase(unittest.HomeserverTestCase):
|
|||
"test_bg_update",
|
||||
table="test_constraint",
|
||||
constraint_name="test_constraint_name",
|
||||
constraint=ForeignKeyConstraint("base_table", [("b", "b")]),
|
||||
constraint=ForeignKeyConstraint(
|
||||
"base_table", [("b", "b")], deferred=False
|
||||
),
|
||||
unique_columns=["a"],
|
||||
)
|
||||
|
||||
|
|
Loading…
Reference in a new issue