Rewrite the user_filter migration again (#6184)

you can't plausibly ALTER TABLE in sqlite, so we create the new table with the
right schema to start with.
pull/6191/head
Richard van der Hoff 2019-10-10 11:28:23 +01:00 committed by GitHub
parent da815c1f69
commit 562b4e51dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 26 deletions

1
changelog.d/6184.misc Normal file
View File

@ -0,0 +1 @@
Update `user_filters` table to have a unique index, and non-null columns. Thanks to @pik for contributing this.

View File

@ -5,42 +5,48 @@ from synapse.storage.engines import PostgresEngine
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
"""
This migration updates the user_filters table as follows:
- drops any (user_id, filter_id) duplicates
- makes the columns NON-NULLable
- turns the index into a UNIQUE index
"""
def run_upgrade(cur, database_engine, *args, **kwargs): def run_upgrade(cur, database_engine, *args, **kwargs):
pass
def run_create(cur, database_engine, *args, **kwargs):
if isinstance(database_engine, PostgresEngine): if isinstance(database_engine, PostgresEngine):
select_clause = """ select_clause = """
CREATE TEMPORARY TABLE user_filters_migration AS
SELECT DISTINCT ON (user_id, filter_id) user_id, filter_id, filter_json SELECT DISTINCT ON (user_id, filter_id) user_id, filter_id, filter_json
FROM user_filters; FROM user_filters
""" """
else: else:
select_clause = """ select_clause = """
CREATE TEMPORARY TABLE user_filters_migration AS SELECT * FROM user_filters GROUP BY user_id, filter_id
SELECT * FROM user_filters GROUP BY user_id, filter_id;
""" """
sql = ( sql = """
""" DROP TABLE IF EXISTS user_filters_migration;
BEGIN; DROP INDEX IF EXISTS user_filters_unique;
%s CREATE TABLE user_filters_migration (
DROP INDEX user_filters_by_user_id_filter_id; user_id TEXT NOT NULL,
DELETE FROM user_filters; filter_id BIGINT NOT NULL,
ALTER TABLE user_filters filter_json BYTEA NOT NULL
ALTER COLUMN user_id SET NOT NULL, );
ALTER COLUMN filter_id SET NOT NULL, INSERT INTO user_filters_migration (user_id, filter_id, filter_json)
ALTER COLUMN filter_json SET NOT NULL; %s;
INSERT INTO user_filters(user_id, filter_id, filter_json) CREATE UNIQUE INDEX user_filters_unique ON user_filters_migration
SELECT * FROM user_filters_migration; (user_id, filter_id);
DROP TABLE user_filters_migration; DROP TABLE user_filters;
CREATE UNIQUE INDEX user_filters_by_user_id_filter_id_unique ALTER TABLE user_filters_migration RENAME TO user_filters;
ON user_filters(user_id, filter_id); """ % (
END; select_clause,
"""
% select_clause
) )
if isinstance(database_engine, PostgresEngine): if isinstance(database_engine, PostgresEngine):
cur.execute(sql) cur.execute(sql)
else: else:
cur.executescript(sql) cur.executescript(sql)
def run_create(cur, database_engine, *args, **kwargs):
pass